From 438359597cd4254558f4d2fd5b54eb32c03e1b4c Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Sat, 27 Nov 2010 22:05:37 +0800 Subject: [PATCH] st/vega: Delay fb state update to vg_validate_state. vg_manager_validate_framebuffer should mark the fb dirty and have vg_validate_state call cso_set_framebuffer. Rename VIEWPORT_DIRTY to FRAMEBUFFER_DIRTY. --- src/gallium/state_trackers/vega/vg_context.c | 34 +++++-- src/gallium/state_trackers/vega/vg_context.h | 4 +- src/gallium/state_trackers/vega/vg_manager.c | 99 +++++++++----------- 3 files changed, 73 insertions(+), 64 deletions(-) diff --git a/src/gallium/state_trackers/vega/vg_context.c b/src/gallium/state_trackers/vega/vg_context.c index d5347838807..037505e2365 100644 --- a/src/gallium/state_trackers/vega/vg_context.c +++ b/src/gallium/state_trackers/vega/vg_context.c @@ -387,27 +387,45 @@ void vg_validate_state(struct vg_context *ctx) raster->gl_rasterization_rules = 1; cso_set_rasterizer(ctx->cso_context, &ctx->state.g3d.rasterizer); } - if ((ctx->state.dirty & VIEWPORT_DIRTY)) { + if ((ctx->state.dirty & FRAMEBUFFER_DIRTY)) { struct pipe_framebuffer_state *fb = &ctx->state.g3d.fb; - const VGint param_bytes = 8 * sizeof(VGfloat); - VGfloat vs_consts[8] = { - 2.f/fb->width, 2.f/fb->height, 1, 1, - -1, -1, 0, 0 - }; struct pipe_resource **cbuf = &ctx->vs_const_buffer; + VGfloat vs_consts[8]; + memset(fb, 0, sizeof(struct pipe_framebuffer_state)); + fb->width = ctx->draw_buffer->width; + fb->height = ctx->draw_buffer->height; + fb->nr_cbufs = 1; + fb->cbufs[0] = ctx->draw_buffer->strb->surface; + fb->zsbuf = ctx->draw_buffer->dsrb->surface; + + cso_set_framebuffer(ctx->cso_context, fb); vg_set_viewport(ctx, VEGA_Y0_BOTTOM); + /* surface coordinates to clipped coordinates */ + vs_consts[0] = 2.0f / fb->width; + vs_consts[1] = 2.0f / fb->height; + vs_consts[2] = 1.0f; + vs_consts[3] = 1.0f; + vs_consts[4] = -1.0f; + vs_consts[5] = -1.0f; + vs_consts[6] = 0.0f; + vs_consts[7] = 0.0f; + pipe_resource_reference(cbuf, NULL); *cbuf = pipe_buffer_create(ctx->pipe->screen, PIPE_BIND_CONSTANT_BUFFER, - param_bytes); + sizeof(vs_consts)); if (*cbuf) { st_no_flush_pipe_buffer_write(ctx, *cbuf, - 0, param_bytes, vs_consts); + 0, sizeof(vs_consts), vs_consts); } ctx->pipe->set_constant_buffer(ctx->pipe, PIPE_SHADER_VERTEX, 0, *cbuf); + + /* we also got a new depth buffer */ + if ((ctx->state.dirty & DEPTH_STENCIL_DIRTY)) + ctx->pipe->clear(ctx->pipe, PIPE_CLEAR_DEPTHSTENCIL, NULL, 0.0, 0); } if ((ctx->state.dirty & VS_DIRTY)) { cso_set_vertex_shader_handle(ctx->cso_context, diff --git a/src/gallium/state_trackers/vega/vg_context.h b/src/gallium/state_trackers/vega/vg_context.h index 80a6c07c693..547674bd2a2 100644 --- a/src/gallium/state_trackers/vega/vg_context.h +++ b/src/gallium/state_trackers/vega/vg_context.h @@ -81,11 +81,11 @@ enum dirty_state { NONE_DIRTY = 0<<0, BLEND_DIRTY = 1<<1, RASTERIZER_DIRTY = 1<<2, - VIEWPORT_DIRTY = 1<<3, + FRAMEBUFFER_DIRTY = 1<<3, VS_DIRTY = 1<<4, DEPTH_STENCIL_DIRTY = 1<<5, ALL_DIRTY = BLEND_DIRTY | RASTERIZER_DIRTY | - VIEWPORT_DIRTY | VS_DIRTY | DEPTH_STENCIL_DIRTY + FRAMEBUFFER_DIRTY | VS_DIRTY | DEPTH_STENCIL_DIRTY }; struct vg_context diff --git a/src/gallium/state_trackers/vega/vg_manager.c b/src/gallium/state_trackers/vega/vg_manager.c index bb15ec024f2..9254d7d1cfb 100644 --- a/src/gallium/state_trackers/vega/vg_manager.c +++ b/src/gallium/state_trackers/vega/vg_manager.c @@ -97,10 +97,17 @@ create_tex_and_view(struct pipe_context *pipe, enum pipe_format format, } static void -setup_new_alpha_mask(struct vg_context *ctx, struct st_framebuffer *stfb) +vg_context_update_alpha_mask_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_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 @@ -108,7 +115,7 @@ setup_new_alpha_mask(struct vg_context *ctx, struct st_framebuffer *stfb) space it makes both of those a lot simpler */ stfb->alpha_mask_view = create_tex_and_view(pipe, - PIPE_FORMAT_B8G8R8A8_UNORM, stfb->width, stfb->height); + PIPE_FORMAT_B8G8R8A8_UNORM, width, height); if (!stfb->alpha_mask_view) { if (old_sampler_view) @@ -120,7 +127,7 @@ setup_new_alpha_mask(struct vg_context *ctx, struct st_framebuffer *stfb) vg_validate_state(ctx); /* alpha mask starts with 1.f alpha */ - mask_fill(0, 0, stfb->width, stfb->height, 1.f); + mask_fill(0, 0, width, height, 1.f); /* if we had an old surface copy it over */ if (old_sampler_view) { @@ -148,6 +155,25 @@ setup_new_alpha_mask(struct vg_context *ctx, struct st_framebuffer *stfb) 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) @@ -220,49 +246,6 @@ vg_context_update_color_rb(struct vg_context *ctx, struct pipe_resource *pt) return TRUE; } -static void -vg_context_update_draw_buffer(struct vg_context *ctx, struct pipe_resource *pt) -{ - struct st_framebuffer *stfb = ctx->draw_buffer; - boolean new_cbuf, new_zsbuf, new_size; - - new_cbuf = vg_context_update_color_rb(ctx, pt); - new_zsbuf = - vg_context_update_depth_stencil_rb(ctx, pt->width0, pt->height0); - - new_size = (stfb->width != pt->width0 || stfb->height != pt->height0); - stfb->width = pt->width0; - stfb->height = pt->height0; - - if (new_cbuf || new_zsbuf || new_size) { - struct pipe_framebuffer_state *state = &ctx->state.g3d.fb; - - memset(state, 0, sizeof(struct pipe_framebuffer_state)); - state->width = stfb->width; - state->height = stfb->height; - state->nr_cbufs = 1; - state->cbufs[0] = stfb->strb->surface; - state->zsbuf = stfb->dsrb->surface; - - cso_set_framebuffer(ctx->cso_context, state); - } - - if (new_zsbuf || new_size) { - ctx->state.dirty |= VIEWPORT_DIRTY; - ctx->state.dirty |= DEPTH_STENCIL_DIRTY;/*to reset the scissors*/ - - ctx->pipe->clear(ctx->pipe, PIPE_CLEAR_DEPTHSTENCIL, NULL, 0.0, 0); - - /* we need all the other state already set */ - - setup_new_alpha_mask(ctx, stfb); - - pipe_sampler_view_reference( &stfb->blend_texture_view, NULL); - stfb->blend_texture_view = create_tex_and_view(ctx->pipe, - PIPE_FORMAT_B8G8R8A8_UNORM, stfb->width, stfb->height); - } -} - /** * Flush the front buffer if the current context renders to the front buffer. */ @@ -304,15 +287,23 @@ vg_manager_validate_framebuffer(struct vg_context *ctx) if (!stfb->iface->validate(stfb->iface, &stfb->strb_att, 1, &pt) || !pt) return; - /* - * unset draw_buffer_invalid first because vg_context_update_draw_buffer - * will cause the framebuffer to be validated again because of a call to - * vg_validate_state - */ p_atomic_set(&ctx->draw_buffer_invalid, FALSE); - vg_context_update_draw_buffer(ctx, pt); -} + if (vg_context_update_color_rb(ctx, pt) || + stfb->width != pt->width0 || + 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 vg_context_notify_invalid_framebuffer(struct st_context_iface *stctxi, -- 2.30.2