wined3d: Export wined3d_extract_shader_input_signature_from_dxbc().
Signed-off-by: Józef Kucia <jkucia@codeweavers.com> Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
4f698de563
commit
b750934589
|
@ -102,22 +102,6 @@ static inline UINT d3d11_bind_flags_from_wined3d(unsigned int bind_flags)
|
||||||
return bind_flags;
|
return bind_flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void read_dword(const char **ptr, DWORD *d)
|
|
||||||
{
|
|
||||||
memcpy(d, *ptr, sizeof(*d));
|
|
||||||
*ptr += sizeof(*d);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline BOOL require_space(size_t offset, size_t count, size_t size, size_t data_size)
|
|
||||||
{
|
|
||||||
return !count || (data_size - offset) / count >= size;
|
|
||||||
}
|
|
||||||
|
|
||||||
void skip_dword_unknown(const char **ptr, unsigned int count) DECLSPEC_HIDDEN;
|
|
||||||
|
|
||||||
HRESULT parse_dxbc(const char *data, SIZE_T data_size,
|
|
||||||
HRESULT (*chunk_handler)(const char *data, DWORD data_size, DWORD tag, void *ctx), void *ctx) DECLSPEC_HIDDEN;
|
|
||||||
|
|
||||||
/* ID3D11Texture1D, ID3D10Texture1D */
|
/* ID3D11Texture1D, ID3D10Texture1D */
|
||||||
struct d3d_texture1d
|
struct d3d_texture1d
|
||||||
{
|
{
|
||||||
|
@ -391,12 +375,6 @@ HRESULT d3d11_compute_shader_create(struct d3d_device *device, const void *byte_
|
||||||
struct d3d11_compute_shader **shader) DECLSPEC_HIDDEN;
|
struct d3d11_compute_shader **shader) DECLSPEC_HIDDEN;
|
||||||
struct d3d11_compute_shader *unsafe_impl_from_ID3D11ComputeShader(ID3D11ComputeShader *iface) DECLSPEC_HIDDEN;
|
struct d3d11_compute_shader *unsafe_impl_from_ID3D11ComputeShader(ID3D11ComputeShader *iface) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
HRESULT shader_parse_signature(DWORD tag, const char *data, DWORD data_size,
|
|
||||||
struct wined3d_shader_signature *s) DECLSPEC_HIDDEN;
|
|
||||||
struct wined3d_shader_signature_element *shader_find_signature_element(const struct wined3d_shader_signature *s,
|
|
||||||
const char *semantic_name, unsigned int semantic_idx, unsigned int stream_idx) DECLSPEC_HIDDEN;
|
|
||||||
void shader_free_signature(struct wined3d_shader_signature *s) DECLSPEC_HIDDEN;
|
|
||||||
|
|
||||||
/* ID3D11ClassLinkage */
|
/* ID3D11ClassLinkage */
|
||||||
struct d3d11_class_linkage
|
struct d3d11_class_linkage
|
||||||
{
|
{
|
||||||
|
|
|
@ -24,19 +24,20 @@
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(d3d11);
|
WINE_DEFAULT_DEBUG_CHANNEL(d3d11);
|
||||||
|
|
||||||
static HRESULT isgn_handler(const char *data, DWORD data_size, DWORD tag, void *ctx)
|
static struct wined3d_shader_signature_element *shader_find_signature_element(const struct wined3d_shader_signature *s,
|
||||||
|
const char *semantic_name, unsigned int semantic_idx, unsigned int stream_idx)
|
||||||
{
|
{
|
||||||
struct wined3d_shader_signature *is = ctx;
|
struct wined3d_shader_signature_element *e = s->elements;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
if (tag != TAG_ISGN)
|
for (i = 0; i < s->element_count; ++i)
|
||||||
return S_OK;
|
|
||||||
|
|
||||||
if (is->elements)
|
|
||||||
{
|
{
|
||||||
FIXME("Multiple input signatures.\n");
|
if (!strcasecmp(e[i].semantic_name, semantic_name) && e[i].semantic_idx == semantic_idx
|
||||||
shader_free_signature(is);
|
&& e[i].stream_idx == stream_idx)
|
||||||
|
return &e[i];
|
||||||
}
|
}
|
||||||
return shader_parse_signature(tag, data, data_size, is);
|
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT d3d11_input_layout_to_wined3d_declaration(const D3D11_INPUT_ELEMENT_DESC *element_descs,
|
static HRESULT d3d11_input_layout_to_wined3d_declaration(const D3D11_INPUT_ELEMENT_DESC *element_descs,
|
||||||
|
@ -47,17 +48,16 @@ static HRESULT d3d11_input_layout_to_wined3d_declaration(const D3D11_INPUT_ELEME
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
memset(&is, 0, sizeof(is));
|
if (FAILED(hr = wined3d_extract_shader_input_signature_from_dxbc(&is, shader_byte_code, shader_byte_code_length)))
|
||||||
if (FAILED(hr = parse_dxbc(shader_byte_code, shader_byte_code_length, isgn_handler, &is)))
|
|
||||||
{
|
{
|
||||||
ERR("Failed to parse input signature.\n");
|
ERR("Failed to extract input signature.\n");
|
||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(*wined3d_elements = heap_calloc(element_count, sizeof(**wined3d_elements))))
|
if (!(*wined3d_elements = heap_calloc(element_count, sizeof(**wined3d_elements))))
|
||||||
{
|
{
|
||||||
ERR("Failed to allocate wined3d vertex element array memory.\n");
|
ERR("Failed to allocate wined3d vertex element array memory.\n");
|
||||||
shader_free_signature(&is);
|
heap_free(is.elements);
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,7 +83,7 @@ static HRESULT d3d11_input_layout_to_wined3d_declaration(const D3D11_INPUT_ELEME
|
||||||
WARN("Unused input element %u.\n", i);
|
WARN("Unused input element %u.\n", i);
|
||||||
}
|
}
|
||||||
|
|
||||||
shader_free_signature(&is);
|
heap_free(is.elements);
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,110 +24,6 @@
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(d3d11);
|
WINE_DEFAULT_DEBUG_CHANNEL(d3d11);
|
||||||
|
|
||||||
static const char *shader_get_string(const char *data, size_t data_size, DWORD offset)
|
|
||||||
{
|
|
||||||
size_t len, max_len;
|
|
||||||
|
|
||||||
if (offset >= data_size)
|
|
||||||
{
|
|
||||||
WARN("Invalid offset %#x (data size %#lx).\n", offset, (long)data_size);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
max_len = data_size - offset;
|
|
||||||
len = strnlen(data + offset, max_len);
|
|
||||||
|
|
||||||
if (len == max_len)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
return data + offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT shader_parse_signature(DWORD tag, const char *data, DWORD data_size,
|
|
||||||
struct wined3d_shader_signature *s)
|
|
||||||
{
|
|
||||||
struct wined3d_shader_signature_element *e;
|
|
||||||
const char *ptr = data;
|
|
||||||
unsigned int i;
|
|
||||||
DWORD count;
|
|
||||||
|
|
||||||
if (!require_space(0, 2, sizeof(DWORD), data_size))
|
|
||||||
{
|
|
||||||
WARN("Invalid data size %#x.\n", data_size);
|
|
||||||
return E_INVALIDARG;
|
|
||||||
}
|
|
||||||
|
|
||||||
read_dword(&ptr, &count);
|
|
||||||
TRACE("%u elements.\n", count);
|
|
||||||
|
|
||||||
skip_dword_unknown(&ptr, 1); /* It seems to always be 0x00000008. */
|
|
||||||
|
|
||||||
if (!require_space(ptr - data, count, 6 * sizeof(DWORD), data_size))
|
|
||||||
{
|
|
||||||
WARN("Invalid count %#x (data size %#x).\n", count, data_size);
|
|
||||||
return E_INVALIDARG;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(e = heap_calloc(count, sizeof(*e))))
|
|
||||||
{
|
|
||||||
ERR("Failed to allocate input signature memory.\n");
|
|
||||||
return E_OUTOFMEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < count; ++i)
|
|
||||||
{
|
|
||||||
DWORD name_offset;
|
|
||||||
|
|
||||||
if (tag == TAG_OSG5)
|
|
||||||
read_dword(&ptr, &e[i].stream_idx);
|
|
||||||
else
|
|
||||||
e[i].stream_idx = 0;
|
|
||||||
read_dword(&ptr, &name_offset);
|
|
||||||
if (!(e[i].semantic_name = shader_get_string(data, data_size, name_offset)))
|
|
||||||
{
|
|
||||||
WARN("Invalid name offset %#x (data size %#x).\n", name_offset, data_size);
|
|
||||||
heap_free(e);
|
|
||||||
return E_INVALIDARG;
|
|
||||||
}
|
|
||||||
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("Stream: %u, semantic: %s, semantic idx: %u, sysval_semantic %#x, "
|
|
||||||
"type %u, register idx: %u, use_mask %#x, input_mask %#x.\n",
|
|
||||||
e[i].stream_idx, debugstr_a(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;
|
|
||||||
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct wined3d_shader_signature_element *shader_find_signature_element(const struct wined3d_shader_signature *s,
|
|
||||||
const char *semantic_name, unsigned int semantic_idx, unsigned int stream_idx)
|
|
||||||
{
|
|
||||||
struct wined3d_shader_signature_element *e = s->elements;
|
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
for (i = 0; i < s->element_count; ++i)
|
|
||||||
{
|
|
||||||
if (!strcasecmp(e[i].semantic_name, semantic_name) && e[i].semantic_idx == semantic_idx
|
|
||||||
&& e[i].stream_idx == stream_idx)
|
|
||||||
return &e[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void shader_free_signature(struct wined3d_shader_signature *s)
|
|
||||||
{
|
|
||||||
heap_free(s->elements);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ID3D11VertexShader methods */
|
/* ID3D11VertexShader methods */
|
||||||
|
|
||||||
static inline struct d3d_vertex_shader *impl_from_ID3D11VertexShader(ID3D11VertexShader *iface)
|
static inline struct d3d_vertex_shader *impl_from_ID3D11VertexShader(ID3D11VertexShader *iface)
|
||||||
|
|
|
@ -871,86 +871,3 @@ HRESULT d3d_set_private_data_interface(struct wined3d_private_store *store,
|
||||||
|
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void skip_dword_unknown(const char **ptr, unsigned int count)
|
|
||||||
{
|
|
||||||
unsigned int i;
|
|
||||||
DWORD d;
|
|
||||||
|
|
||||||
WARN("Skipping %u unknown DWORDs:\n", count);
|
|
||||||
for (i = 0; i < count; ++i)
|
|
||||||
{
|
|
||||||
read_dword(ptr, &d);
|
|
||||||
WARN("\t0x%08x\n", d);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT parse_dxbc(const char *data, SIZE_T data_size,
|
|
||||||
HRESULT (*chunk_handler)(const char *data, DWORD data_size, DWORD tag, void *ctx), void *ctx)
|
|
||||||
{
|
|
||||||
const char *ptr = data;
|
|
||||||
HRESULT hr = S_OK;
|
|
||||||
DWORD chunk_count;
|
|
||||||
DWORD total_size;
|
|
||||||
unsigned int i;
|
|
||||||
DWORD version;
|
|
||||||
DWORD tag;
|
|
||||||
|
|
||||||
read_dword(&ptr, &tag);
|
|
||||||
TRACE("tag: %s.\n", debugstr_an((const char *)&tag, 4));
|
|
||||||
|
|
||||||
if (tag != TAG_DXBC)
|
|
||||||
{
|
|
||||||
WARN("Wrong tag.\n");
|
|
||||||
return E_INVALIDARG;
|
|
||||||
}
|
|
||||||
|
|
||||||
WARN("Ignoring DXBC checksum.\n");
|
|
||||||
skip_dword_unknown(&ptr, 4);
|
|
||||||
|
|
||||||
read_dword(&ptr, &version);
|
|
||||||
TRACE("version: %#x.\n", version);
|
|
||||||
if (version != 0x00000001)
|
|
||||||
{
|
|
||||||
WARN("Got unexpected DXBC version %#x.\n", version);
|
|
||||||
return E_INVALIDARG;
|
|
||||||
}
|
|
||||||
|
|
||||||
read_dword(&ptr, &total_size);
|
|
||||||
TRACE("total size: %#x\n", total_size);
|
|
||||||
|
|
||||||
read_dword(&ptr, &chunk_count);
|
|
||||||
TRACE("chunk count: %#x\n", chunk_count);
|
|
||||||
|
|
||||||
for (i = 0; i < chunk_count; ++i)
|
|
||||||
{
|
|
||||||
DWORD chunk_tag, chunk_size;
|
|
||||||
const char *chunk_ptr;
|
|
||||||
DWORD chunk_offset;
|
|
||||||
|
|
||||||
read_dword(&ptr, &chunk_offset);
|
|
||||||
TRACE("chunk %u at offset %#x\n", i, chunk_offset);
|
|
||||||
|
|
||||||
if (chunk_offset >= data_size || !require_space(chunk_offset, 2, sizeof(DWORD), data_size))
|
|
||||||
{
|
|
||||||
WARN("Invalid chunk offset %#x (data size %#lx).\n", chunk_offset, data_size);
|
|
||||||
return E_FAIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
chunk_ptr = data + chunk_offset;
|
|
||||||
|
|
||||||
read_dword(&chunk_ptr, &chunk_tag);
|
|
||||||
read_dword(&chunk_ptr, &chunk_size);
|
|
||||||
|
|
||||||
if (!require_space(chunk_ptr - data, 1, chunk_size, data_size))
|
|
||||||
{
|
|
||||||
WARN("Invalid chunk size %#x (data size %#lx, chunk offset %#x).\n", chunk_size, data_size, chunk_offset);
|
|
||||||
return E_FAIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
hr = chunk_handler(chunk_ptr, chunk_size, chunk_tag, ctx);
|
|
||||||
if (FAILED(hr)) break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
|
|
|
@ -2103,3 +2103,26 @@ HRESULT shader_extract_from_dxbc(struct wined3d_shader *shader,
|
||||||
|
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static HRESULT shader_isgn_chunk_handler(const char *data, DWORD data_size, DWORD tag, void *ctx)
|
||||||
|
{
|
||||||
|
struct wined3d_shader_signature *is = ctx;
|
||||||
|
|
||||||
|
if (tag != TAG_ISGN)
|
||||||
|
return S_OK;
|
||||||
|
|
||||||
|
if (is->elements)
|
||||||
|
{
|
||||||
|
FIXME("Multiple shader signatures.\n");
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
return shader_parse_signature(tag, data, data_size, is);
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT CDECL wined3d_extract_shader_input_signature_from_dxbc(struct wined3d_shader_signature *signature,
|
||||||
|
const void *code, SIZE_T code_size)
|
||||||
|
{
|
||||||
|
memset(signature, 0, sizeof(*signature));
|
||||||
|
return parse_dxbc(code, code_size, shader_isgn_chunk_handler, signature);
|
||||||
|
}
|
||||||
|
|
|
@ -315,3 +315,5 @@
|
||||||
@ cdecl wined3d_vertex_declaration_decref(ptr)
|
@ cdecl wined3d_vertex_declaration_decref(ptr)
|
||||||
@ cdecl wined3d_vertex_declaration_get_parent(ptr)
|
@ cdecl wined3d_vertex_declaration_get_parent(ptr)
|
||||||
@ cdecl wined3d_vertex_declaration_incref(ptr)
|
@ cdecl wined3d_vertex_declaration_incref(ptr)
|
||||||
|
|
||||||
|
@ cdecl wined3d_extract_shader_input_signature_from_dxbc(ptr ptr long)
|
||||||
|
|
|
@ -2750,6 +2750,9 @@ ULONG __cdecl wined3d_vertex_declaration_decref(struct wined3d_vertex_declaratio
|
||||||
void * __cdecl wined3d_vertex_declaration_get_parent(const struct wined3d_vertex_declaration *declaration);
|
void * __cdecl wined3d_vertex_declaration_get_parent(const struct wined3d_vertex_declaration *declaration);
|
||||||
ULONG __cdecl wined3d_vertex_declaration_incref(struct wined3d_vertex_declaration *declaration);
|
ULONG __cdecl wined3d_vertex_declaration_incref(struct wined3d_vertex_declaration *declaration);
|
||||||
|
|
||||||
|
HRESULT __cdecl wined3d_extract_shader_input_signature_from_dxbc(struct wined3d_shader_signature *signature,
|
||||||
|
const void *byte_code, SIZE_T byte_code_size);
|
||||||
|
|
||||||
/* Return the integer base-2 logarithm of x. Undefined for x == 0. */
|
/* Return the integer base-2 logarithm of x. Undefined for x == 0. */
|
||||||
static inline unsigned int wined3d_log2i(unsigned int x)
|
static inline unsigned int wined3d_log2i(unsigned int x)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue