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.
This commit is contained in:
Chia-I Wu
2010-11-28 03:29:55 +08:00
parent ee0f1ab923
commit 635fe3e192
2 changed files with 184 additions and 182 deletions
@@ -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);
@@ -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