From: Chia-I Wu Date: Sat, 27 Nov 2010 19:29:55 +0000 (+0800) Subject: st/vega: vg_manager should care about only the color buffer. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=635fe3e1927f812a69a68ec3e03d9ab7a2c3a5d9;p=mesa.git st/vega: vg_manager should care about only the color buffer. Move depth/stencil buffer, blend texture view, and alpha mask view creation to vg_context.c. --- diff --git a/src/gallium/state_trackers/vega/vg_context.c b/src/gallium/state_trackers/vega/vg_context.c index b9dbc4f00b0..e76a65604be 100644 --- a/src/gallium/state_trackers/vega/vg_context.c +++ b/src/gallium/state_trackers/vega/vg_context.c @@ -34,6 +34,7 @@ #include "st_inlines.h" #include "vg_manager.h" #include "api.h" +#include "mask.h" #include "pipe/p_context.h" #include "util/u_inlines.h" @@ -44,6 +45,7 @@ #include "util/u_memory.h" #include "util/u_blit.h" #include "util/u_sampler.h" +#include "util/u_format.h" struct vg_context *_vg_context = 0; @@ -268,10 +270,192 @@ void vg_context_remove_object(struct vg_context *ctx, } } +static struct pipe_resource * +create_texture(struct pipe_context *pipe, enum pipe_format format, + VGint width, VGint height) +{ + struct pipe_resource templ; + + memset(&templ, 0, sizeof(templ)); + + if (format != PIPE_FORMAT_NONE) { + templ.format = format; + } + else { + templ.format = PIPE_FORMAT_B8G8R8A8_UNORM; + } + + templ.target = PIPE_TEXTURE_2D; + templ.width0 = width; + templ.height0 = height; + templ.depth0 = 1; + templ.last_level = 0; + + if (util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_ZS, 1)) { + templ.bind = PIPE_BIND_DEPTH_STENCIL; + } else { + templ.bind = (PIPE_BIND_DISPLAY_TARGET | + PIPE_BIND_RENDER_TARGET | + PIPE_BIND_SAMPLER_VIEW); + } + + return pipe->screen->resource_create(pipe->screen, &templ); +} + +static struct pipe_sampler_view * +create_tex_and_view(struct pipe_context *pipe, enum pipe_format format, + VGint width, VGint height) +{ + struct pipe_resource *texture; + struct pipe_sampler_view view_templ; + struct pipe_sampler_view *view; + + texture = create_texture(pipe, format, width, height); + + if (!texture) + return NULL; + + u_sampler_view_default_template(&view_templ, texture, texture->format); + view = pipe->create_sampler_view(pipe, texture, &view_templ); + /* want the texture to go away if the view is freed */ + pipe_resource_reference(&texture, NULL); + + return view; +} + +static void +vg_context_update_alpha_mask_view(struct vg_context *ctx, + uint width, uint height) +{ + struct st_framebuffer *stfb = ctx->draw_buffer; + struct pipe_sampler_view *old_sampler_view = stfb->alpha_mask_view; + struct pipe_context *pipe = ctx->pipe; + + if (old_sampler_view && + old_sampler_view->texture->width0 == width && + old_sampler_view->texture->height0 == height) + return; + + /* + we use PIPE_FORMAT_B8G8R8A8_UNORM because we want to render to + this texture and use it as a sampler, so while this wastes some + space it makes both of those a lot simpler + */ + stfb->alpha_mask_view = create_tex_and_view(pipe, + PIPE_FORMAT_B8G8R8A8_UNORM, width, height); + + if (!stfb->alpha_mask_view) { + if (old_sampler_view) + pipe_sampler_view_reference(&old_sampler_view, NULL); + return; + } + + /* XXX could this call be avoided? */ + vg_validate_state(ctx); + + /* alpha mask starts with 1.f alpha */ + mask_fill(0, 0, width, height, 1.f); + + /* if we had an old surface copy it over */ + if (old_sampler_view) { + struct pipe_subresource subsurf, subold_surf; + subsurf.face = 0; + subsurf.level = 0; + subold_surf.face = 0; + subold_surf.level = 0; + pipe->resource_copy_region(pipe, + stfb->alpha_mask_view->texture, + subsurf, + 0, 0, 0, + old_sampler_view->texture, + subold_surf, + 0, 0, 0, + MIN2(old_sampler_view->texture->width0, + stfb->alpha_mask_view->texture->width0), + MIN2(old_sampler_view->texture->height0, + stfb->alpha_mask_view->texture->height0)); + } + + /* Free the old texture + */ + if (old_sampler_view) + pipe_sampler_view_reference(&old_sampler_view, NULL); +} + +static void +vg_context_update_blend_texture_view(struct vg_context *ctx, + uint width, uint height) +{ + struct pipe_context *pipe = ctx->pipe; + struct st_framebuffer *stfb = ctx->draw_buffer; + struct pipe_sampler_view *old = stfb->blend_texture_view; + + if (old && + old->texture->width0 == width && + old->texture->height0 == height) + return; + + stfb->blend_texture_view = create_tex_and_view(pipe, + PIPE_FORMAT_B8G8R8A8_UNORM, width, height); + + pipe_sampler_view_reference(&old, NULL); +} + +static boolean +vg_context_update_depth_stencil_rb(struct vg_context * ctx, + uint width, uint height) +{ + struct st_renderbuffer *dsrb = ctx->draw_buffer->dsrb; + struct pipe_context *pipe = ctx->pipe; + unsigned surface_usage; + + if ((dsrb->width == width && dsrb->height == height) && dsrb->texture) + return FALSE; + + /* unreference existing ones */ + pipe_surface_reference(&dsrb->surface, NULL); + pipe_resource_reference(&dsrb->texture, NULL); + dsrb->width = dsrb->height = 0; + + /* Probably need dedicated flags for surface usage too: + */ + surface_usage = PIPE_BIND_DEPTH_STENCIL; /* XXX: was: RENDER_TARGET */ + + dsrb->texture = create_texture(pipe, dsrb->format, width, height); + if (!dsrb->texture) + return TRUE; + + dsrb->surface = pipe->screen->get_tex_surface(pipe->screen, + dsrb->texture, + 0, 0, 0, + surface_usage); + if (!dsrb->surface) { + pipe_resource_reference(&dsrb->texture, NULL); + return TRUE; + } + + dsrb->width = width; + dsrb->height = height; + + assert(dsrb->surface->width == width); + assert(dsrb->surface->height == height); + + return TRUE; +} + void vg_validate_state(struct vg_context *ctx) { + struct st_framebuffer *stfb = ctx->draw_buffer; + vg_manager_validate_framebuffer(ctx); + if (vg_context_update_depth_stencil_rb(ctx, stfb->width, stfb->height)) + ctx->state.dirty |= DEPTH_STENCIL_DIRTY; + + /* TODO create as needed */ + vg_context_update_alpha_mask_view(ctx, stfb->width, stfb->height); + vg_context_update_blend_texture_view(ctx, stfb->width, stfb->height); + renderer_validate(ctx->renderer, ctx->state.dirty, ctx->draw_buffer, &ctx->state.vg); diff --git a/src/gallium/state_trackers/vega/vg_manager.c b/src/gallium/state_trackers/vega/vg_manager.c index 9254d7d1cfb..03c8d22ba81 100644 --- a/src/gallium/state_trackers/vega/vg_manager.c +++ b/src/gallium/state_trackers/vega/vg_manager.c @@ -33,189 +33,14 @@ #include "pipe/p_screen.h" #include "util/u_memory.h" #include "util/u_inlines.h" -#include "util/u_format.h" #include "util/u_sampler.h" #include "vg_api.h" #include "vg_manager.h" #include "vg_context.h" #include "image.h" -#include "mask.h" #include "api.h" -static struct pipe_resource * -create_texture(struct pipe_context *pipe, enum pipe_format format, - VGint width, VGint height) -{ - struct pipe_resource templ; - - memset(&templ, 0, sizeof(templ)); - - if (format != PIPE_FORMAT_NONE) { - templ.format = format; - } - else { - templ.format = PIPE_FORMAT_B8G8R8A8_UNORM; - } - - templ.target = PIPE_TEXTURE_2D; - templ.width0 = width; - templ.height0 = height; - templ.depth0 = 1; - templ.last_level = 0; - - if (util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_ZS, 1)) { - templ.bind = PIPE_BIND_DEPTH_STENCIL; - } else { - templ.bind = (PIPE_BIND_DISPLAY_TARGET | - PIPE_BIND_RENDER_TARGET | - PIPE_BIND_SAMPLER_VIEW); - } - - return pipe->screen->resource_create(pipe->screen, &templ); -} - -static struct pipe_sampler_view * -create_tex_and_view(struct pipe_context *pipe, enum pipe_format format, - VGint width, VGint height) -{ - struct pipe_resource *texture; - struct pipe_sampler_view view_templ; - struct pipe_sampler_view *view; - - texture = create_texture(pipe, format, width, height); - - if (!texture) - return NULL; - - u_sampler_view_default_template(&view_templ, texture, texture->format); - view = pipe->create_sampler_view(pipe, texture, &view_templ); - /* want the texture to go away if the view is freed */ - pipe_resource_reference(&texture, NULL); - - return view; -} - -static void -vg_context_update_alpha_mask_view(struct vg_context *ctx, - uint width, uint height) -{ - struct st_framebuffer *stfb = ctx->draw_buffer; - struct pipe_sampler_view *old_sampler_view = stfb->alpha_mask_view; - struct pipe_context *pipe = ctx->pipe; - - if (old_sampler_view && - old_sampler_view->texture->width0 == width && - old_sampler_view->texture->height0 == height) - return; - - /* - we use PIPE_FORMAT_B8G8R8A8_UNORM because we want to render to - this texture and use it as a sampler, so while this wastes some - space it makes both of those a lot simpler - */ - stfb->alpha_mask_view = create_tex_and_view(pipe, - PIPE_FORMAT_B8G8R8A8_UNORM, width, height); - - if (!stfb->alpha_mask_view) { - if (old_sampler_view) - pipe_sampler_view_reference(&old_sampler_view, NULL); - return; - } - - /* XXX could this call be avoided? */ - vg_validate_state(ctx); - - /* alpha mask starts with 1.f alpha */ - mask_fill(0, 0, width, height, 1.f); - - /* if we had an old surface copy it over */ - if (old_sampler_view) { - struct pipe_subresource subsurf, subold_surf; - subsurf.face = 0; - subsurf.level = 0; - subold_surf.face = 0; - subold_surf.level = 0; - pipe->resource_copy_region(pipe, - stfb->alpha_mask_view->texture, - subsurf, - 0, 0, 0, - old_sampler_view->texture, - subold_surf, - 0, 0, 0, - MIN2(old_sampler_view->texture->width0, - stfb->alpha_mask_view->texture->width0), - MIN2(old_sampler_view->texture->height0, - stfb->alpha_mask_view->texture->height0)); - } - - /* Free the old texture - */ - if (old_sampler_view) - pipe_sampler_view_reference(&old_sampler_view, NULL); -} - -static void -vg_context_update_blend_texture_view(struct vg_context *ctx, - uint width, uint height) -{ - struct pipe_context *pipe = ctx->pipe; - struct st_framebuffer *stfb = ctx->draw_buffer; - struct pipe_sampler_view *old = stfb->blend_texture_view; - - if (old && - old->texture->width0 == width && - old->texture->height0 == height) - return; - - stfb->blend_texture_view = create_tex_and_view(pipe, - PIPE_FORMAT_B8G8R8A8_UNORM, width, height); - - pipe_sampler_view_reference(&old, NULL); -} - -static boolean -vg_context_update_depth_stencil_rb(struct vg_context * ctx, - uint width, uint height) -{ - struct st_renderbuffer *dsrb = ctx->draw_buffer->dsrb; - struct pipe_context *pipe = ctx->pipe; - unsigned surface_usage; - - if ((dsrb->width == width && dsrb->height == height) && dsrb->texture) - return FALSE; - - /* unreference existing ones */ - pipe_surface_reference(&dsrb->surface, NULL); - pipe_resource_reference(&dsrb->texture, NULL); - dsrb->width = dsrb->height = 0; - - /* Probably need dedicated flags for surface usage too: - */ - surface_usage = PIPE_BIND_DEPTH_STENCIL; /* XXX: was: RENDER_TARGET */ - - dsrb->texture = create_texture(pipe, dsrb->format, width, height); - if (!dsrb->texture) - return TRUE; - - dsrb->surface = pipe->screen->get_tex_surface(pipe->screen, - dsrb->texture, - 0, 0, 0, - surface_usage); - if (!dsrb->surface) { - pipe_resource_reference(&dsrb->texture, NULL); - return TRUE; - } - - dsrb->width = width; - dsrb->height = height; - - assert(dsrb->surface->width == width); - assert(dsrb->surface->height == height); - - return TRUE; -} - static boolean vg_context_update_color_rb(struct vg_context *ctx, struct pipe_resource *pt) { @@ -294,15 +119,8 @@ vg_manager_validate_framebuffer(struct vg_context *ctx) stfb->height != pt->height0) ctx->state.dirty |= FRAMEBUFFER_DIRTY; - if (vg_context_update_depth_stencil_rb(ctx, pt->width0, pt->height0)) - ctx->state.dirty |= DEPTH_STENCIL_DIRTY; - stfb->width = pt->width0; stfb->height = pt->height0; - - /* TODO create as needed */ - vg_context_update_alpha_mask_view(ctx, stfb->width, stfb->height); - vg_context_update_blend_texture_view(ctx, stfb->width, stfb->height); } static void