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.
This commit is contained in:
Chia-I Wu 2010-11-27 22:05:37 +08:00
parent 3b71cb6ad6
commit 438359597c
3 changed files with 73 additions and 64 deletions

View file

@ -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,

View file

@ -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

View file

@ -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,