gallium/u_blitter: accelerate stencil-only copying
This doesn't seem to be used by anything yet, but better safe than sorry. Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
@@ -79,6 +79,7 @@ struct blitter_context_priv
|
|||||||
where the index is PIPE_TEXTURE_* to be sampled. */
|
where the index is PIPE_TEXTURE_* to be sampled. */
|
||||||
void *fs_texfetch_depth[PIPE_MAX_TEXTURE_TYPES];
|
void *fs_texfetch_depth[PIPE_MAX_TEXTURE_TYPES];
|
||||||
void *fs_texfetch_depthstencil[PIPE_MAX_TEXTURE_TYPES];
|
void *fs_texfetch_depthstencil[PIPE_MAX_TEXTURE_TYPES];
|
||||||
|
void *fs_texfetch_stencil[PIPE_MAX_TEXTURE_TYPES];
|
||||||
|
|
||||||
/* Blend state. */
|
/* Blend state. */
|
||||||
void *blend_write_color; /**< blend state with writemask of RGBA */
|
void *blend_write_color; /**< blend state with writemask of RGBA */
|
||||||
@@ -322,6 +323,8 @@ void util_blitter_destroy(struct blitter_context *blitter)
|
|||||||
pipe->delete_fs_state(pipe, ctx->fs_texfetch_depth[i]);
|
pipe->delete_fs_state(pipe, ctx->fs_texfetch_depth[i]);
|
||||||
if (ctx->fs_texfetch_depthstencil[i])
|
if (ctx->fs_texfetch_depthstencil[i])
|
||||||
pipe->delete_fs_state(pipe, ctx->fs_texfetch_depthstencil[i]);
|
pipe->delete_fs_state(pipe, ctx->fs_texfetch_depthstencil[i]);
|
||||||
|
if (ctx->fs_texfetch_stencil[i])
|
||||||
|
pipe->delete_fs_state(pipe, ctx->fs_texfetch_stencil[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i <= PIPE_MAX_COLOR_BUFS; i++) {
|
for (i = 0; i <= PIPE_MAX_COLOR_BUFS; i++) {
|
||||||
@@ -746,6 +749,26 @@ void *blitter_get_fs_texfetch_depthstencil(struct blitter_context_priv *ctx,
|
|||||||
return ctx->fs_texfetch_depthstencil[tex_target];
|
return ctx->fs_texfetch_depthstencil[tex_target];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static INLINE
|
||||||
|
void *blitter_get_fs_texfetch_stencil(struct blitter_context_priv *ctx,
|
||||||
|
unsigned tex_target)
|
||||||
|
{
|
||||||
|
struct pipe_context *pipe = ctx->base.pipe;
|
||||||
|
|
||||||
|
assert(tex_target < PIPE_MAX_TEXTURE_TYPES);
|
||||||
|
|
||||||
|
/* Create the fragment shader on-demand. */
|
||||||
|
if (!ctx->fs_texfetch_stencil[tex_target]) {
|
||||||
|
unsigned tgsi_tex = pipe_tex_to_tgsi_tex(tex_target);
|
||||||
|
|
||||||
|
ctx->fs_texfetch_stencil[tex_target] =
|
||||||
|
util_make_fragment_tex_shader_writestencil(pipe, tgsi_tex,
|
||||||
|
TGSI_INTERPOLATE_LINEAR);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ctx->fs_texfetch_stencil[tex_target];
|
||||||
|
}
|
||||||
|
|
||||||
static void blitter_set_common_draw_rect_state(struct blitter_context_priv *ctx)
|
static void blitter_set_common_draw_rect_state(struct blitter_context_priv *ctx)
|
||||||
{
|
{
|
||||||
struct pipe_context *pipe = ctx->base.pipe;
|
struct pipe_context *pipe = ctx->base.pipe;
|
||||||
@@ -1056,7 +1079,10 @@ void util_blitter_copy_texture_view(struct blitter_context *blitter,
|
|||||||
pipe->bind_fs_state(pipe,
|
pipe->bind_fs_state(pipe,
|
||||||
blitter_get_fs_texfetch_depth(ctx, src_target));
|
blitter_get_fs_texfetch_depth(ctx, src_target));
|
||||||
} else { /* is_stencil */
|
} else { /* is_stencil */
|
||||||
assert(0);
|
pipe->bind_depth_stencil_alpha_state(pipe,
|
||||||
|
ctx->dsa_keep_depth_write_stencil);
|
||||||
|
pipe->bind_fs_state(pipe,
|
||||||
|
blitter_get_fs_texfetch_stencil(ctx, src_target));
|
||||||
}
|
}
|
||||||
|
|
||||||
fb_state.nr_cbufs = 0;
|
fb_state.nr_cbufs = 0;
|
||||||
|
@@ -264,6 +264,52 @@ util_make_fragment_tex_shader_writedepthstencil(struct pipe_context *pipe,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make a simple fragment texture shader which reads a texture and writes it
|
||||||
|
* as stencil.
|
||||||
|
*/
|
||||||
|
void *
|
||||||
|
util_make_fragment_tex_shader_writestencil(struct pipe_context *pipe,
|
||||||
|
unsigned tex_target,
|
||||||
|
unsigned interp_mode)
|
||||||
|
{
|
||||||
|
struct ureg_program *ureg;
|
||||||
|
struct ureg_src stencil_sampler;
|
||||||
|
struct ureg_src tex;
|
||||||
|
struct ureg_dst out, stencil;
|
||||||
|
struct ureg_src imm;
|
||||||
|
|
||||||
|
ureg = ureg_create( TGSI_PROCESSOR_FRAGMENT );
|
||||||
|
if (ureg == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
stencil_sampler = ureg_DECL_sampler( ureg, 0 );
|
||||||
|
|
||||||
|
tex = ureg_DECL_fs_input( ureg,
|
||||||
|
TGSI_SEMANTIC_GENERIC, 0,
|
||||||
|
interp_mode );
|
||||||
|
|
||||||
|
out = ureg_DECL_output( ureg,
|
||||||
|
TGSI_SEMANTIC_COLOR,
|
||||||
|
0 );
|
||||||
|
|
||||||
|
stencil = ureg_DECL_output( ureg,
|
||||||
|
TGSI_SEMANTIC_STENCIL,
|
||||||
|
0 );
|
||||||
|
|
||||||
|
imm = ureg_imm4f( ureg, 0, 0, 0, 1 );
|
||||||
|
|
||||||
|
ureg_MOV( ureg, out, imm );
|
||||||
|
|
||||||
|
ureg_TEX( ureg,
|
||||||
|
ureg_writemask(stencil, TGSI_WRITEMASK_Y),
|
||||||
|
tex_target, tex, stencil_sampler );
|
||||||
|
ureg_END( ureg );
|
||||||
|
|
||||||
|
return ureg_create_shader_and_destroy( ureg, pipe );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make simple fragment color pass-through shader.
|
* Make simple fragment color pass-through shader.
|
||||||
*/
|
*/
|
||||||
|
@@ -80,6 +80,12 @@ util_make_fragment_tex_shader_writedepthstencil(struct pipe_context *pipe,
|
|||||||
unsigned interp_mode);
|
unsigned interp_mode);
|
||||||
|
|
||||||
|
|
||||||
|
extern void *
|
||||||
|
util_make_fragment_tex_shader_writestencil(struct pipe_context *pipe,
|
||||||
|
unsigned tex_target,
|
||||||
|
unsigned interp_mode);
|
||||||
|
|
||||||
|
|
||||||
extern void *
|
extern void *
|
||||||
util_make_fragment_passthrough_shader(struct pipe_context *pipe);
|
util_make_fragment_passthrough_shader(struct pipe_context *pipe);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user