diff --git a/dlls/d3d10core/d3d10core_private.h b/dlls/d3d10core/d3d10core_private.h index 97038219175..ff723ba4066 100644 --- a/dlls/d3d10core/d3d10core_private.h +++ b/dlls/d3d10core/d3d10core_private.h @@ -34,6 +34,11 @@ #include "wine/wined3d.h" #include "wine/winedxgi.h" +#define MAKE_TAG(ch0, ch1, ch2, ch3) \ + ((DWORD)(ch0) | ((DWORD)(ch1) << 8) | \ + ((DWORD)(ch2) << 16) | ((DWORD)(ch3) << 24 )) +#define TAG_DXBC MAKE_TAG('D', 'X', 'B', 'C') + /* TRACE helper functions */ const char *debug_d3d10_primitive_topology(D3D10_PRIMITIVE_TOPOLOGY topology); const char *debug_dxgi_format(DXGI_FORMAT format); @@ -41,6 +46,24 @@ const char *debug_dxgi_format(DXGI_FORMAT format); DXGI_FORMAT dxgi_format_from_wined3dformat(WINED3DFORMAT format); WINED3DFORMAT wined3dformat_from_dxgi_format(DXGI_FORMAT format); +static inline void read_dword(const char **ptr, DWORD *d) +{ + memcpy(d, *ptr, sizeof(*d)); + *ptr += sizeof(*d); +} + +void skip_dword_unknown(const char **ptr, unsigned int count); + +static inline void read_tag(const char **ptr, DWORD *t, char t_str[5]) +{ + read_dword(ptr, t); + memcpy(t_str, t, 4); + t_str[4] = '\0'; +} + +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); + /* IDirect3D10Device */ extern const struct ID3D10DeviceVtbl d3d10_device_vtbl; extern const struct IUnknownVtbl d3d10_device_inner_unknown_vtbl; diff --git a/dlls/d3d10core/utils.c b/dlls/d3d10core/utils.c index b3e5fef5506..29f1e7a7fb0 100644 --- a/dlls/d3d10core/utils.c +++ b/dlls/d3d10core/utils.c @@ -344,3 +344,68 @@ WINED3DFORMAT wined3dformat_from_dxgi_format(DXGI_FORMAT format) return WINED3DFMT_UNKNOWN; } } + +void skip_dword_unknown(const char **ptr, unsigned int count) +{ + unsigned int i; + DWORD d; + + FIXME("Skipping %u unknown DWORDs:\n", count); + for (i = 0; i < count; ++i) + { + read_dword(ptr, &d); + FIXME("\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; + char tag_str[5]; + unsigned int i; + DWORD tag; + + read_tag(&ptr, &tag, tag_str); + TRACE("tag: %s\n", tag_str); + + if (tag != TAG_DXBC) + { + WARN("Wrong tag.\n"); + return E_FAIL; + } + + /* checksum? */ + skip_dword_unknown(&ptr, 4); + + skip_dword_unknown(&ptr, 1); + + 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); + + chunk_ptr = data + chunk_offset; + + read_dword(&chunk_ptr, &chunk_tag); + read_dword(&chunk_ptr, &chunk_size); + + hr = chunk_handler(chunk_ptr, chunk_size, chunk_tag, ctx); + if (FAILED(hr)) break; + } + + return hr; +}