From: Zebediah Figura zfigura@codeweavers.com
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/wined3d/adapter_vk.c | 1 + dlls/wined3d/cs.c | 34 ++++++++++++++++++++ dlls/wined3d/device.c | 16 +++++++++ dlls/wined3d/directx.c | 1 + dlls/wined3d/state.c | 59 ++++++++++++---------------------- dlls/wined3d/utils.c | 2 ++ dlls/wined3d/wined3d_private.h | 21 +++++++++++- 7 files changed, 94 insertions(+), 40 deletions(-)
diff --git a/dlls/wined3d/adapter_vk.c b/dlls/wined3d/adapter_vk.c index 713aaec9e39..13f4f8c024c 100644 --- a/dlls/wined3d/adapter_vk.c +++ b/dlls/wined3d/adapter_vk.c @@ -40,6 +40,7 @@ static const struct wined3d_state_entry_template misc_state_template_vk[] = {STATE_VDECL, {STATE_VDECL, state_nop}}, {STATE_DEPTH_STENCIL, {STATE_DEPTH_STENCIL, state_nop}}, {STATE_STENCIL_REF, {STATE_STENCIL_REF, state_nop}}, + {STATE_DEPTH_BOUNDS, {STATE_DEPTH_BOUNDS, state_nop}}, {STATE_RASTERIZER, {STATE_RASTERIZER, state_nop}}, {STATE_SCISSORRECT, {STATE_SCISSORRECT, state_nop}}, {STATE_POINTSPRITECOORDORIGIN, {STATE_POINTSPRITECOORDORIGIN, state_nop}}, diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c index 4579cba27fe..bca0b017c1f 100644 --- a/dlls/wined3d/cs.c +++ b/dlls/wined3d/cs.c @@ -109,6 +109,7 @@ enum wined3d_cs_op WINED3D_CS_OP_SET_BLEND_STATE, WINED3D_CS_OP_SET_DEPTH_STENCIL_STATE, WINED3D_CS_OP_SET_RASTERIZER_STATE, + WINED3D_CS_OP_SET_DEPTH_BOUNDS, WINED3D_CS_OP_SET_RENDER_STATE, WINED3D_CS_OP_SET_TEXTURE_STATE, WINED3D_CS_OP_SET_SAMPLER_STATE, @@ -340,6 +341,13 @@ struct wined3d_cs_set_rasterizer_state struct wined3d_rasterizer_state *state; };
+struct wined3d_cs_set_depth_bounds +{ + enum wined3d_cs_op opcode; + bool enable; + float min_depth, max_depth; +}; + struct wined3d_cs_set_render_state { enum wined3d_cs_op opcode; @@ -592,6 +600,7 @@ static const char *debug_cs_op(enum wined3d_cs_op op) WINED3D_TO_STR(WINED3D_CS_OP_SET_BLEND_STATE); WINED3D_TO_STR(WINED3D_CS_OP_SET_DEPTH_STENCIL_STATE); WINED3D_TO_STR(WINED3D_CS_OP_SET_RASTERIZER_STATE); + WINED3D_TO_STR(WINED3D_CS_OP_SET_DEPTH_BOUNDS); WINED3D_TO_STR(WINED3D_CS_OP_SET_RENDER_STATE); WINED3D_TO_STR(WINED3D_CS_OP_SET_TEXTURE_STATE); WINED3D_TO_STR(WINED3D_CS_OP_SET_SAMPLER_STATE); @@ -1750,6 +1759,30 @@ void wined3d_device_context_emit_set_rasterizer_state(struct wined3d_device_cont wined3d_device_context_submit(context, WINED3D_CS_QUEUE_DEFAULT); }
+static void wined3d_cs_exec_set_depth_bounds(struct wined3d_cs *cs, const void *data) +{ + const struct wined3d_cs_set_depth_bounds *op = data; + + cs->state.depth_bounds_enable = op->enable; + cs->state.depth_bounds_min = op->min_depth; + cs->state.depth_bounds_max = op->max_depth; + device_invalidate_state(cs->c.device, STATE_DEPTH_BOUNDS); +} + +void wined3d_device_context_set_depth_bounds(struct wined3d_device_context *context, + bool enable, float min_depth, float max_depth) +{ + struct wined3d_cs_set_depth_bounds *op; + + op = wined3d_device_context_require_space(context, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); + op->opcode = WINED3D_CS_OP_SET_DEPTH_BOUNDS; + op->enable = enable; + op->min_depth = min_depth; + op->max_depth = max_depth; + + wined3d_device_context_submit(context, WINED3D_CS_QUEUE_DEFAULT); +} + static void wined3d_cs_exec_set_render_state(struct wined3d_cs *cs, const void *data) { const struct wined3d_cs_set_render_state *op = data; @@ -2846,6 +2879,7 @@ static void (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void /* WINED3D_CS_OP_SET_BLEND_STATE */ wined3d_cs_exec_set_blend_state, /* WINED3D_CS_OP_SET_DEPTH_STENCIL_STATE */ wined3d_cs_exec_set_depth_stencil_state, /* WINED3D_CS_OP_SET_RASTERIZER_STATE */ wined3d_cs_exec_set_rasterizer_state, + /* WINED3D_CS_OP_SET_DEPTH_BOUNDS */ wined3d_cs_exec_set_depth_bounds, /* WINED3D_CS_OP_SET_RENDER_STATE */ wined3d_cs_exec_set_render_state, /* WINED3D_CS_OP_SET_TEXTURE_STATE */ wined3d_cs_exec_set_texture_state, /* WINED3D_CS_OP_SET_SAMPLER_STATE */ wined3d_cs_exec_set_sampler_state, diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index b294af3c5fa..133ddd1f96e 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -3900,6 +3900,7 @@ void CDECL wined3d_device_apply_stateblock(struct wined3d_device *device, const unsigned int word_bit_count = sizeof(DWORD) * CHAR_BIT; struct wined3d_device_context *context = &device->cs->c; unsigned int i, j, start, idx; + bool set_depth_bounds = false; struct wined3d_range range; uint32_t map;
@@ -4031,6 +4032,13 @@ void CDECL wined3d_device_apply_stateblock(struct wined3d_device *device, set_rasterizer_state = TRUE; break;
+ case WINED3D_RS_ADAPTIVETESS_X: + case WINED3D_RS_ADAPTIVETESS_Z: + case WINED3D_RS_ADAPTIVETESS_W: + set_depth_bounds = true; + wined3d_device_set_render_state(device, idx, state->rs[idx]); + break; + default: wined3d_device_set_render_state(device, idx, state->rs[idx]); break; @@ -4219,6 +4227,14 @@ void CDECL wined3d_device_apply_stateblock(struct wined3d_device *device, } }
+ if (set_depth_bounds) + { + wined3d_device_context_set_depth_bounds(context, + state->rs[WINED3D_RS_ADAPTIVETESS_X] == WINED3DFMT_NVDB, + int_to_float(state->rs[WINED3D_RS_ADAPTIVETESS_Z]), + int_to_float(state->rs[WINED3D_RS_ADAPTIVETESS_W])); + } + for (i = 0; i < ARRAY_SIZE(changed->textureState); ++i) { map = changed->textureState[i]; diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c index 9b6901d25c0..abfd86a6f72 100644 --- a/dlls/wined3d/directx.c +++ b/dlls/wined3d/directx.c @@ -2750,6 +2750,7 @@ static const struct wined3d_state_entry_template misc_state_template_no3d[] = {STATE_SAMPLE_MASK, {STATE_VDECL}}, {STATE_DEPTH_STENCIL, {STATE_VDECL}}, {STATE_STENCIL_REF, {STATE_VDECL}}, + {STATE_DEPTH_BOUNDS, {STATE_VDECL}}, {STATE_STREAMSRC, {STATE_VDECL}}, {STATE_VDECL, {STATE_VDECL, state_nop}}, {STATE_RASTERIZER, {STATE_VDECL}}, diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c index a6d0b174e31..9603a750028 100644 --- a/dlls/wined3d/state.c +++ b/dlls/wined3d/state.c @@ -1210,6 +1210,24 @@ static void depth(struct wined3d_context *context, const struct wined3d_state *s checkGLcall("glDepthFunc"); }
+ if (gl_info->supported[EXT_DEPTH_BOUNDS_TEST]) + { + /* If min is larger than max, an INVALID_VALUE error is generated. + * In d3d9, the test is not performed in this case. */ + if (state->depth_bounds_enable && state->depth_bounds_min <= state->depth_bounds_max) + { + gl_info->gl_ops.gl.p_glEnable(GL_DEPTH_BOUNDS_TEST_EXT); + checkGLcall("glEnable(GL_DEPTH_BOUNDS_TEST_EXT)"); + GL_EXTCALL(glDepthBoundsEXT(state->depth_bounds_min, state->depth_bounds_max)); + checkGLcall("glDepthBoundsEXT"); + } + else + { + gl_info->gl_ops.gl.p_glDisable(GL_DEPTH_BOUNDS_TEST_EXT); + checkGLcall("glDisable(GL_DEPTH_BOUNDS_TEST_EXT)"); + } + } + if (context->last_was_rhw && !isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_PROJECTION))) context_apply_state(context, state, STATE_TRANSFORM(WINED3D_TS_PROJECTION)); } @@ -2060,44 +2078,6 @@ static void state_tessellation(struct wined3d_context *context, const struct win state->render_states[WINED3D_RS_ENABLEADAPTIVETESSELLATION]); }
-static void state_nvdb(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) -{ - const struct wined3d_gl_info *gl_info = wined3d_context_gl(context)->gl_info; - union - { - uint32_t d; - float f; - } zmin, zmax; - - if (state->render_states[WINED3D_RS_ADAPTIVETESS_X] == WINED3DFMT_NVDB) - { - zmin.d = state->render_states[WINED3D_RS_ADAPTIVETESS_Z]; - zmax.d = state->render_states[WINED3D_RS_ADAPTIVETESS_W]; - - /* If zmin is larger than zmax INVALID_VALUE error is generated. - * In d3d9 test is not performed in this case*/ - if (zmin.f <= zmax.f) - { - gl_info->gl_ops.gl.p_glEnable(GL_DEPTH_BOUNDS_TEST_EXT); - checkGLcall("glEnable(GL_DEPTH_BOUNDS_TEST_EXT)"); - GL_EXTCALL(glDepthBoundsEXT(zmin.f, zmax.f)); - checkGLcall("glDepthBoundsEXT(...)"); - } - else - { - gl_info->gl_ops.gl.p_glDisable(GL_DEPTH_BOUNDS_TEST_EXT); - checkGLcall("glDisable(GL_DEPTH_BOUNDS_TEST_EXT)"); - } - } - else - { - gl_info->gl_ops.gl.p_glDisable(GL_DEPTH_BOUNDS_TEST_EXT); - checkGLcall("glDisable(GL_DEPTH_BOUNDS_TEST_EXT)"); - } - - state_tessellation(context, state, STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION)); -} - static void state_wrapu(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { if (state->render_states[WINED3D_RS_WRAPU]) @@ -4740,6 +4720,7 @@ const struct wined3d_state_entry_template misc_state_template_gl[] = { STATE_DEPTH_STENCIL, { STATE_DEPTH_STENCIL, depth_stencil_2s }, EXT_STENCIL_TWO_SIDE }, { STATE_DEPTH_STENCIL, { STATE_DEPTH_STENCIL, depth_stencil }, WINED3D_GL_EXT_NONE }, { STATE_STENCIL_REF, { STATE_DEPTH_STENCIL, NULL }, WINED3D_GL_EXT_NONE }, + { STATE_DEPTH_BOUNDS, { STATE_DEPTH_STENCIL, NULL }, WINED3D_GL_EXT_NONE }, { STATE_STREAMSRC, { STATE_STREAMSRC, streamsrc }, WINED3D_GL_EXT_NONE }, { STATE_VDECL, { STATE_VDECL, vdecl_miscpart }, WINED3D_GL_EXT_NONE }, { STATE_RASTERIZER, { STATE_RASTERIZER, rasterizer_cc }, ARB_CLIP_CONTROL }, @@ -4853,7 +4834,6 @@ const struct wined3d_state_entry_template misc_state_template_gl[] = { STATE_RENDER(WINED3D_RS_ADAPTIVETESS_Y), { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),NULL }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_ADAPTIVETESS_Z), { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),NULL }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_ADAPTIVETESS_W), { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),NULL }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),{ STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),state_nvdb }, EXT_DEPTH_BOUNDS_TEST }, { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),{ STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),state_tessellation }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_MULTISAMPLEANTIALIAS), { STATE_RENDER(WINED3D_RS_MULTISAMPLEANTIALIAS), state_msaa }, ARB_MULTISAMPLE }, { STATE_RENDER(WINED3D_RS_MULTISAMPLEANTIALIAS), { STATE_RENDER(WINED3D_RS_MULTISAMPLEANTIALIAS), state_msaa_w }, WINED3D_GL_EXT_NONE }, @@ -5669,6 +5649,7 @@ static void validate_state_table(struct wined3d_state_entry *state_table) STATE_BLEND_FACTOR, STATE_DEPTH_STENCIL, STATE_STENCIL_REF, + STATE_DEPTH_BOUNDS, }; unsigned int i, current;
diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c index fb350acf56f..d6e9fed06bf 100644 --- a/dlls/wined3d/utils.c +++ b/dlls/wined3d/utils.c @@ -5416,6 +5416,8 @@ const char *debug_d3dstate(uint32_t state) return "STATE_MATERIAL"; if (STATE_IS_RASTERIZER(state)) return "STATE_RASTERIZER"; + if (STATE_IS_DEPTH_BOUNDS(state)) + return "STATE_DEPTH_BOUNDS"; if (STATE_IS_POINTSPRITECOORDORIGIN(state)) return "STATE_POINTSPRITECOORDORIGIN"; if (STATE_IS_BASEVERTEXINDEX(state)) diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 7abf77bb445..459ac7a19c8 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -62,6 +62,18 @@ static inline size_t align(size_t addr, size_t alignment) return (addr + (alignment - 1)) & ~(alignment - 1); }
+static inline float int_to_float(uint32_t i) +{ + union + { + uint32_t u; + float f; + } u; + + u.u = i; + return u.f; +} + #define MAKEDWORD_VERSION(maj, min) (((maj & 0xffffu) << 16) | (min & 0xffffu))
/* Driver quirks */ @@ -1927,7 +1939,10 @@ void dispatch_compute(struct wined3d_device *device, const struct wined3d_state #define STATE_RASTERIZER (STATE_MATERIAL + 1) #define STATE_IS_RASTERIZER(a) ((a) == STATE_RASTERIZER)
-#define STATE_POINTSPRITECOORDORIGIN (STATE_RASTERIZER + 1) +#define STATE_DEPTH_BOUNDS (STATE_RASTERIZER + 1) +#define STATE_IS_DEPTH_BOUNDS(a) ((a) == STATE_DEPTH_BOUNDS) + +#define STATE_POINTSPRITECOORDORIGIN (STATE_DEPTH_BOUNDS + 1) #define STATE_IS_POINTSPRITECOORDORIGIN(a) ((a) == STATE_POINTSPRITECOORDORIGIN)
#define STATE_BASEVERTEXINDEX (STATE_POINTSPRITECOORDORIGIN + 1) @@ -3916,6 +3931,8 @@ struct wined3d_state unsigned int sample_mask; struct wined3d_depth_stencil_state *depth_stencil_state; unsigned int stencil_ref; + bool depth_bounds_enable; + float depth_bounds_min, depth_bounds_max; struct wined3d_rasterizer_state *rasterizer_state; };
@@ -5135,6 +5152,8 @@ void wined3d_cs_init_object(struct wined3d_cs *cs, void (*callback)(void *object), void *object) DECLSPEC_HIDDEN; void wined3d_cs_map_bo_address(struct wined3d_cs *cs, struct wined3d_bo_address *addr, size_t size, unsigned int flags) DECLSPEC_HIDDEN; +void wined3d_device_context_set_depth_bounds(struct wined3d_device_context *context, + bool enable, float min_depth, float max_depth);
static inline void wined3d_cs_finish(struct wined3d_cs *cs, enum wined3d_cs_queue_id queue_id) {