2 * Copyright 2008-2009 Henri Verbeet for CodeWeavers
3 * Copyright 2010 Rico Schüller
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #include "wine/port.h"
24 #include "d3dcompiler_private.h"
26 WINE_DEFAULT_DEBUG_CHANNEL(d3dcompiler);
28 #define WINE_D3DCOMPILER_TO_STR(x) case x: return #x
30 const char *debug_d3dcompiler_d3d_blob_part(D3D_BLOB_PART part)
34 WINE_D3DCOMPILER_TO_STR(D3D_BLOB_INPUT_SIGNATURE_BLOB);
35 WINE_D3DCOMPILER_TO_STR(D3D_BLOB_OUTPUT_SIGNATURE_BLOB);
36 WINE_D3DCOMPILER_TO_STR(D3D_BLOB_INPUT_AND_OUTPUT_SIGNATURE_BLOB);
37 WINE_D3DCOMPILER_TO_STR(D3D_BLOB_PATCH_CONSTANT_SIGNATURE_BLOB);
38 WINE_D3DCOMPILER_TO_STR(D3D_BLOB_ALL_SIGNATURE_BLOB);
39 WINE_D3DCOMPILER_TO_STR(D3D_BLOB_DEBUG_INFO);
40 WINE_D3DCOMPILER_TO_STR(D3D_BLOB_LEGACY_SHADER);
41 WINE_D3DCOMPILER_TO_STR(D3D_BLOB_XNA_PREPASS_SHADER);
42 WINE_D3DCOMPILER_TO_STR(D3D_BLOB_XNA_SHADER);
43 WINE_D3DCOMPILER_TO_STR(D3D_BLOB_TEST_ALTERNATE_SHADER);
44 WINE_D3DCOMPILER_TO_STR(D3D_BLOB_TEST_COMPILE_DETAILS);
45 WINE_D3DCOMPILER_TO_STR(D3D_BLOB_TEST_COMPILE_PERF);
47 FIXME("Unrecognized D3D_BLOB_PART %#x\n", part);
48 return "unrecognized";
52 #undef WINE_D3DCOMPILER_TO_STR
54 void skip_dword_unknown(const char **ptr, unsigned int count)
59 FIXME("Skipping %u unknown DWORDs:\n", count);
60 for (i = 0; i < count; ++i)
63 FIXME("\t0x%08x\n", d);
67 void write_dword_unknown(char **ptr, DWORD d)
69 FIXME("Writing unknown DWORD 0x%08x\n", d);
73 HRESULT dxbc_add_section(struct dxbc *dxbc, DWORD tag, const char *data, DWORD data_size)
75 TRACE("dxbc %p, tag %s, size %#x.\n", dxbc, debugstr_an((const char *)&tag, 4), data_size);
77 if (dxbc->count >= dxbc->size)
79 struct dxbc_section *new_sections;
80 DWORD new_size = dxbc->size << 1;
82 new_sections = HeapReAlloc(GetProcessHeap(), 0, dxbc->sections, new_size * sizeof(*dxbc->sections));
85 ERR("Failed to allocate dxbc section memory\n");
89 dxbc->sections = new_sections;
90 dxbc->size = new_size;
93 dxbc->sections[dxbc->count].tag = tag;
94 dxbc->sections[dxbc->count].data_size = data_size;
95 dxbc->sections[dxbc->count].data = data;
101 HRESULT dxbc_init(struct dxbc *dxbc, UINT size)
103 TRACE("dxbc %p, size %u.\n", dxbc, size);
105 /* use a good starting value for the size if none specified */
108 dxbc->sections = HeapAlloc(GetProcessHeap(), 0, size * sizeof(*dxbc->sections));
111 ERR("Failed to allocate dxbc section memory\n");
112 return E_OUTOFMEMORY;
121 HRESULT dxbc_parse(const char *data, SIZE_T data_size, struct dxbc *dxbc)
123 const char *ptr = data;
126 DWORD tag, total_size, chunk_count;
130 WARN("No data supplied.\n");
134 read_dword(&ptr, &tag);
135 TRACE("tag: %s.\n", debugstr_an((const char *)&tag, 4));
139 WARN("Wrong tag.\n");
144 skip_dword_unknown(&ptr, 4);
146 skip_dword_unknown(&ptr, 1);
148 read_dword(&ptr, &total_size);
149 TRACE("total size: %#x\n", total_size);
151 if (data_size != total_size)
153 WARN("Wrong size supplied.\n");
154 return D3DERR_INVALIDCALL;
157 read_dword(&ptr, &chunk_count);
158 TRACE("chunk count: %#x\n", chunk_count);
160 hr = dxbc_init(dxbc, chunk_count);
163 WARN("Failed to init dxbc\n");
167 for (i = 0; i < chunk_count; ++i)
169 DWORD chunk_tag, chunk_size;
170 const char *chunk_ptr;
173 read_dword(&ptr, &chunk_offset);
174 TRACE("chunk %u at offset %#x\n", i, chunk_offset);
176 chunk_ptr = data + chunk_offset;
178 read_dword(&chunk_ptr, &chunk_tag);
179 read_dword(&chunk_ptr, &chunk_size);
181 hr = dxbc_add_section(dxbc, chunk_tag, chunk_ptr, chunk_size);
184 WARN("Failed to add section to dxbc\n");
192 void dxbc_destroy(struct dxbc *dxbc)
194 TRACE("dxbc %p.\n", dxbc);
196 HeapFree(GetProcessHeap(), 0, dxbc->sections);
199 HRESULT dxbc_write_blob(struct dxbc *dxbc, ID3DBlob **blob)
201 DWORD size = 32, offset = size + 4 * dxbc->count;
207 TRACE("dxbc %p, blob %p.\n", dxbc, blob);
209 for (i = 0; i < dxbc->count; ++i)
211 size += 12 + dxbc->sections[i].data_size;
214 hr = D3DCreateBlob(size, &object);
217 WARN("Failed to create blob\n");
221 ptr = ID3D10Blob_GetBufferPointer(object);
223 write_dword(&ptr, TAG_DXBC);
226 write_dword_unknown(&ptr, 0);
227 write_dword_unknown(&ptr, 0);
228 write_dword_unknown(&ptr, 0);
229 write_dword_unknown(&ptr, 0);
231 /* seems to be always 1 */
232 write_dword_unknown(&ptr, 1);
235 write_dword(&ptr, size);
238 write_dword(&ptr, dxbc->count);
240 /* write the chunk offsets */
241 for (i = 0; i < dxbc->count; ++i)
243 write_dword(&ptr, offset);
244 offset += 8 + dxbc->sections[i].data_size;
247 /* write the chunks */
248 for (i = 0; i < dxbc->count; ++i)
250 write_dword(&ptr, dxbc->sections[i].tag);
251 write_dword(&ptr, dxbc->sections[i].data_size);
252 memcpy(ptr, dxbc->sections[i].data, dxbc->sections[i].data_size);
253 ptr += dxbc->sections[i].data_size;
256 TRACE("Created ID3DBlob %p\n", object);