#include "st_inlines.h"
#include "vg_manager.h"
#include "api.h"
+#include "mask.h"
#include "pipe/p_context.h"
#include "util/u_inlines.h"
#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;
}
}
+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);
#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)
{
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