wined3d: Make depth bounds test a proper state and handle it in wined3d_device_apply_stateblock().

Signed-off-by: Zebediah Figura <zfigura@codeweavers.com>
This commit is contained in:
Zebediah Figura 2022-12-11 12:14:03 -06:00 committed by Alexandre Julliard
parent 798fbd4205
commit cf553129c2
7 changed files with 94 additions and 40 deletions

View file

@ -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}},

View file

@ -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,

View file

@ -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];

View file

@ -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}},

View file

@ -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;

View file

@ -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))

View file

@ -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)
{