This commit is contained in:
elwrcl committed 2026-06-06 13:25:15 +03:00
1 parent 04d4dc8b09
commit 818cab85dc
12511 files changed
+6156641

No files matched your search

+2
View File
@@ -0,0 +1,2 @@
[*.{c,h,cpp,hpp}]
indent_style = tab
+378
View File
@@ -0,0 +1,378 @@
/*
* Copyright 2012-2014, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Artur Wyszynski, [email protected]
* Alexander von Gluck IV, [email protected]
*/
#include "hgl_context.h"
#include <stdio.h>
#include "util/format/u_formats.h"
#include "util/u_atomic.h"
#include "util/format/u_format.h"
#include "util/u_memory.h"
#include "util/u_inlines.h"
#include "state_tracker/st_context.h"
#if MESA_DEBUG
# define TRACE(x...) printf("hgl:frontend: " x)
# define CALLED() TRACE("CALLED: %s\n", __PRETTY_FUNCTION__)
#else
# define TRACE(x...)
# define CALLED()
#endif
#define ERROR(x...) printf("hgl:frontend: " x)
// Perform a safe void to hgl_context cast
static inline struct hgl_context*
hgl_st_context(struct st_context *st)
{
struct hgl_context* context;
assert(st);
context = (struct hgl_context*)st->frontend_context;
assert(context);
return context;
}
// Perform a safe void to hgl_buffer cast
static struct hgl_buffer*
hgl_st_framebuffer(struct pipe_frontend_drawable *drawable)
{
struct hgl_buffer* buffer;
assert(drawable);
buffer = (struct hgl_buffer*)drawable;
assert(buffer);
return buffer;
}
static bool
hgl_st_framebuffer_flush_front(struct st_context *st,
struct pipe_frontend_drawable* drawable, enum st_attachment_type statt)
{
CALLED();
struct hgl_buffer* buffer = hgl_st_framebuffer(drawable);
struct pipe_resource* ptex = buffer->textures[statt];
if (statt != ST_ATTACHMENT_FRONT_LEFT)
return false;
if (!ptex)
return true;
// TODO: pipe_context here??? Might be needed for hw renderers
buffer->screen->flush_frontbuffer(buffer->screen, NULL, ptex, 0, 0,
buffer->winsysContext, 0, NULL);
return true;
}
static bool
hgl_st_framebuffer_validate_textures(struct pipe_frontend_drawable *drawable,
unsigned width, unsigned height, unsigned mask)
{
struct hgl_buffer* buffer;
enum st_attachment_type i;
struct pipe_resource templat;
CALLED();
buffer = hgl_st_framebuffer(drawable);
if (buffer->width != width || buffer->height != height) {
TRACE("validate_textures: size changed: %d, %d -> %d, %d\n",
buffer->width, buffer->height, width, height);
for (i = 0; i < ST_ATTACHMENT_COUNT; i++)
pipe_resource_reference(&buffer->textures[i], NULL);
}
memset(&templat, 0, sizeof(templat));
templat.target = buffer->target;
templat.width0 = width;
templat.height0 = height;
templat.depth0 = 1;
templat.array_size = 1;
templat.last_level = 0;
for (i = 0; i < ST_ATTACHMENT_COUNT; i++) {
enum pipe_format format;
unsigned bind;
if (((1 << i) & buffer->visual.buffer_mask) && buffer->textures[i] == NULL) {
switch (i) {
case ST_ATTACHMENT_FRONT_LEFT:
case ST_ATTACHMENT_BACK_LEFT:
case ST_ATTACHMENT_FRONT_RIGHT:
case ST_ATTACHMENT_BACK_RIGHT:
format = buffer->visual.color_format;
bind = PIPE_BIND_DISPLAY_TARGET | PIPE_BIND_RENDER_TARGET;
break;
case ST_ATTACHMENT_DEPTH_STENCIL:
format = buffer->visual.depth_stencil_format;
bind = PIPE_BIND_DEPTH_STENCIL;
break;
default:
format = PIPE_FORMAT_NONE;
bind = 0;
break;
}
if (format != PIPE_FORMAT_NONE) {
templat.format = format;
templat.bind = bind;
TRACE("resource_create(%d, %d, %d)\n", i, format, bind);
buffer->textures[i] = buffer->screen->resource_create(buffer->screen,
&templat);
if (!buffer->textures[i])
return false;
}
}
}
buffer->width = width;
buffer->height = height;
buffer->mask = mask;
return true;
}
/**
* Called by the st manager to validate the framebuffer (allocate
* its resources).
*/
static bool
hgl_st_framebuffer_validate(struct st_context *st,
struct pipe_frontend_drawable *drawable, const enum st_attachment_type *statts,
unsigned count, struct pipe_resource **out, struct pipe_resource **resolve)
{
struct hgl_buffer* buffer;
unsigned stAttachmentMask, newMask;
unsigned i;
bool resized;
CALLED();
buffer = hgl_st_framebuffer(drawable);
// Build mask of current attachments
stAttachmentMask = 0;
for (i = 0; i < count; i++)
stAttachmentMask |= 1 << statts[i];
newMask = stAttachmentMask & ~buffer->mask;
resized = (buffer->width != buffer->newWidth)
|| (buffer->height != buffer->newHeight);
if (resized || newMask) {
bool ret;
TRACE("%s: resize event. old: %d x %d; new: %d x %d\n", __func__,
buffer->width, buffer->height, buffer->newWidth, buffer->newHeight);
ret = hgl_st_framebuffer_validate_textures(drawable,
buffer->newWidth, buffer->newHeight, stAttachmentMask);
if (!ret)
return ret;
}
for (i = 0; i < count; i++)
pipe_resource_reference(&out[i], buffer->textures[statts[i]]);
return true;
}
static int
hgl_st_manager_get_param(struct pipe_frontend_screen *fscreen, enum st_manager_param param)
{
CALLED();
switch (param) {
case ST_MANAGER_BROKEN_INVALIDATE:
return 1;
}
return 0;
}
static uint32_t hgl_fb_ID = 0;
/**
* Create new framebuffer
*/
struct hgl_buffer *
hgl_create_st_framebuffer(struct hgl_display *display, struct st_visual* visual, void *winsysContext)
{
struct hgl_buffer *buffer;
CALLED();
// Our requires before creating a framebuffer
assert(display);
assert(visual);
buffer = CALLOC_STRUCT(hgl_buffer);
assert(buffer);
// Prepare our buffer
buffer->visual = *visual;
buffer->screen = display->fscreen->screen;
buffer->winsysContext = winsysContext;
if (buffer->screen->caps.npot_textures)
buffer->target = PIPE_TEXTURE_2D;
else
buffer->target = PIPE_TEXTURE_RECT;
// Prepare our frontend interface
buffer->base.flush_front = hgl_st_framebuffer_flush_front;
buffer->base.validate = hgl_st_framebuffer_validate;
buffer->base.visual = &buffer->visual;
p_atomic_set(&buffer->base.stamp, 1);
buffer->base.ID = p_atomic_inc_return(&hgl_fb_ID);
buffer->base.fscreen = display->fscreen;
return buffer;
}
void
hgl_destroy_st_framebuffer(struct hgl_buffer *buffer)
{
CALLED();
int i;
for (i = 0; i < ST_ATTACHMENT_COUNT; i++)
pipe_resource_reference(&buffer->textures[i], NULL);
FREE(buffer);
}
struct hgl_context*
hgl_create_context(struct hgl_display *display, struct st_visual* visual, struct st_context* shared)
{
struct hgl_context* context = CALLOC_STRUCT(hgl_context);
assert(context);
context->display = display;
struct st_context_attribs attribs;
memset(&attribs, 0, sizeof(attribs));
attribs.options.force_glsl_extensions_warn = false;
attribs.profile = API_OPENGL_COMPAT;
attribs.visual = *visual;
attribs.major = 1;
attribs.minor = 0;
enum st_context_error result;
context->st = st_api_create_context(display->fscreen, &attribs, &result, shared);
if (context->st == NULL) {
FREE(context);
return NULL;
}
assert(!context->st->frontend_context);
context->st->frontend_context = (void*)context;
struct st_context *stContext = (struct st_context*)context->st;
return context;
}
void
hgl_destroy_context(struct hgl_context* context)
{
if (context->st) {
st_context_flush(context->st, 0, NULL, NULL, NULL);
st_destroy_context(context->st);
}
FREE(context);
}
void
hgl_get_st_visual(struct st_visual* visual, ulong options)
{
CALLED();
assert(visual);
// Determine color format
if ((options & HGL_INDEX) != 0) {
// Index color
visual->color_format = PIPE_FORMAT_B5G6R5_UNORM;
// TODO: Indexed color depth buffer?
visual->depth_stencil_format = PIPE_FORMAT_NONE;
} else {
// RGB color
visual->color_format = (options & HGL_ALPHA)
? PIPE_FORMAT_BGRA8888_UNORM : PIPE_FORMAT_BGRX8888_UNORM;
// TODO: Determine additional stencil formats
visual->depth_stencil_format = (options & HGL_DEPTH)
? PIPE_FORMAT_Z24_UNORM_S8_UINT : PIPE_FORMAT_NONE;
}
visual->accum_format = (options & HGL_ACCUM)
? PIPE_FORMAT_R16G16B16A16_SNORM : PIPE_FORMAT_NONE;
visual->buffer_mask |= ST_ATTACHMENT_FRONT_LEFT_MASK;
if ((options & HGL_DOUBLE) != 0) {
TRACE("double buffer enabled\n");
visual->buffer_mask |= ST_ATTACHMENT_BACK_LEFT_MASK;
}
#if 0
if ((options & HGL_STEREO) != 0) {
visual->buffer_mask |= ST_ATTACHMENT_FRONT_RIGHT_MASK;
if ((options & HGL_DOUBLE) != 0)
visual->buffer_mask |= ST_ATTACHMENT_BACK_RIGHT_MASK;
}
#endif
if ((options & HGL_DEPTH) || (options & HGL_STENCIL))
visual->buffer_mask |= ST_ATTACHMENT_DEPTH_STENCIL_MASK;
TRACE("%s: Visual color format: %s\n", __func__,
util_format_name(visual->color_format));
}
struct hgl_display*
hgl_create_display(struct pipe_screen* screen)
{
struct hgl_display* display;
display = CALLOC_STRUCT(hgl_display);
assert(display);
display->fscreen = CALLOC_STRUCT(pipe_frontend_screen);
assert(display->fscreen);
display->fscreen->screen = screen;
display->fscreen->get_param = hgl_st_manager_get_param;
// display->fscreen->st_screen is used by llvmpipe
return display;
}
void
hgl_destroy_display(struct hgl_display *display)
{
st_screen_destroy(display->fscreen);
FREE(display->fscreen);
FREE(display);
}
+96
View File
@@ -0,0 +1,96 @@
/*
* Copyright 2009-2023, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Alexander von Gluck IV, [email protected]
*/
#ifndef HGL_CONTEXT_H
#define HGL_CONTEXT_H
#include "util/u_thread.h"
#include "util/format/u_formats.h"
#include "util/compiler.h"
#include "pipe/p_screen.h"
#include "frontend/api.h"
// visual options
#define HGL_RGB 0
#define HGL_INDEX 1
#define HGL_SINGLE 0
#define HGL_DOUBLE 2
#define HGL_DIRECT 0
#define HGL_INDIRECT 4
#define HGL_ACCUM 8
#define HGL_ALPHA 16
#define HGL_DEPTH 32
#define HGL_OVERLAY 64
#define HGL_UNDERLAY 128
#define HGL_STENCIL 512
#define HGL_SHARE_CONTEXT 1024
#ifdef __cplusplus
extern "C" {
#endif
#define CONTEXT_MAX 32
typedef int64 context_id;
struct hgl_buffer
{
struct pipe_frontend_drawable base;
struct st_visual visual;
unsigned width;
unsigned height;
unsigned newWidth;
unsigned newHeight;
unsigned mask;
struct pipe_screen* screen;
void* winsysContext;
enum pipe_texture_target target;
struct pipe_resource* textures[ST_ATTACHMENT_COUNT];
};
struct hgl_display
{
mtx_t mutex;
struct pipe_frontend_screen *fscreen;
};
struct hgl_context
{
struct hgl_display* display;
struct st_context* st;
};
// hgl framebuffer
struct hgl_buffer* hgl_create_st_framebuffer(struct hgl_display *display, struct st_visual* visual, void *winsysContext);
void hgl_destroy_st_framebuffer(struct hgl_buffer *buffer);
struct hgl_context* hgl_create_context(struct hgl_display *display, struct st_visual* visual, struct st_context* shared);
void hgl_destroy_context(struct hgl_context* context);
// hgl visual
void hgl_get_st_visual(struct st_visual* visual, ulong options);
// hgl display
struct hgl_display* hgl_create_display(struct pipe_screen* screen);
void hgl_destroy_display(struct hgl_display *display);
#ifdef __cplusplus
}
#endif
#endif /* HGL_CONTEXT_H */
+17
View File
@@ -0,0 +1,17 @@
# Copyright © 2017 Dylan Baker
# SPDX-License-Identifier: MIT
files_libsthgl = files(
'hgl_context.h',
'hgl.c',
)
libsthgl = static_library(
'sthgl',
files_libsthgl,
include_directories : [
inc_include, inc_util, inc_mesa, inc_src,
inc_gallium, inc_gallium_aux
],
gnu_symbol_visibility : 'hidden',
)