Get the resources that the shader will need to be bound for use by searching the effect framework buffers + local variables.
Signed-off-by: Connor McAdams conmanx360@gmail.com --- dlls/d3d10/d3d10_private.h | 12 ++++++ dlls/d3d10/effect.c | 82 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 94 insertions(+)
diff --git a/dlls/d3d10/d3d10_private.h b/dlls/d3d10/d3d10_private.h index f3b4e65e1c..87e506d668 100644 --- a/dlls/d3d10/d3d10_private.h +++ b/dlls/d3d10/d3d10_private.h @@ -76,6 +76,15 @@ struct d3d10_effect_object } object; };
+struct d3d10_effect_shader_resource +{ + D3D10_SHADER_INPUT_TYPE in_type; + UINT bind_point; + UINT bind_count; + + struct d3d10_effect_variable *resource_variable; +}; + struct d3d10_effect_shader_signature { char *signature; @@ -94,6 +103,9 @@ struct d3d10_effect_shader_variable ID3D10PixelShader *ps; ID3D10GeometryShader *gs; } shader; + + UINT resources; + struct d3d10_effect_shader_resource *shader_resource; };
struct d3d10_effect_state_object_variable diff --git a/dlls/d3d10/effect.c b/dlls/d3d10/effect.c index 9898b7f79f..df95724f95 100644 --- a/dlls/d3d10/effect.c +++ b/dlls/d3d10/effect.c @@ -657,6 +657,82 @@ static HRESULT shader_chunk_handler(const char *data, DWORD data_size, DWORD tag return S_OK; }
+static HRESULT get_fx10_shader_resources(struct d3d10_effect_variable *v, const void *data, size_t data_size) +{ + struct d3d10_effect_variable *tmp; + struct d3d10_effect_shader_variable *shader_var = &v->u.shader; + ID3D10ShaderReflection *reflector; + D3D10_SHADER_DESC desc; + D3D10_SHADER_INPUT_BIND_DESC rsrc_desc; + unsigned int i, y; + HRESULT hr; + + hr = D3D10ReflectShader(data, data_size, &reflector); + if (FAILED(hr)) return hr; + + reflector->lpVtbl->GetDesc(reflector, &desc); + shader_var->resources = desc.BoundResources; + + if (!(shader_var->shader_resource = heap_calloc(shader_var->resources, sizeof(struct d3d10_effect_shader_resource)))) + { + ERR("Failed to allocate shader resource binding information memory.\n"); + hr = E_OUTOFMEMORY; + goto exit; + } + + for (i = 0; i < desc.BoundResources; i++) + { + reflector->lpVtbl->GetResourceBindingDesc(reflector, i, &rsrc_desc); + shader_var->shader_resource[i].in_type = rsrc_desc.Type; + shader_var->shader_resource[i].bind_point = rsrc_desc.BindPoint; + shader_var->shader_resource[i].bind_count = rsrc_desc.BindCount; + + switch (rsrc_desc.Type) + { + case D3D10_SIT_CBUFFER: + case D3D10_SIT_TBUFFER: + for (y = 0; y < v->effect->local_buffer_count; y++) + { + tmp = &v->effect->local_buffers[y]; + + if (tmp->name && !strcmp(rsrc_desc.Name, tmp->name)) + { + shader_var->shader_resource[i].resource_variable = tmp; + break; + } + } + break; + case D3D10_SIT_SAMPLER: + case D3D10_SIT_TEXTURE: + for (y = 0; y < v->effect->local_variable_count; y++) + { + tmp = &v->effect->local_variables[y]; + + if (tmp->name && !strcmp(rsrc_desc.Name, tmp->name)) + { + shader_var->shader_resource[i].resource_variable = tmp; + break; + } + } + break; + default: + break; + } + + if (!shader_var->shader_resource[i].resource_variable) + { + ERR("Failed to find shader resource.\n"); + hr = E_FAIL; + goto exit; + } + } + +exit: + reflector->lpVtbl->Release(reflector); + + return hr; +} + static HRESULT parse_fx10_shader(const char *data, size_t data_size, DWORD offset, struct d3d10_effect_variable *v) { ID3D10Device *device = v->effect->device; @@ -692,6 +768,9 @@ static HRESULT parse_fx10_shader(const char *data, size_t data_size, DWORD offse /* We got a shader VertexShader vs = NULL, so it is fine to skip this. */ if (!dxbc_size) return S_OK;
+ hr = get_fx10_shader_resources(v, (const void *)ptr, dxbc_size); + if (FAILED(hr)) return hr; + switch (v->type->basetype) { case D3D10_SVT_VERTEXSHADER: @@ -2635,6 +2714,9 @@ static void d3d10_effect_shader_variable_destroy(struct d3d10_effect_shader_vari FIXME("Unhandled shader type %s.\n", debug_d3d10_shader_variable_type(type)); break; } + + if (s->resources) + heap_free(s->shader_resource); }
static void d3d10_effect_variable_destroy(struct d3d10_effect_variable *v)