diff --git a/docs/features.txt b/docs/features.txt index db67b0babbe..149a76aa5a7 100644 --- a/docs/features.txt +++ b/docs/features.txt @@ -320,7 +320,7 @@ Khronos, ARB, and OES extensions that are not part of any OpenGL or OpenGL ES ve GL_EXT_shader_framebuffer_fetch DONE (freedreno/a6xx, iris/gen9+, llvmpipe, panfrost, virgl, zink, asahi) GL_EXT_shader_framebuffer_fetch_non_coherent DONE (freedreno/a6xx, iris, llvmpipe, panfrost, virgl, zink, asahi) GL_EXT_color_buffer_half_float DONE (freedreno, iris, llvmpipe, nv50, nvc0, radeonsi, zink, crocus) - GL_EXT_depth_bounds_test DONE (nv50, nvc0, radeonsi, softpipe, zink, iris/gen12+) + GL_EXT_depth_bounds_test DONE (freedreno/a6xx, nv50, nvc0, radeonsi, softpipe, zink, iris/gen12+) GL_EXT_memory_object DONE (freedreno, radeonsi, llvmpipe, zink, d3d12, iris, crocus/gen7+) GL_EXT_memory_object_fd DONE (freedreno, radeonsi, llvmpipe, zink, iris, crocus/gen7+) GL_EXT_memory_object_win32 DONE (zink, d3d12) diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_context.h b/src/gallium/drivers/freedreno/a6xx/fd6_context.h index c6412c00e1d..1ab3fc0b44a 100644 --- a/src/gallium/drivers/freedreno/a6xx/fd6_context.h +++ b/src/gallium/drivers/freedreno/a6xx/fd6_context.h @@ -44,12 +44,13 @@ struct fd6_lrz_state { bool enable : 1; bool write : 1; bool test : 1; + bool z_bounds_enable : 1; enum fd_lrz_direction direction : 2; /* this comes from the fs program state, rather than zsa: */ enum a6xx_ztest_mode z_mode : 2; }; - uint32_t val : 7; + uint32_t val : 8; }; }; diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_emit.cc b/src/gallium/drivers/freedreno/a6xx/fd6_emit.cc index 159e15c635f..cb3147e3497 100644 --- a/src/gallium/drivers/freedreno/a6xx/fd6_emit.cc +++ b/src/gallium/drivers/freedreno/a6xx/fd6_emit.cc @@ -249,7 +249,8 @@ build_lrz(struct fd6_emit *emit) assert_dt OUT_REG(ring, A6XX_GRAS_LRZ_CNTL(.enable = lrz.enable, .lrz_write = lrz.write, .greater = lrz.direction == FD_LRZ_GREATER, - .z_test_enable = lrz.test, )); + .z_test_enable = lrz.test, + .z_bounds_enable = lrz.z_bounds_enable, )); OUT_REG(ring, A6XX_RB_LRZ_CNTL(.enable = lrz.enable, )); OUT_REG(ring, A6XX_RB_DEPTH_PLANE_CNTL(.z_mode = lrz.z_mode, )); @@ -894,8 +895,7 @@ fd6_emit_restore(struct fd_batch *batch, struct fd_ringbuffer *ring) */ WRITE(REG_A6XX_SP_TP_MODE_CNTL, 0xa0 | A6XX_SP_TP_MODE_CNTL_ISAMMODE(ISAMMODE_GL)); - WRITE(REG_A6XX_RB_Z_BOUNDS_MIN, 0); - WRITE(REG_A6XX_RB_Z_BOUNDS_MAX, 0); + OUT_REG(ring, HLSQ_CONTROL_5_REG( CHIP, .linelengthregid = INVALID_REG, diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_zsa.cc b/src/gallium/drivers/freedreno/a6xx/fd6_zsa.cc index 63de39b3d23..0f8076c03b9 100644 --- a/src/gallium/drivers/freedreno/a6xx/fd6_zsa.cc +++ b/src/gallium/drivers/freedreno/a6xx/fd6_zsa.cc @@ -32,6 +32,7 @@ #include "util/u_string.h" #include "fd6_context.h" +#include "fd6_pack.h" #include "fd6_zsa.h" /* update lza state based on stencil-test func: @@ -105,8 +106,22 @@ fd6_zsa_state_create(struct pipe_context *pctx, so->writes_zs = util_writes_depth_stencil(cso); so->writes_z = util_writes_depth(cso); - so->rb_depth_cntl |= - A6XX_RB_DEPTH_CNTL_ZFUNC((enum adreno_compare_func)cso->depth_func); /* maps 1:1 */ + enum adreno_compare_func depth_func = + (enum adreno_compare_func)cso->depth_func; /* maps 1:1 */ + + /* On some GPUs it is necessary to enable z test for depth bounds test + * when UBWC is enabled. Otherwise, the GPU would hang. FUNC_ALWAYS is + * required to pass z test. Relevant tests: + * dEQP-VK.pipeline.extended_dynamic_state.two_draws_dynamic.depth_bounds_test_disable + * dEQP-VK.dynamic_state.ds_state.depth_bounds_1 + */ + if (cso->depth_bounds_test && !cso->depth_enabled && + ctx->screen->info->a6xx.depth_bounds_require_depth_test_quirk) { + so->rb_depth_cntl |= A6XX_RB_DEPTH_CNTL_Z_TEST_ENABLE; + depth_func = FUNC_ALWAYS; + } + + so->rb_depth_cntl |= A6XX_RB_DEPTH_CNTL_ZFUNC(depth_func); if (cso->depth_enabled) { so->rb_depth_cntl |= @@ -214,8 +229,15 @@ fd6_zsa_state_create(struct pipe_context *pctx, (enum adreno_compare_func)cso->alpha_func); } + if (cso->depth_bounds_test) { + so->rb_depth_cntl |= A6XX_RB_DEPTH_CNTL_Z_BOUNDS_ENABLE | + A6XX_RB_DEPTH_CNTL_Z_READ_ENABLE; + so->lrz.z_bounds_enable = true; + } + + /* Build the four state permutations (with/without alpha/depth-clamp)*/ for (int i = 0; i < 4; i++) { - struct fd_ringbuffer *ring = fd_ringbuffer_new_object(ctx->pipe, 9 * 4); + struct fd_ringbuffer *ring = fd_ringbuffer_new_object(ctx->pipe, 12 * 4); OUT_PKT4(ring, REG_A6XX_RB_ALPHA_CONTROL, 1); OUT_RING(ring, @@ -235,6 +257,9 @@ fd6_zsa_state_create(struct pipe_context *pctx, OUT_RING(ring, so->rb_stencilmask); OUT_RING(ring, so->rb_stencilwrmask); + OUT_REG(ring, A6XX_RB_Z_BOUNDS_MIN(cso->depth_bounds_min), + A6XX_RB_Z_BOUNDS_MAX(cso->depth_bounds_max)); + so->stateobj[i] = ring; } diff --git a/src/gallium/drivers/freedreno/freedreno_screen.c b/src/gallium/drivers/freedreno/freedreno_screen.c index 36efb9221e5..619d7b4d162 100644 --- a/src/gallium/drivers/freedreno/freedreno_screen.c +++ b/src/gallium/drivers/freedreno/freedreno_screen.c @@ -255,6 +255,7 @@ fd_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) case PIPE_CAP_MULTI_DRAW_INDIRECT: case PIPE_CAP_DRAW_PARAMETERS: case PIPE_CAP_MULTI_DRAW_INDIRECT_PARAMS: + case PIPE_CAP_DEPTH_BOUNDS_TEST: return is_a6xx(screen); case PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY: