mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 18:18:06 +02:00
softpipe: add support for shader stencil export capability
this allows softpipe to be used to test shader stencil ref exporting. Signed-off-by: Dave Airlie <airlied@redhat.com>
This commit is contained in:
parent
c79e681a68
commit
d8f6ef4565
5 changed files with 67 additions and 12 deletions
|
|
@ -169,9 +169,15 @@ fs_sse_run( const struct sp_fragment_shader *base,
|
|||
case TGSI_SEMANTIC_POSITION:
|
||||
{
|
||||
uint j;
|
||||
for (j = 0; j < 4; j++) {
|
||||
quad->output.depth[j] = machine->Outputs[0].xyzw[2].f[j];
|
||||
}
|
||||
for (j = 0; j < 4; j++)
|
||||
quad->output.depth[j] = machine->Outputs[i].xyzw[2].f[j];
|
||||
}
|
||||
break;
|
||||
case TGSI_SEMANTIC_STENCIL:
|
||||
{
|
||||
uint j;
|
||||
for (j = 0; j < 4; j++)
|
||||
quad->output.stencil[j] = machine->Outputs[i].xyzw[1].f[j];
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -85,6 +85,7 @@ struct quad_header_output
|
|||
/** colors in SOA format (rrrr, gggg, bbbb, aaaa) */
|
||||
float color[PIPE_MAX_COLOR_BUFS][NUM_CHANNELS][QUAD_SIZE];
|
||||
float depth[QUAD_SIZE];
|
||||
uint8_t stencil[QUAD_SIZE];
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -47,6 +47,8 @@ struct depth_data {
|
|||
unsigned bzzzz[QUAD_SIZE]; /**< Z values fetched from depth buffer */
|
||||
unsigned qzzzz[QUAD_SIZE]; /**< Z values from the quad */
|
||||
ubyte stencilVals[QUAD_SIZE];
|
||||
boolean use_shader_stencil_refs;
|
||||
ubyte shader_stencil_refs[QUAD_SIZE];
|
||||
struct softpipe_cached_tile *tile;
|
||||
};
|
||||
|
||||
|
|
@ -186,6 +188,33 @@ convert_quad_depth( struct depth_data *data,
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compute the depth_data::shader_stencil_refs[] values from the float fragment stencil values.
|
||||
*/
|
||||
static void
|
||||
convert_quad_stencil( struct depth_data *data,
|
||||
const struct quad_header *quad )
|
||||
{
|
||||
unsigned j;
|
||||
|
||||
data->use_shader_stencil_refs = TRUE;
|
||||
/* Copy quads stencil values
|
||||
*/
|
||||
switch (data->format) {
|
||||
case PIPE_FORMAT_Z24X8_UNORM:
|
||||
case PIPE_FORMAT_Z24_UNORM_S8_USCALED:
|
||||
case PIPE_FORMAT_X8Z24_UNORM:
|
||||
case PIPE_FORMAT_S8_USCALED_Z24_UNORM:
|
||||
{
|
||||
for (j = 0; j < QUAD_SIZE; j++) {
|
||||
data->shader_stencil_refs[j] = ((unsigned)(quad->output.stencil[j]));
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write data->bzzzz[] values and data->stencilVals into the Z/stencil buffer.
|
||||
|
|
@ -272,8 +301,14 @@ do_stencil_test(struct depth_data *data,
|
|||
{
|
||||
unsigned passMask = 0x0;
|
||||
unsigned j;
|
||||
ubyte refs[QUAD_SIZE];
|
||||
|
||||
ref &= valMask;
|
||||
for (j = 0; j < QUAD_SIZE; j++) {
|
||||
if (data->use_shader_stencil_refs)
|
||||
refs[j] = data->shader_stencil_refs[j] & valMask;
|
||||
else
|
||||
refs[j] = ref & valMask;
|
||||
}
|
||||
|
||||
switch (func) {
|
||||
case PIPE_FUNC_NEVER:
|
||||
|
|
@ -281,42 +316,42 @@ do_stencil_test(struct depth_data *data,
|
|||
break;
|
||||
case PIPE_FUNC_LESS:
|
||||
for (j = 0; j < QUAD_SIZE; j++) {
|
||||
if (ref < (data->stencilVals[j] & valMask)) {
|
||||
if (refs[j] < (data->stencilVals[j] & valMask)) {
|
||||
passMask |= (1 << j);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PIPE_FUNC_EQUAL:
|
||||
for (j = 0; j < QUAD_SIZE; j++) {
|
||||
if (ref == (data->stencilVals[j] & valMask)) {
|
||||
if (refs[j] == (data->stencilVals[j] & valMask)) {
|
||||
passMask |= (1 << j);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PIPE_FUNC_LEQUAL:
|
||||
for (j = 0; j < QUAD_SIZE; j++) {
|
||||
if (ref <= (data->stencilVals[j] & valMask)) {
|
||||
if (refs[j] <= (data->stencilVals[j] & valMask)) {
|
||||
passMask |= (1 << j);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PIPE_FUNC_GREATER:
|
||||
for (j = 0; j < QUAD_SIZE; j++) {
|
||||
if (ref > (data->stencilVals[j] & valMask)) {
|
||||
if (refs[j] > (data->stencilVals[j] & valMask)) {
|
||||
passMask |= (1 << j);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PIPE_FUNC_NOTEQUAL:
|
||||
for (j = 0; j < QUAD_SIZE; j++) {
|
||||
if (ref != (data->stencilVals[j] & valMask)) {
|
||||
if (refs[j] != (data->stencilVals[j] & valMask)) {
|
||||
passMask |= (1 << j);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PIPE_FUNC_GEQUAL:
|
||||
for (j = 0; j < QUAD_SIZE; j++) {
|
||||
if (ref >= (data->stencilVals[j] & valMask)) {
|
||||
if (refs[j] >= (data->stencilVals[j] & valMask)) {
|
||||
passMask |= (1 << j);
|
||||
}
|
||||
}
|
||||
|
|
@ -348,9 +383,14 @@ apply_stencil_op(struct depth_data *data,
|
|||
{
|
||||
unsigned j;
|
||||
ubyte newstencil[QUAD_SIZE];
|
||||
ubyte refs[QUAD_SIZE];
|
||||
|
||||
for (j = 0; j < QUAD_SIZE; j++) {
|
||||
newstencil[j] = data->stencilVals[j];
|
||||
if (data->use_shader_stencil_refs)
|
||||
refs[j] = data->shader_stencil_refs[j];
|
||||
else
|
||||
refs[j] = ref;
|
||||
}
|
||||
|
||||
switch (op) {
|
||||
|
|
@ -367,7 +407,7 @@ apply_stencil_op(struct depth_data *data,
|
|||
case PIPE_STENCIL_OP_REPLACE:
|
||||
for (j = 0; j < QUAD_SIZE; j++) {
|
||||
if (mask & (1 << j)) {
|
||||
newstencil[j] = ref;
|
||||
newstencil[j] = refs[j];
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
@ -688,8 +728,10 @@ depth_test_quads_fallback(struct quad_stage *qs,
|
|||
unsigned i, pass = 0;
|
||||
const struct sp_fragment_shader *fs = qs->softpipe->fs;
|
||||
boolean interp_depth = !fs->info.writes_z;
|
||||
boolean shader_stencil_ref = fs->info.writes_stencil;
|
||||
struct depth_data data;
|
||||
|
||||
data.use_shader_stencil_refs = FALSE;
|
||||
|
||||
if (qs->softpipe->depth_stencil->alpha.enabled) {
|
||||
nr = alpha_test_quads(qs, quads, nr);
|
||||
|
|
@ -716,6 +758,9 @@ depth_test_quads_fallback(struct quad_stage *qs,
|
|||
}
|
||||
|
||||
if (qs->softpipe->depth_stencil->stencil[0].enabled) {
|
||||
if (shader_stencil_ref)
|
||||
convert_quad_stencil(&data, quads[i]);
|
||||
|
||||
depth_stencil_test_quad(qs, &data, quads[i]);
|
||||
write_depth_stencil_values(&data, quads[i]);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,7 +47,8 @@ sp_build_quad_pipeline(struct softpipe_context *sp)
|
|||
sp->framebuffer.zsbuf &&
|
||||
!sp->depth_stencil->alpha.enabled &&
|
||||
!sp->fs->info.uses_kill &&
|
||||
!sp->fs->info.writes_z;
|
||||
!sp->fs->info.writes_z &&
|
||||
!sp->fs->info.writes_stencil;
|
||||
|
||||
sp->quad.first = sp->quad.blend;
|
||||
|
||||
|
|
|
|||
|
|
@ -114,6 +114,8 @@ softpipe_get_param(struct pipe_screen *screen, enum pipe_cap param)
|
|||
return 1;
|
||||
case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE:
|
||||
return 0;
|
||||
case PIPE_CAP_SHADER_STENCIL_EXPORT:
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue