d3d10core: Improve the shader input/output signature parsing code.

Make a copy of the string data, and move the function to shader.c.
This commit is contained in:
Henri Verbeet 2009-05-08 17:44:25 +02:00 committed by Alexandre Julliard
parent 9a579a43b1
commit d6fa27f5a1
3 changed files with 71 additions and 63 deletions

View File

@ -155,6 +155,8 @@ struct d3d10_pixel_shader
}; };
HRESULT shader_extract_from_dxbc(const void *dxbc, SIZE_T dxbc_length, const DWORD **shader_code); HRESULT shader_extract_from_dxbc(const void *dxbc, SIZE_T dxbc_length, const DWORD **shader_code);
HRESULT shader_parse_signature(const char *data, DWORD data_size, struct wined3d_shader_signature *s);
void shader_free_signature(struct wined3d_shader_signature *s);
/* Layered device */ /* Layered device */
enum dxgi_device_layer_id enum dxgi_device_layer_id

View File

@ -24,74 +24,15 @@
WINE_DEFAULT_DEBUG_CHANNEL(d3d10core); WINE_DEFAULT_DEBUG_CHANNEL(d3d10core);
struct input_signature_element
{
const char *semantic_name;
UINT semantic_idx;
DWORD unknown; /* system value semantic? */
DWORD component_type;
UINT register_idx;
DWORD mask;
};
struct input_signature
{
struct input_signature_element *elements;
UINT element_count;
};
static HRESULT parse_isgn(const char *data, struct input_signature *is)
{
struct input_signature_element *e;
const char *ptr = data;
unsigned int i;
DWORD count;
read_dword(&ptr, &count);
TRACE("%u elements\n", count);
skip_dword_unknown(&ptr, 1);
e = HeapAlloc(GetProcessHeap(), 0, count * sizeof(*e));
if (!e)
{
ERR("Failed to allocate input signature memory.\n");
return E_OUTOFMEMORY;
}
for (i = 0; i < count; ++i)
{
UINT name_offset;
read_dword(&ptr, &name_offset);
e[i].semantic_name = data + name_offset;
read_dword(&ptr, &e[i].semantic_idx);
read_dword(&ptr, &e[i].unknown);
read_dword(&ptr, &e[i].component_type);
read_dword(&ptr, &e[i].register_idx);
read_dword(&ptr, &e[i].mask);
TRACE("semantic: %s, semantic idx: %u, unknown %#x, type %u, register idx: %u, use_mask %#x, input_mask %#x\n",
e[i].semantic_name, e[i].semantic_idx, e[i].unknown, e[i].component_type,
e[i].register_idx, (e[i].mask >> 8) & 0xff, e[i].mask & 0xff);
}
is->elements = e;
is->element_count = count;
return S_OK;
}
static HRESULT isgn_handler(const char *data, DWORD data_size, DWORD tag, void *ctx) static HRESULT isgn_handler(const char *data, DWORD data_size, DWORD tag, void *ctx)
{ {
struct input_signature *is = ctx; struct wined3d_shader_signature *is = ctx;
const char *ptr = data;
char tag_str[5]; char tag_str[5];
switch(tag) switch(tag)
{ {
case TAG_ISGN: case TAG_ISGN:
return parse_isgn(ptr, is); return shader_parse_signature(data, data_size, is);
default: default:
memcpy(tag_str, &tag, 4); memcpy(tag_str, &tag, 4);
@ -105,7 +46,7 @@ HRESULT d3d10_input_layout_to_wined3d_declaration(const D3D10_INPUT_ELEMENT_DESC
UINT element_count, const void *shader_byte_code, SIZE_T shader_byte_code_length, UINT element_count, const void *shader_byte_code, SIZE_T shader_byte_code_length,
WINED3DVERTEXELEMENT **wined3d_elements, UINT *wined3d_element_count) WINED3DVERTEXELEMENT **wined3d_elements, UINT *wined3d_element_count)
{ {
struct input_signature is; struct wined3d_shader_signature is;
HRESULT hr; HRESULT hr;
UINT i; UINT i;
@ -157,7 +98,7 @@ HRESULT d3d10_input_layout_to_wined3d_declaration(const D3D10_INPUT_ELEMENT_DESC
} }
} }
HeapFree(GetProcessHeap(), 0, is.elements); shader_free_signature(&is);
return S_OK; return S_OK;
} }

View File

@ -55,6 +55,71 @@ HRESULT shader_extract_from_dxbc(const void *dxbc, SIZE_T dxbc_length, const DWO
return hr; return hr;
} }
HRESULT shader_parse_signature(const char *data, DWORD data_size, struct wined3d_shader_signature *s)
{
struct wined3d_shader_signature_element *e;
unsigned int string_data_offset;
unsigned int string_data_size;
const char *ptr = data;
char *string_data;
unsigned int i;
DWORD count;
read_dword(&ptr, &count);
TRACE("%u elements\n", count);
skip_dword_unknown(&ptr, 1);
e = HeapAlloc(GetProcessHeap(), 0, count * sizeof(*e));
if (!e)
{
ERR("Failed to allocate input signature memory.\n");
return E_OUTOFMEMORY;
}
/* 2 DWORDs for the header, 6 for each element. */
string_data_offset = 2 * sizeof(DWORD) + count * 6 * sizeof(DWORD);
string_data_size = data_size - string_data_offset;
string_data = HeapAlloc(GetProcessHeap(), 0, string_data_size);
if (!string_data)
{
ERR("Failed to allocate string data memory.\n");
HeapFree(GetProcessHeap(), 0, e);
return E_OUTOFMEMORY;
}
memcpy(string_data, data + string_data_offset, string_data_size);
for (i = 0; i < count; ++i)
{
UINT name_offset;
read_dword(&ptr, &name_offset);
e[i].semantic_name = string_data + (name_offset - string_data_offset);
read_dword(&ptr, &e[i].semantic_idx);
read_dword(&ptr, &e[i].sysval_semantic);
read_dword(&ptr, &e[i].component_type);
read_dword(&ptr, &e[i].register_idx);
read_dword(&ptr, &e[i].mask);
TRACE("semantic: %s, semantic idx: %u, sysval_semantic %#x, "
"type %u, register idx: %u, use_mask %#x, input_mask %#x\n",
e[i].semantic_name, e[i].semantic_idx, e[i].sysval_semantic, e[i].component_type,
e[i].register_idx, (e[i].mask >> 8) & 0xff, e[i].mask & 0xff);
}
s->elements = e;
s->element_count = count;
s->string_data = string_data;
return S_OK;
}
void shader_free_signature(struct wined3d_shader_signature *s)
{
HeapFree(GetProcessHeap(), 0, s->string_data);
HeapFree(GetProcessHeap(), 0, s->elements);
}
/* IUnknown methods */ /* IUnknown methods */
static HRESULT STDMETHODCALLTYPE d3d10_vertex_shader_QueryInterface(ID3D10VertexShader *iface, static HRESULT STDMETHODCALLTYPE d3d10_vertex_shader_QueryInterface(ID3D10VertexShader *iface,