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(