mirror of
https://github.com/reactos/wine.git
synced 2025-02-13 08:44:54 +00:00
d3dcompiler: Implement D3DGetBlobPart().
This commit is contained in:
parent
033fd44aa1
commit
ec698dea66
@ -9,7 +9,8 @@ C_SRCS = \
|
||||
blob.c \
|
||||
bytecodewriter.c \
|
||||
compiler.c \
|
||||
d3dcompiler_43_main.c
|
||||
d3dcompiler_43_main.c \
|
||||
utils.c
|
||||
|
||||
LEX_SRCS = asmshader.l
|
||||
BISON_SRCS = asmshader.y
|
||||
|
@ -23,7 +23,6 @@
|
||||
#include "wine/port.h"
|
||||
|
||||
#include "d3dcompiler_private.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(d3dcompiler);
|
||||
|
||||
@ -119,3 +118,40 @@ HRESULT d3dcompiler_blob_init(struct d3dcompiler_blob *blob, SIZE_T data_size)
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT d3dcompiler_get_blob_part(const void *data, SIZE_T data_size, D3D_BLOB_PART part, UINT flags, ID3DBlob **blob)
|
||||
{
|
||||
struct dxbc src_dxbc, dst_dxbc;
|
||||
HRESULT hr;
|
||||
|
||||
if (!data || !data_size || flags || !blob)
|
||||
{
|
||||
WARN("Invalid arguments: data %p, data_size %lu, flags %#x, blob %p\n", data, data_size, flags, blob);
|
||||
return D3DERR_INVALIDCALL;
|
||||
}
|
||||
|
||||
if (part > D3D_BLOB_TEST_COMPILE_PERF
|
||||
|| (part < D3D_BLOB_TEST_ALTERNATE_SHADER && part > D3D_BLOB_XNA_SHADER))
|
||||
{
|
||||
WARN("Invalid D3D_BLOB_PART: part %s\n", debug_d3dcompiler_d3d_blob_part(part));
|
||||
return D3DERR_INVALIDCALL;
|
||||
}
|
||||
|
||||
hr = dxbc_parse(data, data_size, &src_dxbc);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
WARN("Failed to parse blob part\n");
|
||||
return hr;
|
||||
}
|
||||
|
||||
hr = dxbc_write_blob(&dst_dxbc, blob);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
WARN("Failed to write blob part\n");
|
||||
}
|
||||
|
||||
dxbc_destroy(&src_dxbc);
|
||||
dxbc_destroy(&dst_dxbc);
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
@ -83,7 +83,8 @@ HRESULT WINAPI D3DCreateBlob(SIZE_T data_size, ID3DBlob **blob)
|
||||
|
||||
HRESULT WINAPI D3DGetBlobPart(const void *data, SIZE_T data_size, D3D_BLOB_PART part, UINT flags, ID3DBlob **blob)
|
||||
{
|
||||
FIXME("data %p, data_size %lu, part %#x, flags %#x, blob %p stub!\n", data, data_size, part, flags, blob);
|
||||
TRACE("data %p, data_size %lu, part %s, flags %#x, blob %p\n", data,
|
||||
data_size, debug_d3dcompiler_d3d_blob_part(part), flags, blob);
|
||||
|
||||
return E_NOTIMPL;
|
||||
return d3dcompiler_get_blob_part(data, data_size, part, flags, blob);
|
||||
}
|
||||
|
@ -21,7 +21,8 @@
|
||||
#ifndef __WINE_D3DCOMPILER_PRIVATE_H
|
||||
#define __WINE_D3DCOMPILER_PRIVATE_H
|
||||
|
||||
#include <stdarg.h>
|
||||
#include "wine/debug.h"
|
||||
#include "wine/list.h"
|
||||
|
||||
#define COBJMACROS
|
||||
#include "windef.h"
|
||||
@ -37,6 +38,9 @@
|
||||
*/
|
||||
#define D3DERR_INVALIDCALL 0x8876086c
|
||||
|
||||
/* TRACE helper functions */
|
||||
const char *debug_d3dcompiler_d3d_blob_part(D3D_BLOB_PART part);
|
||||
|
||||
/* ID3DBlob */
|
||||
struct d3dcompiler_blob
|
||||
{
|
||||
@ -49,6 +53,9 @@ struct d3dcompiler_blob
|
||||
|
||||
HRESULT d3dcompiler_blob_init(struct d3dcompiler_blob *blob, SIZE_T data_size) DECLSPEC_HIDDEN;
|
||||
|
||||
/* blob handling */
|
||||
HRESULT d3dcompiler_get_blob_part(const void *data, SIZE_T data_size, D3D_BLOB_PART part, UINT flags, ID3DBlob **blob) DECLSPEC_HIDDEN;
|
||||
|
||||
/* Shader assembler definitions */
|
||||
typedef enum _shader_type {
|
||||
ST_VERTEX,
|
||||
@ -570,4 +577,44 @@ struct bwriter_shader *SlAssembleShader(const char *text, char **messages);
|
||||
DWORD SlWriteBytecode(const struct bwriter_shader *shader, int dxversion, DWORD **result);
|
||||
void SlDeleteShader(struct bwriter_shader *shader);
|
||||
|
||||
#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')
|
||||
|
||||
struct dxbc_section
|
||||
{
|
||||
DWORD tag;
|
||||
const char *data;
|
||||
DWORD data_size;
|
||||
};
|
||||
|
||||
struct dxbc
|
||||
{
|
||||
UINT size;
|
||||
UINT count;
|
||||
struct dxbc_section *sections;
|
||||
};
|
||||
|
||||
HRESULT dxbc_write_blob(struct dxbc *dxbc, ID3DBlob **blob) DECLSPEC_HIDDEN;
|
||||
void dxbc_destroy(struct dxbc *dxbc) DECLSPEC_HIDDEN;
|
||||
HRESULT dxbc_parse(const char *data, SIZE_T data_size, struct dxbc *dxbc) DECLSPEC_HIDDEN;
|
||||
HRESULT dxbc_add_section(struct dxbc *dxbc, DWORD tag, const char *data, DWORD data_size) DECLSPEC_HIDDEN;
|
||||
HRESULT dxbc_init(struct dxbc *dxbc, DWORD count) DECLSPEC_HIDDEN;
|
||||
|
||||
static inline void read_dword(const char **ptr, DWORD *d)
|
||||
{
|
||||
memcpy(d, *ptr, sizeof(*d));
|
||||
*ptr += sizeof(*d);
|
||||
}
|
||||
|
||||
static inline void write_dword(char **ptr, DWORD d)
|
||||
{
|
||||
memcpy(*ptr, &d, sizeof(d));
|
||||
*ptr += sizeof(d);
|
||||
}
|
||||
|
||||
void skip_dword_unknown(const char **ptr, unsigned int count) DECLSPEC_HIDDEN;
|
||||
void write_dword_unknown(char **ptr, DWORD d) DECLSPEC_HIDDEN;
|
||||
|
||||
#endif /* __WINE_D3DCOMPILER_PRIVATE_H */
|
||||
|
261
dlls/d3dcompiler_43/utils.c
Normal file
261
dlls/d3dcompiler_43/utils.c
Normal file
@ -0,0 +1,261 @@
|
||||
/*
|
||||
* Copyright 2008-2009 Henri Verbeet for CodeWeavers
|
||||
* Copyright 2010 Rico Schüller
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "wine/port.h"
|
||||
|
||||
#include "d3dcompiler_private.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(d3dcompiler);
|
||||
|
||||
#define WINE_D3DCOMPILER_TO_STR(x) case x: return #x
|
||||
|
||||
const char *debug_d3dcompiler_d3d_blob_part(D3D_BLOB_PART part)
|
||||
{
|
||||
switch(part)
|
||||
{
|
||||
WINE_D3DCOMPILER_TO_STR(D3D_BLOB_INPUT_SIGNATURE_BLOB);
|
||||
WINE_D3DCOMPILER_TO_STR(D3D_BLOB_OUTPUT_SIGNATURE_BLOB);
|
||||
WINE_D3DCOMPILER_TO_STR(D3D_BLOB_INPUT_AND_OUTPUT_SIGNATURE_BLOB);
|
||||
WINE_D3DCOMPILER_TO_STR(D3D_BLOB_PATCH_CONSTANT_SIGNATURE_BLOB);
|
||||
WINE_D3DCOMPILER_TO_STR(D3D_BLOB_ALL_SIGNATURE_BLOB);
|
||||
WINE_D3DCOMPILER_TO_STR(D3D_BLOB_DEBUG_INFO);
|
||||
WINE_D3DCOMPILER_TO_STR(D3D_BLOB_LEGACY_SHADER);
|
||||
WINE_D3DCOMPILER_TO_STR(D3D_BLOB_XNA_PREPASS_SHADER);
|
||||
WINE_D3DCOMPILER_TO_STR(D3D_BLOB_XNA_SHADER);
|
||||
WINE_D3DCOMPILER_TO_STR(D3D_BLOB_TEST_ALTERNATE_SHADER);
|
||||
WINE_D3DCOMPILER_TO_STR(D3D_BLOB_TEST_COMPILE_DETAILS);
|
||||
WINE_D3DCOMPILER_TO_STR(D3D_BLOB_TEST_COMPILE_PERF);
|
||||
default:
|
||||
FIXME("Unrecognized D3D_BLOB_PART %#x\n", part);
|
||||
return "unrecognized";
|
||||
}
|
||||
}
|
||||
|
||||
#undef WINE_D3DCOMPILER_TO_STR
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
void write_dword_unknown(char **ptr, DWORD d)
|
||||
{
|
||||
FIXME("Writing unknown DWORD 0x%08x\n", d);
|
||||
write_dword(ptr, d);
|
||||
}
|
||||
|
||||
HRESULT dxbc_add_section(struct dxbc *dxbc, DWORD tag, const char *data, DWORD data_size)
|
||||
{
|
||||
TRACE("dxbc %p, tag %s, size %#x.\n", dxbc, debugstr_an((const char *)&tag, 4), data_size);
|
||||
|
||||
if (dxbc->count >= dxbc->size)
|
||||
{
|
||||
struct dxbc_section *new_sections;
|
||||
DWORD new_size = dxbc->size << 1;
|
||||
|
||||
new_sections = HeapReAlloc(GetProcessHeap(), 0, dxbc->sections, new_size * sizeof(*dxbc->sections));
|
||||
if (!new_sections)
|
||||
{
|
||||
ERR("Failed to allocate dxbc section memory\n");
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
dxbc->sections = new_sections;
|
||||
dxbc->size = new_size;
|
||||
}
|
||||
|
||||
dxbc->sections[dxbc->count].tag = tag;
|
||||
dxbc->sections[dxbc->count].data_size = data_size;
|
||||
dxbc->sections[dxbc->count].data = data;
|
||||
++dxbc->count;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT dxbc_init(struct dxbc *dxbc, UINT size)
|
||||
{
|
||||
TRACE("dxbc %p, size %u.\n", dxbc, size);
|
||||
|
||||
/* use a good starting value for the size if none specified */
|
||||
if (!size) size = 2;
|
||||
|
||||
dxbc->sections = HeapAlloc(GetProcessHeap(), 0, size * sizeof(*dxbc->sections));
|
||||
if (!dxbc->sections)
|
||||
{
|
||||
ERR("Failed to allocate dxbc section memory\n");
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
dxbc->size = size;
|
||||
dxbc->count = 0;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT dxbc_parse(const char *data, SIZE_T data_size, struct dxbc *dxbc)
|
||||
{
|
||||
const char *ptr = data;
|
||||
HRESULT hr;
|
||||
unsigned int i;
|
||||
DWORD tag, total_size, chunk_count;
|
||||
|
||||
if (!data)
|
||||
{
|
||||
WARN("No data supplied.\n");
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
read_dword(&ptr, &tag);
|
||||
TRACE("tag: %s.\n", debugstr_an((const char *)&tag, 4));
|
||||
|
||||
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);
|
||||
|
||||
if (data_size != total_size)
|
||||
{
|
||||
WARN("Wrong size supplied.\n");
|
||||
return D3DERR_INVALIDCALL;
|
||||
}
|
||||
|
||||
read_dword(&ptr, &chunk_count);
|
||||
TRACE("chunk count: %#x\n", chunk_count);
|
||||
|
||||
hr = dxbc_init(dxbc, chunk_count);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
WARN("Failed to init dxbc\n");
|
||||
return hr;
|
||||
}
|
||||
|
||||
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 = dxbc_add_section(dxbc, chunk_tag, chunk_ptr, chunk_size);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
WARN("Failed to add section to dxbc\n");
|
||||
return hr;
|
||||
}
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
void dxbc_destroy(struct dxbc *dxbc)
|
||||
{
|
||||
TRACE("dxbc %p.\n", dxbc);
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, dxbc->sections);
|
||||
}
|
||||
|
||||
HRESULT dxbc_write_blob(struct dxbc *dxbc, ID3DBlob **blob)
|
||||
{
|
||||
DWORD size = 32, offset = size + 4 * dxbc->count;
|
||||
ID3DBlob *object;
|
||||
HRESULT hr;
|
||||
char *ptr;
|
||||
unsigned int i;
|
||||
|
||||
TRACE("dxbc %p, blob %p.\n", dxbc, blob);
|
||||
|
||||
for (i = 0; i < dxbc->count; ++i)
|
||||
{
|
||||
size += 12 + dxbc->sections[i].data_size;
|
||||
}
|
||||
|
||||
hr = D3DCreateBlob(size, &object);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
WARN("Failed to create blob\n");
|
||||
return hr;
|
||||
}
|
||||
|
||||
ptr = ID3D10Blob_GetBufferPointer(object);
|
||||
|
||||
write_dword(&ptr, TAG_DXBC);
|
||||
|
||||
/* signature(?) */
|
||||
write_dword_unknown(&ptr, 0);
|
||||
write_dword_unknown(&ptr, 0);
|
||||
write_dword_unknown(&ptr, 0);
|
||||
write_dword_unknown(&ptr, 0);
|
||||
|
||||
/* seems to be always 1 */
|
||||
write_dword_unknown(&ptr, 1);
|
||||
|
||||
/* DXBC size */
|
||||
write_dword(&ptr, size);
|
||||
|
||||
/* chunk count */
|
||||
write_dword(&ptr, dxbc->count);
|
||||
|
||||
/* write the chunk offsets */
|
||||
for (i = 0; i < dxbc->count; ++i)
|
||||
{
|
||||
write_dword(&ptr, offset);
|
||||
offset += 8 + dxbc->sections[i].data_size;
|
||||
}
|
||||
|
||||
/* write the chunks */
|
||||
for (i = 0; i < dxbc->count; ++i)
|
||||
{
|
||||
write_dword(&ptr, dxbc->sections[i].tag);
|
||||
write_dword(&ptr, dxbc->sections[i].data_size);
|
||||
memcpy(ptr, dxbc->sections[i].data, dxbc->sections[i].data_size);
|
||||
ptr += dxbc->sections[i].data_size;
|
||||
}
|
||||
|
||||
TRACE("Created ID3DBlob %p\n", object);
|
||||
|
||||
*blob = object;
|
||||
|
||||
return S_OK;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user