util: adapt to clear interface changes
This commit is contained in:
@@ -26,8 +26,8 @@
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Blitter utility to facilitate acceleration of the clear, resource_copy_region,
|
||||
* and resource_fill_region functions.
|
||||
* Blitter utility to facilitate acceleration of the clear, clearRT, clearDS
|
||||
* resource_copy_region functions.
|
||||
*
|
||||
* @author Marek Olšák
|
||||
*/
|
||||
@@ -88,6 +88,7 @@ struct blitter_context_priv
|
||||
void *dsa_write_depth_stencil;
|
||||
void *dsa_write_depth_keep_stencil;
|
||||
void *dsa_keep_depth_stencil;
|
||||
void *dsa_keep_depth_write_stencil;
|
||||
|
||||
void *velem_state;
|
||||
|
||||
@@ -161,8 +162,12 @@ struct blitter_context *util_blitter_create(struct pipe_context *pipe)
|
||||
dsa.stencil[0].writemask = 0xff;
|
||||
ctx->dsa_write_depth_stencil =
|
||||
pipe->create_depth_stencil_alpha_state(pipe, &dsa);
|
||||
/* The DSA state objects which write depth and stencil are created
|
||||
* on-demand. */
|
||||
|
||||
|
||||
dsa.depth.enabled = 0;
|
||||
dsa.depth.writemask = 0;
|
||||
ctx->dsa_keep_depth_write_stencil =
|
||||
pipe->create_depth_stencil_alpha_state(pipe, &dsa);
|
||||
|
||||
/* sampler state */
|
||||
sampler_state = &ctx->template_sampler_state;
|
||||
@@ -234,6 +239,7 @@ void util_blitter_destroy(struct blitter_context *blitter)
|
||||
pipe->delete_depth_stencil_alpha_state(pipe,
|
||||
ctx->dsa_write_depth_keep_stencil);
|
||||
pipe->delete_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_stencil);
|
||||
pipe->delete_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_write_stencil);
|
||||
|
||||
pipe->delete_rasterizer_state(pipe, ctx->rs_state);
|
||||
pipe->delete_vs_state(pipe, ctx->vs_col);
|
||||
@@ -605,11 +611,19 @@ void util_blitter_clear(struct blitter_context *blitter,
|
||||
else
|
||||
pipe->bind_blend_state(pipe, ctx->blend_keep_color);
|
||||
|
||||
if (clear_buffers & PIPE_CLEAR_DEPTHSTENCIL) {
|
||||
if ((clear_buffers & PIPE_CLEAR_DEPTHSTENCIL) == PIPE_CLEAR_DEPTHSTENCIL) {
|
||||
sr.ref_value[0] = stencil & 0xff;
|
||||
pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_stencil);
|
||||
pipe->set_stencil_ref(pipe, &sr);
|
||||
}
|
||||
else if (clear_buffers & PIPE_CLEAR_DEPTH) {
|
||||
pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_keep_stencil);
|
||||
}
|
||||
else if (clear_buffers & PIPE_CLEAR_STENCIL) {
|
||||
sr.ref_value[0] = stencil & 0xff;
|
||||
pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_write_stencil);
|
||||
pipe->set_stencil_ref(pipe, &sr);
|
||||
}
|
||||
else
|
||||
pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
|
||||
|
||||
@@ -766,48 +780,21 @@ void util_blitter_copy_region(struct blitter_context *blitter,
|
||||
pipe_surface_reference(&dstsurf, NULL);
|
||||
}
|
||||
|
||||
/* Fill a region of a surface with a constant value. */
|
||||
void util_blitter_fill_region(struct blitter_context *blitter,
|
||||
struct pipe_resource *dst,
|
||||
struct pipe_subresource subdst,
|
||||
unsigned dstx, unsigned dsty, unsigned dstz,
|
||||
unsigned width, unsigned height,
|
||||
unsigned value)
|
||||
/* Clear a region of a color surface to a constant value. */
|
||||
void util_blitter_clearRT(struct blitter_context *blitter,
|
||||
struct pipe_surface *dstsurf,
|
||||
const float *rgba,
|
||||
unsigned dstx, unsigned dsty,
|
||||
unsigned width, unsigned height)
|
||||
{
|
||||
struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
|
||||
struct pipe_context *pipe = ctx->pipe;
|
||||
struct pipe_screen *screen = pipe->screen;
|
||||
struct pipe_surface *dstsurf;
|
||||
struct pipe_framebuffer_state fb_state;
|
||||
float rgba[4];
|
||||
ubyte ub_rgba[4] = {0};
|
||||
union util_color color;
|
||||
int i;
|
||||
|
||||
assert(dst);
|
||||
if (!dst)
|
||||
assert(dstsurf->texture);
|
||||
if (!dstsurf->texture)
|
||||
return;
|
||||
|
||||
/* check if we can render to the surface */
|
||||
if (util_format_is_depth_or_stencil(dst->format) || /* unlikely, but you never know */
|
||||
!screen->is_format_supported(screen, dst->format, dst->target,
|
||||
dst->nr_samples,
|
||||
PIPE_BIND_RENDER_TARGET, 0)) {
|
||||
util_resource_fill_region(pipe, dst, subdst, dstx, dsty, dstz,
|
||||
width, height, value);
|
||||
return;
|
||||
}
|
||||
|
||||
dstsurf = screen->get_tex_surface(screen, dst, subdst.face, subdst.level,
|
||||
dstz, PIPE_BIND_RENDER_TARGET);
|
||||
|
||||
/* unpack the color */
|
||||
color.ui = value;
|
||||
util_unpack_color_ub(dst->format, &color,
|
||||
ub_rgba, ub_rgba+1, ub_rgba+2, ub_rgba+3);
|
||||
for (i = 0; i < 4; i++)
|
||||
rgba[i] = ubyte_to_float(ub_rgba[i]);
|
||||
|
||||
/* check the saved state */
|
||||
blitter_check_saved_CSOs(ctx);
|
||||
assert(blitter->saved_fb_state.nr_cbufs != ~0);
|
||||
@@ -832,6 +819,63 @@ void util_blitter_fill_region(struct blitter_context *blitter,
|
||||
blitter_set_rectangle(ctx, 0, 0, width, height, dstsurf->width, dstsurf->height, 0);
|
||||
blitter_draw_quad(ctx);
|
||||
blitter_restore_CSOs(ctx);
|
||||
|
||||
pipe_surface_reference(&dstsurf, NULL);
|
||||
}
|
||||
|
||||
/* Clear a region of a depth stencil surface. */
|
||||
void util_blitter_clearDS(struct blitter_context *blitter,
|
||||
struct pipe_surface *dstsurf,
|
||||
unsigned clear_flags,
|
||||
double depth,
|
||||
unsigned stencil,
|
||||
unsigned dstx, unsigned dsty,
|
||||
unsigned width, unsigned height)
|
||||
{
|
||||
struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
|
||||
struct pipe_context *pipe = ctx->pipe;
|
||||
struct pipe_framebuffer_state fb_state;
|
||||
struct pipe_stencil_ref sr = { { 0 } };
|
||||
|
||||
assert(dstsurf->texture);
|
||||
if (!dstsurf->texture)
|
||||
return;
|
||||
|
||||
/* check the saved state */
|
||||
blitter_check_saved_CSOs(ctx);
|
||||
assert(blitter->saved_fb_state.nr_cbufs != ~0);
|
||||
|
||||
/* bind CSOs */
|
||||
pipe->bind_blend_state(pipe, ctx->blend_keep_color);
|
||||
if ((clear_flags & PIPE_CLEAR_DEPTHSTENCIL) == PIPE_CLEAR_DEPTHSTENCIL) {
|
||||
sr.ref_value[0] = stencil & 0xff;
|
||||
pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_stencil);
|
||||
pipe->set_stencil_ref(pipe, &sr);
|
||||
}
|
||||
else if (clear_flags & PIPE_CLEAR_DEPTH) {
|
||||
pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_keep_stencil);
|
||||
}
|
||||
else if (clear_flags & PIPE_CLEAR_STENCIL) {
|
||||
sr.ref_value[0] = stencil & 0xff;
|
||||
pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_write_stencil);
|
||||
pipe->set_stencil_ref(pipe, &sr);
|
||||
}
|
||||
else
|
||||
/* hmm that should be illegal probably, or make it a no-op somewhere */
|
||||
pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
|
||||
|
||||
pipe->bind_rasterizer_state(pipe, ctx->rs_state);
|
||||
pipe->bind_fs_state(pipe, blitter_get_fs_col(ctx, 0));
|
||||
pipe->bind_vs_state(pipe, ctx->vs_col);
|
||||
pipe->bind_vertex_elements_state(pipe, ctx->velem_state);
|
||||
|
||||
/* set a framebuffer state */
|
||||
fb_state.width = dstsurf->width;
|
||||
fb_state.height = dstsurf->height;
|
||||
fb_state.nr_cbufs = 0;
|
||||
fb_state.cbufs[0] = 0;
|
||||
fb_state.zsbuf = dstsurf;
|
||||
pipe->set_framebuffer_state(pipe, &fb_state);
|
||||
|
||||
blitter_set_rectangle(ctx, 0, 0, width, height, dstsurf->width, dstsurf->height, depth);
|
||||
blitter_draw_quad(ctx);
|
||||
blitter_restore_CSOs(ctx);
|
||||
}
|
||||
|
||||
@@ -123,22 +123,33 @@ void util_blitter_copy_region(struct blitter_context *blitter,
|
||||
boolean ignore_stencil);
|
||||
|
||||
/**
|
||||
* Fill a region of a surface with a constant value.
|
||||
*
|
||||
* If the surface cannot be rendered to or it's a depth-stencil format,
|
||||
* a software fallback path is taken.
|
||||
* Clear a region of a (color) surface to a constant value.
|
||||
*
|
||||
* These states must be saved in the blitter in addition to the state objects
|
||||
* already required to be saved:
|
||||
* - framebuffer state
|
||||
*/
|
||||
void util_blitter_fill_region(struct blitter_context *blitter,
|
||||
struct pipe_resource *dst,
|
||||
struct pipe_subresource subdst,
|
||||
unsigned dstx, unsigned dsty, unsigned dstz,
|
||||
unsigned width, unsigned height,
|
||||
unsigned value);
|
||||
void util_blitter_clearRT(struct blitter_context *blitter,
|
||||
struct pipe_surface *dst,
|
||||
const float *rgba,
|
||||
unsigned dstx, unsigned dsty,
|
||||
unsigned width, unsigned height);
|
||||
|
||||
/**
|
||||
* Clear a region of a depth-stencil surface, both stencil and depth
|
||||
* or only one of them if this is a combined depth-stencil surface.
|
||||
*
|
||||
* These states must be saved in the blitter in addition to the state objects
|
||||
* already required to be saved:
|
||||
* - framebuffer state
|
||||
*/
|
||||
void util_blitter_clearDS(struct blitter_context *blitter,
|
||||
struct pipe_surface *dst,
|
||||
unsigned clear_flags,
|
||||
double depth,
|
||||
unsigned stencil,
|
||||
unsigned dstx, unsigned dsty,
|
||||
unsigned width, unsigned height);
|
||||
|
||||
/* The functions below should be used to save currently bound constant state
|
||||
* objects inside a driver. The objects are automatically restored at the end
|
||||
|
||||
@@ -31,9 +31,6 @@
|
||||
|
||||
#include "pipe/p_context.h"
|
||||
#include "pipe/p_state.h"
|
||||
#include "util/u_pack_color.h"
|
||||
#include "util/u_rect.h"
|
||||
#include "util/u_surface.h"
|
||||
|
||||
|
||||
/**
|
||||
@@ -46,25 +43,17 @@ util_clear(struct pipe_context *pipe,
|
||||
const float *rgba, double depth, unsigned stencil)
|
||||
{
|
||||
if (buffers & PIPE_CLEAR_COLOR) {
|
||||
struct pipe_surface *ps = framebuffer->cbufs[0];
|
||||
struct pipe_subresource subdst;
|
||||
union util_color uc;
|
||||
|
||||
subdst.face = ps->face;
|
||||
subdst.level = ps->level;
|
||||
util_pack_color(rgba, ps->format, &uc);
|
||||
pipe->resource_fill_region(pipe, ps->texture, subdst, 0, 0, ps->zslice,
|
||||
ps->width, ps->height, uc.ui);
|
||||
unsigned i;
|
||||
for (i = 0; i < framebuffer->nr_cbufs; i++) {
|
||||
struct pipe_surface *ps = framebuffer->cbufs[i];
|
||||
pipe->clearRT(pipe, ps, rgba, 0, 0, ps->width, ps->height);
|
||||
}
|
||||
}
|
||||
|
||||
if (buffers & PIPE_CLEAR_DEPTHSTENCIL) {
|
||||
struct pipe_surface *ps = framebuffer->zsbuf;
|
||||
struct pipe_subresource subdst;
|
||||
|
||||
subdst.face = ps->face;
|
||||
subdst.level = ps->level;
|
||||
pipe->resource_fill_region(pipe, ps->texture, subdst, 0, 0, ps->zslice,
|
||||
ps->width, ps->height,
|
||||
util_pack_z_stencil(ps->format, depth, stencil));
|
||||
pipe->clearDS(pipe, ps, buffers & PIPE_CLEAR_DEPTHSTENCIL,
|
||||
depth, stencil,
|
||||
0, 0, ps->width, ps->height);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
#include "util/u_inlines.h"
|
||||
#include "util/u_rect.h"
|
||||
#include "util/u_surface.h"
|
||||
#include "util/u_pack_color.h"
|
||||
|
||||
|
||||
/**
|
||||
@@ -195,26 +196,33 @@ util_resource_copy_region(struct pipe_context *pipe,
|
||||
|
||||
|
||||
/**
|
||||
* Fallback for pipe->resource_fill_region() function.
|
||||
* Fallback for pipe->clearRT() function.
|
||||
* XXX this looks too hackish to be really useful.
|
||||
* cpp > 4 looks like a gross hack at best...
|
||||
* and we're missing the equivalent clearDS fallback.
|
||||
* Plus can't use these transfer fallbacks when clearing
|
||||
* multisampled surfaces for instance.
|
||||
*/
|
||||
void
|
||||
util_resource_fill_region(struct pipe_context *pipe,
|
||||
struct pipe_resource *dst,
|
||||
struct pipe_subresource subdst,
|
||||
unsigned dstx, unsigned dsty, unsigned dstz,
|
||||
unsigned width, unsigned height, unsigned value)
|
||||
util_clearRT(struct pipe_context *pipe,
|
||||
struct pipe_surface *dst,
|
||||
const float *rgba,
|
||||
unsigned dstx, unsigned dsty,
|
||||
unsigned width, unsigned height)
|
||||
{
|
||||
struct pipe_transfer *dst_trans;
|
||||
void *dst_map;
|
||||
union util_color uc;
|
||||
|
||||
assert(dst);
|
||||
if (!dst)
|
||||
assert(dst->texture);
|
||||
if (!dst->texture)
|
||||
return;
|
||||
util_pack_color(rgba, dst->texture->format, &uc);
|
||||
dst_trans = pipe_get_transfer(pipe,
|
||||
dst,
|
||||
subdst.face,
|
||||
subdst.level,
|
||||
dstz,
|
||||
dst->texture,
|
||||
dst->face,
|
||||
dst->level,
|
||||
dst->zslice,
|
||||
PIPE_TRANSFER_WRITE,
|
||||
dstx, dsty, width, height);
|
||||
|
||||
@@ -225,22 +233,26 @@ util_resource_fill_region(struct pipe_context *pipe,
|
||||
if (dst_map) {
|
||||
assert(dst_trans->stride > 0);
|
||||
|
||||
switch (util_format_get_blocksize(dst->format)) {
|
||||
switch (util_format_get_blocksize(dst->texture->format)) {
|
||||
case 1:
|
||||
case 2:
|
||||
case 4:
|
||||
util_fill_rect(dst_map, dst->format,
|
||||
dst_trans->stride,
|
||||
0, 0, width, height, value);
|
||||
util_pack_color(rgba, dst->texture->format, &uc);
|
||||
util_fill_rect(dst_map, dst->texture->format,
|
||||
dst_trans->stride,
|
||||
0, 0, width, height, uc.ui);
|
||||
break;
|
||||
case 8:
|
||||
{
|
||||
/* expand the 4-byte clear value to an 8-byte value */
|
||||
/* should probably not convert back from ubyte but not
|
||||
sure what this code really achieved since it doesn't even
|
||||
check for format type... */
|
||||
ushort *row = (ushort *) dst_map;
|
||||
ushort val0 = UBYTE_TO_USHORT((value >> 0) & 0xff);
|
||||
ushort val1 = UBYTE_TO_USHORT((value >> 8) & 0xff);
|
||||
ushort val2 = UBYTE_TO_USHORT((value >> 16) & 0xff);
|
||||
ushort val3 = UBYTE_TO_USHORT((value >> 24) & 0xff);
|
||||
ushort val0 = UBYTE_TO_USHORT((uc.ui >> 0) & 0xff);
|
||||
ushort val1 = UBYTE_TO_USHORT((uc.ui >> 8) & 0xff);
|
||||
ushort val2 = UBYTE_TO_USHORT((uc.ui >> 16) & 0xff);
|
||||
ushort val3 = UBYTE_TO_USHORT((uc.ui >> 24) & 0xff);
|
||||
unsigned i, j;
|
||||
val0 = (val0 << 8) | val0;
|
||||
val1 = (val1 << 8) | val1;
|
||||
|
||||
@@ -57,11 +57,11 @@ util_resource_copy_region(struct pipe_context *pipe,
|
||||
unsigned w, unsigned h);
|
||||
|
||||
extern void
|
||||
util_resource_fill_region(struct pipe_context *pipe,
|
||||
struct pipe_resource *dst,
|
||||
struct pipe_subresource subdst,
|
||||
unsigned dstx, unsigned dsty, unsigned dstz,
|
||||
unsigned width, unsigned height, unsigned value);
|
||||
util_clearRT(struct pipe_context *pipe,
|
||||
struct pipe_surface *dst,
|
||||
const float *rgba,
|
||||
unsigned dstx, unsigned dsty,
|
||||
unsigned width, unsigned height);
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user