diff options
author | Alexander von Gluck IV <[email protected]> | 2014-12-29 21:51:46 +0000 |
---|---|---|
committer | Alexander von Gluck IV <[email protected]> | 2015-01-01 21:33:36 -0500 |
commit | 290553b6d637779cb733549a582230437545d335 (patch) | |
tree | ef0d08cccb015fd247279815afb3c08b0ade74c7 /src/gallium/state_trackers/hgl/hgl.c | |
parent | b77eaafcdc1b9f050d44d46608e542a9e593da3e (diff) |
gallium/state_tracker: Rewrite Haiku's state tracker
* More gallium-like
* Leverage stamps properly and don't call mesa functions
Diffstat (limited to 'src/gallium/state_trackers/hgl/hgl.c')
-rw-r--r-- | src/gallium/state_trackers/hgl/hgl.c | 338 |
1 files changed, 191 insertions, 147 deletions
diff --git a/src/gallium/state_trackers/hgl/hgl.c b/src/gallium/state_trackers/hgl/hgl.c index 0b302903c04..b75dc26bc39 100644 --- a/src/gallium/state_trackers/hgl/hgl.c +++ b/src/gallium/state_trackers/hgl/hgl.c @@ -1,5 +1,5 @@ /* - * Copyright 2012-2013, Haiku, Inc. All Rights Reserved. + * Copyright 2012-2014, Haiku, Inc. All Rights Reserved. * Distributed under the terms of the MIT License. * * Authors: @@ -10,12 +10,11 @@ #include "GLView.h" -#include "main/context.h" -#include "main/framebuffer.h" -#include "main/renderbuffer.h" #include "pipe/p_format.h" #include "util/u_atomic.h" +#include "util/u_format.h" #include "util/u_memory.h" +#include "util/u_inlines.h" #include "hgl_context.h" @@ -30,18 +29,38 @@ #define ERROR(x...) printf("hgl:state_tracker: " x) +// Perform a safe void to hgl_context cast +static INLINE struct hgl_context* +hgl_st_context(struct st_context_iface *stctxi) +{ + struct hgl_context* context; + assert(stctxi); + context = (struct hgl_context*)stctxi->st_manager_private; + assert(context); + return context; +} + + +// Perform a safe void to hgl_buffer cast +static INLINE struct hgl_buffer* +hgl_st_framebuffer(struct st_framebuffer_iface *stfbi) +{ + struct hgl_buffer* buffer; + assert(stfbi); + buffer = (struct hgl_buffer*)stfbi->st_manager_private; + assert(buffer); + return buffer; +} + + static boolean -hgl_st_framebuffer_flush_front(struct st_context_iface *stctx, - struct st_framebuffer_iface* stfb, enum st_attachment_type statt) +hgl_st_framebuffer_flush_front(struct st_context_iface *stctxi, + struct st_framebuffer_iface* stfbi, enum st_attachment_type statt) { CALLED(); - struct hgl_context* context = (struct hgl_context*)stfb->st_manager_private; - - if (!context) { - ERROR("%s: Couldn't obtain valid hgl_context!\n", __func__); - return FALSE; - } + //struct hgl_context* context = hgl_st_context(stctxi); + //struct hgl_buffer* buffer = hgl_st_context(stfbi); #if 0 struct stw_st_framebuffer *stwfb = stw_st_framebuffer(stfb); @@ -56,77 +75,125 @@ hgl_st_framebuffer_flush_front(struct st_context_iface *stctx, } +static boolean +hgl_st_framebuffer_validate_textures(struct st_framebuffer_iface *stfbi, + unsigned width, unsigned height, unsigned mask) +{ + struct hgl_buffer* buffer; + enum st_attachment_type i; + struct pipe_resource templat; + + CALLED(); + + buffer = hgl_st_framebuffer(stfbi); + + if (buffer->width != width || buffer->height != 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; + + 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; + 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 boolean -hgl_st_framebuffer_validate(struct st_context_iface *stctx, +hgl_st_framebuffer_validate(struct st_context_iface *stctxi, struct st_framebuffer_iface *stfbi, const enum st_attachment_type *statts, unsigned count, struct pipe_resource **out) { + struct hgl_context* context; + struct hgl_buffer* buffer; + unsigned stAttachmentMask, newMask; + unsigned i; + boolean resized; + CALLED(); - if (!stfbi) { - ERROR("%s: Invalid st framebuffer interface!\n", __func__); - return FALSE; - } + context = hgl_st_context(stctxi); + buffer = hgl_st_framebuffer(stfbi); - struct hgl_context* context = (struct hgl_context*)stfbi->st_manager_private; + //int32 width = 0; + //int32 height = 0; + //get_bitmap_size(context->bitmap, &width, &height); - if (!context) { - ERROR("%s: Couldn't obtain valid hgl_context!\n", __func__); - return FALSE; - } + // Build mask of current attachments + stAttachmentMask = 0; + for (i = 0; i < count; i++) + stAttachmentMask |= 1 << statts[i]; - int32 width = 0; - int32 height = 0; - get_bitmap_size(context->bitmap, &width, &height); + newMask = stAttachmentMask & ~buffer->mask; - struct pipe_resource templat; - memset(&templat, 0, sizeof(templat)); - templat.target = PIPE_TEXTURE_RECT; - templat.width0 = width; - templat.height0 = height; - templat.depth0 = 1; - templat.array_size = 1; - templat.usage = PIPE_USAGE_DEFAULT; - - if (context->stVisual && context->manager && context->manager->screen) { - TRACE("%s: Updating resources\n", __func__); - for (unsigned i = 0; i < count; i++) { - enum pipe_format format = PIPE_FORMAT_NONE; - unsigned bind = 0; - - switch(statts[i]) { - case ST_ATTACHMENT_FRONT_LEFT: - case ST_ATTACHMENT_BACK_LEFT: - format = context->stVisual->color_format; - bind = PIPE_BIND_DISPLAY_TARGET - | PIPE_BIND_RENDER_TARGET; - break; - case ST_ATTACHMENT_DEPTH_STENCIL: - format = context->stVisual->depth_stencil_format; - bind = PIPE_BIND_DEPTH_STENCIL; - break; - case ST_ATTACHMENT_ACCUM: - format = context->stVisual->accum_format; - bind = PIPE_BIND_RENDER_TARGET; - break; - default: - format = PIPE_FORMAT_NONE; - break; - } - - if (format != PIPE_FORMAT_NONE) { - templat.format = format; - templat.bind = bind; - - struct pipe_screen* screen = context->manager->screen; - context->textures[i] = screen->resource_create(screen, &templat); - out[i] = context->textures[i]; - } - } + resized = (buffer->width != context->width) + || (buffer->height != context->height); + + if (resized || newMask) { + boolean ret; + TRACE("%s: resize event. old: %d x %d; new: %d x %d\n", __func__, + buffer->width, buffer->height, context->width, context->height); + + ret = hgl_st_framebuffer_validate_textures(stfbi, + context->width, context->height, stAttachmentMask); + + if (!ret) + return ret; + + // TODO: Simply update attachments + //if (!resized) { + + //} + } + + for (i = 0; i < count; i++) { + out[i] = NULL; + pipe_resource_reference(&out[i], buffer->textures[statts[i]]); } return TRUE; @@ -140,9 +207,6 @@ hgl_st_manager_get_param(struct st_manager *smapi, enum st_manager_param param) switch (param) { case ST_MANAGER_BROKEN_INVALIDATE: - TRACE("%s: TODO: How should we handle BROKEN_INVALIDATE calls?\n", - __func__); - // For now we force validation of the framebuffer. return 1; } @@ -156,53 +220,58 @@ hgl_st_manager_get_param(struct st_manager *smapi, enum st_manager_param param) struct hgl_buffer * hgl_create_st_framebuffer(struct hgl_context* context) { + struct hgl_buffer *buffer; CALLED(); - struct hgl_buffer *buffer = CALLOC_STRUCT(hgl_buffer); - + // Our requires before creating a framebuffer assert(context); + assert(context->screen); assert(context->stVisual); - if (buffer) { - // Copy context visual into framebuffer - memcpy(&buffer->visual, context->stVisual, sizeof(struct st_visual)); + buffer = CALLOC_STRUCT(hgl_buffer); + assert(buffer); - // calloc and configure our st_framebuffer interface - buffer->stfbi = CALLOC_STRUCT(st_framebuffer_iface); - if (!buffer->stfbi) { - ERROR("%s: Couldn't calloc framebuffer!\n", __func__); - return NULL; - } + // calloc and configure our st_framebuffer interface + buffer->stfbi = CALLOC_STRUCT(st_framebuffer_iface); + assert(buffer->stfbi); - struct st_framebuffer_iface* stfbi = buffer->stfbi; - p_atomic_set(&stfbi->stamp, 1); - stfbi->flush_front = hgl_st_framebuffer_flush_front; - stfbi->validate = hgl_st_framebuffer_validate; - stfbi->st_manager_private = (void*)context; - stfbi->visual = &buffer->visual; + // Prepare our buffer + buffer->visual = context->stVisual; + buffer->screen = context->screen; - // TODO: Do we need linked list? - } + if (context->screen->get_param(buffer->screen, PIPE_CAP_NPOT_TEXTURES)) + buffer->target = PIPE_TEXTURE_2D; + else + buffer->target = PIPE_TEXTURE_RECT; + + // Prepare our state_tracker interface + buffer->stfbi->flush_front = hgl_st_framebuffer_flush_front; + buffer->stfbi->validate = hgl_st_framebuffer_validate; + buffer->stfbi->visual = context->stVisual; + + p_atomic_set(&buffer->stfbi->stamp, 1); + buffer->stfbi->st_manager_private = (void*)buffer; - return buffer; + return buffer; } struct st_manager * -hgl_create_st_manager(struct pipe_screen* screen) +hgl_create_st_manager(struct hgl_context* context) { + struct st_manager* manager; + CALLED(); - assert(screen); - struct st_manager* manager = CALLOC_STRUCT(st_manager); + // Required things + assert(context); + assert(context->screen); - if (!manager) { - ERROR("%s: Couldn't allocate state tracker manager!\n", __func__); - return NULL; - } + manager = CALLOC_STRUCT(st_manager); + assert(manager); //manager->display = dpy; - manager->screen = screen; + manager->screen = context->screen; manager->get_param = hgl_st_manager_get_param; return manager; @@ -221,56 +290,26 @@ hgl_destroy_st_manager(struct st_manager *manager) struct st_visual* hgl_create_st_visual(ulong options) { - struct st_visual* visual = CALLOC_STRUCT(st_visual); - if (!visual) { - ERROR("%s: Couldn't allocate st_visual\n", __func__); - return NULL; - } + struct st_visual* visual; - // Calculate visual configuration - const GLboolean rgbFlag = ((options & BGL_INDEX) == 0); - const GLboolean alphaFlag = ((options & BGL_ALPHA) == BGL_ALPHA); - const GLboolean dblFlag = ((options & BGL_DOUBLE) == BGL_DOUBLE); - const GLboolean stereoFlag = false; - const GLboolean depthFlag = ((options & BGL_DEPTH) == BGL_DEPTH); - const GLboolean stencilFlag = ((options & BGL_STENCIL) == BGL_STENCIL); - const GLboolean accumFlag = ((options & BGL_ACCUM) == BGL_ACCUM); - - const GLint red = rgbFlag ? 8 : 5; - const GLint green = rgbFlag ? 8 : 5; - const GLint blue = rgbFlag ? 8 : 5; - const GLint alpha = alphaFlag ? 8 : 0; - - TRACE("rgb :\t%d\n", (bool)rgbFlag); - TRACE("alpha :\t%d\n", (bool)alphaFlag); - TRACE("dbl :\t%d\n", (bool)dblFlag); - TRACE("stereo :\t%d\n", (bool)stereoFlag); - TRACE("depth :\t%d\n", (bool)depthFlag); - TRACE("stencil :\t%d\n", (bool)stencilFlag); - TRACE("accum :\t%d\n", (bool)accumFlag); - TRACE("red :\t%d\n", red); - TRACE("green :\t%d\n", green); - TRACE("blue :\t%d\n", blue); - TRACE("alpha :\t%d\n", alpha); + CALLED(); + + visual = CALLOC_STRUCT(st_visual); + assert(visual); // Determine color format - if (red == 8) { - // Color format - if (alpha == 8) - visual->color_format = PIPE_FORMAT_B8G8R8A8_UNORM; - else - visual->color_format = PIPE_FORMAT_B8G8R8X8_UNORM; - - // Depth buffer - if (depthFlag) - visual->depth_stencil_format = PIPE_FORMAT_Z32_UNORM; - else - visual->depth_stencil_format = PIPE_FORMAT_NONE; - } else { + if ((options & BGL_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 & BGL_ALPHA) + ? PIPE_FORMAT_BGRA8888_UNORM : PIPE_FORMAT_BGRX8888_UNORM; + // TODO: Determine additional stencil formats + visual->depth_stencil_format = (options & BGL_DEPTH) + ? PIPE_FORMAT_Z24_UNORM_S8_UINT : PIPE_FORMAT_NONE; } visual->accum_format = (options & BGL_ACCUM) @@ -279,20 +318,25 @@ hgl_create_st_visual(ulong options) visual->buffer_mask |= ST_ATTACHMENT_FRONT_LEFT_MASK; visual->render_buffer = ST_ATTACHMENT_FRONT_LEFT; - if (dblFlag) { + if ((options & BGL_DOUBLE) != 0) { visual->buffer_mask |= ST_ATTACHMENT_BACK_LEFT_MASK; visual->render_buffer = ST_ATTACHMENT_BACK_LEFT; } - if (stereoFlag) { + #if 0 + if ((options & BGL_STEREO) != 0) { visual->buffer_mask |= ST_ATTACHMENT_FRONT_RIGHT_MASK; - if (dblFlag) + if ((options & BGL_DOUBLE) != 0) visual->buffer_mask |= ST_ATTACHMENT_BACK_RIGHT_MASK; } + #endif if ((options & BGL_DEPTH) || (options & BGL_STENCIL)) visual->buffer_mask |= ST_ATTACHMENT_DEPTH_STENCIL_MASK; + TRACE("%s: Visual color format: %s\n", __func__, + util_format_name(visual->color_format)); + return visual; } |