Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/d3d10/d3d10_private.h | 12 +++++-- dlls/d3d10/effect.c | 74 +++++++++++++++++++------------------- dlls/d3d10/tests/effect.c | 28 +++++++++++++++ 3 files changed, 75 insertions(+), 39 deletions(-)
diff --git a/dlls/d3d10/d3d10_private.h b/dlls/d3d10/d3d10_private.h index 1ebbbd11ea3..f799d27b323 100644 --- a/dlls/d3d10/d3d10_private.h +++ b/dlls/d3d10/d3d10_private.h @@ -226,6 +226,12 @@ struct d3d10_effect_variable } u; };
+struct d3d10_effect_pass_shader_desc +{ + struct d3d10_effect_variable *shader; + unsigned int index; +}; + /* ID3D10EffectPass */ struct d3d10_effect_pass { @@ -238,9 +244,9 @@ struct d3d10_effect_pass struct d3d10_effect_object *objects; struct d3d10_effect_variable *annotations;
- D3D10_PASS_SHADER_DESC vs; - D3D10_PASS_SHADER_DESC ps; - D3D10_PASS_SHADER_DESC gs; + struct d3d10_effect_pass_shader_desc vs; + struct d3d10_effect_pass_shader_desc ps; + struct d3d10_effect_pass_shader_desc gs; UINT stencil_ref; UINT sample_mask; float blend_factor[4]; diff --git a/dlls/d3d10/effect.c b/dlls/d3d10/effect.c index 301c7cb55dd..dd4e04d6374 100644 --- a/dlls/d3d10/effect.c +++ b/dlls/d3d10/effect.c @@ -1944,8 +1944,8 @@ static HRESULT parse_fx10_object(const char *data, size_t data_size, ID3D10EffectShaderVariable *sv = variable->lpVtbl->AsShader(variable); if (FAILED(hr = sv->lpVtbl->GetVertexShader(sv, variable_idx, &o->object.vs))) return hr; - o->pass->vs.pShaderVariable = sv; - o->pass->vs.ShaderIndex = variable_idx; + o->pass->vs.shader = impl_from_ID3D10EffectVariable((ID3D10EffectVariable *)sv); + o->pass->vs.index = variable_idx; break; }
@@ -1954,8 +1954,8 @@ static HRESULT parse_fx10_object(const char *data, size_t data_size, ID3D10EffectShaderVariable *sv = variable->lpVtbl->AsShader(variable); if (FAILED(hr = sv->lpVtbl->GetPixelShader(sv, variable_idx, &o->object.ps))) return hr; - o->pass->ps.pShaderVariable = sv; - o->pass->ps.ShaderIndex = variable_idx; + o->pass->ps.shader = impl_from_ID3D10EffectVariable((ID3D10EffectVariable *)sv); + o->pass->ps.index = variable_idx; break; }
@@ -1964,8 +1964,8 @@ static HRESULT parse_fx10_object(const char *data, size_t data_size, ID3D10EffectShaderVariable *sv = variable->lpVtbl->AsShader(variable); if (FAILED(hr = sv->lpVtbl->GetGeometryShader(sv, variable_idx, &o->object.gs))) return hr; - o->pass->gs.pShaderVariable = sv; - o->pass->gs.ShaderIndex = variable_idx; + o->pass->gs.shader = impl_from_ID3D10EffectVariable((ID3D10EffectVariable *)sv); + o->pass->gs.index = variable_idx; break; }
@@ -2018,9 +2018,9 @@ static HRESULT parse_fx10_pass(const char *data, size_t data_size, return E_OUTOFMEMORY; }
- p->vs.pShaderVariable = (ID3D10EffectShaderVariable *)&null_shader_variable.ID3D10EffectVariable_iface; - p->ps.pShaderVariable = (ID3D10EffectShaderVariable *)&null_shader_variable.ID3D10EffectVariable_iface; - p->gs.pShaderVariable = (ID3D10EffectShaderVariable *)&null_shader_variable.ID3D10EffectVariable_iface; + p->vs.shader = &null_shader_variable; + p->ps.shader = &null_shader_variable; + p->gs.shader = &null_shader_variable;
for (i = 0; i < p->object_count; ++i) { @@ -3819,7 +3819,7 @@ static HRESULT STDMETHODCALLTYPE d3d10_effect_pass_GetDesc(ID3D10EffectPass *ifa return E_INVALIDARG; }
- s = &impl_from_ID3D10EffectShaderVariable(pass->vs.pShaderVariable)->u.shader; + s = &pass->vs.shader->u.shader;
desc->Name = pass->name; desc->Annotations = pass->annotation_count; @@ -3843,23 +3843,24 @@ static HRESULT STDMETHODCALLTYPE d3d10_effect_pass_GetDesc(ID3D10EffectPass *ifa static HRESULT STDMETHODCALLTYPE d3d10_effect_pass_GetVertexShaderDesc(ID3D10EffectPass *iface, D3D10_PASS_SHADER_DESC *desc) { - struct d3d10_effect_pass *This = impl_from_ID3D10EffectPass(iface); + struct d3d10_effect_pass *pass = impl_from_ID3D10EffectPass(iface);
- TRACE("iface %p, desc %p\n", iface, desc); + TRACE("iface %p, desc %p.\n", iface, desc);
- if (This == &null_pass) + if (pass == &null_pass) { - WARN("Null pass specified\n"); + WARN("Null pass specified.\n"); return E_FAIL; }
if (!desc) { - WARN("Invalid argument specified\n"); + WARN("Invalid argument specified.\n"); return E_INVALIDARG; }
- *desc = This->vs; + desc->pShaderVariable = (ID3D10EffectShaderVariable *)&pass->vs.shader->ID3D10EffectVariable_iface; + desc->ShaderIndex = pass->vs.index;
return S_OK; } @@ -3867,23 +3868,24 @@ static HRESULT STDMETHODCALLTYPE d3d10_effect_pass_GetVertexShaderDesc(ID3D10Eff static HRESULT STDMETHODCALLTYPE d3d10_effect_pass_GetGeometryShaderDesc(ID3D10EffectPass *iface, D3D10_PASS_SHADER_DESC *desc) { - struct d3d10_effect_pass *This = impl_from_ID3D10EffectPass(iface); + struct d3d10_effect_pass *pass = impl_from_ID3D10EffectPass(iface);
- TRACE("iface %p, desc %p\n", iface, desc); + TRACE("iface %p, desc %p.\n", iface, desc);
- if (This == &null_pass) + if (pass == &null_pass) { - WARN("Null pass specified\n"); + WARN("Null pass specified.\n"); return E_FAIL; }
if (!desc) { - WARN("Invalid argument specified\n"); + WARN("Invalid argument specified.\n"); return E_INVALIDARG; }
- *desc = This->gs; + desc->pShaderVariable = (ID3D10EffectShaderVariable *)&pass->gs.shader->ID3D10EffectVariable_iface; + desc->ShaderIndex = pass->gs.index;
return S_OK; } @@ -3891,23 +3893,24 @@ static HRESULT STDMETHODCALLTYPE d3d10_effect_pass_GetGeometryShaderDesc(ID3D10E static HRESULT STDMETHODCALLTYPE d3d10_effect_pass_GetPixelShaderDesc(ID3D10EffectPass *iface, D3D10_PASS_SHADER_DESC *desc) { - struct d3d10_effect_pass *This = impl_from_ID3D10EffectPass(iface); + struct d3d10_effect_pass *pass = impl_from_ID3D10EffectPass(iface);
- TRACE("iface %p, desc %p\n", iface, desc); + TRACE("iface %p, desc %p.\n", iface, desc);
- if (This == &null_pass) + if (pass == &null_pass) { - WARN("Null pass specified\n"); + WARN("Null pass specified.\n"); return E_FAIL; }
if (!desc) { - WARN("Invalid argument specified\n"); + WARN("Invalid argument specified.\n"); return E_INVALIDARG; }
- *desc = This->ps; + desc->pShaderVariable = (ID3D10EffectShaderVariable *)&pass->ps.shader->ID3D10EffectVariable_iface; + desc->ShaderIndex = pass->ps.index;
return S_OK; } @@ -3992,9 +3995,8 @@ static void set_sampler(ID3D10Device *device, D3D10_SHADER_VARIABLE_TYPE shader_ } }
-static void apply_shader_resources(ID3D10Device *device, struct ID3D10EffectShaderVariable *variable) +static void apply_shader_resources(ID3D10Device *device, struct d3d10_effect_variable *v) { - struct d3d10_effect_variable *v = impl_from_ID3D10EffectShaderVariable(variable); struct d3d10_effect_shader_variable *sv = &v->u.shader; struct d3d10_effect_shader_resource *sr; struct d3d10_effect_variable *rsrc_v; @@ -4092,12 +4094,12 @@ static HRESULT STDMETHODCALLTYPE d3d10_effect_pass_Apply(ID3D10EffectPass *iface
if (flags) FIXME("Ignoring flags (%#x)\n", flags);
- if (pass->vs.pShaderVariable != (ID3D10EffectShaderVariable *)&null_shader_variable.ID3D10EffectVariable_iface) - apply_shader_resources(device, pass->vs.pShaderVariable); - if (pass->gs.pShaderVariable != (ID3D10EffectShaderVariable *)&null_shader_variable.ID3D10EffectVariable_iface) - apply_shader_resources(device, pass->gs.pShaderVariable); - if (pass->ps.pShaderVariable != (ID3D10EffectShaderVariable *)&null_shader_variable.ID3D10EffectVariable_iface) - apply_shader_resources(device, pass->ps.pShaderVariable); + if (pass->vs.shader != &null_shader_variable) + apply_shader_resources(device, pass->vs.shader); + if (pass->gs.shader != &null_shader_variable) + apply_shader_resources(device, pass->gs.shader); + if (pass->ps.shader != &null_shader_variable) + apply_shader_resources(device, pass->ps.shader);
for (i = 0; i < pass->object_count; ++i) { diff --git a/dlls/d3d10/tests/effect.c b/dlls/d3d10/tests/effect.c index 3561e99f338..06c5aa68776 100644 --- a/dlls/d3d10/tests/effect.c +++ b/dlls/d3d10/tests/effect.c @@ -2911,6 +2911,7 @@ static void test_effect_local_shader(void) *p3_anon_vs, *p3_anon_ps, *p3_anon_gs, *p6_vs, *p6_ps, *p6_gs, *gs, *ps, *vs; D3D10_EFFECT_SHADER_DESC shaderdesc; D3D10_SIGNATURE_PARAMETER_DESC sign; + D3D10_STATE_BLOCK_MASK mask; ID3D10Device *device; ULONG refcount;
@@ -3010,6 +3011,20 @@ if (0)
/* pass 0 */ p = t->lpVtbl->GetPassByIndex(t, 0); + + /* Pass without Set*Shader() instructions */ + hr = D3D10StateBlockMaskDisableAll(&mask); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + hr = p->lpVtbl->ComputeStateBlockMask(p, &mask); +todo_wine + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ret = D3D10StateBlockMaskGetSetting(&mask, D3D10_DST_VS, 0); + ok(!ret, "Unexpected mask.\n"); + ret = D3D10StateBlockMaskGetSetting(&mask, D3D10_DST_PS, 0); + ok(!ret, "Unexpected mask.\n"); + ret = D3D10StateBlockMaskGetSetting(&mask, D3D10_DST_GS, 0); + ok(!ret, "Unexpected mask.\n"); + hr = p->lpVtbl->GetVertexShaderDesc(p, &pdesc); ok(hr == S_OK, "GetVertexShaderDesc got %x, expected %x\n", hr, S_OK); ok(pdesc.pShaderVariable == null_shader, "Got %p, expected %p\n", pdesc.pShaderVariable, null_shader); @@ -3145,6 +3160,19 @@ if (0) ok(typedesc.UnpackedSize == 0x0, "UnpackedSize is %#x, expected 0x0\n", typedesc.UnpackedSize); ok(typedesc.Stride == 0x0, "Stride is %#x, expected 0x0\n", typedesc.Stride);
+ /* Pass is using Set*Shader(NULL) */ + hr = D3D10StateBlockMaskDisableAll(&mask); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + hr = p->lpVtbl->ComputeStateBlockMask(p, &mask); +todo_wine { + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ret = D3D10StateBlockMaskGetSetting(&mask, D3D10_DST_VS, 0); + ok(ret, "Unexpected mask.\n"); + ret = D3D10StateBlockMaskGetSetting(&mask, D3D10_DST_PS, 0); + ok(ret, "Unexpected mask.\n"); + ret = D3D10StateBlockMaskGetSetting(&mask, D3D10_DST_GS, 0); + ok(ret, "Unexpected mask.\n"); +} /* pass 2 */ p = t->lpVtbl->GetPassByIndex(t, 2);
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/d3d10/effect.c | 13 +++++++++++-- dlls/d3d10/tests/effect.c | 4 +--- 2 files changed, 12 insertions(+), 5 deletions(-)
diff --git a/dlls/d3d10/effect.c b/dlls/d3d10/effect.c index dd4e04d6374..70f6c3b3166 100644 --- a/dlls/d3d10/effect.c +++ b/dlls/d3d10/effect.c @@ -4113,9 +4113,18 @@ static HRESULT STDMETHODCALLTYPE d3d10_effect_pass_Apply(ID3D10EffectPass *iface static HRESULT STDMETHODCALLTYPE d3d10_effect_pass_ComputeStateBlockMask(ID3D10EffectPass *iface, D3D10_STATE_BLOCK_MASK *mask) { - FIXME("iface %p, mask %p stub!\n", iface, mask); + struct d3d10_effect_pass *pass = impl_from_ID3D10EffectPass(iface);
- return E_NOTIMPL; + FIXME("iface %p, mask %p semi-stub!\n", iface, mask); + + if (pass->vs.shader != &null_shader_variable) + D3D10StateBlockMaskEnableCapture(mask, D3D10_DST_VS, 0, 1); + if (pass->ps.shader != &null_shader_variable) + D3D10StateBlockMaskEnableCapture(mask, D3D10_DST_PS, 0, 1); + if (pass->gs.shader != &null_shader_variable) + D3D10StateBlockMaskEnableCapture(mask, D3D10_DST_GS, 0, 1); + + return S_OK; }
static const struct ID3D10EffectPassVtbl d3d10_effect_pass_vtbl = diff --git a/dlls/d3d10/tests/effect.c b/dlls/d3d10/tests/effect.c index 06c5aa68776..f3b81a2c58d 100644 --- a/dlls/d3d10/tests/effect.c +++ b/dlls/d3d10/tests/effect.c @@ -3016,7 +3016,6 @@ if (0) hr = D3D10StateBlockMaskDisableAll(&mask); ok(hr == S_OK, "Unexpected hr %#x.\n", hr); hr = p->lpVtbl->ComputeStateBlockMask(p, &mask); -todo_wine ok(hr == S_OK, "Unexpected hr %#x.\n", hr); ret = D3D10StateBlockMaskGetSetting(&mask, D3D10_DST_VS, 0); ok(!ret, "Unexpected mask.\n"); @@ -3164,7 +3163,6 @@ todo_wine hr = D3D10StateBlockMaskDisableAll(&mask); ok(hr == S_OK, "Unexpected hr %#x.\n", hr); hr = p->lpVtbl->ComputeStateBlockMask(p, &mask); -todo_wine { ok(hr == S_OK, "Unexpected hr %#x.\n", hr); ret = D3D10StateBlockMaskGetSetting(&mask, D3D10_DST_VS, 0); ok(ret, "Unexpected mask.\n"); @@ -3172,7 +3170,7 @@ todo_wine { ok(ret, "Unexpected mask.\n"); ret = D3D10StateBlockMaskGetSetting(&mask, D3D10_DST_GS, 0); ok(ret, "Unexpected mask.\n"); -} + /* pass 2 */ p = t->lpVtbl->GetPassByIndex(t, 2);
Signed-off-by: Matteo Bruni mbruni@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/d3d10/stateblock.c | 16 ++++++++-------- include/d3d10effect.h | 4 ++-- 2 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/dlls/d3d10/stateblock.c b/dlls/d3d10/stateblock.c index ccc8a0e504e..fef78872a49 100644 --- a/dlls/d3d10/stateblock.c +++ b/dlls/d3d10/stateblock.c @@ -73,8 +73,8 @@ static const char *debug_d3d10_device_state_types(D3D10_DEVICE_STATE_TYPES t) { WINE_D3D10_TO_STR(D3D10_DST_SO_BUFFERS); WINE_D3D10_TO_STR(D3D10_DST_OM_RENDER_TARGETS); - WINE_D3D10_TO_STR(D3D10_DST_DEPTH_STENCIL_STATE); - WINE_D3D10_TO_STR(D3D10_DST_BLEND_STATE); + WINE_D3D10_TO_STR(D3D10_DST_OM_DEPTH_STENCIL_STATE); + WINE_D3D10_TO_STR(D3D10_DST_OM_BLEND_STATE); WINE_D3D10_TO_STR(D3D10_DST_VS); WINE_D3D10_TO_STR(D3D10_DST_VS_SAMPLERS); WINE_D3D10_TO_STR(D3D10_DST_VS_SHADER_RESOURCES); @@ -696,9 +696,9 @@ HRESULT WINAPI D3D10StateBlockMaskDisableCapture(D3D10_STATE_BLOCK_MASK *mask, return stateblock_mask_clear_bits(&mask->SOBuffers, 1, start_idx, count); case D3D10_DST_OM_RENDER_TARGETS: return stateblock_mask_clear_bits(&mask->OMRenderTargets, 1, start_idx, count); - case D3D10_DST_DEPTH_STENCIL_STATE: + case D3D10_DST_OM_DEPTH_STENCIL_STATE: return stateblock_mask_clear_bits(&mask->OMDepthStencilState, 1, start_idx, count); - case D3D10_DST_BLEND_STATE: + case D3D10_DST_OM_BLEND_STATE: return stateblock_mask_clear_bits(&mask->OMBlendState, 1, start_idx, count); case D3D10_DST_VS: return stateblock_mask_clear_bits(&mask->VS, 1, start_idx, count); @@ -783,9 +783,9 @@ HRESULT WINAPI D3D10StateBlockMaskEnableCapture(D3D10_STATE_BLOCK_MASK *mask, return stateblock_mask_set_bits(&mask->SOBuffers, 1, start_idx, count); case D3D10_DST_OM_RENDER_TARGETS: return stateblock_mask_set_bits(&mask->OMRenderTargets, 1, start_idx, count); - case D3D10_DST_DEPTH_STENCIL_STATE: + case D3D10_DST_OM_DEPTH_STENCIL_STATE: return stateblock_mask_set_bits(&mask->OMDepthStencilState, 1, start_idx, count); - case D3D10_DST_BLEND_STATE: + case D3D10_DST_OM_BLEND_STATE: return stateblock_mask_set_bits(&mask->OMBlendState, 1, start_idx, count); case D3D10_DST_VS: return stateblock_mask_set_bits(&mask->VS, 1, start_idx, count); @@ -858,9 +858,9 @@ BOOL WINAPI D3D10StateBlockMaskGetSetting(D3D10_STATE_BLOCK_MASK *mask, return stateblock_mask_get_bit(&mask->SOBuffers, 1, idx); case D3D10_DST_OM_RENDER_TARGETS: return stateblock_mask_get_bit(&mask->OMRenderTargets, 1, idx); - case D3D10_DST_DEPTH_STENCIL_STATE: + case D3D10_DST_OM_DEPTH_STENCIL_STATE: return stateblock_mask_get_bit(&mask->OMDepthStencilState, 1, idx); - case D3D10_DST_BLEND_STATE: + case D3D10_DST_OM_BLEND_STATE: return stateblock_mask_get_bit(&mask->OMBlendState, 1, idx); case D3D10_DST_VS: return stateblock_mask_get_bit(&mask->VS, 1, idx); diff --git a/include/d3d10effect.h b/include/d3d10effect.h index b4a33daca48..a4574c41fe4 100644 --- a/include/d3d10effect.h +++ b/include/d3d10effect.h @@ -34,8 +34,8 @@ typedef enum _D3D10_DEVICE_STATE_TYPES { D3D10_DST_SO_BUFFERS = 1, D3D10_DST_OM_RENDER_TARGETS, - D3D10_DST_DEPTH_STENCIL_STATE, - D3D10_DST_BLEND_STATE, + D3D10_DST_OM_DEPTH_STENCIL_STATE, + D3D10_DST_OM_BLEND_STATE, D3D10_DST_VS, D3D10_DST_VS_SAMPLERS, D3D10_DST_VS_SHADER_RESOURCES,
Signed-off-by: Matteo Bruni mbruni@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/d3d10/d3d10_private.h | 2 +- dlls/d3d10/effect.c | 22 ++++++++++++++++++---- dlls/d3d10/tests/effect.c | 17 +++++++++++++++++ 3 files changed, 36 insertions(+), 5 deletions(-)
diff --git a/dlls/d3d10/d3d10_private.h b/dlls/d3d10/d3d10_private.h index f799d27b323..4e35a2f319d 100644 --- a/dlls/d3d10/d3d10_private.h +++ b/dlls/d3d10/d3d10_private.h @@ -79,7 +79,6 @@ struct d3d10_effect_object enum d3d10_effect_object_type type; union { - ID3D10RasterizerState *rs; ID3D10DepthStencilState *ds; ID3D10BlendState *bs; ID3D10VertexShader *vs; @@ -247,6 +246,7 @@ struct d3d10_effect_pass struct d3d10_effect_pass_shader_desc vs; struct d3d10_effect_pass_shader_desc ps; struct d3d10_effect_pass_shader_desc gs; + struct d3d10_effect_variable *rasterizer; UINT stencil_ref; UINT sample_mask; float blend_factor[4]; diff --git a/dlls/d3d10/effect.c b/dlls/d3d10/effect.c index 70f6c3b3166..66eb723fe9c 100644 --- a/dlls/d3d10/effect.c +++ b/dlls/d3d10/effect.c @@ -1918,8 +1918,19 @@ static HRESULT parse_fx10_object(const char *data, size_t data_size, case D3D10_EOT_RASTERIZER_STATE: { ID3D10EffectRasterizerVariable *rv = variable->lpVtbl->AsRasterizer(variable); - if (FAILED(hr = rv->lpVtbl->GetRasterizerState(rv, variable_idx, &o->object.rs))) - return hr; + if (!rv->lpVtbl->IsValid(rv)) + { + WARN("Invalid variable type.\n"); + return E_FAIL; + } + v = impl_from_ID3D10EffectVariable(variable); + if (v->type->element_count) + { + if (variable_idx >= v->type->element_count) return E_FAIL; + o->pass->rasterizer = &v->elements[variable_idx]; + } + else + o->pass->rasterizer = v; break; }
@@ -2903,8 +2914,7 @@ static HRESULT d3d10_effect_object_apply(struct d3d10_effect_object *o) switch(o->type) { case D3D10_EOT_RASTERIZER_STATE: - ID3D10Device_RSSetState(device, o->object.rs); - return S_OK; + break;
case D3D10_EOT_DEPTH_STENCIL_STATE: ID3D10Device_OMSetDepthStencilState(device, o->object.ds, o->pass->stencil_ref); @@ -2935,6 +2945,8 @@ static HRESULT d3d10_effect_object_apply(struct d3d10_effect_object *o) FIXME("Unhandled effect object type %#x.\n", o->type); return E_FAIL; } + + return S_OK; }
static void d3d10_effect_shader_variable_destroy(struct d3d10_effect_shader_variable *s, @@ -4100,6 +4112,8 @@ static HRESULT STDMETHODCALLTYPE d3d10_effect_pass_Apply(ID3D10EffectPass *iface apply_shader_resources(device, pass->gs.shader); if (pass->ps.shader != &null_shader_variable) apply_shader_resources(device, pass->ps.shader); + if (pass->rasterizer) + ID3D10Device_RSSetState(device, pass->rasterizer->u.state.object.rasterizer);
for (i = 0; i < pass->object_count; ++i) { diff --git a/dlls/d3d10/tests/effect.c b/dlls/d3d10/tests/effect.c index f3b81a2c58d..1a06ff95365 100644 --- a/dlls/d3d10/tests/effect.c +++ b/dlls/d3d10/tests/effect.c @@ -4195,6 +4195,7 @@ static void test_effect_state_groups(void) UINT sample_mask, stencil_ref; ID3D10EffectBlendVariable *b; D3D10_BLEND_DESC blend_desc; + D3D10_STATE_BLOCK_MASK mask; D3D10_PASS_DESC pass_desc; ID3D10EffectVariable *v; ID3D10EffectPass *pass; @@ -4203,6 +4204,7 @@ static void test_effect_state_groups(void) ID3D10Device *device; ULONG refcount; HRESULT hr; + BOOL ret;
if (!(device = create_device())) { @@ -4323,6 +4325,21 @@ static void test_effect_state_groups(void) ok(pass_desc.BlendFactor[1] == 0.6f, "Got unexpected BlendFactor[1] %.8e.\n", pass_desc.BlendFactor[1]); ok(pass_desc.BlendFactor[2] == 0.7f, "Got unexpected BlendFactor[2] %.8e.\n", pass_desc.BlendFactor[2]); ok(pass_desc.BlendFactor[3] == 0.8f, "Got unexpected BlendFactor[3] %.8e.\n", pass_desc.BlendFactor[3]); + + hr = D3D10StateBlockMaskDisableAll(&mask); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + hr = pass->lpVtbl->ComputeStateBlockMask(pass, &mask); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ret = D3D10StateBlockMaskGetSetting(&mask, D3D10_DST_RS_RASTERIZER_STATE, 0); +todo_wine + ok(ret, "Unexpected mask.\n"); + ret = D3D10StateBlockMaskGetSetting(&mask, D3D10_DST_OM_DEPTH_STENCIL_STATE, 0); +todo_wine + ok(ret, "Unexpected mask.\n"); + ret = D3D10StateBlockMaskGetSetting(&mask, D3D10_DST_OM_BLEND_STATE, 0); +todo_wine + ok(ret, "Unexpected mask.\n"); + hr = pass->lpVtbl->Apply(pass, 0); ok(SUCCEEDED(hr), "Failed to apply pass, hr %#x.\n", hr);
Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- This one (and similarly the following two, obviously) could have used a mention in the commit subject or message about fixing D3D10_EOO_CONST_INDEX rasterizer state settings. Any known game that's affected by this?
BTW, this will need to be changed again to allow for D3D10_EOO_VAR_INDEX (assuming that's possible for rasterizer state) since the index is not known at parse time. It's a step in the right direction though.
On 10/7/21 9:44 PM, Matteo Bruni wrote:
Signed-off-by: Matteo Bruni mbruni@codeweavers.com
This one (and similarly the following two, obviously) could have used a mention in the commit subject or message about fixing D3D10_EOO_CONST_INDEX rasterizer state settings. Any known game that's affected by this?
I'm not aware of a specific game. It's just something that works uniformly for every object type.
BTW, this will need to be changed again to allow for D3D10_EOO_VAR_INDEX (assuming that's possible for rasterizer state) since the index is not known at parse time. It's a step in the right direction though.
Not changed, but extended. For dynamic changes I was thinking about keeping an array of {propid,EOO,{var|var+index_var|var+index_expression|expression}}. This way it will have to be refreshed on Apply(), by iterating over these, checking for changed/dirty vars. The point is that separate index value in main structure is only useful for shaders, because you have to return it.
On Thu, Oct 7, 2021 at 9:19 PM Nikolay Sivov nsivov@codeweavers.com wrote:
On 10/7/21 9:44 PM, Matteo Bruni wrote:
BTW, this will need to be changed again to allow for D3D10_EOO_VAR_INDEX (assuming that's possible for rasterizer state) since the index is not known at parse time. It's a step in the right direction though.
Not changed, but extended. For dynamic changes I was thinking about keeping an array of {propid,EOO,{var|var+index_var|var+index_expression|expression}}. This way it will have to be refreshed on Apply(), by iterating over these, checking for changed/dirty vars. The point is that separate index value in main structure is only useful for shaders, because you have to return it.
Okay, I see, that should work.
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/d3d10/d3d10_private.h | 2 +- dlls/d3d10/effect.c | 23 +++++++++++++++++------ 2 files changed, 18 insertions(+), 7 deletions(-)
diff --git a/dlls/d3d10/d3d10_private.h b/dlls/d3d10/d3d10_private.h index 4e35a2f319d..5a0308ee42a 100644 --- a/dlls/d3d10/d3d10_private.h +++ b/dlls/d3d10/d3d10_private.h @@ -79,7 +79,6 @@ struct d3d10_effect_object enum d3d10_effect_object_type type; union { - ID3D10DepthStencilState *ds; ID3D10BlendState *bs; ID3D10VertexShader *vs; ID3D10PixelShader *ps; @@ -247,6 +246,7 @@ struct d3d10_effect_pass struct d3d10_effect_pass_shader_desc ps; struct d3d10_effect_pass_shader_desc gs; struct d3d10_effect_variable *rasterizer; + struct d3d10_effect_variable *depth_stencil; UINT stencil_ref; UINT sample_mask; float blend_factor[4]; diff --git a/dlls/d3d10/effect.c b/dlls/d3d10/effect.c index 66eb723fe9c..4a293601902 100644 --- a/dlls/d3d10/effect.c +++ b/dlls/d3d10/effect.c @@ -1937,8 +1937,19 @@ static HRESULT parse_fx10_object(const char *data, size_t data_size, case D3D10_EOT_DEPTH_STENCIL_STATE: { ID3D10EffectDepthStencilVariable *dv = variable->lpVtbl->AsDepthStencil(variable); - if (FAILED(hr = dv->lpVtbl->GetDepthStencilState(dv, variable_idx, &o->object.ds))) - return hr; + if (!dv->lpVtbl->IsValid(dv)) + { + WARN("Invalid variable type.\n"); + return E_FAIL; + } + v = impl_from_ID3D10EffectVariable(variable); + if (v->type->element_count) + { + if (variable_idx >= v->type->element_count) return E_FAIL; + o->pass->depth_stencil = &v->elements[variable_idx]; + } + else + o->pass->depth_stencil = v; break; }
@@ -2914,11 +2925,8 @@ static HRESULT d3d10_effect_object_apply(struct d3d10_effect_object *o) switch(o->type) { case D3D10_EOT_RASTERIZER_STATE: - break; - case D3D10_EOT_DEPTH_STENCIL_STATE: - ID3D10Device_OMSetDepthStencilState(device, o->object.ds, o->pass->stencil_ref); - return S_OK; + break;
case D3D10_EOT_BLEND_STATE: ID3D10Device_OMSetBlendState(device, o->object.bs, o->pass->blend_factor, o->pass->sample_mask); @@ -4114,6 +4122,9 @@ static HRESULT STDMETHODCALLTYPE d3d10_effect_pass_Apply(ID3D10EffectPass *iface apply_shader_resources(device, pass->ps.shader); if (pass->rasterizer) ID3D10Device_RSSetState(device, pass->rasterizer->u.state.object.rasterizer); + if (pass->depth_stencil) + ID3D10Device_OMSetDepthStencilState(device, pass->depth_stencil->u.state.object.depth_stencil, + pass->stencil_ref);
for (i = 0; i < pass->object_count; ++i) {
Signed-off-by: Matteo Bruni mbruni@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/d3d10/d3d10_private.h | 2 +- dlls/d3d10/effect.c | 31 ++++++++++++++++++++----------- 2 files changed, 21 insertions(+), 12 deletions(-)
diff --git a/dlls/d3d10/d3d10_private.h b/dlls/d3d10/d3d10_private.h index 5a0308ee42a..6979d2a114e 100644 --- a/dlls/d3d10/d3d10_private.h +++ b/dlls/d3d10/d3d10_private.h @@ -79,7 +79,6 @@ struct d3d10_effect_object enum d3d10_effect_object_type type; union { - ID3D10BlendState *bs; ID3D10VertexShader *vs; ID3D10PixelShader *ps; ID3D10GeometryShader *gs; @@ -247,6 +246,7 @@ struct d3d10_effect_pass struct d3d10_effect_pass_shader_desc gs; struct d3d10_effect_variable *rasterizer; struct d3d10_effect_variable *depth_stencil; + struct d3d10_effect_variable *blend; UINT stencil_ref; UINT sample_mask; float blend_factor[4]; diff --git a/dlls/d3d10/effect.c b/dlls/d3d10/effect.c index 4a293601902..afcd292356e 100644 --- a/dlls/d3d10/effect.c +++ b/dlls/d3d10/effect.c @@ -1956,8 +1956,19 @@ static HRESULT parse_fx10_object(const char *data, size_t data_size, case D3D10_EOT_BLEND_STATE: { ID3D10EffectBlendVariable *bv = variable->lpVtbl->AsBlend(variable); - if (FAILED(hr = bv->lpVtbl->GetBlendState(bv, variable_idx, &o->object.bs))) - return hr; + if (!bv->lpVtbl->IsValid(bv)) + { + WARN("Invalid variable type.\n"); + return E_FAIL; + } + v = impl_from_ID3D10EffectVariable(variable); + if (v->type->element_count) + { + if (variable_idx >= v->type->element_count) return E_FAIL; + o->pass->blend = &v->elements[variable_idx]; + } + else + o->pass->blend = v; break; }
@@ -2926,11 +2937,11 @@ static HRESULT d3d10_effect_object_apply(struct d3d10_effect_object *o) { case D3D10_EOT_RASTERIZER_STATE: case D3D10_EOT_DEPTH_STENCIL_STATE: - break; - case D3D10_EOT_BLEND_STATE: - ID3D10Device_OMSetBlendState(device, o->object.bs, o->pass->blend_factor, o->pass->sample_mask); - return S_OK; + case D3D10_EOT_STENCIL_REF: + case D3D10_EOT_BLEND_FACTOR: + case D3D10_EOT_SAMPLE_MASK: + break;
case D3D10_EOT_VERTEXSHADER: ID3D10Device_VSSetShader(device, o->object.vs); @@ -2944,11 +2955,6 @@ static HRESULT d3d10_effect_object_apply(struct d3d10_effect_object *o) ID3D10Device_GSSetShader(device, o->object.gs); return S_OK;
- case D3D10_EOT_STENCIL_REF: - case D3D10_EOT_BLEND_FACTOR: - case D3D10_EOT_SAMPLE_MASK: - return S_OK; - default: FIXME("Unhandled effect object type %#x.\n", o->type); return E_FAIL; @@ -4125,6 +4131,9 @@ static HRESULT STDMETHODCALLTYPE d3d10_effect_pass_Apply(ID3D10EffectPass *iface if (pass->depth_stencil) ID3D10Device_OMSetDepthStencilState(device, pass->depth_stencil->u.state.object.depth_stencil, pass->stencil_ref); + if (pass->blend) + ID3D10Device_OMSetBlendState(device, pass->blend->u.state.object.blend, + pass->blend_factor, pass->sample_mask);
for (i = 0; i < pass->object_count; ++i) {
Signed-off-by: Matteo Bruni mbruni@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/d3d10/effect.c | 6 ++++++ dlls/d3d10/tests/effect.c | 3 --- 2 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/dlls/d3d10/effect.c b/dlls/d3d10/effect.c index afcd292356e..0ba906375d7 100644 --- a/dlls/d3d10/effect.c +++ b/dlls/d3d10/effect.c @@ -4157,6 +4157,12 @@ static HRESULT STDMETHODCALLTYPE d3d10_effect_pass_ComputeStateBlockMask(ID3D10E D3D10StateBlockMaskEnableCapture(mask, D3D10_DST_PS, 0, 1); if (pass->gs.shader != &null_shader_variable) D3D10StateBlockMaskEnableCapture(mask, D3D10_DST_GS, 0, 1); + if (pass->rasterizer) + D3D10StateBlockMaskEnableCapture(mask, D3D10_DST_RS_RASTERIZER_STATE, 0, 1); + if (pass->depth_stencil) + D3D10StateBlockMaskEnableCapture(mask, D3D10_DST_OM_DEPTH_STENCIL_STATE, 0, 1); + if (pass->blend) + D3D10StateBlockMaskEnableCapture(mask, D3D10_DST_OM_BLEND_STATE, 0, 1);
return S_OK; } diff --git a/dlls/d3d10/tests/effect.c b/dlls/d3d10/tests/effect.c index 1a06ff95365..781abb46745 100644 --- a/dlls/d3d10/tests/effect.c +++ b/dlls/d3d10/tests/effect.c @@ -4331,13 +4331,10 @@ static void test_effect_state_groups(void) hr = pass->lpVtbl->ComputeStateBlockMask(pass, &mask); ok(hr == S_OK, "Unexpected hr %#x.\n", hr); ret = D3D10StateBlockMaskGetSetting(&mask, D3D10_DST_RS_RASTERIZER_STATE, 0); -todo_wine ok(ret, "Unexpected mask.\n"); ret = D3D10StateBlockMaskGetSetting(&mask, D3D10_DST_OM_DEPTH_STENCIL_STATE, 0); -todo_wine ok(ret, "Unexpected mask.\n"); ret = D3D10StateBlockMaskGetSetting(&mask, D3D10_DST_OM_BLEND_STATE, 0); -todo_wine ok(ret, "Unexpected mask.\n");
hr = pass->lpVtbl->Apply(pass, 0);
Signed-off-by: Matteo Bruni mbruni@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/d3d10/d3d10_private.h | 15 --- dlls/d3d10/effect.c | 185 +++++++++++++------------------------ 2 files changed, 64 insertions(+), 136 deletions(-)
diff --git a/dlls/d3d10/d3d10_private.h b/dlls/d3d10/d3d10_private.h index 6979d2a114e..fbcc36e5e06 100644 --- a/dlls/d3d10/d3d10_private.h +++ b/dlls/d3d10/d3d10_private.h @@ -73,19 +73,6 @@ struct d3d10_matrix float m[4][4]; };
-struct d3d10_effect_object -{ - struct d3d10_effect_pass *pass; - enum d3d10_effect_object_type type; - union - { - ID3D10VertexShader *vs; - ID3D10PixelShader *ps; - ID3D10GeometryShader *gs; - IUnknown *object; - } object; -}; - struct d3d10_effect_shader_resource { D3D10_SHADER_INPUT_TYPE in_type; @@ -236,9 +223,7 @@ struct d3d10_effect_pass
struct d3d10_effect_technique *technique; char *name; - DWORD object_count; DWORD annotation_count; - struct d3d10_effect_object *objects; struct d3d10_effect_variable *annotations;
struct d3d10_effect_pass_shader_desc vs; diff --git a/dlls/d3d10/effect.c b/dlls/d3d10/effect.c index 0ba906375d7..d4e44a7f419 100644 --- a/dlls/d3d10/effect.c +++ b/dlls/d3d10/effect.c @@ -1734,17 +1734,17 @@ static BOOL parse_fx10_state_group(const char *data, size_t data_size, }
static HRESULT parse_fx10_object(const char *data, size_t data_size, - const char **ptr, struct d3d10_effect_object *o) + const char **ptr, struct d3d10_effect_pass *pass) { ID3D10EffectVariable *variable = &null_variable.ID3D10EffectVariable_iface; const char *data_ptr = NULL; DWORD offset, sodecl_offset; enum d3d10_effect_object_operation operation; HRESULT hr; - struct d3d10_effect *effect = o->pass->technique->effect; + struct d3d10_effect *effect = pass->technique->effect; ID3D10Effect *e = &effect->ID3D10Effect_iface; struct d3d10_effect_variable *v; - DWORD tmp, variable_idx = 0; + DWORD tmp, object_type, variable_idx = 0; const char *name; size_t name_len;
@@ -1754,8 +1754,8 @@ static HRESULT parse_fx10_object(const char *data, size_t data_size, return E_FAIL; }
- read_dword(ptr, &o->type); - TRACE("Effect object is of type %#x.\n", o->type); + read_dword(ptr, &object_type); + TRACE("Effect object is of type %#x.\n", object_type);
read_dword(ptr, &tmp); TRACE("Effect object index %#x.\n", tmp); @@ -1771,7 +1771,7 @@ static HRESULT parse_fx10_object(const char *data, size_t data_size, case D3D10_EOO_CONST: TRACE("Copy variable values\n");
- switch (o->type) + switch (object_type) { case D3D10_EOT_VERTEXSHADER: TRACE("Vertex shader\n"); @@ -1789,7 +1789,7 @@ static HRESULT parse_fx10_object(const char *data, size_t data_size, break;
case D3D10_EOT_STENCIL_REF: - if (!read_value_list(data, data_size, offset, D3D10_SVT_UINT, 0, 1, &o->pass->stencil_ref)) + if (!read_value_list(data, data_size, offset, D3D10_SVT_UINT, 0, 1, &pass->stencil_ref)) { ERR("Failed to read stencil ref.\n"); return E_FAIL; @@ -1797,7 +1797,7 @@ static HRESULT parse_fx10_object(const char *data, size_t data_size, break;
case D3D10_EOT_SAMPLE_MASK: - if (!read_value_list(data, data_size, offset, D3D10_SVT_UINT, 0, 1, &o->pass->sample_mask)) + if (!read_value_list(data, data_size, offset, D3D10_SVT_UINT, 0, 1, &pass->sample_mask)) { FIXME("Failed to read sample mask.\n"); return E_FAIL; @@ -1805,7 +1805,7 @@ static HRESULT parse_fx10_object(const char *data, size_t data_size, break;
case D3D10_EOT_BLEND_FACTOR: - if (!read_value_list(data, data_size, offset, D3D10_SVT_FLOAT, 0, 4, &o->pass->blend_factor[0])) + if (!read_value_list(data, data_size, offset, D3D10_SVT_FLOAT, 0, 4, &pass->blend_factor[0])) { FIXME("Failed to read blend factor.\n"); return E_FAIL; @@ -1813,7 +1813,7 @@ static HRESULT parse_fx10_object(const char *data, size_t data_size, break;
default: - FIXME("Unhandled object type %#x\n", o->type); + FIXME("Unhandled object type %#x\n", object_type); return E_FAIL; } break; @@ -1873,7 +1873,7 @@ static HRESULT parse_fx10_object(const char *data, size_t data_size, read_dword(&data_ptr, &sodecl_offset);
if (FAILED(hr = parse_fx10_anonymous_shader(effect, - &effect->anonymous_shaders[effect->anonymous_shader_current], o->type))) + &effect->anonymous_shaders[effect->anonymous_shader_current], object_type))) return hr;
v = &effect->anonymous_shaders[effect->anonymous_shader_current].shader; @@ -1893,7 +1893,7 @@ static HRESULT parse_fx10_object(const char *data, size_t data_size, TRACE("Stream output declaration: %s.\n", debugstr_a(v->u.shader.stream_output_declaration)); }
- switch (o->type) + switch (object_type) { case D3D10_EOT_VERTEXSHADER: case D3D10_EOT_PIXELSHADER: @@ -1903,7 +1903,7 @@ static HRESULT parse_fx10_object(const char *data, size_t data_size, break;
default: - FIXME("Unhandled object type %#x\n", o->type); + FIXME("Unhandled object type %#x\n", object_type); return E_FAIL; } break; @@ -1913,7 +1913,7 @@ static HRESULT parse_fx10_object(const char *data, size_t data_size, return E_FAIL; }
- switch (o->type) + switch (object_type) { case D3D10_EOT_RASTERIZER_STATE: { @@ -1927,10 +1927,10 @@ static HRESULT parse_fx10_object(const char *data, size_t data_size, if (v->type->element_count) { if (variable_idx >= v->type->element_count) return E_FAIL; - o->pass->rasterizer = &v->elements[variable_idx]; + pass->rasterizer = &v->elements[variable_idx]; } else - o->pass->rasterizer = v; + pass->rasterizer = v; break; }
@@ -1946,10 +1946,10 @@ static HRESULT parse_fx10_object(const char *data, size_t data_size, if (v->type->element_count) { if (variable_idx >= v->type->element_count) return E_FAIL; - o->pass->depth_stencil = &v->elements[variable_idx]; + pass->depth_stencil = &v->elements[variable_idx]; } else - o->pass->depth_stencil = v; + pass->depth_stencil = v; break; }
@@ -1965,40 +1965,34 @@ static HRESULT parse_fx10_object(const char *data, size_t data_size, if (v->type->element_count) { if (variable_idx >= v->type->element_count) return E_FAIL; - o->pass->blend = &v->elements[variable_idx]; + pass->blend = &v->elements[variable_idx]; } else - o->pass->blend = v; + pass->blend = v; break; }
case D3D10_EOT_VERTEXSHADER: { ID3D10EffectShaderVariable *sv = variable->lpVtbl->AsShader(variable); - if (FAILED(hr = sv->lpVtbl->GetVertexShader(sv, variable_idx, &o->object.vs))) - return hr; - o->pass->vs.shader = impl_from_ID3D10EffectVariable((ID3D10EffectVariable *)sv); - o->pass->vs.index = variable_idx; + pass->vs.shader = impl_from_ID3D10EffectVariable((ID3D10EffectVariable *)sv); + pass->vs.index = variable_idx; break; }
case D3D10_EOT_PIXELSHADER: { ID3D10EffectShaderVariable *sv = variable->lpVtbl->AsShader(variable); - if (FAILED(hr = sv->lpVtbl->GetPixelShader(sv, variable_idx, &o->object.ps))) - return hr; - o->pass->ps.shader = impl_from_ID3D10EffectVariable((ID3D10EffectVariable *)sv); - o->pass->ps.index = variable_idx; + pass->ps.shader = impl_from_ID3D10EffectVariable((ID3D10EffectVariable *)sv); + pass->ps.index = variable_idx; break; }
case D3D10_EOT_GEOMETRYSHADER: { ID3D10EffectShaderVariable *sv = variable->lpVtbl->AsShader(variable); - if (FAILED(hr = sv->lpVtbl->GetGeometryShader(sv, variable_idx, &o->object.gs))) - return hr; - o->pass->gs.shader = impl_from_ID3D10EffectVariable((ID3D10EffectVariable *)sv); - o->pass->gs.index = variable_idx; + pass->gs.shader = impl_from_ID3D10EffectVariable((ID3D10EffectVariable *)sv); + pass->gs.index = variable_idx; break; }
@@ -2008,7 +2002,7 @@ static HRESULT parse_fx10_object(const char *data, size_t data_size, break;
default: - FIXME("Unhandled object type %#x.\n", o->type); + FIXME("Unhandled object type %#x.\n", object_type); return E_FAIL; }
@@ -2018,9 +2012,9 @@ static HRESULT parse_fx10_object(const char *data, size_t data_size, static HRESULT parse_fx10_pass(const char *data, size_t data_size, const char **ptr, struct d3d10_effect_pass *p) { + DWORD offset, object_count; HRESULT hr = S_OK; unsigned int i; - DWORD offset;
read_dword(ptr, &offset); TRACE("Pass name at offset %#x.\n", offset); @@ -2032,8 +2026,8 @@ static HRESULT parse_fx10_pass(const char *data, size_t data_size, } TRACE("Pass name: %s.\n", debugstr_a(p->name));
- read_dword(ptr, &p->object_count); - TRACE("Pass has %u effect objects.\n", p->object_count); + read_dword(ptr, &object_count); + TRACE("Pass has %u effect objects.\n", object_count);
read_dword(ptr, &p->annotation_count); TRACE("Pass has %u annotations.\n", p->annotation_count); @@ -2045,23 +2039,13 @@ static HRESULT parse_fx10_pass(const char *data, size_t data_size, return hr; }
- if (!(p->objects = heap_calloc(p->object_count, sizeof(*p->objects)))) - { - ERR("Failed to allocate effect objects memory.\n"); - return E_OUTOFMEMORY; - } - p->vs.shader = &null_shader_variable; p->ps.shader = &null_shader_variable; p->gs.shader = &null_shader_variable;
- for (i = 0; i < p->object_count; ++i) + for (i = 0; i < object_count; ++i) { - struct d3d10_effect_object *o = &p->objects[i]; - - o->pass = p; - - if (FAILED(hr = parse_fx10_object(data, data_size, ptr, o))) + if (FAILED(hr = parse_fx10_object(data, data_size, ptr, p))) return hr; }
@@ -2927,42 +2911,6 @@ HRESULT d3d10_effect_parse(struct d3d10_effect *This, const void *data, SIZE_T d return parse_dxbc(data, data_size, fx10_chunk_handler, This); }
-static HRESULT d3d10_effect_object_apply(struct d3d10_effect_object *o) -{ - ID3D10Device *device = o->pass->technique->effect->device; - - TRACE("effect object %p, type %#x.\n", o, o->type); - - switch(o->type) - { - case D3D10_EOT_RASTERIZER_STATE: - case D3D10_EOT_DEPTH_STENCIL_STATE: - case D3D10_EOT_BLEND_STATE: - case D3D10_EOT_STENCIL_REF: - case D3D10_EOT_BLEND_FACTOR: - case D3D10_EOT_SAMPLE_MASK: - break; - - case D3D10_EOT_VERTEXSHADER: - ID3D10Device_VSSetShader(device, o->object.vs); - return S_OK; - - case D3D10_EOT_PIXELSHADER: - ID3D10Device_PSSetShader(device, o->object.ps); - return S_OK; - - case D3D10_EOT_GEOMETRYSHADER: - ID3D10Device_GSSetShader(device, o->object.gs); - return S_OK; - - default: - FIXME("Unhandled effect object type %#x.\n", o->type); - return E_FAIL; - } - - return S_OK; -} - static void d3d10_effect_shader_variable_destroy(struct d3d10_effect_shader_variable *s, D3D10_SHADER_VARIABLE_TYPE type) { @@ -3087,25 +3035,6 @@ static void d3d10_effect_variable_destroy(struct d3d10_effect_variable *v) } }
-static void d3d10_effect_object_destroy(struct d3d10_effect_object *o) -{ - switch (o->type) - { - case D3D10_EOT_RASTERIZER_STATE: - case D3D10_EOT_DEPTH_STENCIL_STATE: - case D3D10_EOT_BLEND_STATE: - case D3D10_EOT_VERTEXSHADER: - case D3D10_EOT_PIXELSHADER: - case D3D10_EOT_GEOMETRYSHADER: - if (o->object.object) - IUnknown_Release(o->object.object); - break; - - default: - break; - } -} - static void d3d10_effect_pass_destroy(struct d3d10_effect_pass *p) { unsigned int i; @@ -3114,15 +3043,6 @@ static void d3d10_effect_pass_destroy(struct d3d10_effect_pass *p)
heap_free(p->name);
- if (p->objects) - { - for (i = 0; i < p->object_count; ++i) - { - d3d10_effect_object_destroy(&p->objects[i]); - } - heap_free(p->objects); - } - if (p->annotations) { for (i = 0; i < p->annotation_count; ++i) @@ -4109,12 +4029,35 @@ static void apply_shader_resources(ID3D10Device *device, struct d3d10_effect_var } }
+static void d3d10_effect_pass_set_shader(struct d3d10_effect_pass *pass, + const struct d3d10_effect_pass_shader_desc *shader_desc) +{ + ID3D10Device *device = pass->technique->effect->device; + struct d3d10_effect_variable *v = shader_desc->shader; + + if (v->type->element_count) + v = &v->elements[shader_desc->index]; + + switch (v->type->basetype) + { + case D3D10_SVT_VERTEXSHADER: + ID3D10Device_VSSetShader(device, v->u.shader.shader.vs); + break; + case D3D10_SVT_PIXELSHADER: + ID3D10Device_PSSetShader(device, v->u.shader.shader.ps); + break; + case D3D10_SVT_GEOMETRYSHADER: + ID3D10Device_GSSetShader(device, v->u.shader.shader.gs); + break; + default: + WARN("Unexpected shader type %u.\n", v->type->basetype); + } +} + static HRESULT STDMETHODCALLTYPE d3d10_effect_pass_Apply(ID3D10EffectPass *iface, UINT flags) { struct d3d10_effect_pass *pass = impl_from_ID3D10EffectPass(iface); ID3D10Device *device = pass->technique->effect->device; - HRESULT hr = S_OK; - unsigned int i;
TRACE("iface %p, flags %#x\n", iface, flags);
@@ -4134,14 +4077,14 @@ static HRESULT STDMETHODCALLTYPE d3d10_effect_pass_Apply(ID3D10EffectPass *iface if (pass->blend) ID3D10Device_OMSetBlendState(device, pass->blend->u.state.object.blend, pass->blend_factor, pass->sample_mask); + if (pass->vs.shader != &null_shader_variable) + d3d10_effect_pass_set_shader(pass, &pass->vs); + if (pass->ps.shader != &null_shader_variable) + d3d10_effect_pass_set_shader(pass, &pass->ps); + if (pass->gs.shader != &null_shader_variable) + d3d10_effect_pass_set_shader(pass, &pass->gs);
- for (i = 0; i < pass->object_count; ++i) - { - hr = d3d10_effect_object_apply(&pass->objects[i]); - if (FAILED(hr)) break; - } - - return hr; + return S_OK; }
static HRESULT STDMETHODCALLTYPE d3d10_effect_pass_ComputeStateBlockMask(ID3D10EffectPass *iface,
On Wed, Oct 6, 2021 at 9:54 AM Nikolay Sivov nsivov@codeweavers.com wrote:
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com
dlls/d3d10/d3d10_private.h | 15 --- dlls/d3d10/effect.c | 185 +++++++++++++------------------------ 2 files changed, 64 insertions(+), 136 deletions(-)
Love to see that! Very nice patch overall.
There's only a couple of small things...
diff --git a/dlls/d3d10/effect.c b/dlls/d3d10/effect.c index 0ba906375d7..d4e44a7f419 100644 --- a/dlls/d3d10/effect.c +++ b/dlls/d3d10/effect.c
@@ -4109,12 +4029,35 @@ static void apply_shader_resources(ID3D10Device *device, struct d3d10_effect_var } }
+static void d3d10_effect_pass_set_shader(struct d3d10_effect_pass *pass,
const struct d3d10_effect_pass_shader_desc *shader_desc)
+{
- ID3D10Device *device = pass->technique->effect->device;
- struct d3d10_effect_variable *v = shader_desc->shader;
- if (v->type->element_count)
v = &v->elements[shader_desc->index];
- switch (v->type->basetype)
- {
case D3D10_SVT_VERTEXSHADER:
ID3D10Device_VSSetShader(device, v->u.shader.shader.vs);
break;
case D3D10_SVT_PIXELSHADER:
ID3D10Device_PSSetShader(device, v->u.shader.shader.ps);
break;
case D3D10_SVT_GEOMETRYSHADER:
ID3D10Device_GSSetShader(device, v->u.shader.shader.gs);
break;
default:
WARN("Unexpected shader type %u.\n", v->type->basetype);
- }
+}
Like in some of the previous patches, this is actually a fix to shaders arrays / D3D10_EOO_CONST_INDEX, which would be nice to mention. FWIW this is more D3D10_EOO_VAR_INDEX-ready than the others.
static HRESULT STDMETHODCALLTYPE d3d10_effect_pass_Apply(ID3D10EffectPass *iface, UINT flags) { struct d3d10_effect_pass *pass = impl_from_ID3D10EffectPass(iface); ID3D10Device *device = pass->technique->effect->device;
HRESULT hr = S_OK;
unsigned int i;
TRACE("iface %p, flags %#x\n", iface, flags);
@@ -4134,14 +4077,14 @@ static HRESULT STDMETHODCALLTYPE d3d10_effect_pass_Apply(ID3D10EffectPass *iface if (pass->blend) ID3D10Device_OMSetBlendState(device, pass->blend->u.state.object.blend, pass->blend_factor, pass->sample_mask);
- if (pass->vs.shader != &null_shader_variable)
d3d10_effect_pass_set_shader(pass, &pass->vs);
- if (pass->ps.shader != &null_shader_variable)
d3d10_effect_pass_set_shader(pass, &pass->ps);
- if (pass->gs.shader != &null_shader_variable)
d3d10_effect_pass_set_shader(pass, &pass->gs);
- for (i = 0; i < pass->object_count; ++i)
- {
hr = d3d10_effect_object_apply(&pass->objects[i]);
if (FAILED(hr)) break;
- }
- return hr;
- return S_OK;
}
I suspect you still want to set the shaders unconditionally (e.g. what if pass 0 sets a non-NULL geometry shader and pass 1 sets NULL?)
On 10/7/21 9:45 PM, Matteo Bruni wrote:
On Wed, Oct 6, 2021 at 9:54 AM Nikolay Sivov nsivov@codeweavers.com wrote:
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com
dlls/d3d10/d3d10_private.h | 15 --- dlls/d3d10/effect.c | 185 +++++++++++++------------------------ 2 files changed, 64 insertions(+), 136 deletions(-)
Love to see that! Very nice patch overall.
There's only a couple of small things...
diff --git a/dlls/d3d10/effect.c b/dlls/d3d10/effect.c index 0ba906375d7..d4e44a7f419 100644 --- a/dlls/d3d10/effect.c +++ b/dlls/d3d10/effect.c @@ -4109,12 +4029,35 @@ static void apply_shader_resources(ID3D10Device *device, struct d3d10_effect_var } }
+static void d3d10_effect_pass_set_shader(struct d3d10_effect_pass *pass,
const struct d3d10_effect_pass_shader_desc *shader_desc)
+{
- ID3D10Device *device = pass->technique->effect->device;
- struct d3d10_effect_variable *v = shader_desc->shader;
- if (v->type->element_count)
v = &v->elements[shader_desc->index];
- switch (v->type->basetype)
- {
case D3D10_SVT_VERTEXSHADER:
ID3D10Device_VSSetShader(device, v->u.shader.shader.vs);
break;
case D3D10_SVT_PIXELSHADER:
ID3D10Device_PSSetShader(device, v->u.shader.shader.ps);
break;
case D3D10_SVT_GEOMETRYSHADER:
ID3D10Device_GSSetShader(device, v->u.shader.shader.gs);
break;
default:
WARN("Unexpected shader type %u.\n", v->type->basetype);
- }
+}
Like in some of the previous patches, this is actually a fix to shaders arrays / D3D10_EOO_CONST_INDEX, which would be nice to mention. FWIW this is more D3D10_EOO_VAR_INDEX-ready than the others.
Existing code already picked correct shader object, using GetVertexShader(index, &vs) methods on shader variable interface. So arrays were already working I believe, but yes, that didn't make it easier to support variable index, let alone switching between variables.
static HRESULT STDMETHODCALLTYPE d3d10_effect_pass_Apply(ID3D10EffectPass *iface, UINT flags) { struct d3d10_effect_pass *pass = impl_from_ID3D10EffectPass(iface); ID3D10Device *device = pass->technique->effect->device;
HRESULT hr = S_OK;
unsigned int i;
TRACE("iface %p, flags %#x\n", iface, flags);
@@ -4134,14 +4077,14 @@ static HRESULT STDMETHODCALLTYPE d3d10_effect_pass_Apply(ID3D10EffectPass *iface if (pass->blend) ID3D10Device_OMSetBlendState(device, pass->blend->u.state.object.blend, pass->blend_factor, pass->sample_mask);
- if (pass->vs.shader != &null_shader_variable)
d3d10_effect_pass_set_shader(pass, &pass->vs);
- if (pass->ps.shader != &null_shader_variable)
d3d10_effect_pass_set_shader(pass, &pass->ps);
- if (pass->gs.shader != &null_shader_variable)
d3d10_effect_pass_set_shader(pass, &pass->gs);
- for (i = 0; i < pass->object_count; ++i)
- {
hr = d3d10_effect_object_apply(&pass->objects[i]);
if (FAILED(hr)) break;
- }
- return hr;
- return S_OK;
}
I suspect you still want to set the shaders unconditionally (e.g. what if pass 0 sets a non-NULL geometry shader and pass 1 sets NULL?)
That's why I sent some state block mask tests. There appears to be a difference between SetPixelShader(NULL) and no SetPixelShader() instruction at all. Currently, and that's what existing code did, we use null_shader_variable as initial value, and anonymous_{vs|gs|ps} for assigned NULL values. I believe that is also visible with SHADER_PASS_DESC, that never returns NULL vars.
On Thu, Oct 7, 2021 at 9:00 PM Nikolay Sivov nsivov@codeweavers.com wrote:
On 10/7/21 9:45 PM, Matteo Bruni wrote:
On Wed, Oct 6, 2021 at 9:54 AM Nikolay Sivov nsivov@codeweavers.com wrote:
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com
dlls/d3d10/d3d10_private.h | 15 --- dlls/d3d10/effect.c | 185 +++++++++++++------------------------ 2 files changed, 64 insertions(+), 136 deletions(-)
Love to see that! Very nice patch overall.
There's only a couple of small things...
diff --git a/dlls/d3d10/effect.c b/dlls/d3d10/effect.c index 0ba906375d7..d4e44a7f419 100644 --- a/dlls/d3d10/effect.c +++ b/dlls/d3d10/effect.c @@ -4109,12 +4029,35 @@ static void apply_shader_resources(ID3D10Device *device, struct d3d10_effect_var } }
+static void d3d10_effect_pass_set_shader(struct d3d10_effect_pass *pass,
const struct d3d10_effect_pass_shader_desc *shader_desc)
+{
- ID3D10Device *device = pass->technique->effect->device;
- struct d3d10_effect_variable *v = shader_desc->shader;
- if (v->type->element_count)
v = &v->elements[shader_desc->index];
- switch (v->type->basetype)
- {
case D3D10_SVT_VERTEXSHADER:
ID3D10Device_VSSetShader(device, v->u.shader.shader.vs);
break;
case D3D10_SVT_PIXELSHADER:
ID3D10Device_PSSetShader(device, v->u.shader.shader.ps);
break;
case D3D10_SVT_GEOMETRYSHADER:
ID3D10Device_GSSetShader(device, v->u.shader.shader.gs);
break;
default:
WARN("Unexpected shader type %u.\n", v->type->basetype);
- }
+}
Like in some of the previous patches, this is actually a fix to shaders arrays / D3D10_EOO_CONST_INDEX, which would be nice to mention. FWIW this is more D3D10_EOO_VAR_INDEX-ready than the others.
Existing code already picked correct shader object, using GetVertexShader(index, &vs) methods on shader variable interface. So arrays were already working I believe, but yes, that didn't make it easier to support variable index, let alone switching between variables.
static HRESULT STDMETHODCALLTYPE d3d10_effect_pass_Apply(ID3D10EffectPass *iface, UINT flags) { struct d3d10_effect_pass *pass = impl_from_ID3D10EffectPass(iface); ID3D10Device *device = pass->technique->effect->device;
HRESULT hr = S_OK;
unsigned int i;
TRACE("iface %p, flags %#x\n", iface, flags);
@@ -4134,14 +4077,14 @@ static HRESULT STDMETHODCALLTYPE d3d10_effect_pass_Apply(ID3D10EffectPass *iface if (pass->blend) ID3D10Device_OMSetBlendState(device, pass->blend->u.state.object.blend, pass->blend_factor, pass->sample_mask);
- if (pass->vs.shader != &null_shader_variable)
d3d10_effect_pass_set_shader(pass, &pass->vs);
- if (pass->ps.shader != &null_shader_variable)
d3d10_effect_pass_set_shader(pass, &pass->ps);
- if (pass->gs.shader != &null_shader_variable)
d3d10_effect_pass_set_shader(pass, &pass->gs);
- for (i = 0; i < pass->object_count; ++i)
- {
hr = d3d10_effect_object_apply(&pass->objects[i]);
if (FAILED(hr)) break;
- }
- return hr;
- return S_OK;
}
I suspect you still want to set the shaders unconditionally (e.g. what if pass 0 sets a non-NULL geometry shader and pass 1 sets NULL?)
That's why I sent some state block mask tests. There appears to be a difference between SetPixelShader(NULL) and no SetPixelShader() instruction at all. Currently, and that's what existing code did, we use null_shader_variable as initial value, and anonymous_{vs|gs|ps} for assigned NULL values. I believe that is also visible with SHADER_PASS_DESC, that never returns NULL vars.
Ah, interesting. I'll have another look to make sure but it sounds like the patch is fine.