Signed-off-by: Connor McAdams conmanx360@gmail.com --- dlls/d3d10/d3d10_private.h | 12 ++++++ dlls/d3d10/effect.c | 87 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 99 insertions(+)
diff --git a/dlls/d3d10/d3d10_private.h b/dlls/d3d10/d3d10_private.h index e02ea376bb..21fae15505 100644 --- a/dlls/d3d10/d3d10_private.h +++ b/dlls/d3d10/d3d10_private.h @@ -81,6 +81,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; @@ -99,6 +108,9 @@ struct d3d10_effect_shader_variable ID3D10PixelShader *ps; ID3D10GeometryShader *gs; } shader; + + UINT resource_count; + 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 f620191955..580b6079cf 100644 --- a/dlls/d3d10/effect.c +++ b/dlls/d3d10/effect.c @@ -656,6 +656,87 @@ 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_shader_variable *sv = &v->u.shader; + struct d3d10_effect_shader_resource *sr; + D3D10_SHADER_INPUT_BIND_DESC rsrc_desc; + struct d3d10_effect_variable *var; + ID3D10ShaderReflection *reflector; + D3D10_SHADER_DESC desc; + unsigned int i, y; + HRESULT hr; + + hr = D3D10ReflectShader(data, data_size, &reflector); + if (FAILED(hr)) return hr; + + reflector->lpVtbl->GetDesc(reflector, &desc); + sv->resource_count = desc.BoundResources; + + if (!(sv->shader_resource = heap_calloc(sv->resource_count, sizeof(*sv->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); + sr = &sv->shader_resource[i]; + + sr->in_type = rsrc_desc.Type; + sr->bind_point = rsrc_desc.BindPoint; + sr->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) + { + var = &v->effect->local_buffers[y]; + + if (!strcmp(rsrc_desc.Name, var->name)) + { + sr->resource_variable = var; + break; + } + } + break; + + case D3D10_SIT_SAMPLER: + case D3D10_SIT_TEXTURE: + for (y = 0; y < v->effect->local_variable_count; ++y) + { + var = &v->effect->local_variables[y]; + + if (!strcmp(rsrc_desc.Name, var->name)) + { + sr->resource_variable = var; + break; + } + } + break; + + default: + break; + } + + if (!sr->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; @@ -691,6 +772,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: @@ -2623,6 +2707,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->resource_count) + heap_free(s->shader_resource); }
static void d3d10_effect_variable_destroy(struct d3d10_effect_variable *v)