mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2025-04-13 05:43:18 -07:00
vkd3d-utils: Implement D3DGetBlobPart().
This was largely adapted from Wine's d3dcompiler_43, with some style adjustments.
This commit is contained in:
parent
0dc40d7c1e
commit
b63c853688
Notes:
Alexandre Julliard
2023-10-18 22:51:37 +02:00
Approved-by: Matteo Bruni (@Mystral) Approved-by: Giovanni Mascellani (@giomasce) Approved-by: Henri Verbeet (@hverbeet) Approved-by: Alexandre Julliard (@julliard) Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/414
@ -49,6 +49,26 @@
|
||||
((uint32_t)(ch0) | ((uint32_t)(ch1) << 8) \
|
||||
| ((uint32_t)(ch2) << 16) | ((uint32_t)(ch3) << 24))
|
||||
|
||||
#define TAG_AON9 VKD3D_MAKE_TAG('A', 'o', 'n', '9')
|
||||
#define TAG_DXBC VKD3D_MAKE_TAG('D', 'X', 'B', 'C')
|
||||
#define TAG_DXIL VKD3D_MAKE_TAG('D', 'X', 'I', 'L')
|
||||
#define TAG_ISG1 VKD3D_MAKE_TAG('I', 'S', 'G', '1')
|
||||
#define TAG_ISGN VKD3D_MAKE_TAG('I', 'S', 'G', 'N')
|
||||
#define TAG_OSG1 VKD3D_MAKE_TAG('O', 'S', 'G', '1')
|
||||
#define TAG_OSG5 VKD3D_MAKE_TAG('O', 'S', 'G', '5')
|
||||
#define TAG_OSGN VKD3D_MAKE_TAG('O', 'S', 'G', 'N')
|
||||
#define TAG_PCSG VKD3D_MAKE_TAG('P', 'C', 'S', 'G')
|
||||
#define TAG_PSG1 VKD3D_MAKE_TAG('P', 'S', 'G', '1')
|
||||
#define TAG_RD11 VKD3D_MAKE_TAG('R', 'D', '1', '1')
|
||||
#define TAG_RDEF VKD3D_MAKE_TAG('R', 'D', 'E', 'F')
|
||||
#define TAG_RTS0 VKD3D_MAKE_TAG('R', 'T', 'S', '0')
|
||||
#define TAG_SDBG VKD3D_MAKE_TAG('S', 'D', 'B', 'G')
|
||||
#define TAG_SHDR VKD3D_MAKE_TAG('S', 'H', 'D', 'R')
|
||||
#define TAG_SHEX VKD3D_MAKE_TAG('S', 'H', 'E', 'X')
|
||||
#define TAG_TEXT VKD3D_MAKE_TAG('T', 'E', 'X', 'T')
|
||||
#define TAG_XNAP VKD3D_MAKE_TAG('X', 'N', 'A', 'P')
|
||||
#define TAG_XNAS VKD3D_MAKE_TAG('X', 'N', 'A', 'S')
|
||||
|
||||
static inline size_t align(size_t addr, size_t alignment)
|
||||
{
|
||||
return (addr + (alignment - 1)) & ~(alignment - 1);
|
||||
|
@ -58,6 +58,27 @@
|
||||
#define D3DCOMPILE_SECDATA_PRESERVE_TEMPLATE_SLOTS 0x00000002
|
||||
#define D3DCOMPILE_SECDATA_REQUIRE_TEMPLATE_MATCH 0x00000004
|
||||
|
||||
typedef enum D3D_BLOB_PART
|
||||
{
|
||||
D3D_BLOB_INPUT_SIGNATURE_BLOB,
|
||||
D3D_BLOB_OUTPUT_SIGNATURE_BLOB,
|
||||
D3D_BLOB_INPUT_AND_OUTPUT_SIGNATURE_BLOB,
|
||||
D3D_BLOB_PATCH_CONSTANT_SIGNATURE_BLOB,
|
||||
D3D_BLOB_ALL_SIGNATURE_BLOB,
|
||||
D3D_BLOB_DEBUG_INFO,
|
||||
D3D_BLOB_LEGACY_SHADER,
|
||||
D3D_BLOB_XNA_PREPASS_SHADER,
|
||||
D3D_BLOB_XNA_SHADER,
|
||||
D3D_BLOB_PDB,
|
||||
D3D_BLOB_PRIVATE_DATA,
|
||||
D3D_BLOB_ROOT_SIGNATURE,
|
||||
D3D_BLOB_DEBUG_NAME,
|
||||
D3D_BLOB_TEST_ALTERNATE_SHADER = 0x8000,
|
||||
D3D_BLOB_TEST_COMPILE_DETAILS,
|
||||
D3D_BLOB_TEST_COMPILE_PERF,
|
||||
D3D_BLOB_TEST_COMPILE_REPORT
|
||||
} D3D_BLOB_PART;
|
||||
|
||||
HRESULT WINAPI D3DCompile(const void *data, SIZE_T data_size, const char *filename,
|
||||
const D3D_SHADER_MACRO *macros, ID3DInclude *include, const char *entrypoint,
|
||||
const char *profile, UINT flags, UINT effect_flags, ID3DBlob **shader, ID3DBlob **error_messages);
|
||||
@ -67,6 +88,7 @@ HRESULT WINAPI D3DCompile2(const void *data, SIZE_T data_size, const char *filen
|
||||
const void *secondary_data, SIZE_T secondary_data_size, ID3DBlob **shader,
|
||||
ID3DBlob **error_messages);
|
||||
HRESULT WINAPI D3DCreateBlob(SIZE_T size, ID3DBlob **blob);
|
||||
HRESULT WINAPI D3DGetBlobPart(const void *data, SIZE_T data_size, D3D_BLOB_PART part, UINT flags, ID3DBlob **blob);
|
||||
HRESULT WINAPI D3DPreprocess(const void *data, SIZE_T size, const char *filename, const D3D_SHADER_MACRO *macros,
|
||||
ID3DInclude *include, ID3DBlob **shader, ID3DBlob **error_messages);
|
||||
|
||||
|
@ -51,6 +51,9 @@ extern "C" {
|
||||
# define VKD3D_UTILS_API VKD3D_IMPORT
|
||||
#endif
|
||||
|
||||
/** \since 1.10 */
|
||||
typedef enum D3D_BLOB_PART D3D_BLOB_PART;
|
||||
|
||||
/* 1.0 */
|
||||
VKD3D_UTILS_API HANDLE vkd3d_create_event(void);
|
||||
VKD3D_UTILS_API HRESULT vkd3d_signal_event(HANDLE event);
|
||||
@ -101,6 +104,10 @@ VKD3D_UTILS_API HRESULT WINAPI D3DPreprocess(const void *data, SIZE_T size, cons
|
||||
*/
|
||||
VKD3D_UTILS_API void vkd3d_utils_set_log_callback(PFN_vkd3d_log callback);
|
||||
|
||||
/** \since 1.10 */
|
||||
VKD3D_UTILS_API HRESULT WINAPI D3DGetBlobPart(const void *data,
|
||||
SIZE_T data_size, D3D_BLOB_PART part, UINT flags, ID3DBlob **blob);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
@ -1524,23 +1524,6 @@ static inline void *vkd3d_find_struct_(const struct vkd3d_struct *chain,
|
||||
#define VKD3D_DXBC_HEADER_SIZE (8 * sizeof(uint32_t))
|
||||
#define VKD3D_DXBC_CHUNK_ALIGNMENT sizeof(uint32_t)
|
||||
|
||||
#define TAG_AON9 VKD3D_MAKE_TAG('A', 'o', 'n', '9')
|
||||
#define TAG_DXBC VKD3D_MAKE_TAG('D', 'X', 'B', 'C')
|
||||
#define TAG_DXIL VKD3D_MAKE_TAG('D', 'X', 'I', 'L')
|
||||
#define TAG_ISG1 VKD3D_MAKE_TAG('I', 'S', 'G', '1')
|
||||
#define TAG_ISGN VKD3D_MAKE_TAG('I', 'S', 'G', 'N')
|
||||
#define TAG_OSG1 VKD3D_MAKE_TAG('O', 'S', 'G', '1')
|
||||
#define TAG_OSG5 VKD3D_MAKE_TAG('O', 'S', 'G', '5')
|
||||
#define TAG_OSGN VKD3D_MAKE_TAG('O', 'S', 'G', 'N')
|
||||
#define TAG_PCSG VKD3D_MAKE_TAG('P', 'C', 'S', 'G')
|
||||
#define TAG_PSG1 VKD3D_MAKE_TAG('P', 'S', 'G', '1')
|
||||
#define TAG_RD11 VKD3D_MAKE_TAG('R', 'D', '1', '1')
|
||||
#define TAG_RDEF VKD3D_MAKE_TAG('R', 'D', 'E', 'F')
|
||||
#define TAG_RTS0 VKD3D_MAKE_TAG('R', 'T', 'S', '0')
|
||||
#define TAG_SHDR VKD3D_MAKE_TAG('S', 'H', 'D', 'R')
|
||||
#define TAG_SHEX VKD3D_MAKE_TAG('S', 'H', 'E', 'X')
|
||||
#define TAG_TEXT VKD3D_MAKE_TAG('T', 'E', 'X', 'T')
|
||||
|
||||
#define DXBC_MAX_SECTION_COUNT 5
|
||||
|
||||
struct dxbc_writer
|
||||
|
@ -11,6 +11,7 @@ global:
|
||||
D3DCompile;
|
||||
D3DCompile2;
|
||||
D3DCreateBlob;
|
||||
D3DGetBlobPart;
|
||||
D3DPreprocess;
|
||||
vkd3d_create_event;
|
||||
vkd3d_destroy_event;
|
||||
|
@ -21,6 +21,35 @@
|
||||
|
||||
VKD3D_DEBUG_ENV_NAME("VKD3D_DEBUG");
|
||||
|
||||
static const char *debug_d3d_blob_part(D3D_BLOB_PART part)
|
||||
{
|
||||
switch (part)
|
||||
{
|
||||
#define TO_STR(x) case x: return #x
|
||||
TO_STR(D3D_BLOB_INPUT_SIGNATURE_BLOB);
|
||||
TO_STR(D3D_BLOB_OUTPUT_SIGNATURE_BLOB);
|
||||
TO_STR(D3D_BLOB_INPUT_AND_OUTPUT_SIGNATURE_BLOB);
|
||||
TO_STR(D3D_BLOB_PATCH_CONSTANT_SIGNATURE_BLOB);
|
||||
TO_STR(D3D_BLOB_ALL_SIGNATURE_BLOB);
|
||||
TO_STR(D3D_BLOB_DEBUG_INFO);
|
||||
TO_STR(D3D_BLOB_LEGACY_SHADER);
|
||||
TO_STR(D3D_BLOB_XNA_PREPASS_SHADER);
|
||||
TO_STR(D3D_BLOB_XNA_SHADER);
|
||||
TO_STR(D3D_BLOB_PDB);
|
||||
TO_STR(D3D_BLOB_PRIVATE_DATA);
|
||||
TO_STR(D3D_BLOB_ROOT_SIGNATURE);
|
||||
TO_STR(D3D_BLOB_DEBUG_NAME);
|
||||
|
||||
TO_STR(D3D_BLOB_TEST_ALTERNATE_SHADER);
|
||||
TO_STR(D3D_BLOB_TEST_COMPILE_DETAILS);
|
||||
TO_STR(D3D_BLOB_TEST_COMPILE_PERF);
|
||||
TO_STR(D3D_BLOB_TEST_COMPILE_REPORT);
|
||||
#undef TO_STR
|
||||
default:
|
||||
return vkd3d_dbg_sprintf("<D3D_BLOB_PART %#x>", part);
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT WINAPI D3D12GetDebugInterface(REFIID iid, void **debug)
|
||||
{
|
||||
FIXME("iid %s, debug %p stub!\n", debugstr_guid(iid), debug);
|
||||
@ -554,6 +583,182 @@ HRESULT WINAPI D3DCreateBlob(SIZE_T data_size, ID3DBlob **blob)
|
||||
return hr;
|
||||
}
|
||||
|
||||
static bool check_blob_part(uint32_t tag, D3D_BLOB_PART part)
|
||||
{
|
||||
bool add = false;
|
||||
|
||||
switch (part)
|
||||
{
|
||||
case D3D_BLOB_INPUT_SIGNATURE_BLOB:
|
||||
if (tag == TAG_ISGN)
|
||||
add = true;
|
||||
break;
|
||||
|
||||
case D3D_BLOB_OUTPUT_SIGNATURE_BLOB:
|
||||
if (tag == TAG_OSGN || tag == TAG_OSG5)
|
||||
add = true;
|
||||
break;
|
||||
|
||||
case D3D_BLOB_INPUT_AND_OUTPUT_SIGNATURE_BLOB:
|
||||
if (tag == TAG_ISGN || tag == TAG_OSGN || tag == TAG_OSG5)
|
||||
add = true;
|
||||
break;
|
||||
|
||||
case D3D_BLOB_PATCH_CONSTANT_SIGNATURE_BLOB:
|
||||
if (tag == TAG_PCSG)
|
||||
add = true;
|
||||
break;
|
||||
|
||||
case D3D_BLOB_ALL_SIGNATURE_BLOB:
|
||||
if (tag == TAG_ISGN || tag == TAG_OSGN || tag == TAG_OSG5 || tag == TAG_PCSG)
|
||||
add = true;
|
||||
break;
|
||||
|
||||
case D3D_BLOB_DEBUG_INFO:
|
||||
if (tag == TAG_SDBG)
|
||||
add = true;
|
||||
break;
|
||||
|
||||
case D3D_BLOB_LEGACY_SHADER:
|
||||
if (tag == TAG_AON9)
|
||||
add = true;
|
||||
break;
|
||||
|
||||
case D3D_BLOB_XNA_PREPASS_SHADER:
|
||||
if (tag == TAG_XNAP)
|
||||
add = true;
|
||||
break;
|
||||
|
||||
case D3D_BLOB_XNA_SHADER:
|
||||
if (tag == TAG_XNAS)
|
||||
add = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
FIXME("Unhandled D3D_BLOB_PART %s.\n", debug_d3d_blob_part(part));
|
||||
break;
|
||||
}
|
||||
|
||||
TRACE("%s tag %s.\n", add ? "Add" : "Skip", debugstr_an((const char *)&tag, 4));
|
||||
|
||||
return add;
|
||||
}
|
||||
|
||||
static HRESULT get_blob_part(const void *data, SIZE_T data_size,
|
||||
D3D_BLOB_PART part, unsigned int flags, ID3DBlob **blob)
|
||||
{
|
||||
const struct vkd3d_shader_code src_dxbc = {.code = data, .size = data_size};
|
||||
struct vkd3d_shader_dxbc_section_desc *sections;
|
||||
struct vkd3d_shader_dxbc_desc src_dxbc_desc;
|
||||
struct vkd3d_shader_code dst_dxbc;
|
||||
unsigned int section_count, i;
|
||||
HRESULT hr;
|
||||
int ret;
|
||||
|
||||
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 %s.\n", debug_d3d_blob_part(part));
|
||||
return D3DERR_INVALIDCALL;
|
||||
}
|
||||
|
||||
if ((ret = vkd3d_shader_parse_dxbc(&src_dxbc, 0, &src_dxbc_desc, NULL)) < 0)
|
||||
{
|
||||
WARN("Failed to parse source data, ret %d.\n", ret);
|
||||
return D3DERR_INVALIDCALL;
|
||||
}
|
||||
|
||||
if (!(sections = vkd3d_calloc(src_dxbc_desc.section_count, sizeof(*sections))))
|
||||
{
|
||||
ERR("Failed to allocate sections memory.\n");
|
||||
vkd3d_shader_free_dxbc(&src_dxbc_desc);
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
for (i = 0, section_count = 0; i < src_dxbc_desc.section_count; ++i)
|
||||
{
|
||||
const struct vkd3d_shader_dxbc_section_desc *src_section = &src_dxbc_desc.sections[i];
|
||||
|
||||
if (check_blob_part(src_section->tag, part))
|
||||
sections[section_count++] = *src_section;
|
||||
}
|
||||
|
||||
switch (part)
|
||||
{
|
||||
case D3D_BLOB_INPUT_SIGNATURE_BLOB:
|
||||
case D3D_BLOB_OUTPUT_SIGNATURE_BLOB:
|
||||
case D3D_BLOB_PATCH_CONSTANT_SIGNATURE_BLOB:
|
||||
case D3D_BLOB_DEBUG_INFO:
|
||||
case D3D_BLOB_LEGACY_SHADER:
|
||||
case D3D_BLOB_XNA_PREPASS_SHADER:
|
||||
case D3D_BLOB_XNA_SHADER:
|
||||
if (section_count != 1)
|
||||
section_count = 0;
|
||||
break;
|
||||
|
||||
case D3D_BLOB_INPUT_AND_OUTPUT_SIGNATURE_BLOB:
|
||||
if (section_count != 2)
|
||||
section_count = 0;
|
||||
break;
|
||||
|
||||
case D3D_BLOB_ALL_SIGNATURE_BLOB:
|
||||
if (section_count != 3)
|
||||
section_count = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
FIXME("Unhandled D3D_BLOB_PART %s.\n", debug_d3d_blob_part(part));
|
||||
break;
|
||||
}
|
||||
|
||||
if (!section_count)
|
||||
{
|
||||
WARN("Nothing to write into the blob.\n");
|
||||
hr = E_FAIL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Some parts aren't full DXBCs, they contain only the data. */
|
||||
if (section_count == 1 && (part == D3D_BLOB_DEBUG_INFO || part == D3D_BLOB_LEGACY_SHADER
|
||||
|| part == D3D_BLOB_XNA_PREPASS_SHADER || part == D3D_BLOB_XNA_SHADER))
|
||||
{
|
||||
dst_dxbc = sections[0].data;
|
||||
}
|
||||
else if ((ret = vkd3d_shader_serialize_dxbc(section_count, sections, &dst_dxbc, NULL) < 0))
|
||||
{
|
||||
WARN("Failed to serialise DXBC, ret %d.\n", ret);
|
||||
hr = hresult_from_vkd3d_result(ret);
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (FAILED(hr = D3DCreateBlob(dst_dxbc.size, blob)))
|
||||
WARN("Failed to create blob, hr %#x.\n", hr);
|
||||
else
|
||||
memcpy(ID3D10Blob_GetBufferPointer(*blob), dst_dxbc.code, dst_dxbc.size);
|
||||
if (dst_dxbc.code != sections[0].data.code)
|
||||
vkd3d_shader_free_shader_code(&dst_dxbc);
|
||||
|
||||
done:
|
||||
vkd3d_free(sections);
|
||||
vkd3d_shader_free_dxbc(&src_dxbc_desc);
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT WINAPI D3DGetBlobPart(const void *data, SIZE_T data_size, D3D_BLOB_PART part, UINT flags, ID3DBlob **blob)
|
||||
{
|
||||
TRACE("data %p, data_size %lu, part %s, flags %#x, blob %p.\n", data,
|
||||
data_size, debug_d3d_blob_part(part), flags, blob);
|
||||
|
||||
return get_blob_part(data, data_size, part, flags, blob);
|
||||
}
|
||||
|
||||
void vkd3d_utils_set_log_callback(PFN_vkd3d_log callback)
|
||||
{
|
||||
vkd3d_set_log_callback(callback);
|
||||
|
@ -52,8 +52,6 @@ enum
|
||||
OPTION_TEXT_FORMATTING,
|
||||
};
|
||||
|
||||
#define TAG_DXBC VKD3D_MAKE_TAG('D', 'X', 'B', 'C')
|
||||
|
||||
static const struct source_type_info
|
||||
{
|
||||
enum vkd3d_shader_source_type type;
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user