Handle this render state similarly to D3DRS_ZFUNC, by mapping it in the client DLLs.
As far as I can tell, save for the fact that it's only supposed to apply to lines forming a convex outline, it's roughly equivalent to D3DRS_ANTIALIASEDLINEENABLE. We definitely handled it the same way.
Curiously, even though we supported the render state, we didn't set the corresponding capability bit. Do that now.
Signed-off-by: Chip Davis cdavis@codeweavers.com --- dlls/d3d8/device.c | 13 +++++++++++-- dlls/ddraw/ddraw.c | 2 ++ dlls/ddraw/device.c | 10 ++++++++-- dlls/wined3d/state.c | 13 +++++-------- dlls/wined3d/stateblock.c | 1 - dlls/wined3d/utils.c | 1 - include/wine/wined3d.h | 2 -- 7 files changed, 26 insertions(+), 16 deletions(-)
diff --git a/dlls/d3d8/device.c b/dlls/d3d8/device.c index 6a67f817785..07f6dccbcbf 100644 --- a/dlls/d3d8/device.c +++ b/dlls/d3d8/device.c @@ -422,6 +422,9 @@ void d3dcaps_from_wined3dcaps(D3DCAPS8 *caps, const struct wined3d_caps *wined3d | D3DPTFILTERCAPS_MIPFLINEAR | D3DPTFILTERCAPS_MAGFPOINT | D3DPTFILTERCAPS_MAGFLINEAR | D3DPTFILTERCAPS_MAGFANISOTROPIC | D3DPTFILTERCAPS_MAGFAFLATCUBIC | D3DPTFILTERCAPS_MAGFGAUSSIANCUBIC; + if (caps->LineCaps & WINED3DLINECAPS_ANTIALIAS) + caps->RasterCaps |= D3DPRASTERCAPS_ANTIALIASEDGES; + caps->LineCaps &= ~WINED3DLINECAPS_ANTIALIAS; caps->StencilCaps &= ~WINED3DSTENCILCAPS_TWOSIDED; caps->VertexProcessingCaps &= D3DVTXPCAPS_TEXGEN | D3DVTXPCAPS_MATERIALSOURCE7 | D3DVTXPCAPS_DIRECTIONALLIGHTS | D3DVTXPCAPS_POSITIONALLIGHTS | D3DVTXPCAPS_LOCALVIEWER @@ -446,9 +449,15 @@ static enum wined3d_transform_state wined3d_transform_state_from_d3d(D3DTRANSFOR
static enum wined3d_render_state wined3d_render_state_from_d3d(D3DRENDERSTATETYPE state) { - if (state == D3DRS_ZBIAS) + switch (state) + { + case D3DRS_ZBIAS: return WINED3D_RS_DEPTHBIAS; - return (enum wined3d_render_state)state; + case D3DRS_EDGEANTIALIAS: + return WINED3D_RS_ANTIALIASEDLINEENABLE; + default: + return (enum wined3d_render_state)state; + } }
static enum wined3d_primitive_type wined3d_primitive_type_from_d3d(D3DPRIMITIVETYPE type) diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c index 95e9fba9011..4ebf51d040c 100644 --- a/dlls/ddraw/ddraw.c +++ b/dlls/ddraw/ddraw.c @@ -1340,6 +1340,8 @@ HRESULT ddraw_get_d3dcaps(const struct ddraw *ddraw, D3DDEVICEDESC7 *caps) if (caps->dpcLineCaps.dwRasterCaps & WINED3DPRASTERCAPS_DEPTHBIAS) caps->dpcLineCaps.dwRasterCaps = (caps->dpcLineCaps.dwRasterCaps | D3DPRASTERCAPS_ZBIAS) & ~WINED3DPRASTERCAPS_DEPTHBIAS; + if (wined3d_caps.LineCaps & WINED3DLINECAPS_ANTIALIAS) + caps->dpcLineCaps.dwRasterCaps |= D3DPRASTERCAPS_ANTIALIASEDGES;
caps->dpcLineCaps.dwZCmpCaps &= ( D3DPCMPCAPS_NEVER | D3DPCMPCAPS_LESS | D3DPCMPCAPS_EQUAL | diff --git a/dlls/ddraw/device.c b/dlls/ddraw/device.c index e09100dfdc7..47856a05fb2 100644 --- a/dlls/ddraw/device.c +++ b/dlls/ddraw/device.c @@ -74,9 +74,15 @@ static inline WORD d3d_fpu_setup(void)
static enum wined3d_render_state wined3d_render_state_from_ddraw(D3DRENDERSTATETYPE state) { - if (state == D3DRENDERSTATE_ZBIAS) + switch (state) + { + case D3DRENDERSTATE_ZBIAS: return WINED3D_RS_DEPTHBIAS; - return (enum wined3d_render_state)state; + case D3DRENDERSTATE_EDGEANTIALIAS: + return WINED3D_RS_ANTIALIASEDLINEENABLE; + default: + return (enum wined3d_render_state)state; + } }
static enum wined3d_transform_state wined3d_transform_state_from_ddraw(D3DTRANSFORMSTATETYPE state) diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c index d375122781b..1cb9f222eab 100644 --- a/dlls/wined3d/state.c +++ b/dlls/wined3d/state.c @@ -1798,12 +1798,9 @@ static void state_msaa(struct wined3d_context *context, const struct wined3d_sta } }
-static void state_line_antialias(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) +static void line_antialias(const struct wined3d_rasterizer_state *r, const struct wined3d_gl_info *gl_info) { - const struct wined3d_gl_info *gl_info = wined3d_context_gl(context)->gl_info; - const struct wined3d_rasterizer_state *r = state->rasterizer_state; - - if (state->render_states[WINED3D_RS_EDGEANTIALIAS] || (r && r->desc.line_antialias)) + if (r && r->desc.line_antialias) { gl_info->gl_ops.gl.p_glEnable(GL_LINE_SMOOTH); checkGLcall("glEnable(GL_LINE_SMOOTH)"); @@ -4427,7 +4424,7 @@ static void rasterizer(struct wined3d_context *context, const struct wined3d_sta cullmode(r, gl_info); depth_clip(r, gl_info); scissor(r, gl_info); - state_line_antialias(context, state, STATE_RENDER(WINED3D_RS_ANTIALIASEDLINEENABLE)); + line_antialias(r, gl_info); }
static void rasterizer_cc(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) @@ -4445,7 +4442,7 @@ static void rasterizer_cc(struct wined3d_context *context, const struct wined3d_ cullmode(r, gl_info); depth_clip(r, gl_info); scissor(r, gl_info); - state_line_antialias(context, state, STATE_RENDER(WINED3D_RS_ANTIALIASEDLINEENABLE)); + line_antialias(r, gl_info); }
static void psorigin_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) @@ -4602,7 +4599,6 @@ const struct wined3d_state_entry_template misc_state_template[] = { STATE_COMPUTE_UNORDERED_ACCESS_VIEW_BINDING, { STATE_COMPUTE_UNORDERED_ACCESS_VIEW_BINDING, state_uav_warn }, WINED3D_GL_EXT_NONE }, { STATE_STREAM_OUTPUT, { STATE_STREAM_OUTPUT, state_so, }, WINED3D_GL_VERSION_3_2 }, { STATE_STREAM_OUTPUT, { STATE_STREAM_OUTPUT, state_so_warn, }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3D_RS_EDGEANTIALIAS), { STATE_RENDER(WINED3D_RS_EDGEANTIALIAS), state_line_antialias}, WINED3D_GL_EXT_NONE }, { STATE_BLEND, { STATE_BLEND, blend_dbb }, ARB_DRAW_BUFFERS_BLEND }, { STATE_BLEND, { STATE_BLEND, blend_db2 }, EXT_DRAW_BUFFERS2 }, { STATE_BLEND, { STATE_BLEND, blend }, WINED3D_GL_EXT_NONE }, @@ -5504,6 +5500,7 @@ static void validate_state_table(struct wined3d_state_entry *state_table) { 8, 8}, { 17, 22}, { 27, 27}, + { 40, 40}, { 42, 45}, { 47, 47}, { 61, 127}, diff --git a/dlls/wined3d/stateblock.c b/dlls/wined3d/stateblock.c index 48d133485b8..7e97c84c19e 100644 --- a/dlls/wined3d/stateblock.c +++ b/dlls/wined3d/stateblock.c @@ -1665,7 +1665,6 @@ static void init_default_render_states(DWORD rs[WINEHIGHEST_RENDER_STATE + 1], c rs[WINED3D_RS_FOGEND] = tmpfloat.d; tmpfloat.f = 1.0f; rs[WINED3D_RS_FOGDENSITY] = tmpfloat.d; - rs[WINED3D_RS_EDGEANTIALIAS] = FALSE; rs[WINED3D_RS_RANGEFOGENABLE] = FALSE; rs[WINED3D_RS_STENCILENABLE] = FALSE; rs[WINED3D_RS_STENCILFAIL] = WINED3D_STENCIL_OP_KEEP; diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c index 335d502ab0b..004c33f8ea9 100644 --- a/dlls/wined3d/utils.c +++ b/dlls/wined3d/utils.c @@ -4919,7 +4919,6 @@ const char *debug_d3drenderstate(enum wined3d_render_state state) D3DSTATE_TO_STR(WINED3D_RS_FOGEND); D3DSTATE_TO_STR(WINED3D_RS_FOGDENSITY); D3DSTATE_TO_STR(WINED3D_RS_STIPPLEENABLE); - D3DSTATE_TO_STR(WINED3D_RS_EDGEANTIALIAS); D3DSTATE_TO_STR(WINED3D_RS_COLORKEYENABLE); D3DSTATE_TO_STR(WINED3D_RS_MIPMAPLODBIAS); D3DSTATE_TO_STR(WINED3D_RS_RANGEFOGENABLE); diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index 0b3b41896e4..d3eb8100cd8 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -310,7 +310,6 @@ enum wined3d_render_state WINED3D_RS_FOGEND = 37, WINED3D_RS_FOGDENSITY = 38, WINED3D_RS_STIPPLEENABLE = 39, - WINED3D_RS_EDGEANTIALIAS = 40, WINED3D_RS_COLORKEYENABLE = 41, WINED3D_RS_MIPMAPLODBIAS = 46, WINED3D_RS_RANGEFOGENABLE = 48, @@ -1209,7 +1208,6 @@ enum wined3d_shader_type #define WINED3DPRASTERCAPS_STIPPLE 0x00000200 #define WINED3DPRASTERCAPS_ANTIALIASSORTDEPENDENT 0x00000400 #define WINED3DPRASTERCAPS_ANTIALIASSORTINDEPENDENT 0x00000800 -#define WINED3DPRASTERCAPS_ANTIALIASEDGES 0x00001000 #define WINED3DPRASTERCAPS_MIPMAPLODBIAS 0x00002000 #define WINED3DPRASTERCAPS_ZBUFFERLESSHSR 0x00008000 #define WINED3DPRASTERCAPS_FOGRANGE 0x00010000
I'm curious as to why Zeb didn't move this with the other rasterizer states. Perhaps it's because the default is different in d3d8/9 vs. d3d10+.
Signed-off-by: Chip Davis cdavis@codeweavers.com --- dlls/d3d11/device.c | 15 +++---------- dlls/d3d11/state.c | 1 + dlls/wined3d/device.c | 2 ++ dlls/wined3d/state.c | 46 +++++++++++++++++++-------------------- dlls/wined3d/stateblock.c | 4 ++++ include/wine/wined3d.h | 1 + 6 files changed, 33 insertions(+), 36 deletions(-)
diff --git a/dlls/d3d11/device.c b/dlls/d3d11/device.c index 7544bc86f4b..7c75431780c 100644 --- a/dlls/d3d11/device.c +++ b/dlls/d3d11/device.c @@ -896,18 +896,9 @@ static void STDMETHODCALLTYPE d3d11_immediate_context_RSSetState(ID3D11DeviceCon TRACE("iface %p, rasterizer_state %p.\n", iface, rasterizer_state);
wined3d_mutex_lock(); - if (!(rasterizer_state_impl = unsafe_impl_from_ID3D11RasterizerState(rasterizer_state))) - { - wined3d_device_set_rasterizer_state(device->wined3d_device, NULL); - wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_MULTISAMPLEANTIALIAS, FALSE); - wined3d_mutex_unlock(); - return; - } - - wined3d_device_set_rasterizer_state(device->wined3d_device, rasterizer_state_impl->wined3d_state); - - desc = &rasterizer_state_impl->desc; - wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_MULTISAMPLEANTIALIAS, desc->MultisampleEnable); + rasterizer_state_impl = unsafe_impl_from_ID3D11RasterizerState(rasterizer_state); + wined3d_device_set_rasterizer_state(device->wined3d_device, + rasterizer_state_impl ? rasterizer_state_impl->wined3d_state : NULL); wined3d_mutex_unlock(); }
diff --git a/dlls/d3d11/state.c b/dlls/d3d11/state.c index 32ef44091c4..6d7f70664e7 100644 --- a/dlls/d3d11/state.c +++ b/dlls/d3d11/state.c @@ -1118,6 +1118,7 @@ static HRESULT d3d_rasterizer_state_init(struct d3d_rasterizer_state *state, str wined3d_desc.scale_bias = desc->SlopeScaledDepthBias; wined3d_desc.depth_clip = desc->DepthClipEnable; wined3d_desc.scissor = desc->ScissorEnable; + wined3d_desc.multisample = desc->MultisampleEnable; wined3d_desc.line_antialias = desc->AntialiasedLineEnable;
/* We cannot fail after creating a wined3d_rasterizer_state object. It diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index ee007568d46..8baf9b9df19 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -3608,6 +3608,7 @@ void CDECL wined3d_device_apply_stateblock(struct wined3d_device *device, case WINED3D_RS_SLOPESCALEDEPTHBIAS: case WINED3D_RS_DEPTHBIAS: case WINED3D_RS_SCISSORTESTENABLE: + case WINED3D_RS_MULTISAMPLEANTIALIAS: case WINED3D_RS_ANTIALIASEDLINEENABLE: set_rasterizer_state = TRUE; break; @@ -3639,6 +3640,7 @@ void CDECL wined3d_device_apply_stateblock(struct wined3d_device *device, desc.scale_bias = bias.f; desc.depth_clip = TRUE; desc.scissor = state->rs[WINED3D_RS_SCISSORTESTENABLE]; + desc.multisample = state->rs[WINED3D_RS_MULTISAMPLEANTIALIAS]; desc.line_antialias = state->rs[WINED3D_RS_ANTIALIASEDLINEENABLE];
if ((entry = wine_rb_get(&device->rasterizer_states, &desc))) diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c index 1cb9f222eab..d7792f46168 100644 --- a/dlls/wined3d/state.c +++ b/dlls/wined3d/state.c @@ -1776,28 +1776,6 @@ static void state_wrap(struct wined3d_context *context, const struct wined3d_sta FIXME("(WINED3D_RS_WRAP0) Texture wrapping not yet supported.\n"); }
-static void state_msaa_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) -{ - if (state->render_states[WINED3D_RS_MULTISAMPLEANTIALIAS]) - WARN("Multisample antialiasing not supported by GL.\n"); -} - -static void state_msaa(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; - - if (state->render_states[WINED3D_RS_MULTISAMPLEANTIALIAS]) - { - gl_info->gl_ops.gl.p_glEnable(GL_MULTISAMPLE_ARB); - checkGLcall("glEnable(GL_MULTISAMPLE_ARB)"); - } - else - { - gl_info->gl_ops.gl.p_glDisable(GL_MULTISAMPLE_ARB); - checkGLcall("glDisable(GL_MULTISAMPLE_ARB)"); - } -} - static void line_antialias(const struct wined3d_rasterizer_state *r, const struct wined3d_gl_info *gl_info) { if (r && r->desc.line_antialias) @@ -4407,6 +4385,25 @@ static void depth_clip(const struct wined3d_rasterizer_state *r, const struct wi checkGLcall("depth clip"); }
+static void multisample(const struct wined3d_rasterizer_state *r, const struct wined3d_gl_info *gl_info) +{ + if (r && r->desc.multisample) + { + if (gl_info->supported[ARB_MULTISAMPLE]) + { + gl_info->gl_ops.gl.p_glEnable(GL_MULTISAMPLE); + checkGLcall("glEnable GL_MULTISAMPLE"); + } + else + WARN("Multisample antialiasing not supported by GL.\n"); + } + else if (gl_info->supported[ARB_MULTISAMPLE]) + { + gl_info->gl_ops.gl.p_glDisable(GL_MULTISAMPLE); + checkGLcall("glDisable GL_MULTISAMPLE"); + } +} + static void rasterizer(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; @@ -4424,6 +4421,7 @@ static void rasterizer(struct wined3d_context *context, const struct wined3d_sta cullmode(r, gl_info); depth_clip(r, gl_info); scissor(r, gl_info); + multisample(r, gl_info); line_antialias(r, gl_info); }
@@ -4442,6 +4440,7 @@ static void rasterizer_cc(struct wined3d_context *context, const struct wined3d_ cullmode(r, gl_info); depth_clip(r, gl_info); scissor(r, gl_info); + multisample(r, gl_info); line_antialias(r, gl_info); }
@@ -4736,8 +4735,6 @@ const struct wined3d_state_entry_template misc_state_template[] = { 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 }, { STATE_RENDER(WINED3D_RS_MULTISAMPLEMASK), { STATE_RENDER(WINED3D_RS_MULTISAMPLEMASK), state_multisampmask }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_DEBUGMONITORTOKEN), { STATE_RENDER(WINED3D_RS_DEBUGMONITORTOKEN), state_debug_monitor }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_ZVISIBLE), { STATE_RENDER(WINED3D_RS_ZVISIBLE), state_zvisible }, WINED3D_GL_EXT_NONE }, @@ -5505,6 +5502,7 @@ static void validate_state_table(struct wined3d_state_entry *state_table) { 47, 47}, { 61, 127}, {149, 150}, + {161, 161}, {168, 169}, {171, 171}, {174, 177}, diff --git a/dlls/wined3d/stateblock.c b/dlls/wined3d/stateblock.c index 7e97c84c19e..84b64eae7aa 100644 --- a/dlls/wined3d/stateblock.c +++ b/dlls/wined3d/stateblock.c @@ -1925,6 +1925,10 @@ static HRESULT stateblock_init(struct wined3d_stateblock *stateblock, const stru if (type == WINED3D_SBT_RECORDED || type == WINED3D_SBT_PRIMARY) return WINED3D_OK;
+ /* The default multisample state in d3d9 and under is TRUE, but FALSE in d3d10 and up. Force the multisample + * antialiasing state to be marked changed regardless of the stateblock type to ensure it is set correctly. */ + stateblock->changed.renderState[WINED3D_RS_MULTISAMPLEANTIALIAS >> 5] |= 1u << (WINED3D_RS_MULTISAMPLEANTIALIAS & 0x1f); + TRACE("Updating changed flags appropriate for type %#x.\n", type);
switch (type) diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index d3eb8100cd8..f9a0d9e0f89 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -2043,6 +2043,7 @@ struct wined3d_rasterizer_state_desc float scale_bias; BOOL depth_clip; BOOL scissor; + BOOL multisample; BOOL line_antialias; };
Signed-off-by: Chip Davis cdavis@codeweavers.com --- dlls/d3d11/device.c | 8 +++----- dlls/wined3d/cs.c | 6 +++++- dlls/wined3d/device.c | 27 +++++++++++++++++---------- dlls/wined3d/state.c | 18 +++++++++--------- dlls/wined3d/utils.c | 2 ++ dlls/wined3d/wined3d_private.h | 8 ++++++-- include/wine/wined3d.h | 4 ++-- 7 files changed, 44 insertions(+), 29 deletions(-)
diff --git a/dlls/d3d11/device.c b/dlls/d3d11/device.c index 7c75431780c..23d05e08b49 100644 --- a/dlls/d3d11/device.c +++ b/dlls/d3d11/device.c @@ -715,13 +715,12 @@ static void STDMETHODCALLTYPE d3d11_immediate_context_OMSetBlendState(ID3D11Devi blend_factor = default_blend_factor;
wined3d_mutex_lock(); - wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_MULTISAMPLEMASK, sample_mask); if (!(blend_state_impl = unsafe_impl_from_ID3D11BlendState(blend_state))) wined3d_device_set_blend_state(device->wined3d_device, NULL, - (const struct wined3d_color *)blend_factor); + (const struct wined3d_color *)blend_factor, sample_mask); else wined3d_device_set_blend_state(device->wined3d_device, blend_state_impl->wined3d_state, - (const struct wined3d_color *)blend_factor); + (const struct wined3d_color *)blend_factor, sample_mask); wined3d_mutex_unlock(); }
@@ -1877,7 +1876,7 @@ static void STDMETHODCALLTYPE d3d11_immediate_context_OMGetBlendState(ID3D11Devi
wined3d_mutex_lock(); if ((wined3d_state = wined3d_device_get_blend_state(device->wined3d_device, - (struct wined3d_color *)blend_factor))) + (struct wined3d_color *)blend_factor, sample_mask))) { blend_state_impl = wined3d_blend_state_get_parent(wined3d_state); ID3D11BlendState_AddRef(*blend_state = &blend_state_impl->ID3D11BlendState_iface); @@ -1886,7 +1885,6 @@ static void STDMETHODCALLTYPE d3d11_immediate_context_OMGetBlendState(ID3D11Devi { *blend_state = NULL; } - *sample_mask = wined3d_device_get_render_state(device->wined3d_device, WINED3D_RS_MULTISAMPLEMASK); wined3d_mutex_unlock(); }
diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c index 899d5a712e4..943ffe9af62 100644 --- a/dlls/wined3d/cs.c +++ b/dlls/wined3d/cs.c @@ -265,6 +265,7 @@ struct wined3d_cs_set_blend_state enum wined3d_cs_op opcode; struct wined3d_blend_state *state; struct wined3d_color factor; + unsigned int sample_mask; };
struct wined3d_cs_set_rasterizer_state @@ -1565,11 +1566,13 @@ static void wined3d_cs_exec_set_blend_state(struct wined3d_cs *cs, const void *d device_invalidate_state(cs->device, STATE_BLEND); } state->blend_factor = op->factor; + state->sample_mask = op->sample_mask; device_invalidate_state(cs->device, STATE_BLEND_FACTOR); + device_invalidate_state(cs->device, STATE_SAMPLE_MASK); }
void wined3d_cs_emit_set_blend_state(struct wined3d_cs *cs, struct wined3d_blend_state *state, - const struct wined3d_color *blend_factor) + const struct wined3d_color *blend_factor, unsigned int sample_mask) { struct wined3d_cs_set_blend_state *op;
@@ -1577,6 +1580,7 @@ void wined3d_cs_emit_set_blend_state(struct wined3d_cs *cs, struct wined3d_blend op->opcode = WINED3D_CS_OP_SET_BLEND_STATE; op->state = state; op->factor = *blend_factor; + op->sample_mask = sample_mask;
wined3d_cs_submit(cs, WINED3D_CS_QUEUE_DEFAULT); } diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 8baf9b9df19..4c60c140784 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -1678,34 +1678,38 @@ static void resolve_depth_buffer(struct wined3d_device *device) }
void CDECL wined3d_device_set_blend_state(struct wined3d_device *device, - struct wined3d_blend_state *blend_state, const struct wined3d_color *blend_factor) + struct wined3d_blend_state *blend_state, const struct wined3d_color *blend_factor, unsigned int sample_mask) { struct wined3d_state *state = &device->state; struct wined3d_blend_state *prev;
- TRACE("device %p, blend_state %p, blend_factor %s.\n", device, blend_state, debug_color(blend_factor)); + TRACE("device %p, blend_state %p, blend_factor %s, sample_mask 0x%08x.\n", device, blend_state, + debug_color(blend_factor), sample_mask);
prev = state->blend_state; - if (prev == blend_state && !memcmp(blend_factor, &state->blend_factor, sizeof(*blend_factor))) + if (prev == blend_state && !memcmp(blend_factor, &state->blend_factor, sizeof(*blend_factor)) + && sample_mask == state->sample_mask) return;
if (blend_state) wined3d_blend_state_incref(blend_state); state->blend_state = blend_state; state->blend_factor = *blend_factor; - wined3d_cs_emit_set_blend_state(device->cs, blend_state, blend_factor); + state->sample_mask = sample_mask; + wined3d_cs_emit_set_blend_state(device->cs, blend_state, blend_factor, sample_mask); if (prev) wined3d_blend_state_decref(prev); }
struct wined3d_blend_state * CDECL wined3d_device_get_blend_state(const struct wined3d_device *device, - struct wined3d_color *blend_factor) + struct wined3d_color *blend_factor, unsigned int *sample_mask) { const struct wined3d_state *state = &device->state;
- TRACE("device %p, blend_factor %p.\n", device, blend_factor); + TRACE("device %p, blend_factor %p, sample_mask %p.\n", device, blend_factor, sample_mask);
*blend_factor = state->blend_factor; + *sample_mask = state->sample_mask; return state->blend_state; }
@@ -3588,6 +3592,7 @@ void CDECL wined3d_device_apply_stateblock(struct wined3d_device *device, switch (idx) { case WINED3D_RS_BLENDFACTOR: + case WINED3D_RS_MULTISAMPLEMASK: case WINED3D_RS_ALPHABLENDENABLE: case WINED3D_RS_SRCBLEND: case WINED3D_RS_DESTBLEND: @@ -3667,6 +3672,7 @@ void CDECL wined3d_device_apply_stateblock(struct wined3d_device *device, struct wined3d_blend_state_desc desc; struct wine_rb_entry *entry; struct wined3d_color colour; + unsigned int sample_mask;
memset(&desc, 0, sizeof(desc)); desc.alpha_to_coverage = state->alpha_to_coverage; @@ -3710,20 +3716,21 @@ void CDECL wined3d_device_apply_stateblock(struct wined3d_device *device, } }
+ wined3d_device_get_blend_state(device, &colour, &sample_mask); if (wined3d_bitmap_is_set(changed->renderState, WINED3D_RS_BLENDFACTOR)) wined3d_color_from_d3dcolor(&colour, state->rs[WINED3D_RS_BLENDFACTOR]); - else - wined3d_device_get_blend_state(device, &colour); + if (wined3d_bitmap_is_set(changed->renderState, WINED3D_RS_MULTISAMPLEMASK)) + sample_mask = state->rs[WINED3D_RS_MULTISAMPLEMASK];
if ((entry = wine_rb_get(&device->blend_states, &desc))) { blend_state = WINE_RB_ENTRY_VALUE(entry, struct wined3d_blend_state, entry); - wined3d_device_set_blend_state(device, blend_state, &colour); + wined3d_device_set_blend_state(device, blend_state, &colour, sample_mask); } else if (SUCCEEDED(wined3d_blend_state_create(device, &desc, NULL, &wined3d_null_parent_ops, &blend_state))) { - wined3d_device_set_blend_state(device, blend_state, &colour); + wined3d_device_set_blend_state(device, blend_state, &colour, sample_mask); if (wine_rb_put(&device->blend_states, &desc, &blend_state->entry) == -1) { ERR("Failed to insert blend state.\n"); diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c index d7792f46168..42666e9ccc2 100644 --- a/dlls/wined3d/state.c +++ b/dlls/wined3d/state.c @@ -552,6 +552,12 @@ static void state_blend_factor(struct wined3d_context *context, const struct win checkGLcall("glBlendColor"); }
+static void state_multisampmask(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) +{ + if (state->sample_mask != 0xffffffff) + FIXME("Sample mask %#x not yet implemented.\n", state->sample_mask); +} + static BOOL is_blend_enabled(struct wined3d_context *context, const struct wined3d_state *state, UINT index) { const struct wined3d_blend_state *b = state->blend_state; @@ -1901,13 +1907,6 @@ static void state_antialias(struct wined3d_context *context, const struct wined3 FIXME("Antialias not supported yet.\n"); }
-static void state_multisampmask(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) -{ - if (state->render_states[WINED3D_RS_MULTISAMPLEMASK] != 0xffffffff) - FIXME("WINED3D_RS_MULTISAMPLEMASK %#x not yet implemented.\n", - state->render_states[WINED3D_RS_MULTISAMPLEMASK]); -} - static void state_patchedgestyle(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { if (state->render_states[WINED3D_RS_PATCHEDGESTYLE] != WINED3D_PATCH_EDGE_DISCRETE) @@ -4603,6 +4602,7 @@ const struct wined3d_state_entry_template misc_state_template[] = { STATE_BLEND, { STATE_BLEND, blend }, WINED3D_GL_EXT_NONE }, { STATE_BLEND_FACTOR, { STATE_BLEND_FACTOR, state_blend_factor }, EXT_BLEND_COLOR }, { STATE_BLEND_FACTOR, { STATE_BLEND_FACTOR, state_blend_factor_w}, WINED3D_GL_EXT_NONE }, + { STATE_SAMPLE_MASK, { STATE_SAMPLE_MASK, state_multisampmask }, 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 }, @@ -4735,7 +4735,6 @@ const struct wined3d_state_entry_template misc_state_template[] = { 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_MULTISAMPLEMASK), { STATE_RENDER(WINED3D_RS_MULTISAMPLEMASK), state_multisampmask }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_DEBUGMONITORTOKEN), { STATE_RENDER(WINED3D_RS_DEBUGMONITORTOKEN), state_debug_monitor }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_ZVISIBLE), { STATE_RENDER(WINED3D_RS_ZVISIBLE), state_zvisible }, WINED3D_GL_EXT_NONE }, /* Samplers */ @@ -5502,7 +5501,7 @@ static void validate_state_table(struct wined3d_state_entry *state_table) { 47, 47}, { 61, 127}, {149, 150}, - {161, 161}, + {161, 162}, {168, 169}, {171, 171}, {174, 177}, @@ -5544,6 +5543,7 @@ static void validate_state_table(struct wined3d_state_entry *state_table) STATE_COLOR_KEY, STATE_BLEND, STATE_BLEND_FACTOR, + STATE_SAMPLE_MASK, }; unsigned int i, current;
diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c index 004c33f8ea9..916d90cf215 100644 --- a/dlls/wined3d/utils.c +++ b/dlls/wined3d/utils.c @@ -5245,6 +5245,8 @@ const char *debug_d3dstate(DWORD state) return "STATE_BLEND"; if (STATE_IS_BLEND_FACTOR(state)) return "STATE_BLEND_FACTOR"; + if (STATE_IS_SAMPLE_MASK(state)) + return "STATE_SAMPLE_MASK";
return wine_dbg_sprintf("UNKNOWN_STATE(%#x)", state); } diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index fac53aca28c..db17305c76b 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -1711,7 +1711,10 @@ enum wined3d_pipeline #define STATE_BLEND_FACTOR (STATE_BLEND + 1) #define STATE_IS_BLEND_FACTOR(a) ((a) == STATE_BLEND_FACTOR)
-#define STATE_COMPUTE_OFFSET (STATE_BLEND_FACTOR + 1) +#define STATE_SAMPLE_MASK (STATE_BLEND_FACTOR + 1) +#define STATE_IS_SAMPLE_MASK(a) ((a) == STATE_SAMPLE_MASK) + +#define STATE_COMPUTE_OFFSET (STATE_SAMPLE_MASK + 1)
#define STATE_COMPUTE_SHADER (STATE_COMPUTE_OFFSET) #define STATE_IS_COMPUTE_SHADER(a) ((a) == STATE_COMPUTE_SHADER) @@ -3231,6 +3234,7 @@ struct wined3d_state DWORD render_states[WINEHIGHEST_RENDER_STATE + 1]; struct wined3d_blend_state *blend_state; struct wined3d_color blend_factor; + unsigned int sample_mask; struct wined3d_rasterizer_state *rasterizer_state; };
@@ -4083,7 +4087,7 @@ void wined3d_cs_emit_present(struct wined3d_cs *cs, struct wined3d_swapchain *sw void wined3d_cs_emit_query_issue(struct wined3d_cs *cs, struct wined3d_query *query, DWORD flags) DECLSPEC_HIDDEN; void wined3d_cs_emit_reset_state(struct wined3d_cs *cs) DECLSPEC_HIDDEN; void wined3d_cs_emit_set_blend_state(struct wined3d_cs *cs, struct wined3d_blend_state *state, - const struct wined3d_color *blend_factor) DECLSPEC_HIDDEN; + const struct wined3d_color *blend_factor, unsigned int sample_mask) DECLSPEC_HIDDEN; void wined3d_cs_emit_set_clip_plane(struct wined3d_cs *cs, UINT plane_idx, const struct wined3d_vec4 *plane) DECLSPEC_HIDDEN; void wined3d_cs_emit_set_color_key(struct wined3d_cs *cs, struct wined3d_texture *texture, diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index f9a0d9e0f89..3b541714f4f 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -2336,7 +2336,7 @@ HRESULT __cdecl wined3d_device_end_scene(struct wined3d_device *device); void __cdecl wined3d_device_evict_managed_resources(struct wined3d_device *device); UINT __cdecl wined3d_device_get_available_texture_mem(const struct wined3d_device *device); struct wined3d_blend_state * __cdecl wined3d_device_get_blend_state(const struct wined3d_device *device, - struct wined3d_color *blend_factor); + struct wined3d_color *blend_factor, unsigned int *sample_mask); HRESULT __cdecl wined3d_device_get_clip_status(const struct wined3d_device *device, struct wined3d_clip_status *clip_status); struct wined3d_shader * __cdecl wined3d_device_get_compute_shader(const struct wined3d_device *device); @@ -2419,7 +2419,7 @@ void __cdecl wined3d_device_resolve_sub_resource(struct wined3d_device *device, enum wined3d_format_id format_id); void __cdecl wined3d_device_set_base_vertex_index(struct wined3d_device *device, INT base_index); void __cdecl wined3d_device_set_blend_state(struct wined3d_device *device, struct wined3d_blend_state *blend_state, - const struct wined3d_color *blend_factor); + const struct wined3d_color *blend_factor, unsigned int sample_mask); HRESULT __cdecl wined3d_device_set_clip_status(struct wined3d_device *device, const struct wined3d_clip_status *clip_status); void __cdecl wined3d_device_set_compute_shader(struct wined3d_device *device, struct wined3d_shader *shader);
Move the depth enable state to it.
Signed-off-by: Chip Davis cdavis@codeweavers.com --- dlls/d3d11/d3d11_private.h | 1 + dlls/d3d11/device.c | 4 +- dlls/d3d11/state.c | 57 ++++++++++++++------- dlls/wined3d/context.c | 5 +- dlls/wined3d/cs.c | 30 +++++++++++- dlls/wined3d/device.c | 90 ++++++++++++++++++++++++++++++++-- dlls/wined3d/state.c | 76 ++++++++++++++++++++++++++-- dlls/wined3d/utils.c | 9 +++- dlls/wined3d/wined3d.spec | 7 +++ dlls/wined3d/wined3d_private.h | 22 ++++++++- include/wine/wined3d.h | 16 ++++++ 11 files changed, 283 insertions(+), 34 deletions(-)
diff --git a/dlls/d3d11/d3d11_private.h b/dlls/d3d11/d3d11_private.h index 48c76959fae..a7258cada71 100644 --- a/dlls/d3d11/d3d11_private.h +++ b/dlls/d3d11/d3d11_private.h @@ -440,6 +440,7 @@ struct d3d_depthstencil_state LONG refcount;
struct wined3d_private_store private_store; + struct wined3d_depth_stencil_state *wined3d_state; D3D11_DEPTH_STENCIL_DESC desc; struct wine_rb_entry entry; ID3D11Device2 *device; diff --git a/dlls/d3d11/device.c b/dlls/d3d11/device.c index 23d05e08b49..ed290750ac3 100644 --- a/dlls/d3d11/device.c +++ b/dlls/d3d11/device.c @@ -726,7 +726,6 @@ static void STDMETHODCALLTYPE d3d11_immediate_context_OMSetBlendState(ID3D11Devi
static void set_default_depth_stencil_state(struct wined3d_device *wined3d_device) { - wined3d_device_set_render_state(wined3d_device, WINED3D_RS_ZENABLE, TRUE); wined3d_device_set_render_state(wined3d_device, WINED3D_RS_ZWRITEENABLE, D3D11_DEPTH_WRITE_MASK_ALL); wined3d_device_set_render_state(wined3d_device, WINED3D_RS_ZFUNC, WINED3D_CMP_LESS); wined3d_device_set_render_state(wined3d_device, WINED3D_RS_STENCILENABLE, FALSE); @@ -746,6 +745,7 @@ static void STDMETHODCALLTYPE d3d11_immediate_context_OMSetDepthStencilState(ID3 device->stencil_ref = stencil_ref; if (!(device->depth_stencil_state = unsafe_impl_from_ID3D11DepthStencilState(depth_stencil_state))) { + wined3d_device_set_depth_stencil_state(device->wined3d_device, NULL); set_default_depth_stencil_state(device->wined3d_device); wined3d_mutex_unlock(); return; @@ -756,7 +756,7 @@ static void STDMETHODCALLTYPE d3d11_immediate_context_OMSetDepthStencilState(ID3 front = &desc->FrontFace; back = &desc->BackFace;
- wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_ZENABLE, desc->DepthEnable); + wined3d_device_set_depth_stencil_state(device->wined3d_device, device->depth_stencil_state->wined3d_state); if (desc->DepthEnable) { wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_ZWRITEENABLE, desc->DepthWriteMask); diff --git a/dlls/d3d11/state.c b/dlls/d3d11/state.c index 6d7f70664e7..6d3736a1d95 100644 --- a/dlls/d3d11/state.c +++ b/dlls/d3d11/state.c @@ -496,12 +496,6 @@ static ULONG STDMETHODCALLTYPE d3d11_depthstencil_state_AddRef(ID3D11DepthStenci return refcount; }
-static void d3d_depthstencil_state_cleanup(struct d3d_depthstencil_state *state) -{ - wined3d_private_store_cleanup(&state->private_store); - ID3D11Device2_Release(state->device); -} - static ULONG STDMETHODCALLTYPE d3d11_depthstencil_state_Release(ID3D11DepthStencilState *iface) { struct d3d_depthstencil_state *state = impl_from_ID3D11DepthStencilState(iface); @@ -511,12 +505,11 @@ static ULONG STDMETHODCALLTYPE d3d11_depthstencil_state_Release(ID3D11DepthStenc
if (!refcount) { - struct d3d_device *device = impl_from_ID3D11Device2(state->device); wined3d_mutex_lock(); - wine_rb_remove(&device->depthstencil_states, &state->entry); - d3d_depthstencil_state_cleanup(state); + wined3d_depth_stencil_state_decref(state->wined3d_state); wined3d_mutex_unlock(); - heap_free(state); + + ID3D11Device2_Release(state->device); }
return refcount; @@ -695,9 +688,45 @@ static const struct ID3D10DepthStencilStateVtbl d3d10_depthstencil_state_vtbl = d3d10_depthstencil_state_GetDesc, };
+static void STDMETHODCALLTYPE d3d_depthstencil_state_wined3d_object_destroyed(void *parent) +{ + struct d3d_depthstencil_state *state = parent; + struct d3d_device *device = impl_from_ID3D11Device2(state->device); + + wine_rb_remove(&device->depthstencil_states, &state->entry); + wined3d_private_store_cleanup(&state->private_store); + heap_free(parent); +} + +static const struct wined3d_parent_ops d3d_depthstencil_state_wined3d_parent_ops = +{ + d3d_depthstencil_state_wined3d_object_destroyed, +}; + static HRESULT d3d_depthstencil_state_init(struct d3d_depthstencil_state *state, struct d3d_device *device, const D3D11_DEPTH_STENCIL_DESC *desc) { + struct wined3d_depth_stencil_state_desc wined3d_desc; + HRESULT hr; + + wined3d_desc.depth = desc->DepthEnable; + + if (wine_rb_put(&device->depthstencil_states, desc, &state->entry) == -1) + { + ERR("Failed to insert depth/stencil state entry.\n"); + return E_FAIL; + } + + /* We cannot fail after creating a wined3d_depth_stencil_state object. It + * would lead to double free. */ + if (FAILED(hr = wined3d_depth_stencil_state_create(device->wined3d_device, &wined3d_desc, + state, &d3d_depthstencil_state_wined3d_parent_ops, &state->wined3d_state))) + { + WARN("Failed to create wined3d depth/stencil state, hr %#x.\n", hr); + wine_rb_remove(&device->depthstencil_states, &state->entry); + return hr; + } + state->ID3D11DepthStencilState_iface.lpVtbl = &d3d11_depthstencil_state_vtbl; state->ID3D10DepthStencilState_iface.lpVtbl = &d3d10_depthstencil_state_vtbl; state->refcount = 1; @@ -783,14 +812,6 @@ HRESULT d3d_depthstencil_state_create(struct d3d_device *device, const D3D11_DEP return hr; }
- if (wine_rb_put(&device->depthstencil_states, &tmp_desc, &object->entry) == -1) - { - ERR("Failed to insert depthstencil state entry.\n"); - d3d_depthstencil_state_cleanup(object); - heap_free(object); - wined3d_mutex_unlock(); - return E_FAIL; - } wined3d_mutex_unlock();
TRACE("Created depthstencil state %p.\n", object); diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c index 41dbca24dbc..e280b6cd91b 100644 --- a/dlls/wined3d/context.c +++ b/dlls/wined3d/context.c @@ -3146,7 +3146,7 @@ void wined3d_context_gl_apply_blit_state(struct wined3d_context_gl *context_gl, context_invalidate_state(context, STATE_RENDER(WINED3D_RS_ALPHATESTENABLE)); } gl_info->gl_ops.gl.p_glDisable(GL_DEPTH_TEST); - context_invalidate_state(context, STATE_RENDER(WINED3D_RS_ZENABLE)); + context_invalidate_state(context, STATE_DEPTH_STENCIL); gl_info->gl_ops.gl.p_glDisable(GL_BLEND); gl_info->gl_ops.gl.p_glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); context_invalidate_state(context, STATE_BLEND); @@ -5193,7 +5193,8 @@ void draw_primitive(struct wined3d_device *device, const struct wined3d_state *s * that we never copy the stencil data.*/ DWORD location = context->render_offscreen ? dsv->resource->draw_binding : WINED3D_LOCATION_DRAWABLE;
- if (state->render_states[WINED3D_RS_ZWRITEENABLE] || state->render_states[WINED3D_RS_ZENABLE]) + if (!state->depth_stencil_state || state->render_states[WINED3D_RS_ZWRITEENABLE] + || state->depth_stencil_state->desc.depth) wined3d_rendertarget_view_load_location(dsv, context, location); else wined3d_rendertarget_view_prepare_location(dsv, context, location); diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c index 943ffe9af62..42dba4daa4b 100644 --- a/dlls/wined3d/cs.c +++ b/dlls/wined3d/cs.c @@ -49,6 +49,7 @@ enum wined3d_cs_op WINED3D_CS_OP_SET_SAMPLER, WINED3D_CS_OP_SET_SHADER, WINED3D_CS_OP_SET_BLEND_STATE, + WINED3D_CS_OP_SET_DEPTH_STENCIL_STATE, WINED3D_CS_OP_SET_RASTERIZER_STATE, WINED3D_CS_OP_SET_RENDER_STATE, WINED3D_CS_OP_SET_TEXTURE_STATE, @@ -268,6 +269,12 @@ struct wined3d_cs_set_blend_state unsigned int sample_mask; };
+struct wined3d_cs_set_depth_stencil_state +{ + enum wined3d_cs_op opcode; + struct wined3d_depth_stencil_state *state; +}; + struct wined3d_cs_set_rasterizer_state { enum wined3d_cs_op opcode; @@ -1148,7 +1155,7 @@ static void wined3d_cs_exec_set_depth_stencil_view(struct wined3d_cs *cs, const if (!prev != !op->view) { /* Swapping NULL / non NULL depth stencil affects the depth and tests */ - device_invalidate_state(device, STATE_RENDER(WINED3D_RS_ZENABLE)); + device_invalidate_state(device, STATE_DEPTH_STENCIL); device_invalidate_state(device, STATE_RENDER(WINED3D_RS_STENCILENABLE)); device_invalidate_state(device, STATE_RENDER(WINED3D_RS_STENCILWRITEMASK)); device_invalidate_state(device, STATE_RASTERIZER); @@ -1585,6 +1592,26 @@ void wined3d_cs_emit_set_blend_state(struct wined3d_cs *cs, struct wined3d_blend wined3d_cs_submit(cs, WINED3D_CS_QUEUE_DEFAULT); }
+static void wined3d_cs_exec_set_depth_stencil_state(struct wined3d_cs *cs, const void *data) +{ + const struct wined3d_cs_set_depth_stencil_state *op = data; + struct wined3d_state *state = &cs->state; + + state->depth_stencil_state = op->state; + device_invalidate_state(cs->device, STATE_DEPTH_STENCIL); +} + +void wined3d_cs_emit_set_depth_stencil_state(struct wined3d_cs *cs, struct wined3d_depth_stencil_state *state) +{ + struct wined3d_cs_set_depth_stencil_state *op; + + op = wined3d_cs_require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); + op->opcode = WINED3D_CS_OP_SET_DEPTH_STENCIL_STATE; + op->state = state; + + wined3d_cs_submit(cs, WINED3D_CS_QUEUE_DEFAULT); +} + static void wined3d_cs_exec_set_rasterizer_state(struct wined3d_cs *cs, const void *data) { const struct wined3d_cs_set_rasterizer_state *op = data; @@ -2536,6 +2563,7 @@ static void (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void /* WINED3D_CS_OP_SET_SAMPLER */ wined3d_cs_exec_set_sampler, /* WINED3D_CS_OP_SET_SHADER */ wined3d_cs_exec_set_shader, /* 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_RENDER_STATE */ wined3d_cs_exec_set_render_state, /* WINED3D_CS_OP_SET_TEXTURE_STATE */ wined3d_cs_exec_set_texture_state, diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 4c60c140784..3993b2a6fcf 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -532,6 +532,13 @@ static void device_leftover_blend_state(struct wine_rb_entry *entry, void *conte ERR("Leftover blend state %p.\n", blend_state); }
+static void device_leftover_depth_stencil_state(struct wine_rb_entry *entry, void *context) +{ + struct wined3d_depth_stencil_state *state = WINE_RB_ENTRY_VALUE(entry, struct wined3d_depth_stencil_state, entry); + + ERR("Leftover depth/stencil state %p.\n", state); +} + void wined3d_device_cleanup(struct wined3d_device *device) { unsigned int i; @@ -569,6 +576,7 @@ void wined3d_device_cleanup(struct wined3d_device *device) wine_rb_destroy(&device->samplers, device_leftover_sampler, NULL); wine_rb_destroy(&device->rasterizer_states, device_leftover_rasterizer_state, NULL); wine_rb_destroy(&device->blend_states, device_leftover_blend_state, NULL); + wine_rb_destroy(&device->depth_stencil_states, device_leftover_depth_stencil_state, NULL);
wined3d_decref(device->wined3d); device->wined3d = NULL; @@ -1124,6 +1132,13 @@ static void device_free_blend_state(struct wine_rb_entry *entry, void *context) wined3d_blend_state_decref(blend_state); }
+static void device_free_depth_stencil_state(struct wine_rb_entry *entry, void *context) +{ + struct wined3d_depth_stencil_state *state = WINE_RB_ENTRY_VALUE(entry, struct wined3d_depth_stencil_state, entry); + + wined3d_depth_stencil_state_decref(state); +} + void wined3d_device_uninit_3d(struct wined3d_device *device) { BOOL no3d = device->wined3d->flags & WINED3D_NO3D; @@ -1166,6 +1181,7 @@ void wined3d_device_uninit_3d(struct wined3d_device *device) wine_rb_clear(&device->samplers, device_free_sampler, NULL); wine_rb_clear(&device->rasterizer_states, device_free_rasterizer_state, NULL); wine_rb_clear(&device->blend_states, device_free_blend_state, NULL); + wine_rb_clear(&device->depth_stencil_states, device_free_depth_stencil_state, NULL);
LIST_FOR_EACH_ENTRY_SAFE(resource, cursor, &device->resources, struct wined3d_resource, resource_list_entry) { @@ -1713,6 +1729,33 @@ struct wined3d_blend_state * CDECL wined3d_device_get_blend_state(const struct w return state->blend_state; }
+void CDECL wined3d_device_set_depth_stencil_state(struct wined3d_device *device, + struct wined3d_depth_stencil_state *depth_stencil_state) +{ + struct wined3d_state *state = &device->state; + struct wined3d_depth_stencil_state *prev; + + TRACE("device %p, depth_stencil_state %p.\n", device, depth_stencil_state); + + prev = state->depth_stencil_state; + if (prev == depth_stencil_state) + return; + + if (depth_stencil_state) + wined3d_depth_stencil_state_incref(depth_stencil_state); + state->depth_stencil_state = depth_stencil_state; + wined3d_cs_emit_set_depth_stencil_state(device->cs, depth_stencil_state); + if (prev) + wined3d_depth_stencil_state_decref(prev); +} + +struct wined3d_depth_stencil_state * CDECL wined3d_device_get_depth_stencil_state(const struct wined3d_device *device) +{ + TRACE("device %p.\n", device); + + return device->state.depth_stencil_state; +} + void CDECL wined3d_device_set_rasterizer_state(struct wined3d_device *device, struct wined3d_rasterizer_state *rasterizer_state) { @@ -3503,7 +3546,7 @@ void CDECL wined3d_device_apply_stateblock(struct wined3d_device *device, const struct wined3d_stateblock_state *state = &stateblock->stateblock_state; const struct wined3d_saved_states *changed = &stateblock->changed; const unsigned int word_bit_count = sizeof(DWORD) * CHAR_BIT; - BOOL set_blend_state = FALSE, set_rasterizer_state = FALSE; + BOOL set_blend_state = FALSE, set_depth_stencil_state = FALSE, set_rasterizer_state = FALSE; unsigned int i, j, start, idx; struct wined3d_range range; uint32_t map; @@ -3608,6 +3651,10 @@ void CDECL wined3d_device_apply_stateblock(struct wined3d_device *device, set_blend_state = TRUE; break;
+ case WINED3D_RS_ZENABLE: + set_depth_stencil_state = TRUE; + break; + case WINED3D_RS_FILLMODE: case WINED3D_RS_CULLMODE: case WINED3D_RS_SLOPESCALEDEPTHBIAS: @@ -3739,6 +3786,32 @@ void CDECL wined3d_device_apply_stateblock(struct wined3d_device *device, } }
+ if (set_depth_stencil_state) + { + struct wined3d_depth_stencil_state *depth_stencil_state; + struct wined3d_depth_stencil_state_desc desc; + struct wine_rb_entry *entry; + + memset(&desc, 0, sizeof(desc)); + desc.depth = state->rs[WINED3D_RS_ZENABLE]; + + if ((entry = wine_rb_get(&device->depth_stencil_states, &desc))) + { + depth_stencil_state = WINE_RB_ENTRY_VALUE(entry, struct wined3d_depth_stencil_state, entry); + wined3d_device_set_depth_stencil_state(device, depth_stencil_state); + } + else if (SUCCEEDED(wined3d_depth_stencil_state_create(device, &desc, NULL, + &wined3d_null_parent_ops, &depth_stencil_state))) + { + wined3d_device_set_depth_stencil_state(device, depth_stencil_state); + if (wine_rb_put(&device->depth_stencil_states, &desc, &depth_stencil_state->entry) == -1) + { + ERR("Failed to insert depth/stencil state.\n"); + wined3d_depth_stencil_state_decref(depth_stencil_state); + } + } + } + for (i = 0; i < ARRAY_SIZE(changed->textureState); ++i) { map = changed->textureState[i]; @@ -4240,8 +4313,8 @@ HRESULT CDECL wined3d_device_validate_device(const struct wined3d_device *device } }
- if (state->render_states[WINED3D_RS_ZENABLE] || state->render_states[WINED3D_RS_ZWRITEENABLE] - || state->render_states[WINED3D_RS_STENCILENABLE]) + if (!state->depth_stencil_state || state->depth_stencil_state->desc.depth + || state->render_states[WINED3D_RS_ZWRITEENABLE] || state->render_states[WINED3D_RS_STENCILENABLE]) { struct wined3d_rendertarget_view *rt = device->state.fb.render_targets[0]; struct wined3d_rendertarget_view *ds = device->state.fb.depth_stencil; @@ -5343,6 +5416,7 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device, wine_rb_clear(&device->samplers, device_free_sampler, NULL); wine_rb_clear(&device->rasterizer_states, device_free_rasterizer_state, NULL); wine_rb_clear(&device->blend_states, device_free_blend_state, NULL); + wine_rb_clear(&device->depth_stencil_states, device_free_depth_stencil_state, NULL);
if (reset_state) { @@ -5540,6 +5614,13 @@ static int wined3d_blend_state_compare(const void *key, const struct wine_rb_ent return memcmp(&state->desc, key, sizeof(state->desc)); }
+static int wined3d_depth_stencil_state_compare(const void *key, const struct wine_rb_entry *entry) +{ + const struct wined3d_depth_stencil_state *state = WINE_RB_ENTRY_VALUE(entry, struct wined3d_depth_stencil_state, entry); + + return memcmp(&state->desc, key, sizeof(state->desc)); +} + static BOOL wined3d_select_feature_level(const struct wined3d_adapter *adapter, const enum wined3d_feature_level *levels, unsigned int level_count, enum wined3d_feature_level *selected_level) @@ -5601,6 +5682,7 @@ HRESULT wined3d_device_init(struct wined3d_device *device, struct wined3d *wined wine_rb_init(&device->samplers, wined3d_sampler_compare); wine_rb_init(&device->rasterizer_states, wined3d_rasterizer_state_compare); wine_rb_init(&device->blend_states, wined3d_blend_state_compare); + wine_rb_init(&device->depth_stencil_states, wined3d_depth_stencil_state_compare);
if (vertex_pipeline->vp_states && fragment_pipeline->states && FAILED(hr = compile_state_table(device->state_table, device->multistate_funcs, @@ -5611,6 +5693,7 @@ HRESULT wined3d_device_init(struct wined3d_device *device, struct wined3d *wined wine_rb_destroy(&device->samplers, NULL, NULL); wine_rb_destroy(&device->rasterizer_states, NULL, NULL); wine_rb_destroy(&device->blend_states, NULL, NULL); + wine_rb_destroy(&device->depth_stencil_states, NULL, NULL); wined3d_decref(device->wined3d); return hr; } @@ -5637,6 +5720,7 @@ err: wine_rb_destroy(&device->samplers, NULL, NULL); wine_rb_destroy(&device->rasterizer_states, NULL, NULL); wine_rb_destroy(&device->blend_states, NULL, NULL); + wine_rb_destroy(&device->depth_stencil_states, NULL, NULL); wined3d_decref(device->wined3d); return hr; } diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c index 42666e9ccc2..decfd996566 100644 --- a/dlls/wined3d/state.c +++ b/dlls/wined3d/state.c @@ -109,6 +109,67 @@ HRESULT CDECL wined3d_blend_state_create(struct wined3d_device *device, return WINED3D_OK; }
+ULONG CDECL wined3d_depth_stencil_state_incref(struct wined3d_depth_stencil_state *state) +{ + ULONG refcount = InterlockedIncrement(&state->refcount); + + TRACE("%p increasing refcount to %u.\n", state, refcount); + + return refcount; +} + +static void wined3d_depth_stencil_state_destroy_object(void *object) +{ + heap_free(object); +} + +ULONG CDECL wined3d_depth_stencil_state_decref(struct wined3d_depth_stencil_state *state) +{ + ULONG refcount = InterlockedDecrement(&state->refcount); + struct wined3d_device *device = state->device; + + TRACE("%p decreasing refcount to %u.\n", state, refcount); + + if (!refcount) + { + state->parent_ops->wined3d_object_destroyed(state->parent); + wined3d_cs_destroy_object(device->cs, wined3d_depth_stencil_state_destroy_object, state); + } + + return refcount; +} + +void * CDECL wined3d_depth_stencil_state_get_parent(const struct wined3d_depth_stencil_state *state) +{ + TRACE("depth_stencil_state %p.\n", state); + + return state->parent; +} + +HRESULT CDECL wined3d_depth_stencil_state_create(struct wined3d_device *device, + const struct wined3d_depth_stencil_state_desc *desc, void *parent, + const struct wined3d_parent_ops *parent_ops, struct wined3d_depth_stencil_state **state) +{ + struct wined3d_depth_stencil_state *object; + + TRACE("device %p, desc %p, parent %p, parent_ops %p, state %p.\n", + device, desc, parent, parent_ops, state); + + if (!(object = heap_alloc_zero(sizeof(*object)))) + return E_OUTOFMEMORY; + + object->refcount = 1; + object->desc = *desc; + object->parent = parent; + object->parent_ops = parent_ops; + object->device = device; + + TRACE("Created depth/stencil state %p.\n", object); + *state = object; + + return WINED3D_OK; +} + ULONG CDECL wined3d_rasterizer_state_incref(struct wined3d_rasterizer_state *state) { ULONG refcount = InterlockedIncrement(&state->refcount); @@ -230,10 +291,11 @@ static void state_lighting(struct wined3d_context *context, const struct wined3d } }
-static void state_zenable(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) +static void depth(struct wined3d_context *context, const struct wined3d_state *state) { - enum wined3d_depth_buffer_type zenable = state->render_states[WINED3D_RS_ZENABLE]; const struct wined3d_gl_info *gl_info = wined3d_context_gl(context)->gl_info; + const struct wined3d_depth_stencil_state *ds = state->depth_stencil_state; + enum wined3d_depth_buffer_type zenable = ds ? ds->desc.depth : WINED3D_ZB_TRUE;
/* No z test without depth stencil buffers */ if (!state->fb.depth_stencil) @@ -266,6 +328,11 @@ static void state_zenable(struct wined3d_context *context, const struct wined3d_ context_apply_state(context, state, STATE_TRANSFORM(WINED3D_TS_PROJECTION)); }
+static void depthstencil(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) +{ + depth(context, state); +} + static void cullmode(const struct wined3d_rasterizer_state *r, const struct wined3d_gl_info *gl_info) { enum wined3d_cull mode = r ? r->desc.cull_mode : WINED3D_CULL_BACK; @@ -4603,6 +4670,7 @@ const struct wined3d_state_entry_template misc_state_template[] = { STATE_BLEND_FACTOR, { STATE_BLEND_FACTOR, state_blend_factor }, EXT_BLEND_COLOR }, { STATE_BLEND_FACTOR, { STATE_BLEND_FACTOR, state_blend_factor_w}, WINED3D_GL_EXT_NONE }, { STATE_SAMPLE_MASK, { STATE_SAMPLE_MASK, state_multisampmask }, WINED3D_GL_EXT_NONE }, + { STATE_DEPTH_STENCIL, { STATE_DEPTH_STENCIL, depthstencil }, 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 }, @@ -4670,7 +4738,6 @@ const struct wined3d_state_entry_template misc_state_template[] = { STATE_INDEXBUFFER, { STATE_INDEXBUFFER, state_nop }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_ANTIALIAS), { STATE_RENDER(WINED3D_RS_ANTIALIAS), state_antialias }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_TEXTUREPERSPECTIVE), { STATE_RENDER(WINED3D_RS_TEXTUREPERSPECTIVE), state_nop }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3D_RS_ZENABLE), { STATE_RENDER(WINED3D_RS_ZENABLE), state_zenable }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_WRAPU), { STATE_RENDER(WINED3D_RS_WRAPU), state_wrapu }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_WRAPV), { STATE_RENDER(WINED3D_RS_WRAPV), state_wrapv }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_LINEPATTERN), { STATE_RENDER(WINED3D_RS_LINEPATTERN), state_linepattern }, WINED3D_GL_LEGACY_CONTEXT }, @@ -5493,7 +5560,7 @@ static void validate_state_table(struct wined3d_state_entry *state_table) { { 1, 1}, { 3, 3}, - { 8, 8}, + { 7, 8}, { 17, 22}, { 27, 27}, { 40, 40}, @@ -5544,6 +5611,7 @@ static void validate_state_table(struct wined3d_state_entry *state_table) STATE_BLEND, STATE_BLEND_FACTOR, STATE_SAMPLE_MASK, + STATE_DEPTH_STENCIL, }; unsigned int i, current;
diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c index 916d90cf215..753d0080fd7 100644 --- a/dlls/wined3d/utils.c +++ b/dlls/wined3d/utils.c @@ -5247,6 +5247,8 @@ const char *debug_d3dstate(DWORD state) return "STATE_BLEND_FACTOR"; if (STATE_IS_SAMPLE_MASK(state)) return "STATE_SAMPLE_MASK"; + if (STATE_IS_DEPTH_STENCIL(state)) + return "STATE_DEPTH_STENCIL";
return wine_dbg_sprintf("UNKNOWN_STATE(%#x)", state); } @@ -5495,8 +5497,11 @@ void get_projection_matrix(const struct wined3d_context *context, const struct w float y_offset = flip ? (center_offset - (2.0f * y) - h) / h : (center_offset - (2.0f * y) - h) / -h; - enum wined3d_depth_buffer_type zenable = state->fb.depth_stencil ? - state->render_states[WINED3D_RS_ZENABLE] : WINED3D_ZB_FALSE; + enum wined3d_depth_buffer_type zenable = WINED3D_ZB_TRUE; + if (!state->fb.depth_stencil) + zenable = WINED3D_ZB_FALSE; + else if (state->depth_stencil_state) + zenable = state->depth_stencil_state->desc.depth; float z_scale = zenable ? clip_control ? 1.0f : 2.0f : 0.0f; float z_offset = zenable ? clip_control ? 0.0f : -1.0f : 0.0f; const struct wined3d_matrix projection = diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec index 22a9a9dd740..48dc739784c 100644 --- a/dlls/wined3d/wined3d.spec +++ b/dlls/wined3d/wined3d.spec @@ -32,6 +32,11 @@ @ cdecl wined3d_buffer_get_resource(ptr) @ cdecl wined3d_buffer_incref(ptr)
+@ cdecl wined3d_depth_stencil_state_create(ptr ptr ptr ptr ptr) +@ cdecl wined3d_depth_stencil_state_decref(ptr) +@ cdecl wined3d_depth_stencil_state_get_parent(ptr) +@ cdecl wined3d_depth_stencil_state_incref(ptr) + @ cdecl wined3d_device_acquire_focus_window(ptr ptr) @ cdecl wined3d_device_apply_stateblock(ptr ptr) @ cdecl wined3d_device_begin_scene(ptr) @@ -62,6 +67,7 @@ @ cdecl wined3d_device_get_cs_resource_view(ptr long) @ cdecl wined3d_device_get_cs_sampler(ptr long) @ cdecl wined3d_device_get_cs_uav(ptr long) +@ cdecl wined3d_device_get_depth_stencil_state(ptr) @ cdecl wined3d_device_get_depth_stencil_view(ptr) @ cdecl wined3d_device_get_device_caps(ptr ptr) @ cdecl wined3d_device_get_display_mode(ptr long ptr ptr) @@ -116,6 +122,7 @@ @ cdecl wined3d_device_set_cs_uav(ptr long ptr long) @ cdecl wined3d_device_set_cursor_position(ptr long long long) @ cdecl wined3d_device_set_cursor_properties(ptr long long ptr long) +@ cdecl wined3d_device_set_depth_stencil_state(ptr ptr) @ cdecl wined3d_device_set_depth_stencil_view(ptr ptr) @ cdecl wined3d_device_set_dialog_box_mode(ptr long) @ cdecl wined3d_device_set_domain_shader(ptr ptr) diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index db17305c76b..a051406a7a3 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -1705,7 +1705,10 @@ enum wined3d_pipeline #define STATE_STREAM_OUTPUT (STATE_COLOR_KEY + 1) #define STATE_IS_STREAM_OUTPUT(a) ((a) == STATE_STREAM_OUTPUT)
-#define STATE_BLEND (STATE_STREAM_OUTPUT + 1) +#define STATE_DEPTH_STENCIL (STATE_STREAM_OUTPUT + 1) +#define STATE_IS_DEPTH_STENCIL(a) ((a) == STATE_DEPTH_STENCIL) + +#define STATE_BLEND (STATE_DEPTH_STENCIL + 1) #define STATE_IS_BLEND(a) ((a) == STATE_BLEND)
#define STATE_BLEND_FACTOR (STATE_BLEND + 1) @@ -3154,6 +3157,18 @@ struct wined3d_blend_state struct wine_rb_entry entry; };
+struct wined3d_depth_stencil_state +{ + LONG refcount; + struct wined3d_depth_stencil_state_desc desc; + + void *parent; + const struct wined3d_parent_ops *parent_ops; + + struct wined3d_device *device; + struct wine_rb_entry entry; +}; + struct wined3d_rasterizer_state { LONG refcount; @@ -3235,6 +3250,7 @@ struct wined3d_state struct wined3d_blend_state *blend_state; struct wined3d_color blend_factor; unsigned int sample_mask; + struct wined3d_depth_stencil_state *depth_stencil_state; struct wined3d_rasterizer_state *rasterizer_state; };
@@ -3303,7 +3319,7 @@ struct wined3d_device
struct list resources; /* a linked list to track resources created by the device */ struct list shaders; /* a linked list to track shaders (pixel and vertex) */ - struct wine_rb_tree samplers, rasterizer_states, blend_states; + struct wine_rb_tree samplers, rasterizer_states, blend_states, depth_stencil_states;
/* Render Target Support */ struct wined3d_rendertarget_view *auto_depth_stencil_view; @@ -4094,6 +4110,8 @@ void wined3d_cs_emit_set_color_key(struct wined3d_cs *cs, struct wined3d_texture WORD flags, const struct wined3d_color_key *color_key) DECLSPEC_HIDDEN; void wined3d_cs_emit_set_constant_buffer(struct wined3d_cs *cs, enum wined3d_shader_type type, UINT cb_idx, struct wined3d_buffer *buffer) DECLSPEC_HIDDEN; +void wined3d_cs_emit_set_depth_stencil_state(struct wined3d_cs *cs, + struct wined3d_depth_stencil_state *state) DECLSPEC_HIDDEN; void wined3d_cs_emit_set_depth_stencil_view(struct wined3d_cs *cs, struct wined3d_rendertarget_view *view) DECLSPEC_HIDDEN; void wined3d_cs_emit_set_index_buffer(struct wined3d_cs *cs, struct wined3d_buffer *buffer, diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index 3b541714f4f..55dad1bfd6b 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -2033,6 +2033,11 @@ struct wined3d_blend_state_desc } rt[WINED3D_MAX_RENDER_TARGETS]; };
+struct wined3d_depth_stencil_state_desc +{ + enum wined3d_depth_buffer_type depth; +}; + struct wined3d_rasterizer_state_desc { enum wined3d_fill_mode fill_mode; @@ -2191,6 +2196,7 @@ struct wined3d; struct wined3d_adapter; struct wined3d_blend_state; struct wined3d_buffer; +struct wined3d_depth_stencil_state; struct wined3d_device; struct wined3d_output; struct wined3d_palette; @@ -2349,6 +2355,7 @@ struct wined3d_shader_resource_view * __cdecl wined3d_device_get_cs_resource_vie struct wined3d_sampler * __cdecl wined3d_device_get_cs_sampler(const struct wined3d_device *device, unsigned int idx); struct wined3d_unordered_access_view * __cdecl wined3d_device_get_cs_uav(const struct wined3d_device *device, unsigned int idx); +struct wined3d_depth_stencil_state * __cdecl wined3d_device_get_depth_stencil_state(const struct wined3d_device *device); struct wined3d_rendertarget_view * __cdecl wined3d_device_get_depth_stencil_view(const struct wined3d_device *device); HRESULT __cdecl wined3d_device_get_device_caps(const struct wined3d_device *device, struct wined3d_caps *caps); HRESULT __cdecl wined3d_device_get_display_mode(const struct wined3d_device *device, UINT swapchain_idx, @@ -2435,6 +2442,8 @@ void __cdecl wined3d_device_set_cursor_position(struct wined3d_device *device, int x_screen_space, int y_screen_space, DWORD flags); HRESULT __cdecl wined3d_device_set_cursor_properties(struct wined3d_device *device, UINT x_hotspot, UINT y_hotspot, struct wined3d_texture *texture, unsigned int sub_resource_idx); +void __cdecl wined3d_device_set_depth_stencil_state(struct wined3d_device *device, + struct wined3d_depth_stencil_state *depth_stencil_state); HRESULT __cdecl wined3d_device_set_depth_stencil_view(struct wined3d_device *device, struct wined3d_rendertarget_view *view); HRESULT __cdecl wined3d_device_set_dialog_box_mode(struct wined3d_device *device, BOOL enable_dialogs); @@ -2618,6 +2627,13 @@ ULONG __cdecl wined3d_blend_state_decref(struct wined3d_blend_state *state); void * __cdecl wined3d_blend_state_get_parent(const struct wined3d_blend_state *state); ULONG __cdecl wined3d_blend_state_incref(struct wined3d_blend_state *state);
+HRESULT __cdecl wined3d_depth_stencil_state_create(struct wined3d_device *device, + const struct wined3d_depth_stencil_state_desc *desc, void *parent, + const struct wined3d_parent_ops *parent_ops, struct wined3d_depth_stencil_state **state); +ULONG __cdecl wined3d_depth_stencil_state_decref(struct wined3d_depth_stencil_state *state); +void * __cdecl wined3d_depth_stencil_state_get_parent(const struct wined3d_depth_stencil_state *state); +ULONG __cdecl wined3d_depth_stencil_state_incref(struct wined3d_depth_stencil_state *state); + HRESULT __cdecl wined3d_rasterizer_state_create(struct wined3d_device *device, const struct wined3d_rasterizer_state_desc *desc, void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_rasterizer_state **state);
Signed-off-by: Chip Davis cdavis@codeweavers.com --- dlls/d3d11/device.c | 2 -- dlls/d3d11/state.c | 1 + dlls/wined3d/context.c | 4 ++-- dlls/wined3d/device.c | 6 ++++-- dlls/wined3d/state.c | 29 ++++++++++++----------------- dlls/wined3d/surface.c | 2 +- include/wine/wined3d.h | 1 + 7 files changed, 21 insertions(+), 24 deletions(-)
diff --git a/dlls/d3d11/device.c b/dlls/d3d11/device.c index ed290750ac3..72203ee80c0 100644 --- a/dlls/d3d11/device.c +++ b/dlls/d3d11/device.c @@ -726,7 +726,6 @@ static void STDMETHODCALLTYPE d3d11_immediate_context_OMSetBlendState(ID3D11Devi
static void set_default_depth_stencil_state(struct wined3d_device *wined3d_device) { - wined3d_device_set_render_state(wined3d_device, WINED3D_RS_ZWRITEENABLE, D3D11_DEPTH_WRITE_MASK_ALL); wined3d_device_set_render_state(wined3d_device, WINED3D_RS_ZFUNC, WINED3D_CMP_LESS); wined3d_device_set_render_state(wined3d_device, WINED3D_RS_STENCILENABLE, FALSE); } @@ -759,7 +758,6 @@ static void STDMETHODCALLTYPE d3d11_immediate_context_OMSetDepthStencilState(ID3 wined3d_device_set_depth_stencil_state(device->wined3d_device, device->depth_stencil_state->wined3d_state); if (desc->DepthEnable) { - wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_ZWRITEENABLE, desc->DepthWriteMask); wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_ZFUNC, desc->DepthFunc); }
diff --git a/dlls/d3d11/state.c b/dlls/d3d11/state.c index 6d3736a1d95..503842dce0b 100644 --- a/dlls/d3d11/state.c +++ b/dlls/d3d11/state.c @@ -710,6 +710,7 @@ static HRESULT d3d_depthstencil_state_init(struct d3d_depthstencil_state *state, HRESULT hr;
wined3d_desc.depth = desc->DepthEnable; + wined3d_desc.depth_writemask = desc->DepthWriteMask;
if (wine_rb_put(&device->depthstencil_states, desc, &state->entry) == -1) { diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c index e280b6cd91b..81a51b51ce7 100644 --- a/dlls/wined3d/context.c +++ b/dlls/wined3d/context.c @@ -5193,7 +5193,7 @@ void draw_primitive(struct wined3d_device *device, const struct wined3d_state *s * that we never copy the stencil data.*/ DWORD location = context->render_offscreen ? dsv->resource->draw_binding : WINED3D_LOCATION_DRAWABLE;
- if (!state->depth_stencil_state || state->render_states[WINED3D_RS_ZWRITEENABLE] + if (!state->depth_stencil_state || state->depth_stencil_state->desc.depth_writemask || state->depth_stencil_state->desc.depth) wined3d_rendertarget_view_load_location(dsv, context, location); else @@ -5210,7 +5210,7 @@ void draw_primitive(struct wined3d_device *device, const struct wined3d_state *s return; }
- if (dsv && state->render_states[WINED3D_RS_ZWRITEENABLE]) + if (dsv && (!state->depth_stencil_state || state->depth_stencil_state->desc.depth_writemask)) { DWORD location = context->render_offscreen ? dsv->resource->draw_binding : WINED3D_LOCATION_DRAWABLE;
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 3993b2a6fcf..1b7cfd062ee 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -399,7 +399,7 @@ void device_clear_render_targets(struct wined3d_device *device, UINT rt_count, c if (flags & WINED3DCLEAR_ZBUFFER) { gl_info->gl_ops.gl.p_glDepthMask(GL_TRUE); - context_invalidate_state(context, STATE_RENDER(WINED3D_RS_ZWRITEENABLE)); + context_invalidate_state(context, STATE_DEPTH_STENCIL); gl_info->gl_ops.gl.p_glClearDepth(depth); checkGLcall("glClearDepth"); clear_mask = clear_mask | GL_DEPTH_BUFFER_BIT; @@ -3652,6 +3652,7 @@ void CDECL wined3d_device_apply_stateblock(struct wined3d_device *device, break;
case WINED3D_RS_ZENABLE: + case WINED3D_RS_ZWRITEENABLE: set_depth_stencil_state = TRUE; break;
@@ -3794,6 +3795,7 @@ void CDECL wined3d_device_apply_stateblock(struct wined3d_device *device,
memset(&desc, 0, sizeof(desc)); desc.depth = state->rs[WINED3D_RS_ZENABLE]; + desc.depth_writemask = state->rs[WINED3D_RS_ZWRITEENABLE];
if ((entry = wine_rb_get(&device->depth_stencil_states, &desc))) { @@ -4314,7 +4316,7 @@ HRESULT CDECL wined3d_device_validate_device(const struct wined3d_device *device }
if (!state->depth_stencil_state || state->depth_stencil_state->desc.depth - || state->render_states[WINED3D_RS_ZWRITEENABLE] || state->render_states[WINED3D_RS_STENCILENABLE]) + || state->depth_stencil_state->desc.depth_writemask || state->render_states[WINED3D_RS_STENCILENABLE]) { struct wined3d_rendertarget_view *rt = device->state.fb.render_targets[0]; struct wined3d_rendertarget_view *ds = device->state.fb.depth_stencil; diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c index decfd996566..dcb7840fa10 100644 --- a/dlls/wined3d/state.c +++ b/dlls/wined3d/state.c @@ -324,6 +324,17 @@ static void depth(struct wined3d_context *context, const struct wined3d_state *s break; }
+ if (!ds || ds->desc.depth_writemask) + { + gl_info->gl_ops.gl.p_glDepthMask(GL_TRUE); + checkGLcall("glDepthMask TRUE"); + } + else + { + gl_info->gl_ops.gl.p_glDepthMask(GL_FALSE); + checkGLcall("glDepthMask FALSE"); + } + if (context->last_was_rhw && !isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_PROJECTION))) context_apply_state(context, state, STATE_TRANSFORM(WINED3D_TS_PROJECTION)); } @@ -401,22 +412,6 @@ static void state_ditherenable(struct wined3d_context *context, const struct win } }
-static void state_zwriteenable(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; - - if (state->render_states[WINED3D_RS_ZWRITEENABLE]) - { - gl_info->gl_ops.gl.p_glDepthMask(1); - checkGLcall("glDepthMask(1)"); - } - else - { - gl_info->gl_ops.gl.p_glDepthMask(0); - checkGLcall("glDepthMask(0)"); - } -} - GLenum wined3d_gl_compare_func(enum wined3d_cmp_func f) { switch (f) @@ -4745,7 +4740,6 @@ const struct wined3d_state_entry_template misc_state_template[] = { STATE_RENDER(WINED3D_RS_MONOENABLE), { STATE_RENDER(WINED3D_RS_MONOENABLE), state_monoenable }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_ROP2), { STATE_RENDER(WINED3D_RS_ROP2), state_rop2 }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_PLANEMASK), { STATE_RENDER(WINED3D_RS_PLANEMASK), state_planemask }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3D_RS_ZWRITEENABLE), { STATE_RENDER(WINED3D_RS_ZWRITEENABLE), state_zwriteenable }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_LASTPIXEL), { STATE_RENDER(WINED3D_RS_LASTPIXEL), state_lastpixel }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_ZFUNC), { STATE_RENDER(WINED3D_RS_ZFUNC), state_zfunc }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_DITHERENABLE), { STATE_RENDER(WINED3D_RS_DITHERENABLE), state_ditherenable }, WINED3D_GL_EXT_NONE }, @@ -5561,6 +5555,7 @@ static void validate_state_table(struct wined3d_state_entry *state_table) { 1, 1}, { 3, 3}, { 7, 8}, + { 14, 14}, { 17, 22}, { 27, 27}, { 40, 40}, diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c index e965203950e..c10c2039cc7 100644 --- a/dlls/wined3d/surface.c +++ b/dlls/wined3d/surface.c @@ -117,7 +117,7 @@ static void texture2d_depth_blt_fbo(const struct wined3d_device *device, struct if (gl_mask & GL_DEPTH_BUFFER_BIT) { gl_info->gl_ops.gl.p_glDepthMask(GL_TRUE); - context_invalidate_state(context, STATE_RENDER(WINED3D_RS_ZWRITEENABLE)); + context_invalidate_state(context, STATE_DEPTH_STENCIL); } if (gl_mask & GL_STENCIL_BUFFER_BIT) { diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index 55dad1bfd6b..7f5aa5cb038 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -2036,6 +2036,7 @@ struct wined3d_blend_state_desc struct wined3d_depth_stencil_state_desc { enum wined3d_depth_buffer_type depth; + unsigned int depth_writemask; };
struct wined3d_rasterizer_state_desc
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=69432
Your paranoid android.
=== debiant (32 bit report) ===
d3d11: Unhandled exception: page fault on read access to 0x00000061 in 32-bit code (0x6515c2cf).
d3d8: stateblock.c:1155: Test failed: Chain stage 2, render state 0xa1: expected 0x1, got 0. stateblock.c:1155: Test failed: Chain stage 2, render state 0xa1: expected 0x1, got 0.
Report validation errors: d3d11:d3d11 crashed (c0000005)
=== debiant (32 bit Chinese:China report) ===
d3d11: Unhandled exception: page fault on read access to 0x000076b1 in 32-bit code (0x6515c2cf).
d3d8: stateblock.c:1155: Test failed: Chain stage 2, render state 0xa1: expected 0x1, got 0. stateblock.c:1155: Test failed: Chain stage 2, render state 0xa1: expected 0x1, got 0.
Report validation errors: d3d11:d3d11 crashed (c0000005)
=== debiant (32 bit WoW report) ===
d3d11: d3d11.c:6118: Test succeeded inside todo block: Got unexpected PrimitivesStorageNeeded: 0.
d3d8: stateblock.c:1155: Test failed: Chain stage 2, render state 0xa1: expected 0x1, got 0. stateblock.c:1155: Test failed: Chain stage 2, render state 0xa1: expected 0x1, got 0.
Report validation errors: d3d11:d3d11 has no test summary line (early exit of the main process?) d3d11:d3d11 has unaccounted for failure messages d3d11:d3d11 has unaccounted for todo messages d3d11:d3d11 has unaccounted for skip messages d3d11:d3d11 returned success despite having failures
=== debiant (64 bit WoW report) ===
d3d11: Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x6515c2ca).
d3d8: stateblock.c:1155: Test failed: Chain stage 2, render state 0xa1: expected 0x1, got 0. stateblock.c:1155: Test failed: Chain stage 2, render state 0xa1: expected 0x1, got 0.
Report validation errors: d3d11:d3d11 crashed (c0000005)
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=69431
Your paranoid android.
=== debiant (32 bit report) ===
d3d11: Unhandled exception: page fault on read access to 0x00000039 in 32-bit code (0x6515c30f).
d3d8: stateblock.c:1155: Test failed: Chain stage 2, render state 0xa1: expected 0x1, got 0. stateblock.c:1155: Test failed: Chain stage 2, render state 0xa1: expected 0x1, got 0.
Report validation errors: d3d11:d3d11 crashed (c0000005)
=== debiant (32 bit Chinese:China report) ===
d3d8: stateblock.c:1155: Test failed: Chain stage 2, render state 0xa1: expected 0x1, got 0. stateblock.c:1155: Test failed: Chain stage 2, render state 0xa1: expected 0x1, got 0.
Report validation errors: d3d11:d3d11 has no test summary line (early exit of the main process?) d3d11:d3d11 has unaccounted for failure messages d3d11:d3d11 has unaccounted for todo messages d3d11:d3d11 has unaccounted for skip messages d3d11:d3d11 returned success despite having failures
=== debiant (32 bit WoW report) ===
d3d11: Unhandled exception: page fault on read access to 0x00000eb9 in 32-bit code (0x6515c30f).
d3d8: stateblock.c:1155: Test failed: Chain stage 2, render state 0xa1: expected 0x1, got 0. stateblock.c:1155: Test failed: Chain stage 2, render state 0xa1: expected 0x1, got 0.
Report validation errors: d3d11:d3d11 crashed (c0000005)
=== debiant (64 bit WoW report) ===
d3d8: stateblock.c:1155: Test failed: Chain stage 2, render state 0xa1: expected 0x1, got 0. stateblock.c:1155: Test failed: Chain stage 2, render state 0xa1: expected 0x1, got 0.
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=69430
Your paranoid android.
=== debiant (32 bit report) ===
d3d8: stateblock.c:1155: Test failed: Chain stage 2, render state 0xa1: expected 0x1, got 0. stateblock.c:1155: Test failed: Chain stage 2, render state 0xa1: expected 0x1, got 0.
=== debiant (32 bit Chinese:China report) ===
d3d8: stateblock.c:1155: Test failed: Chain stage 2, render state 0xa1: expected 0x1, got 0. stateblock.c:1155: Test failed: Chain stage 2, render state 0xa1: expected 0x1, got 0.
=== debiant (32 bit WoW report) ===
d3d8: stateblock.c:1155: Test failed: Chain stage 2, render state 0xa1: expected 0x1, got 0. stateblock.c:1155: Test failed: Chain stage 2, render state 0xa1: expected 0x1, got 0.
=== debiant (64 bit WoW report) ===
d3d8: stateblock.c:1155: Test failed: Chain stage 2, render state 0xa1: expected 0x1, got 0. stateblock.c:1155: Test failed: Chain stage 2, render state 0xa1: expected 0x1, got 0.
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=69429
Your paranoid android.
=== debiant (32 bit report) ===
d3d8: stateblock.c:1155: Test failed: Chain stage 2, render state 0xa1: expected 0x1, got 0. stateblock.c:1155: Test failed: Chain stage 2, render state 0xa1: expected 0x1, got 0.
=== debiant (32 bit Chinese:China report) ===
d3d8: stateblock.c:1155: Test failed: Chain stage 2, render state 0xa1: expected 0x1, got 0. stateblock.c:1155: Test failed: Chain stage 2, render state 0xa1: expected 0x1, got 0.
=== debiant (32 bit WoW report) ===
d3d8: stateblock.c:1155: Test failed: Chain stage 2, render state 0xa1: expected 0x1, got 0. stateblock.c:1155: Test failed: Chain stage 2, render state 0xa1: expected 0x1, got 0.
=== debiant (64 bit WoW report) ===
d3d8: stateblock.c:1155: Test failed: Chain stage 2, render state 0xa1: expected 0x1, got 0. stateblock.c:1155: Test failed: Chain stage 2, render state 0xa1: expected 0x1, got 0.
On 4/13/20 2:27 AM, Chip Davis wrote:
I'm curious as to why Zeb didn't move this with the other rasterizer states. Perhaps it's because the default is different in d3d8/9 vs. d3d10+.
Signed-off-by: Chip Davis cdavis@codeweavers.com
The problem isn't just that the default state is different, but that changing the default state to disabled (even just for d3d11) breaks resolve for blits. I don't understand that code very well and I didn't want to spend that long trying to find the right places to invalidate it.
I suspect also the preferred solution is to always default to FALSE in wined3d and use wined3d_stateblock_set_render_state() in the client libraries, as is done for WINED3D_RS_ZENABLE and WINED3D_RS_POINTSIZE_MIN in d3d8.
dlls/d3d11/device.c | 15 +++---------- dlls/d3d11/state.c | 1 + dlls/wined3d/device.c | 2 ++ dlls/wined3d/state.c | 46 +++++++++++++++++++-------------------- dlls/wined3d/stateblock.c | 4 ++++ include/wine/wined3d.h | 1 + 6 files changed, 33 insertions(+), 36 deletions(-)
diff --git a/dlls/d3d11/device.c b/dlls/d3d11/device.c index 7544bc86f4b..7c75431780c 100644 --- a/dlls/d3d11/device.c +++ b/dlls/d3d11/device.c @@ -896,18 +896,9 @@ static void STDMETHODCALLTYPE d3d11_immediate_context_RSSetState(ID3D11DeviceCon TRACE("iface %p, rasterizer_state %p.\n", iface, rasterizer_state);
wined3d_mutex_lock();
- if (!(rasterizer_state_impl = unsafe_impl_from_ID3D11RasterizerState(rasterizer_state)))
- {
wined3d_device_set_rasterizer_state(device->wined3d_device, NULL);
wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_MULTISAMPLEANTIALIAS, FALSE);
wined3d_mutex_unlock();
return;
- }
- wined3d_device_set_rasterizer_state(device->wined3d_device, rasterizer_state_impl->wined3d_state);
- desc = &rasterizer_state_impl->desc;
- wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_MULTISAMPLEANTIALIAS, desc->MultisampleEnable);
- rasterizer_state_impl = unsafe_impl_from_ID3D11RasterizerState(rasterizer_state);
- wined3d_device_set_rasterizer_state(device->wined3d_device,
}rasterizer_state_impl ? rasterizer_state_impl->wined3d_state : NULL); wined3d_mutex_unlock();
diff --git a/dlls/d3d11/state.c b/dlls/d3d11/state.c index 32ef44091c4..6d7f70664e7 100644 --- a/dlls/d3d11/state.c +++ b/dlls/d3d11/state.c @@ -1118,6 +1118,7 @@ static HRESULT d3d_rasterizer_state_init(struct d3d_rasterizer_state *state, str wined3d_desc.scale_bias = desc->SlopeScaledDepthBias; wined3d_desc.depth_clip = desc->DepthClipEnable; wined3d_desc.scissor = desc->ScissorEnable;
wined3d_desc.multisample = desc->MultisampleEnable; wined3d_desc.line_antialias = desc->AntialiasedLineEnable;
/* We cannot fail after creating a wined3d_rasterizer_state object. It
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index ee007568d46..8baf9b9df19 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -3608,6 +3608,7 @@ void CDECL wined3d_device_apply_stateblock(struct wined3d_device *device, case WINED3D_RS_SLOPESCALEDEPTHBIAS: case WINED3D_RS_DEPTHBIAS: case WINED3D_RS_SCISSORTESTENABLE:
case WINED3D_RS_MULTISAMPLEANTIALIAS: case WINED3D_RS_ANTIALIASEDLINEENABLE: set_rasterizer_state = TRUE; break;
@@ -3639,6 +3640,7 @@ void CDECL wined3d_device_apply_stateblock(struct wined3d_device *device, desc.scale_bias = bias.f; desc.depth_clip = TRUE; desc.scissor = state->rs[WINED3D_RS_SCISSORTESTENABLE];
desc.multisample = state->rs[WINED3D_RS_MULTISAMPLEANTIALIAS]; desc.line_antialias = state->rs[WINED3D_RS_ANTIALIASEDLINEENABLE]; if ((entry = wine_rb_get(&device->rasterizer_states, &desc)))
diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c index 1cb9f222eab..d7792f46168 100644 --- a/dlls/wined3d/state.c +++ b/dlls/wined3d/state.c @@ -1776,28 +1776,6 @@ static void state_wrap(struct wined3d_context *context, const struct wined3d_sta FIXME("(WINED3D_RS_WRAP0) Texture wrapping not yet supported.\n"); }
-static void state_msaa_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) -{
- if (state->render_states[WINED3D_RS_MULTISAMPLEANTIALIAS])
WARN("Multisample antialiasing not supported by GL.\n");
-}
-static void state_msaa(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;
- if (state->render_states[WINED3D_RS_MULTISAMPLEANTIALIAS])
- {
gl_info->gl_ops.gl.p_glEnable(GL_MULTISAMPLE_ARB);
checkGLcall("glEnable(GL_MULTISAMPLE_ARB)");
- }
- else
- {
gl_info->gl_ops.gl.p_glDisable(GL_MULTISAMPLE_ARB);
checkGLcall("glDisable(GL_MULTISAMPLE_ARB)");
- }
-}
- static void line_antialias(const struct wined3d_rasterizer_state *r, const struct wined3d_gl_info *gl_info) { if (r && r->desc.line_antialias)
@@ -4407,6 +4385,25 @@ static void depth_clip(const struct wined3d_rasterizer_state *r, const struct wi checkGLcall("depth clip"); }
+static void multisample(const struct wined3d_rasterizer_state *r, const struct wined3d_gl_info *gl_info) +{
- if (r && r->desc.multisample)
- {
if (gl_info->supported[ARB_MULTISAMPLE])
{
gl_info->gl_ops.gl.p_glEnable(GL_MULTISAMPLE);
checkGLcall("glEnable GL_MULTISAMPLE");
}
else
WARN("Multisample antialiasing not supported by GL.\n");
- }
- else if (gl_info->supported[ARB_MULTISAMPLE])
- {
gl_info->gl_ops.gl.p_glDisable(GL_MULTISAMPLE);
checkGLcall("glDisable GL_MULTISAMPLE");
- }
+}
- static void rasterizer(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;
@@ -4424,6 +4421,7 @@ static void rasterizer(struct wined3d_context *context, const struct wined3d_sta cullmode(r, gl_info); depth_clip(r, gl_info); scissor(r, gl_info);
- multisample(r, gl_info); line_antialias(r, gl_info); }
@@ -4442,6 +4440,7 @@ static void rasterizer_cc(struct wined3d_context *context, const struct wined3d_ cullmode(r, gl_info); depth_clip(r, gl_info); scissor(r, gl_info);
- multisample(r, gl_info); line_antialias(r, gl_info); }
@@ -4736,8 +4735,6 @@ const struct wined3d_state_entry_template misc_state_template[] = { 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 }, { STATE_RENDER(WINED3D_RS_MULTISAMPLEMASK), { STATE_RENDER(WINED3D_RS_MULTISAMPLEMASK), state_multisampmask }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_DEBUGMONITORTOKEN), { STATE_RENDER(WINED3D_RS_DEBUGMONITORTOKEN), state_debug_monitor }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_ZVISIBLE), { STATE_RENDER(WINED3D_RS_ZVISIBLE), state_zvisible }, WINED3D_GL_EXT_NONE },
@@ -5505,6 +5502,7 @@ static void validate_state_table(struct wined3d_state_entry *state_table) { 47, 47}, { 61, 127}, {149, 150},
{161, 161}, {168, 169}, {171, 171}, {174, 177},
diff --git a/dlls/wined3d/stateblock.c b/dlls/wined3d/stateblock.c index 7e97c84c19e..84b64eae7aa 100644 --- a/dlls/wined3d/stateblock.c +++ b/dlls/wined3d/stateblock.c @@ -1925,6 +1925,10 @@ static HRESULT stateblock_init(struct wined3d_stateblock *stateblock, const stru if (type == WINED3D_SBT_RECORDED || type == WINED3D_SBT_PRIMARY) return WINED3D_OK;
/* The default multisample state in d3d9 and under is TRUE, but FALSE in d3d10 and up. Force the multisample
* antialiasing state to be marked changed regardless of the stateblock type to ensure it is set correctly. */
stateblock->changed.renderState[WINED3D_RS_MULTISAMPLEANTIALIAS >> 5] |= 1u << (WINED3D_RS_MULTISAMPLEANTIALIAS & 0x1f);
TRACE("Updating changed flags appropriate for type %#x.\n", type); switch (type)
diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index d3eb8100cd8..f9a0d9e0f89 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -2043,6 +2043,7 @@ struct wined3d_rasterizer_state_desc float scale_bias; BOOL depth_clip; BOOL scissor;
- BOOL multisample; BOOL line_antialias; };