diff --git a/libs/vkd3d/state.c b/libs/vkd3d/state.c index e31f0712..48be0aa8 100644 --- a/libs/vkd3d/state.c +++ b/libs/vkd3d/state.c @@ -19,6 +19,8 @@ #include "vkd3d_private.h" +#include + /* ID3D12RootSignature */ static inline struct d3d12_root_signature *impl_from_ID3D12RootSignature(ID3D12RootSignature *iface) { @@ -1190,6 +1192,70 @@ struct d3d12_pipeline_state *unsafe_impl_from_ID3D12PipelineState(ID3D12Pipeline return impl_from_ID3D12PipelineState(iface); } +static void dump_shader(const char *path, const char *prefix, const void *data, size_t size) +{ + static unsigned int shader_id = 0; + char filename[1024]; + FILE *f; + + snprintf(filename, ARRAY_SIZE(filename), "%s/vkd3d-shader-%s-%u.dxbc", path, prefix, shader_id); + if (!(f = fopen(filename, "wb"))) + { + ERR("Failed to open %s for dumping shader.\n", filename); + return; + } + + if (fwrite(data, 1, size, f) != size) + ERR("Failed to write shader to %s.\n", filename); + if (fclose(f)) + ERR("Failed to close stream %s.\n", filename); + + ++shader_id; +} + +static void dump_shader_stage(VkShaderStageFlagBits stage, const void *data, size_t size) +{ + static bool enabled = true; + const char *prefix; + const char *path; + + if (!enabled) + return; + + if (!(path = getenv("VKD3D_SHADER_DUMP_PATH"))) + { + enabled = false; + return; + } + + switch (stage) + { + case VK_SHADER_STAGE_VERTEX_BIT: + prefix = "vs"; + break; + case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT: + prefix = "hs"; + break; + case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT: + prefix = "ds"; + break; + case VK_SHADER_STAGE_GEOMETRY_BIT: + prefix = "gs"; + break; + case VK_SHADER_STAGE_FRAGMENT_BIT: + prefix = "ps"; + break; + case VK_SHADER_STAGE_COMPUTE_BIT: + prefix = "cs"; + break; + default: + prefix = "unk"; + break; + } + + dump_shader(path, prefix, data, size); +} + static HRESULT create_shader_stage(struct d3d12_device *device, struct VkPipelineShaderStageCreateInfo *stage_desc, enum VkShaderStageFlagBits stage, const D3D12_SHADER_BYTECODE *code, const struct vkd3d_shader_interface *shader_interface) @@ -1212,6 +1278,7 @@ static HRESULT create_shader_stage(struct d3d12_device *device, shader_desc.pNext = NULL; shader_desc.flags = 0; + dump_shader_stage(stage, code->pShaderBytecode, code->BytecodeLength); if (FAILED(hr = vkd3d_shader_compile_dxbc(&dxbc, &spirv, 0, shader_interface))) { WARN("Failed to compile shader, hr %#x.\n", hr);