softpipe: Implement GL_EXT_depth_bounds_test
This is a little bit contorted because the Z storage for the tile is either float or int depending on the Z format, so we have to be careful about types when comparing. Reviewed-by: Eric Anholt <eric@anholt.net> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/9287>
This commit is contained in:
@@ -1860,7 +1860,6 @@ spec/egl_nok_swap_region/basic: skip
|
|||||||
spec/egl_nok_texture_from_pixmap/basic: skip
|
spec/egl_nok_texture_from_pixmap/basic: skip
|
||||||
spec/ext_demote_to_helper_invocation/execution/demote: skip
|
spec/ext_demote_to_helper_invocation/execution/demote: skip
|
||||||
spec/ext_demote_to_helper_invocation/execution/demote_with_derivatives: skip
|
spec/ext_demote_to_helper_invocation/execution/demote_with_derivatives: skip
|
||||||
spec/ext_depth_bounds_test/depth_bounds: skip
|
|
||||||
spec/ext_direct_state_access/indexed-state-queries 12/getdoublei_vext: skip
|
spec/ext_direct_state_access/indexed-state-queries 12/getdoublei_vext: skip
|
||||||
spec/ext_direct_state_access/indexed-state-queries 12/getfloati_vext: skip
|
spec/ext_direct_state_access/indexed-state-queries 12/getfloati_vext: skip
|
||||||
spec/ext_direct_state_access/indexed-state-queries 12/getpointeri_vext: skip
|
spec/ext_direct_state_access/indexed-state-queries 12/getpointeri_vext: skip
|
||||||
|
@@ -747,6 +747,76 @@ alpha_test_quads(struct quad_stage *qs,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* EXT_depth_bounds_test has some careful language about precision:
|
||||||
|
*
|
||||||
|
* At what precision is the depth bounds test carried out?
|
||||||
|
*
|
||||||
|
* RESOLUTION: For the purposes of the test, the bounds are converted
|
||||||
|
* to fixed-point as though they were to be written to the depth buffer,
|
||||||
|
* and the comparison uses those quantized bounds.
|
||||||
|
*
|
||||||
|
* We choose the obvious interpretation that Z32F needs no such conversion.
|
||||||
|
*/
|
||||||
|
static unsigned
|
||||||
|
depth_bounds_test_quads(struct quad_stage *qs,
|
||||||
|
struct quad_header *quads[],
|
||||||
|
unsigned nr,
|
||||||
|
struct depth_data *data)
|
||||||
|
{
|
||||||
|
struct pipe_depth_stencil_alpha_state *dsa = qs->softpipe->depth_stencil;
|
||||||
|
unsigned i = 0, pass_nr = 0;
|
||||||
|
enum pipe_format format = util_format_get_depth_only(data->format);
|
||||||
|
double min = dsa->depth_bounds_min;
|
||||||
|
double max = dsa->depth_bounds_max;
|
||||||
|
|
||||||
|
for (i = 0; i < nr; i++) {
|
||||||
|
unsigned j = 0, passMask = 0;
|
||||||
|
|
||||||
|
get_depth_stencil_values(data, quads[i]);
|
||||||
|
|
||||||
|
if (format == PIPE_FORMAT_Z32_FLOAT) {
|
||||||
|
for (j = 0; j < TGSI_QUAD_SIZE; j++) {
|
||||||
|
double z = uif(data->bzzzz[j]);
|
||||||
|
|
||||||
|
if (z >= min && z <= max)
|
||||||
|
passMask |= (1 << j);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
unsigned imin, imax;
|
||||||
|
|
||||||
|
if (format == PIPE_FORMAT_Z16_UNORM) {
|
||||||
|
imin = ((unsigned) (min * 65535.0)) & 0xffff;
|
||||||
|
imax = ((unsigned) (max * 65535.0)) & 0xffff;
|
||||||
|
} else if (format == PIPE_FORMAT_Z32_UNORM) {
|
||||||
|
imin = (unsigned) (min * 4294967295.0);
|
||||||
|
imax = (unsigned) (max * 4294967295.0);
|
||||||
|
} else if (format == PIPE_FORMAT_Z24X8_UNORM ||
|
||||||
|
format == PIPE_FORMAT_X8Z24_UNORM) {
|
||||||
|
imin = ((unsigned) (min * 16777215.0)) & 0xffffff;
|
||||||
|
imax = ((unsigned) (max * 16777215.0)) & 0xffffff;
|
||||||
|
} else {
|
||||||
|
unreachable("Unknown depth buffer format");
|
||||||
|
}
|
||||||
|
|
||||||
|
for (j = 0; j < TGSI_QUAD_SIZE; j++) {
|
||||||
|
unsigned iz = data->bzzzz[j];
|
||||||
|
|
||||||
|
if (iz >= imin && iz <= imax)
|
||||||
|
passMask |= (1 << j);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
quads[i]->inout.mask &= passMask;
|
||||||
|
|
||||||
|
if (quads[i]->inout.mask)
|
||||||
|
quads[pass_nr++] = quads[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return pass_nr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static unsigned mask_count[16] =
|
static unsigned mask_count[16] =
|
||||||
{
|
{
|
||||||
0, /* 0x0 */
|
0, /* 0x0 */
|
||||||
@@ -781,18 +851,15 @@ depth_test_quads_fallback(struct quad_stage *qs,
|
|||||||
const struct tgsi_shader_info *fsInfo = &qs->softpipe->fs_variant->info;
|
const struct tgsi_shader_info *fsInfo = &qs->softpipe->fs_variant->info;
|
||||||
boolean interp_depth = !fsInfo->writes_z || qs->softpipe->early_depth;
|
boolean interp_depth = !fsInfo->writes_z || qs->softpipe->early_depth;
|
||||||
boolean shader_stencil_ref = fsInfo->writes_stencil;
|
boolean shader_stencil_ref = fsInfo->writes_stencil;
|
||||||
|
boolean have_zs = !!qs->softpipe->framebuffer.zsbuf;
|
||||||
struct depth_data data;
|
struct depth_data data;
|
||||||
unsigned vp_idx = quads[0]->input.viewport_index;
|
unsigned vp_idx = quads[0]->input.viewport_index;
|
||||||
|
|
||||||
data.use_shader_stencil_refs = FALSE;
|
data.use_shader_stencil_refs = FALSE;
|
||||||
|
|
||||||
if (qs->softpipe->depth_stencil->alpha_enabled) {
|
if (have_zs && (qs->softpipe->depth_stencil->depth_enabled ||
|
||||||
nr = alpha_test_quads(qs, quads, nr);
|
qs->softpipe->depth_stencil->stencil[0].enabled ||
|
||||||
}
|
qs->softpipe->depth_stencil->depth_bounds_test)) {
|
||||||
|
|
||||||
if (qs->softpipe->framebuffer.zsbuf &&
|
|
||||||
(qs->softpipe->depth_stencil->depth_enabled ||
|
|
||||||
qs->softpipe->depth_stencil->stencil[0].enabled)) {
|
|
||||||
float near_val, far_val;
|
float near_val, far_val;
|
||||||
|
|
||||||
data.ps = qs->softpipe->framebuffer.zsbuf;
|
data.ps = qs->softpipe->framebuffer.zsbuf;
|
||||||
@@ -806,7 +873,29 @@ depth_test_quads_fallback(struct quad_stage *qs,
|
|||||||
far_val = near_val + (qs->softpipe->viewports[vp_idx].scale[2] * 2.0);
|
far_val = near_val + (qs->softpipe->viewports[vp_idx].scale[2] * 2.0);
|
||||||
data.minval = MIN2(near_val, far_val);
|
data.minval = MIN2(near_val, far_val);
|
||||||
data.maxval = MAX2(near_val, far_val);
|
data.maxval = MAX2(near_val, far_val);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* EXT_depth_bounds_test says:
|
||||||
|
*
|
||||||
|
* Where should the depth bounds test take place in the OpenGL fragment
|
||||||
|
* processing pipeline?
|
||||||
|
*
|
||||||
|
* RESOLUTION: After scissor test, before alpha test. In practice,
|
||||||
|
* this is a logical placement of the test. An implementation is
|
||||||
|
* free to perform the test in a manner that is consistent with the
|
||||||
|
* specified ordering.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (have_zs && qs->softpipe->depth_stencil->depth_bounds_test) {
|
||||||
|
nr = depth_bounds_test_quads(qs, quads, nr, &data);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (qs->softpipe->depth_stencil->alpha_enabled) {
|
||||||
|
nr = alpha_test_quads(qs, quads, nr);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (have_zs && (qs->softpipe->depth_stencil->depth_enabled ||
|
||||||
|
qs->softpipe->depth_stencil->stencil[0].enabled)) {
|
||||||
for (i = 0; i < nr; i++) {
|
for (i = 0; i < nr; i++) {
|
||||||
get_depth_stencil_values(&data, quads[i]);
|
get_depth_stencil_values(&data, quads[i]);
|
||||||
|
|
||||||
@@ -915,6 +1004,8 @@ choose_depth_test(struct quad_stage *qs,
|
|||||||
|
|
||||||
boolean clipped = !qs->softpipe->rasterizer->depth_clip_near;
|
boolean clipped = !qs->softpipe->rasterizer->depth_clip_near;
|
||||||
|
|
||||||
|
boolean depth_bounds = qs->softpipe->depth_stencil->depth_bounds_test;
|
||||||
|
|
||||||
if(!qs->softpipe->framebuffer.zsbuf)
|
if(!qs->softpipe->framebuffer.zsbuf)
|
||||||
depth = depthwrite = stencil = FALSE;
|
depth = depthwrite = stencil = FALSE;
|
||||||
|
|
||||||
@@ -926,7 +1017,8 @@ choose_depth_test(struct quad_stage *qs,
|
|||||||
!depth &&
|
!depth &&
|
||||||
!occlusion &&
|
!occlusion &&
|
||||||
!clipped &&
|
!clipped &&
|
||||||
!stencil) {
|
!stencil &&
|
||||||
|
!depth_bounds) {
|
||||||
qs->run = depth_noop;
|
qs->run = depth_noop;
|
||||||
}
|
}
|
||||||
else if (!alpha &&
|
else if (!alpha &&
|
||||||
@@ -935,7 +1027,8 @@ choose_depth_test(struct quad_stage *qs,
|
|||||||
depthwrite &&
|
depthwrite &&
|
||||||
!occlusion &&
|
!occlusion &&
|
||||||
!clipped &&
|
!clipped &&
|
||||||
!stencil)
|
!stencil &&
|
||||||
|
!depth_bounds)
|
||||||
{
|
{
|
||||||
if (qs->softpipe->framebuffer.zsbuf->format == PIPE_FORMAT_Z16_UNORM) {
|
if (qs->softpipe->framebuffer.zsbuf->format == PIPE_FORMAT_Z16_UNORM) {
|
||||||
switch (depthfunc) {
|
switch (depthfunc) {
|
||||||
|
@@ -146,6 +146,7 @@ softpipe_get_param(struct pipe_screen *screen, enum pipe_cap param)
|
|||||||
case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
|
case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
|
||||||
return 1;
|
return 1;
|
||||||
case PIPE_CAP_DEPTH_CLIP_DISABLE:
|
case PIPE_CAP_DEPTH_CLIP_DISABLE:
|
||||||
|
case PIPE_CAP_DEPTH_BOUNDS_TEST:
|
||||||
return 1;
|
return 1;
|
||||||
case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS:
|
case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS:
|
||||||
return PIPE_MAX_SO_BUFFERS;
|
return PIPE_MAX_SO_BUFFERS;
|
||||||
|
Reference in New Issue
Block a user