Signed-off-by: Connor McAdams conmanx360@gmail.com --- dlls/d3d10/effect.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-)
diff --git a/dlls/d3d10/effect.c b/dlls/d3d10/effect.c index 2360e5a025..e2c18ce049 100644 --- a/dlls/d3d10/effect.c +++ b/dlls/d3d10/effect.c @@ -124,6 +124,11 @@ static inline struct d3d10_effect_variable *impl_from_ID3D10EffectVariable(ID3D1 return CONTAINING_RECORD(iface, struct d3d10_effect_variable, ID3D10EffectVariable_iface); }
+static inline struct d3d10_effect_variable *impl_from_ID3D10EffectShaderVariable(ID3D10EffectShaderVariable *iface) +{ + return CONTAINING_RECORD(iface, struct d3d10_effect_variable, ID3D10EffectVariable_iface); +} + struct d3d10_effect_state_property_info { UINT id; @@ -6639,7 +6644,7 @@ static HRESULT STDMETHODCALLTYPE d3d10_effect_shader_variable_GetShaderDesc( static HRESULT STDMETHODCALLTYPE d3d10_effect_shader_variable_GetVertexShader( ID3D10EffectShaderVariable *iface, UINT index, ID3D10VertexShader **shader) { - struct d3d10_effect_variable *v = impl_from_ID3D10EffectVariable((ID3D10EffectVariable *)iface); + struct d3d10_effect_variable *v = impl_from_ID3D10EffectShaderVariable(iface);
TRACE("iface %p, index %u, shader %p.\n", iface, index, shader);
@@ -6661,7 +6666,7 @@ static HRESULT STDMETHODCALLTYPE d3d10_effect_shader_variable_GetVertexShader( static HRESULT STDMETHODCALLTYPE d3d10_effect_shader_variable_GetGeometryShader( ID3D10EffectShaderVariable *iface, UINT index, ID3D10GeometryShader **shader) { - struct d3d10_effect_variable *v = impl_from_ID3D10EffectVariable((ID3D10EffectVariable *)iface); + struct d3d10_effect_variable *v = impl_from_ID3D10EffectShaderVariable(iface);
TRACE("iface %p, index %u, shader %p.\n", iface, index, shader);
@@ -6683,7 +6688,7 @@ static HRESULT STDMETHODCALLTYPE d3d10_effect_shader_variable_GetGeometryShader( static HRESULT STDMETHODCALLTYPE d3d10_effect_shader_variable_GetPixelShader( ID3D10EffectShaderVariable *iface, UINT index, ID3D10PixelShader **shader) { - struct d3d10_effect_variable *v = impl_from_ID3D10EffectVariable((ID3D10EffectVariable *)iface); + struct d3d10_effect_variable *v = impl_from_ID3D10EffectShaderVariable(iface);
TRACE("iface %p, index %u, shader %p.\n", iface, index, shader);
@@ -6706,7 +6711,7 @@ static HRESULT STDMETHODCALLTYPE d3d10_effect_shader_variable_GetInputSignatureE ID3D10EffectShaderVariable *iface, UINT shader_index, UINT element_index, D3D10_SIGNATURE_PARAMETER_DESC *desc) { - struct d3d10_effect_variable *This = (struct d3d10_effect_variable *)iface; + struct d3d10_effect_variable *v = impl_from_ID3D10EffectShaderVariable(iface); struct d3d10_effect_shader_variable *s; D3D10_SIGNATURE_PARAMETER_DESC *d;
@@ -6720,13 +6725,13 @@ static HRESULT STDMETHODCALLTYPE d3d10_effect_shader_variable_GetInputSignatureE }
/* Check shader_index, this crashes on W7/DX10 */ - if (shader_index >= This->effect->used_shader_count) + if (shader_index >= v->effect->used_shader_count) { WARN("This should crash on W7/DX10!\n"); return E_FAIL; }
- s = &This->effect->used_shaders[shader_index]->u.shader; + s = &v->effect->used_shaders[shader_index]->u.shader; if (!s->input_signature.signature) { WARN("No shader signature\n"); @@ -6762,7 +6767,7 @@ static HRESULT STDMETHODCALLTYPE d3d10_effect_shader_variable_GetOutputSignature ID3D10EffectShaderVariable *iface, UINT shader_index, UINT element_index, D3D10_SIGNATURE_PARAMETER_DESC *desc) { - struct d3d10_effect_variable *This = (struct d3d10_effect_variable *)iface; + struct d3d10_effect_variable *v = impl_from_ID3D10EffectShaderVariable(iface); struct d3d10_effect_shader_variable *s; D3D10_SIGNATURE_PARAMETER_DESC *d;
@@ -6776,13 +6781,13 @@ static HRESULT STDMETHODCALLTYPE d3d10_effect_shader_variable_GetOutputSignature }
/* Check shader_index, this crashes on W7/DX10 */ - if (shader_index >= This->effect->used_shader_count) + if (shader_index >= v->effect->used_shader_count) { WARN("This should crash on W7/DX10!\n"); return E_FAIL; }
- s = &This->effect->used_shaders[shader_index]->u.shader; + s = &v->effect->used_shaders[shader_index]->u.shader; if (!s->output_signature.signature) { WARN("No shader signature\n");
Signed-off-by: Connor McAdams conmanx360@gmail.com --- dlls/d3d10/effect.c | 123 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 120 insertions(+), 3 deletions(-)
diff --git a/dlls/d3d10/effect.c b/dlls/d3d10/effect.c index e2c18ce049..3d397a38eb 100644 --- a/dlls/d3d10/effect.c +++ b/dlls/d3d10/effect.c @@ -3619,9 +3619,119 @@ static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_pass_GetAnno return &null_variable.ID3D10EffectVariable_iface; }
+static void update_buffer(ID3D10Device *device, struct d3d10_effect_variable *v) +{ + struct d3d10_effect_buffer_variable *b = &v->u.buffer; + + if (!b->changed) + return; + + ID3D10Device_UpdateSubresource(device, (ID3D10Resource *)b->buffer, 0, NULL, + b->local_buffer, v->data_size, 0); + + b->changed = FALSE; +} + +static void apply_shader_resources(ID3D10Device *device, struct ID3D10EffectShaderVariable *variable) +{ + 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; + ID3D10ShaderResourceView **srv; + unsigned int i; + + for (i = 0; i < sv->resource_count; ++i) + { + sr = &sv->resources[i]; + rsrc_v = sr->variable; + + switch (sr->in_type) + { + case D3D10_SIT_CBUFFER: + update_buffer(device, rsrc_v); + switch (v->type->basetype) + { + case D3D10_SVT_VERTEXSHADER: + ID3D10Device_VSSetConstantBuffers(device, sr->bind_point, sr->bind_count, + &rsrc_v->u.buffer.buffer); + break; + + case D3D10_SVT_PIXELSHADER: + ID3D10Device_PSSetConstantBuffers(device, sr->bind_point, sr->bind_count, + &rsrc_v->u.buffer.buffer); + break; + + case D3D10_SVT_GEOMETRYSHADER: + ID3D10Device_GSSetConstantBuffers(device, sr->bind_point, sr->bind_count, + &rsrc_v->u.buffer.buffer); + break; + + default: + WARN("Incorrect shader type to bind constant buffer.\n"); + break; + } + break; + + case D3D10_SIT_TBUFFER: + update_buffer(device, rsrc_v); + srv = &rsrc_v->u.buffer.resource_view; + + switch (v->type->basetype) + { + case D3D10_SVT_VERTEXSHADER: + ID3D10Device_VSSetShaderResources(device, sr->bind_point, sr->bind_count, srv); + break; + + case D3D10_SVT_PIXELSHADER: + ID3D10Device_PSSetShaderResources(device, sr->bind_point, sr->bind_count, srv); + break; + + case D3D10_SVT_GEOMETRYSHADER: + ID3D10Device_GSSetShaderResources(device, sr->bind_point, sr->bind_count, srv); + break; + + default: + WARN("Incorrect shader type to bind shader resource view.\n"); + break; + } + break; + + case D3D10_SIT_SAMPLER: + switch (v->type->basetype) + { + case D3D10_SVT_VERTEXSHADER: + ID3D10Device_VSSetSamplers(device, sr->bind_point, sr->bind_count, + &rsrc_v->u.state.object.sampler); + break; + + case D3D10_SVT_PIXELSHADER: + ID3D10Device_PSSetSamplers(device, sr->bind_point, sr->bind_count, + &rsrc_v->u.state.object.sampler); + break; + + case D3D10_SVT_GEOMETRYSHADER: + ID3D10Device_GSSetSamplers(device, sr->bind_point, sr->bind_count, + &rsrc_v->u.state.object.sampler); + break; + + default: + WARN("Incorrect shader type to bind sampler.\n"); + break; + } + break; + + default: + WARN("Unhandled shader resource %#x.\n", sr->in_type); + break; + } + } +} + static HRESULT STDMETHODCALLTYPE d3d10_effect_pass_Apply(ID3D10EffectPass *iface, UINT flags) { - struct d3d10_effect_pass *This = impl_from_ID3D10EffectPass(iface); + struct d3d10_effect_pass *pass = impl_from_ID3D10EffectPass(iface); + ID3D10Device *device = pass->technique->effect->device; HRESULT hr = S_OK; unsigned int i;
@@ -3629,9 +3739,16 @@ static HRESULT STDMETHODCALLTYPE d3d10_effect_pass_Apply(ID3D10EffectPass *iface
if (flags) FIXME("Ignoring flags (%#x)\n", flags);
- for (i = 0; i < This->object_count; ++i) + 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); + + for (i = 0; i < pass->object_count; ++i) { - hr = d3d10_effect_object_apply(&This->objects[i]); + hr = d3d10_effect_object_apply(&pass->objects[i]); if (FAILED(hr)) break; }
Signed-off-by: Matteo Bruni mbruni@codeweavers.com
Signed-off-by: Connor McAdams conmanx360@gmail.com --- dlls/d3d10/d3d10_private.h | 7 +++ dlls/d3d10/effect.c | 114 ++++++++++++++++++++++++++++++++++--- 2 files changed, 114 insertions(+), 7 deletions(-)
diff --git a/dlls/d3d10/d3d10_private.h b/dlls/d3d10/d3d10_private.h index 21d7f964e8..5d7c4e128b 100644 --- a/dlls/d3d10/d3d10_private.h +++ b/dlls/d3d10/d3d10_private.h @@ -131,6 +131,12 @@ struct d3d10_effect_state_object_variable } object; };
+struct d3d10_effect_resource_variable +{ + ID3D10ShaderResourceView **resource_view; + BOOL parent; +}; + struct d3d10_effect_buffer_variable { ID3D10Buffer *buffer; @@ -196,6 +202,7 @@ struct d3d10_effect_variable struct d3d10_effect_state_object_variable state; struct d3d10_effect_shader_variable shader; struct d3d10_effect_buffer_variable buffer; + struct d3d10_effect_resource_variable resource; } u; };
diff --git a/dlls/d3d10/effect.c b/dlls/d3d10/effect.c index 3d397a38eb..91cb189362 100644 --- a/dlls/d3d10/effect.c +++ b/dlls/d3d10/effect.c @@ -2079,6 +2079,28 @@ static HRESULT parse_fx10_local_variable(const char *data, size_t data_size, case D3D10_SVT_TEXTURE2DMSARRAY: case D3D10_SVT_TEXTURE3D: case D3D10_SVT_TEXTURECUBE: + if (!v->type->element_count) + i = 1; + else + i = v->type->element_count; + + if (!(v->u.resource.resource_view = heap_calloc(i, sizeof(ID3D10ShaderResourceView *)))) + { + ERR("Failed to allocate shader resource view array memory.\n"); + return E_OUTOFMEMORY; + } + v->u.resource.parent = TRUE; + + if (v->elements) + { + for (i = 0; i < v->type->element_count; ++i) + { + v->elements[i].u.resource.resource_view = &v->u.resource.resource_view[i]; + v->elements[i].u.resource.parent = FALSE; + } + } + break; + case D3D10_SVT_RENDERTARGETVIEW: case D3D10_SVT_DEPTHSTENCILVIEW: case D3D10_SVT_BUFFER: @@ -2716,7 +2738,7 @@ static void d3d10_effect_shader_variable_destroy(struct d3d10_effect_shader_vari
static void d3d10_effect_variable_destroy(struct d3d10_effect_variable *v) { - unsigned int i; + unsigned int i, elem_count;
TRACE("variable %p.\n", v);
@@ -2779,6 +2801,31 @@ static void d3d10_effect_variable_destroy(struct d3d10_effect_variable *v) ID3D10SamplerState_Release(v->u.state.object.sampler); break;
+ case D3D10_SVT_TEXTURE1D: + case D3D10_SVT_TEXTURE1DARRAY: + case D3D10_SVT_TEXTURE2D: + case D3D10_SVT_TEXTURE2DARRAY: + case D3D10_SVT_TEXTURE2DMS: + case D3D10_SVT_TEXTURE2DMSARRAY: + case D3D10_SVT_TEXTURE3D: + case D3D10_SVT_TEXTURECUBE: + if (!v->u.resource.parent) + break; + + if (!v->type->element_count) + elem_count = 1; + else + elem_count = v->type->element_count; + + for (i = 0; i < elem_count; ++i) + { + if (v->u.resource.resource_view[i]) + ID3D10ShaderResourceView_Release(v->u.resource.resource_view[i]); + } + + heap_free(v->u.resource.resource_view); + break; + default: break; } @@ -3674,8 +3721,14 @@ static void apply_shader_resources(ID3D10Device *device, struct ID3D10EffectShad break;
case D3D10_SIT_TBUFFER: - update_buffer(device, rsrc_v); - srv = &rsrc_v->u.buffer.resource_view; + case D3D10_SIT_TEXTURE: + if (sr->in_type == D3D10_SIT_TBUFFER) + { + update_buffer(device, rsrc_v); + srv = &rsrc_v->u.buffer.resource_view; + } + else + srv = rsrc_v->u.resource.resource_view;
switch (v->type->basetype) { @@ -5924,8 +5977,27 @@ static const struct ID3D10EffectStringVariableVtbl d3d10_effect_string_variable_ d3d10_effect_string_variable_GetStringArray, };
+static void set_shader_resource_variable(ID3D10ShaderResourceView **src, ID3D10ShaderResourceView **dst) +{ + if (*dst == *src) + return; + + if (*dst) + ID3D10ShaderResourceView_Release(*dst); + if (*src) + ID3D10ShaderResourceView_AddRef(*src); + + *dst = *src; +} + /* ID3D10EffectVariable methods */
+static inline struct d3d10_effect_variable *impl_from_ID3D10EffectShaderResourceVariable( + ID3D10EffectShaderResourceVariable *iface) +{ + return CONTAINING_RECORD(iface, struct d3d10_effect_variable, ID3D10EffectVariable_iface); +} + static BOOL STDMETHODCALLTYPE d3d10_effect_shader_resource_variable_IsValid(ID3D10EffectShaderResourceVariable *iface) { TRACE("iface %p\n", iface); @@ -6082,9 +6154,13 @@ static HRESULT STDMETHODCALLTYPE d3d10_effect_shader_resource_variable_GetRawVal static HRESULT STDMETHODCALLTYPE d3d10_effect_shader_resource_variable_SetResource( ID3D10EffectShaderResourceVariable *iface, ID3D10ShaderResourceView *resource) { - FIXME("iface %p, resource %p stub!\n", iface, resource); + struct d3d10_effect_variable *effect_var = impl_from_ID3D10EffectShaderResourceVariable(iface);
- return E_NOTIMPL; + TRACE("iface %p, resource %p.\n", iface, resource); + + set_shader_resource_variable(&resource, effect_var->u.resource.resource_view); + + return S_OK; }
static HRESULT STDMETHODCALLTYPE d3d10_effect_shader_resource_variable_GetResource( @@ -6098,9 +6174,33 @@ static HRESULT STDMETHODCALLTYPE d3d10_effect_shader_resource_variable_GetResour static HRESULT STDMETHODCALLTYPE d3d10_effect_shader_resource_variable_SetResourceArray( ID3D10EffectShaderResourceVariable *iface, ID3D10ShaderResourceView **resources, UINT offset, UINT count) { - FIXME("iface %p, resources %p, offset %u, count %u stub!\n", iface, resources, offset, count); + struct d3d10_effect_variable *effect_var = impl_from_ID3D10EffectShaderResourceVariable(iface); + ID3D10ShaderResourceView **rsrc_view; + UINT i;
- return E_NOTIMPL; + TRACE("iface %p, resources %p, offset %u, count %u.\n", iface, resources, offset, count); + + if (!effect_var->type->element_count) + return d3d10_effect_shader_resource_variable_SetResource(iface, *resources); + + if (offset >= effect_var->type->element_count) + { + WARN("Offset %u larger than element count %u, ignoring.\n", offset, effect_var->type->element_count); + return S_OK; + } + + if (count > effect_var->type->element_count - offset) + { + WARN("Offset %u, count %u overruns the variable (element count %u), fixing up.\n", + offset, count, effect_var->type->element_count); + count = effect_var->type->element_count - offset; + } + + rsrc_view = &effect_var->u.resource.resource_view[offset]; + for (i = 0; i < count; ++i) + set_shader_resource_variable(&resources[i], &rsrc_view[i]); + + return S_OK; }
static HRESULT STDMETHODCALLTYPE d3d10_effect_shader_resource_variable_GetResourceArray(
On Wed, Mar 25, 2020 at 7:17 PM Connor McAdams conmanx360@gmail.com wrote:
Signed-off-by: Connor McAdams conmanx360@gmail.com
dlls/d3d10/d3d10_private.h | 7 +++ dlls/d3d10/effect.c | 114 ++++++++++++++++++++++++++++++++++--- 2 files changed, 114 insertions(+), 7 deletions(-)
diff --git a/dlls/d3d10/d3d10_private.h b/dlls/d3d10/d3d10_private.h index 21d7f964e8..5d7c4e128b 100644 --- a/dlls/d3d10/d3d10_private.h +++ b/dlls/d3d10/d3d10_private.h @@ -131,6 +131,12 @@ struct d3d10_effect_state_object_variable } object; };
+struct d3d10_effect_resource_variable +{
- ID3D10ShaderResourceView **resource_view;
- BOOL parent;
+};
Just to give a couple more naming options: that could also be srv or view.
struct d3d10_effect_buffer_variable { ID3D10Buffer *buffer; @@ -196,6 +202,7 @@ struct d3d10_effect_variable struct d3d10_effect_state_object_variable state; struct d3d10_effect_shader_variable shader; struct d3d10_effect_buffer_variable buffer;
} u;struct d3d10_effect_resource_variable resource;
};
diff --git a/dlls/d3d10/effect.c b/dlls/d3d10/effect.c index 3d397a38eb..91cb189362 100644 --- a/dlls/d3d10/effect.c +++ b/dlls/d3d10/effect.c @@ -2079,6 +2079,28 @@ static HRESULT parse_fx10_local_variable(const char *data, size_t data_size, case D3D10_SVT_TEXTURE2DMSARRAY: case D3D10_SVT_TEXTURE3D: case D3D10_SVT_TEXTURECUBE:
if (!v->type->element_count)
i = 1;
else
i = v->type->element_count;
if (!(v->u.resource.resource_view = heap_calloc(i, sizeof(ID3D10ShaderResourceView *))))
sizeof(*v->u.resource.resource_view)
@@ -5924,8 +5977,27 @@ static const struct ID3D10EffectStringVariableVtbl d3d10_effect_string_variable_ d3d10_effect_string_variable_GetStringArray, };
+static void set_shader_resource_variable(ID3D10ShaderResourceView **src, ID3D10ShaderResourceView **dst) +{
- if (*dst == *src)
return;
- if (*dst)
ID3D10ShaderResourceView_Release(*dst);
- if (*src)
ID3D10ShaderResourceView_AddRef(*src);
- *dst = *src;
+}
Nitpick: can you swap the order of the if (*src) / if (*dst)? I know it doesn't matter since there is the equality check just above, but with the AddRef() before the Release() it becomes obviously correct and a bit easier to read.
@@ -6082,9 +6154,13 @@ static HRESULT STDMETHODCALLTYPE d3d10_effect_shader_resource_variable_GetRawVal static HRESULT STDMETHODCALLTYPE d3d10_effect_shader_resource_variable_SetResource( ID3D10EffectShaderResourceVariable *iface, ID3D10ShaderResourceView *resource) {
- FIXME("iface %p, resource %p stub!\n", iface, resource);
- struct d3d10_effect_variable *effect_var = impl_from_ID3D10EffectShaderResourceVariable(iface);
Just var is fine.
- return E_NOTIMPL;
- TRACE("iface %p, resource %p.\n", iface, resource);
- set_shader_resource_variable(&resource, effect_var->u.resource.resource_view);
- return S_OK;
}
static HRESULT STDMETHODCALLTYPE d3d10_effect_shader_resource_variable_GetResource( @@ -6098,9 +6174,33 @@ static HRESULT STDMETHODCALLTYPE d3d10_effect_shader_resource_variable_GetResour static HRESULT STDMETHODCALLTYPE d3d10_effect_shader_resource_variable_SetResourceArray( ID3D10EffectShaderResourceVariable *iface, ID3D10ShaderResourceView **resources, UINT offset, UINT count) {
- FIXME("iface %p, resources %p, offset %u, count %u stub!\n", iface, resources, offset, count);
- struct d3d10_effect_variable *effect_var = impl_from_ID3D10EffectShaderResourceVariable(iface);
- ID3D10ShaderResourceView **rsrc_view;
- UINT i;
unsigned int i;
Signed-off-by: Connor McAdams conmanx360@gmail.com --- dlls/d3d10/tests/effect.c | 226 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 226 insertions(+)
diff --git a/dlls/d3d10/tests/effect.c b/dlls/d3d10/tests/effect.c index 7b9bcfb50d..289766af68 100644 --- a/dlls/d3d10/tests/effect.c +++ b/dlls/d3d10/tests/effect.c @@ -5359,6 +5359,231 @@ static void test_effect_matrix_variable(void) ok(!refcount, "Device has %u references left.\n", refcount); }
+/* + * test_effect_resource_variable + */ +#if 0 +Texture2D t0; +Texture2D t_a[2]; + +float4 VS( float4 Pos : POSITION ) : SV_POSITION { return float4(1.0f, 1.0f, 1.0f, 1.0f); } + +float4 PS( float4 Pos : SV_POSITION ) : SV_Target +{ + uint4 tmp; + + tmp = t0.Load(int3(0, 0, 0)); + tmp = t_a[0].Load(int4(0, 0, 0, 0)); + tmp = t_a[1].Load(int4(0, 0, 0, 0)); + return float4(1.0f, 1.0f, 0.0f, 1.0f) + tmp; +} + +technique10 rsrc_test +{ + pass p0 + { + SetVertexShader(CompileShader(vs_4_0, VS())); + SetPixelShader(CompileShader(ps_4_0, PS())); + } +} +#endif +static DWORD fx_test_resource_variable[] = +{ + 0x43425844, 0x767a8421, 0xdcbfffe6, 0x83df123d, 0x189ce72a, 0x00000001, 0x0000065a, 0x00000001, + 0x00000024, 0x30315846, 0x0000062e, 0xfeff1001, 0x00000000, 0x00000000, 0x00000002, 0x00000000, + 0x00000000, 0x00000000, 0x00000001, 0x00000582, 0x00000000, 0x00000003, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0x00000002, 0x00000000, 0x74786554, + 0x32657275, 0x00040044, 0x00020000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x000c0000, + 0x30740000, 0x00000400, 0x00000200, 0x00000200, 0x00000000, 0x00000000, 0x00000000, 0x00000c00, + 0x615f7400, 0x72737200, 0x65745f63, 0x70007473, 0x01b40030, 0x58440000, 0x338d4342, 0xc5a69f46, + 0x56883ae5, 0xa98fccc2, 0x00018ead, 0x01b40000, 0x00050000, 0x00340000, 0x008c0000, 0x00c00000, + 0x00f40000, 0x01380000, 0x44520000, 0x00504645, 0x00000000, 0x00000000, 0x00000000, 0x001c0000, + 0x04000000, 0x0100fffe, 0x001c0000, 0x694d0000, 0x736f7263, 0x2074666f, 0x20295228, 0x4c534c48, + 0x61685320, 0x20726564, 0x706d6f43, 0x72656c69, 0x322e3920, 0x35392e39, 0x31332e32, 0xab003131, + 0x5349abab, 0x002c4e47, 0x00010000, 0x00080000, 0x00200000, 0x00000000, 0x00000000, 0x00030000, + 0x00000000, 0x000f0000, 0x4f500000, 0x49544953, 0xab004e4f, 0x534fabab, 0x002c4e47, 0x00010000, + 0x00080000, 0x00200000, 0x00000000, 0x00010000, 0x00030000, 0x00000000, 0x000f0000, 0x56530000, + 0x534f505f, 0x4f495449, 0x4853004e, 0x003c5244, 0x00400000, 0x000f0001, 0x00670000, 0x20f20400, + 0x00000010, 0x00010000, 0x00360000, 0x20f20800, 0x00000010, 0x40020000, 0x00000000, 0x00003f80, + 0x00003f80, 0x00003f80, 0x003e3f80, 0x54530100, 0x00745441, 0x00020000, 0x00000000, 0x00000000, + 0x00010000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00010000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x005a0000, 0x00000000, 0x035c0000, 0x58440000, 0xe3754342, 0x3e477f40, + 0xed6f143f, 0xf16d26ce, 0x00010c3a, 0x035c0000, 0x00050000, 0x00340000, 0x00d00000, 0x01040000, + 0x01380000, 0x02e00000, 0x44520000, 0x00944645, 0x00000000, 0x00000000, 0x00020000, 0x001c0000, + 0x04000000, 0x0100ffff, 0x00630000, 0x005c0000, 0x00020000, 0x00050000, 0x00040000, 0xffff0000, + 0x0000ffff, 0x00010000, 0x000c0000, 0x005f0000, 0x00020000, 0x00050000, 0x00040000, 0xffff0000, + 0x0001ffff, 0x00020000, 0x000c0000, 0x30740000, 0x615f7400, 0x63694d00, 0x6f736f72, 0x28207466, + 0x48202952, 0x204c534c, 0x64616853, 0x43207265, 0x69706d6f, 0x2072656c, 0x39322e39, 0x3235392e, + 0x3131332e, 0x53490031, 0x002c4e47, 0x00010000, 0x00080000, 0x00200000, 0x00000000, 0x00010000, + 0x00030000, 0x00000000, 0x000f0000, 0x56530000, 0x534f505f, 0x4f495449, 0x534f004e, 0x002c4e47, + 0x00010000, 0x00080000, 0x00200000, 0x00000000, 0x00000000, 0x00030000, 0x00000000, 0x000f0000, + 0x56530000, 0x7261545f, 0x00746567, 0x4853abab, 0x01a05244, 0x00400000, 0x00680000, 0x18580000, + 0x70000400, 0x00000010, 0x55550000, 0x18580000, 0x70000400, 0x00010010, 0x55550000, 0x18580000, + 0x70000400, 0x00020010, 0x55550000, 0x00650000, 0x20f20300, 0x00000010, 0x00680000, 0x00020200, + 0x002d0000, 0x00f20a00, 0x00000010, 0x40020000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x7e460000, 0x00000010, 0x001c0000, 0x00f20500, 0x00000010, 0x0e460000, 0x00000010, 0x00560000, + 0x00f20500, 0x00000010, 0x0e460000, 0x00000010, 0x002d0000, 0x00f20a00, 0x00010010, 0x40020000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x7e460000, 0x00010010, 0x00000000, 0x00f20700, + 0x00000010, 0x0e460000, 0x00000010, 0x0e460000, 0x00010010, 0x001c0000, 0x00f20500, 0x00000010, + 0x0e460000, 0x00000010, 0x00560000, 0x00f20500, 0x00000010, 0x0e460000, 0x00000010, 0x002d0000, + 0x00f20a00, 0x00010010, 0x40020000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x7e460000, + 0x00020010, 0x00000000, 0x00f20700, 0x00000010, 0x0e460000, 0x00000010, 0x0e460000, 0x00010010, + 0x001c0000, 0x00f20500, 0x00000010, 0x0e460000, 0x00000010, 0x00560000, 0x00f20500, 0x00000010, + 0x0e460000, 0x00000010, 0x00000000, 0x20f20a00, 0x00000010, 0x0e460000, 0x00000010, 0x40020000, + 0x00000000, 0x00003f80, 0x00003f80, 0x00000000, 0x003e3f80, 0x54530100, 0x00745441, 0x000d0000, + 0x00020000, 0x00000000, 0x00010000, 0x00030000, 0x00000000, 0x00000000, 0x00010000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00060000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x021a0000, 0x00000000, 0x002a0000, 0x000e0000, + 0x00000000, 0xffff0000, 0x0000ffff, 0x00490000, 0x002d0000, 0x00000000, 0xffff0000, 0x0000ffff, + 0x004d0000, 0x00010000, 0x00000000, 0x00570000, 0x00020000, 0x00000000, 0x00060000, 0x00000000, + 0x00070000, 0x02120000, 0x00070000, 0x00000000, 0x00070000, 0x057a0000, 0x00000000, +}; + +static void create_effect_texture_resource(ID3D10Device *device, ID3D10ShaderResourceView **srv, + ID3D10Texture2D **tex) +{ + D3D10_TEXTURE2D_DESC tex_desc; + HRESULT hr; + + tex_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + tex_desc.Width = 8; + tex_desc.Height = 8; + tex_desc.ArraySize = 1; + tex_desc.MipLevels = 0; + tex_desc.BindFlags = D3D10_BIND_SHADER_RESOURCE; + tex_desc.Usage = D3D10_USAGE_DEFAULT; + tex_desc.CPUAccessFlags = 0; + tex_desc.SampleDesc.Count = 1; + tex_desc.SampleDesc.Quality = 0; + tex_desc.MiscFlags = 0; + + hr = ID3D10Device_CreateTexture2D(device, &tex_desc, NULL, tex); + ok(SUCCEEDED(hr), "Failed to create a 2D texture, hr %#x.\n", hr); + hr = ID3D10Device_CreateShaderResourceView(device, (ID3D10Resource *)*tex, NULL, srv); + ok(SUCCEEDED(hr), "Failed to create a shader resource view, hr %#x.\n", hr); +} + +static void get_effect_shader_resource_variable(ID3D10EffectVariable *var, + ID3D10EffectShaderResourceVariable **srv) +{ + D3D10_EFFECT_TYPE_DESC type_desc; + ID3D10EffectType *type; + HRESULT hr; + + type = var->lpVtbl->GetType(var); + hr = type->lpVtbl->GetDesc(type, &type_desc); + ok(SUCCEEDED(hr), "GetDesc failed (%x).\n", hr); + ok(type_desc.Type == D3D10_SVT_TEXTURE2D, "Type is %x, expected %x.\n", type_desc.Type, D3D10_SVT_TEXTURE2D); + *srv = var->lpVtbl->AsShaderResource(var); +} + +static void test_effect_resource_variable(void) +{ + ID3D10ShaderResourceView *srv0, *srv_a[2], *srv_tmp[2]; + ID3D10EffectShaderResourceVariable *t0, *t_a, *t_a_0; + ID3D10EffectTechnique *technique; + ID3D10Texture2D *tex0, *tex_a[2]; + ID3D10EffectVariable *var; + ID3D10EffectPass *pass; + ID3D10Device *device; + ID3D10Effect *effect; + unsigned int i; + ULONG refcount; + HRESULT hr; + + if (!(device = create_device())) + { + skip("Failed to create device, skipping tests.\n"); + return; + } + + hr = create_effect(fx_test_resource_variable, 0, device, NULL, &effect); + ok(SUCCEEDED(hr), "D3D10CreateEffectFromMemory failed (%x).\n", hr); + + var = effect->lpVtbl->GetVariableByName(effect, "t0"); + get_effect_shader_resource_variable(var, &t0); + create_effect_texture_resource(device, &srv0, &tex0); + hr = t0->lpVtbl->SetResource(t0, srv0); + ok(hr == S_OK, "Failed to SetResource, hr %#x.\n", hr); + + var = effect->lpVtbl->GetVariableByName(effect, "t_a"); + get_effect_shader_resource_variable(var, &t_a); + for (i = 0; i < 2; ++i) + create_effect_texture_resource(device, &srv_a[i], &tex_a[i]); + hr = t_a->lpVtbl->SetResourceArray(t_a, srv_a, 0, 2); + ok(hr == S_OK, "Failed to SetResourceArray, hr %#x.\n", hr); + + /* Apply the pass to bind the resource to the shader. */ + technique = effect->lpVtbl->GetTechniqueByName(effect, "rsrc_test"); + ok(!!technique, "Failed to get technique.\n"); + pass = technique->lpVtbl->GetPassByName(technique, "p0"); + ok(!!pass, "Failed to get pass.\n"); + hr = pass->lpVtbl->Apply(pass, 0); + ok(SUCCEEDED(hr), "Failed to apply pass, hr %#x.\n", hr); + + ID3D10Device_PSGetShaderResources(device, 0, 1, &srv_tmp[0]); + ok(srv0 == srv_tmp[0], "Shader resource view was not bound to the shader.\n"); + ID3D10ShaderResourceView_Release(srv_tmp[0]); + + ID3D10Device_PSGetShaderResources(device, 1, 2, srv_tmp); + for (i = 0; i < 2; ++i) + { + ok(srv_a[i] == srv_tmp[i], "Shader resource view was not bound to the shader.\n"); + ID3D10ShaderResourceView_Release(srv_tmp[i]); + } + + /* Test individual array element variable SetResource. */ + var = t_a->lpVtbl->GetElement(t_a, 1); + get_effect_shader_resource_variable(var, &t_a_0); + hr = t_a_0->lpVtbl->SetResource(t_a_0, srv0); + ok(hr == S_OK, "Failed to SetResource, hr %#x.\n", hr); + + hr = pass->lpVtbl->Apply(pass, 0); + ok(SUCCEEDED(hr), "Failed to apply pass, hr %#x.\n", hr); + + ID3D10Device_PSGetShaderResources(device, 1, 2, srv_tmp); + ok(srv0 == srv_tmp[1], "Shader resource view was not bound to the shader.\n"); + for (i = 0; i < 2; ++i) + ID3D10ShaderResourceView_Release(srv_tmp[i]); + + /* Test offset. */ + hr = t_a->lpVtbl->SetResourceArray(t_a, srv_a, 1, 1); + ok(hr == S_OK, "Failed to SetResourceArray, hr %#x.\n", hr); + + hr = pass->lpVtbl->Apply(pass, 0); + ok(SUCCEEDED(hr), "Failed to apply pass, hr %#x.\n", hr); + + ID3D10Device_PSGetShaderResources(device, 1, 2, srv_tmp); + ok(srv_a[0] == srv_tmp[1], "Shader resource view was not bound to the shader.\n"); + for (i = 0; i < 2; ++i) + ID3D10ShaderResourceView_Release(srv_tmp[i]); + + /* If the offset or write size is larger than the element size of the + * texture, due to there being no bounds checking, an access violation + * occurs. */ + if (0) + { + hr = t_a->lpVtbl->SetResourceArray(t_a, srv_a, 2, 2); + ok(hr == S_OK, "Failed to SetResourceArray, hr %#x.\n", hr); + } + + ID3D10ShaderResourceView_Release(srv0); + ID3D10Texture2D_Release(tex0); + for (i = 0; i < 2; ++i) + { + ID3D10ShaderResourceView_Release(srv_a[i]); + ID3D10Texture2D_Release(tex_a[i]); + } + + effect->lpVtbl->Release(effect); + + refcount = ID3D10Device_Release(device); + ok(!refcount, "Device has %u references left.\n", refcount); +} + START_TEST(effect) { test_effect_constant_buffer_type(); @@ -5374,4 +5599,5 @@ START_TEST(effect) test_effect_scalar_variable(); test_effect_vector_variable(); test_effect_matrix_variable(); + test_effect_resource_variable(); }
On Wed, Mar 25, 2020 at 7:17 PM Connor McAdams conmanx360@gmail.com wrote:
- hr = ID3D10Device_CreateTexture2D(device, &tex_desc, NULL, tex);
- ok(SUCCEEDED(hr), "Failed to create a 2D texture, hr %#x.\n", hr);
- hr = ID3D10Device_CreateShaderResourceView(device, (ID3D10Resource *)*tex, NULL, srv);
- ok(SUCCEEDED(hr), "Failed to create a shader resource view, hr %#x.\n", hr);
Please use the same style as the previous tests:
ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+}
+static void get_effect_shader_resource_variable(ID3D10EffectVariable *var,
ID3D10EffectShaderResourceVariable **srv)
+{
- D3D10_EFFECT_TYPE_DESC type_desc;
- ID3D10EffectType *type;
- HRESULT hr;
- type = var->lpVtbl->GetType(var);
- hr = type->lpVtbl->GetDesc(type, &type_desc);
- ok(SUCCEEDED(hr), "GetDesc failed (%x).\n", hr);
Same.
- ok(type_desc.Type == D3D10_SVT_TEXTURE2D, "Type is %x, expected %x.\n", type_desc.Type, D3D10_SVT_TEXTURE2D);
- *srv = var->lpVtbl->AsShaderResource(var);
+}
+static void test_effect_resource_variable(void) +{
- ID3D10ShaderResourceView *srv0, *srv_a[2], *srv_tmp[2];
- ID3D10EffectShaderResourceVariable *t0, *t_a, *t_a_0;
- ID3D10EffectTechnique *technique;
- ID3D10Texture2D *tex0, *tex_a[2];
- ID3D10EffectVariable *var;
- ID3D10EffectPass *pass;
- ID3D10Device *device;
- ID3D10Effect *effect;
- unsigned int i;
- ULONG refcount;
- HRESULT hr;
- if (!(device = create_device()))
- {
skip("Failed to create device, skipping tests.\n");
return;
- }
- hr = create_effect(fx_test_resource_variable, 0, device, NULL, &effect);
- ok(SUCCEEDED(hr), "D3D10CreateEffectFromMemory failed (%x).\n", hr);
- var = effect->lpVtbl->GetVariableByName(effect, "t0");
- get_effect_shader_resource_variable(var, &t0);
- create_effect_texture_resource(device, &srv0, &tex0);
- hr = t0->lpVtbl->SetResource(t0, srv0);
- ok(hr == S_OK, "Failed to SetResource, hr %#x.\n", hr);
Same, here and elsewhere below.