1 /* 2 * Copyright 2009 Henri Verbeet for CodeWeavers 3 * Copyright 2010 Rico Schüller 4 * 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. 9 * 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. 14 * 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 18 * 19 */ 20 21 #include "config.h" 22 #include "wine/port.h" 23 24 #include "d3dcompiler_private.h" 25 26 WINE_DEFAULT_DEBUG_CHANNEL(d3dcompiler); 27 28 enum D3DCOMPILER_SIGNATURE_ELEMENT_SIZE 29 { 30 D3DCOMPILER_SIGNATURE_ELEMENT_SIZE6 = 6, 31 D3DCOMPILER_SIGNATURE_ELEMENT_SIZE7 = 7, 32 }; 33 34 #define D3DCOMPILER_SHADER_TARGET_VERSION_MASK 0xffff 35 #define D3DCOMPILER_SHADER_TARGET_SHADERTYPE_MASK 0xffff0000 36 37 struct d3dcompiler_shader_signature 38 { 39 D3D11_SIGNATURE_PARAMETER_DESC *elements; 40 UINT element_count; 41 char *string_data; 42 }; 43 44 struct d3dcompiler_shader_reflection_type 45 { 46 ID3D11ShaderReflectionType ID3D11ShaderReflectionType_iface; 47 48 DWORD id; 49 struct wine_rb_entry entry; 50 51 struct d3dcompiler_shader_reflection *reflection; 52 53 D3D11_SHADER_TYPE_DESC desc; 54 struct d3dcompiler_shader_reflection_type_member *members; 55 }; 56 57 struct d3dcompiler_shader_reflection_type_member 58 { 59 char *name; 60 DWORD offset; 61 struct d3dcompiler_shader_reflection_type *type; 62 }; 63 64 struct d3dcompiler_shader_reflection_variable 65 { 66 ID3D11ShaderReflectionVariable ID3D11ShaderReflectionVariable_iface; 67 68 struct d3dcompiler_shader_reflection_constant_buffer *constant_buffer; 69 struct d3dcompiler_shader_reflection_type *type; 70 71 char *name; 72 UINT start_offset; 73 UINT size; 74 UINT flags; 75 void *default_value; 76 }; 77 78 struct d3dcompiler_shader_reflection_constant_buffer 79 { 80 ID3D11ShaderReflectionConstantBuffer ID3D11ShaderReflectionConstantBuffer_iface; 81 82 struct d3dcompiler_shader_reflection *reflection; 83 84 char *name; 85 D3D_CBUFFER_TYPE type; 86 UINT variable_count; 87 UINT size; 88 UINT flags; 89 90 struct d3dcompiler_shader_reflection_variable *variables; 91 }; 92 93 /* ID3D11ShaderReflection */ 94 struct d3dcompiler_shader_reflection 95 { 96 ID3D11ShaderReflection ID3D11ShaderReflection_iface; 97 LONG refcount; 98 99 DWORD target; 100 char *creator; 101 UINT flags; 102 UINT version; 103 UINT bound_resource_count; 104 UINT constant_buffer_count; 105 106 UINT mov_instruction_count; 107 UINT conversion_instruction_count; 108 UINT instruction_count; 109 UINT emit_instruction_count; 110 D3D_PRIMITIVE_TOPOLOGY gs_output_topology; 111 UINT gs_max_output_vertex_count; 112 D3D_PRIMITIVE input_primitive; 113 UINT cut_instruction_count; 114 UINT dcl_count; 115 UINT static_flow_control_count; 116 UINT float_instruction_count; 117 UINT temp_register_count; 118 UINT int_instruction_count; 119 UINT uint_instruction_count; 120 UINT temp_array_count; 121 UINT array_instruction_count; 122 UINT texture_normal_instructions; 123 UINT texture_load_instructions; 124 UINT texture_comp_instructions; 125 UINT texture_bias_instructions; 126 UINT texture_gradient_instructions; 127 UINT dynamic_flow_control_count; 128 UINT c_control_points; 129 D3D_TESSELLATOR_OUTPUT_PRIMITIVE hs_output_primitive; 130 D3D_TESSELLATOR_PARTITIONING hs_prtitioning; 131 D3D_TESSELLATOR_DOMAIN tessellator_domain; 132 133 struct d3dcompiler_shader_signature *isgn; 134 struct d3dcompiler_shader_signature *osgn; 135 struct d3dcompiler_shader_signature *pcsg; 136 char *resource_string; 137 D3D11_SHADER_INPUT_BIND_DESC *bound_resources; 138 struct d3dcompiler_shader_reflection_constant_buffer *constant_buffers; 139 struct wine_rb_tree types; 140 }; 141 142 static struct d3dcompiler_shader_reflection_type *get_reflection_type(struct d3dcompiler_shader_reflection *reflection, const char *data, DWORD offset); 143 144 static const struct ID3D11ShaderReflectionConstantBufferVtbl d3dcompiler_shader_reflection_constant_buffer_vtbl; 145 static const struct ID3D11ShaderReflectionVariableVtbl d3dcompiler_shader_reflection_variable_vtbl; 146 static const struct ID3D11ShaderReflectionTypeVtbl d3dcompiler_shader_reflection_type_vtbl; 147 148 /* null objects - needed for invalid calls */ 149 static struct d3dcompiler_shader_reflection_constant_buffer null_constant_buffer = {{&d3dcompiler_shader_reflection_constant_buffer_vtbl}}; 150 static struct d3dcompiler_shader_reflection_type null_type = {{&d3dcompiler_shader_reflection_type_vtbl}}; 151 static struct d3dcompiler_shader_reflection_variable null_variable = {{&d3dcompiler_shader_reflection_variable_vtbl}, 152 &null_constant_buffer, &null_type}; 153 154 static BOOL copy_name(const char *ptr, char **name) 155 { 156 size_t name_len; 157 158 if (!ptr) return TRUE; 159 160 name_len = strlen(ptr) + 1; 161 if (name_len == 1) 162 { 163 return TRUE; 164 } 165 166 *name = HeapAlloc(GetProcessHeap(), 0, name_len); 167 if (!*name) 168 { 169 ERR("Failed to allocate name memory.\n"); 170 return FALSE; 171 } 172 173 memcpy(*name, ptr, name_len); 174 175 return TRUE; 176 } 177 178 static BOOL copy_value(const char *ptr, void **value, DWORD size) 179 { 180 if (!ptr || !size) return TRUE; 181 182 *value = HeapAlloc(GetProcessHeap(), 0, size); 183 if (!*value) 184 { 185 ERR("Failed to allocate value memory.\n"); 186 return FALSE; 187 } 188 189 memcpy(*value, ptr, size); 190 191 return TRUE; 192 } 193 194 static int d3dcompiler_shader_reflection_type_compare(const void *key, const struct wine_rb_entry *entry) 195 { 196 const struct d3dcompiler_shader_reflection_type *t = WINE_RB_ENTRY_VALUE(entry, const struct d3dcompiler_shader_reflection_type, entry); 197 const DWORD *id = key; 198 199 return *id - t->id; 200 } 201 202 static void free_type_member(struct d3dcompiler_shader_reflection_type_member *member) 203 { 204 if (member) 205 { 206 HeapFree(GetProcessHeap(), 0, member->name); 207 } 208 } 209 210 static void d3dcompiler_shader_reflection_type_destroy(struct wine_rb_entry *entry, void *context) 211 { 212 struct d3dcompiler_shader_reflection_type *t = WINE_RB_ENTRY_VALUE(entry, struct d3dcompiler_shader_reflection_type, entry); 213 unsigned int i; 214 215 TRACE("reflection type %p.\n", t); 216 217 if (t->members) 218 { 219 for (i = 0; i < t->desc.Members; ++i) 220 { 221 free_type_member(&t->members[i]); 222 } 223 HeapFree(GetProcessHeap(), 0, t->members); 224 } 225 226 HeapFree(GetProcessHeap(), 0, t); 227 } 228 229 static void free_signature(struct d3dcompiler_shader_signature *sig) 230 { 231 TRACE("Free signature %p\n", sig); 232 233 HeapFree(GetProcessHeap(), 0, sig->elements); 234 HeapFree(GetProcessHeap(), 0, sig->string_data); 235 } 236 237 static void free_variable(struct d3dcompiler_shader_reflection_variable *var) 238 { 239 if (var) 240 { 241 HeapFree(GetProcessHeap(), 0, var->name); 242 HeapFree(GetProcessHeap(), 0, var->default_value); 243 } 244 } 245 246 static void free_constant_buffer(struct d3dcompiler_shader_reflection_constant_buffer *cb) 247 { 248 if (cb->variables) 249 { 250 unsigned int i; 251 252 for (i = 0; i < cb->variable_count; ++i) 253 { 254 free_variable(&cb->variables[i]); 255 } 256 HeapFree(GetProcessHeap(), 0, cb->variables); 257 } 258 259 HeapFree(GetProcessHeap(), 0, cb->name); 260 } 261 262 static void reflection_cleanup(struct d3dcompiler_shader_reflection *ref) 263 { 264 TRACE("Cleanup %p\n", ref); 265 266 if (ref->isgn) 267 { 268 free_signature(ref->isgn); 269 HeapFree(GetProcessHeap(), 0, ref->isgn); 270 } 271 272 if (ref->osgn) 273 { 274 free_signature(ref->osgn); 275 HeapFree(GetProcessHeap(), 0, ref->osgn); 276 } 277 278 if (ref->pcsg) 279 { 280 free_signature(ref->pcsg); 281 HeapFree(GetProcessHeap(), 0, ref->pcsg); 282 } 283 284 if (ref->constant_buffers) 285 { 286 unsigned int i; 287 288 for (i = 0; i < ref->constant_buffer_count; ++i) 289 { 290 free_constant_buffer(&ref->constant_buffers[i]); 291 } 292 } 293 294 wine_rb_destroy(&ref->types, d3dcompiler_shader_reflection_type_destroy, NULL); 295 HeapFree(GetProcessHeap(), 0, ref->constant_buffers); 296 HeapFree(GetProcessHeap(), 0, ref->bound_resources); 297 HeapFree(GetProcessHeap(), 0, ref->resource_string); 298 HeapFree(GetProcessHeap(), 0, ref->creator); 299 } 300 301 /* IUnknown methods */ 302 303 static inline struct d3dcompiler_shader_reflection *impl_from_ID3D11ShaderReflection(ID3D11ShaderReflection *iface) 304 { 305 return CONTAINING_RECORD(iface, struct d3dcompiler_shader_reflection, ID3D11ShaderReflection_iface); 306 } 307 308 static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_QueryInterface(ID3D11ShaderReflection *iface, REFIID riid, void **object) 309 { 310 TRACE("iface %p, riid %s, object %p\n", iface, debugstr_guid(riid), object); 311 312 if (IsEqualGUID(riid, &IID_ID3D11ShaderReflection) 313 || IsEqualGUID(riid, &IID_IUnknown)) 314 { 315 IUnknown_AddRef(iface); 316 *object = iface; 317 return S_OK; 318 } 319 320 WARN("%s not implemented, returning E_NOINTERFACE\n", debugstr_guid(riid)); 321 322 *object = NULL; 323 return E_NOINTERFACE; 324 } 325 326 static ULONG STDMETHODCALLTYPE d3dcompiler_shader_reflection_AddRef(ID3D11ShaderReflection *iface) 327 { 328 struct d3dcompiler_shader_reflection *This = impl_from_ID3D11ShaderReflection(iface); 329 ULONG refcount = InterlockedIncrement(&This->refcount); 330 331 TRACE("%p increasing refcount to %u\n", This, refcount); 332 333 return refcount; 334 } 335 336 static ULONG STDMETHODCALLTYPE d3dcompiler_shader_reflection_Release(ID3D11ShaderReflection *iface) 337 { 338 struct d3dcompiler_shader_reflection *This = impl_from_ID3D11ShaderReflection(iface); 339 ULONG refcount = InterlockedDecrement(&This->refcount); 340 341 TRACE("%p decreasing refcount to %u\n", This, refcount); 342 343 if (!refcount) 344 { 345 reflection_cleanup(This); 346 HeapFree(GetProcessHeap(), 0, This); 347 } 348 349 return refcount; 350 } 351 352 /* ID3D11ShaderReflection methods */ 353 354 static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetDesc(ID3D11ShaderReflection *iface, D3D11_SHADER_DESC *desc) 355 { 356 struct d3dcompiler_shader_reflection *This = impl_from_ID3D11ShaderReflection(iface); 357 358 FIXME("iface %p, desc %p partial stub!\n", iface, desc); 359 360 if (!desc) 361 { 362 WARN("Invalid argument specified\n"); 363 return E_FAIL; 364 } 365 366 desc->Version = This->version; 367 desc->Creator = This->creator; 368 desc->Flags = This->flags; 369 desc->ConstantBuffers = This->constant_buffer_count; 370 desc->BoundResources = This->bound_resource_count; 371 desc->InputParameters = This->isgn ? This->isgn->element_count : 0; 372 desc->OutputParameters = This->osgn ? This->osgn->element_count : 0; 373 desc->InstructionCount = This->instruction_count; 374 desc->TempRegisterCount = This->temp_register_count; 375 desc->TempArrayCount = This->temp_array_count; 376 desc->DefCount = 0; 377 desc->DclCount = This->dcl_count; 378 desc->TextureNormalInstructions = This->texture_normal_instructions; 379 desc->TextureLoadInstructions = This->texture_load_instructions; 380 desc->TextureCompInstructions = This->texture_comp_instructions; 381 desc->TextureBiasInstructions = This->texture_bias_instructions; 382 desc->TextureGradientInstructions = This->texture_gradient_instructions; 383 desc->FloatInstructionCount = This->float_instruction_count; 384 desc->IntInstructionCount = This->int_instruction_count; 385 desc->UintInstructionCount = This->uint_instruction_count; 386 desc->StaticFlowControlCount = This->static_flow_control_count; 387 desc->DynamicFlowControlCount = This->dynamic_flow_control_count; 388 desc->MacroInstructionCount = 0; 389 desc->ArrayInstructionCount = This->array_instruction_count; 390 desc->CutInstructionCount = This->cut_instruction_count; 391 desc->EmitInstructionCount = This->emit_instruction_count; 392 desc->GSOutputTopology = This->gs_output_topology; 393 desc->GSMaxOutputVertexCount = This->gs_max_output_vertex_count; 394 desc->InputPrimitive = This->input_primitive; 395 desc->PatchConstantParameters = This->pcsg ? This->pcsg->element_count : 0; 396 desc->cGSInstanceCount = 0; 397 desc->cControlPoints = This->c_control_points; 398 desc->HSOutputPrimitive = This->hs_output_primitive; 399 desc->HSPartitioning = This->hs_prtitioning; 400 desc->TessellatorDomain = This->tessellator_domain; 401 desc->cBarrierInstructions = 0; 402 desc->cInterlockedInstructions = 0; 403 desc->cTextureStoreInstructions = 0; 404 405 return S_OK; 406 } 407 408 static struct ID3D11ShaderReflectionConstantBuffer * STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetConstantBufferByIndex( 409 ID3D11ShaderReflection *iface, UINT index) 410 { 411 struct d3dcompiler_shader_reflection *This = impl_from_ID3D11ShaderReflection(iface); 412 413 TRACE("iface %p, index %u\n", iface, index); 414 415 if (index >= This->constant_buffer_count) 416 { 417 WARN("Invalid argument specified\n"); 418 return &null_constant_buffer.ID3D11ShaderReflectionConstantBuffer_iface; 419 } 420 421 return &This->constant_buffers[index].ID3D11ShaderReflectionConstantBuffer_iface; 422 } 423 424 static struct ID3D11ShaderReflectionConstantBuffer * STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetConstantBufferByName( 425 ID3D11ShaderReflection *iface, const char *name) 426 { 427 struct d3dcompiler_shader_reflection *This = impl_from_ID3D11ShaderReflection(iface); 428 unsigned int i; 429 430 TRACE("iface %p, name %s\n", iface, debugstr_a(name)); 431 432 if (!name) 433 { 434 WARN("Invalid argument specified\n"); 435 return &null_constant_buffer.ID3D11ShaderReflectionConstantBuffer_iface; 436 } 437 438 for (i = 0; i < This->constant_buffer_count; ++i) 439 { 440 struct d3dcompiler_shader_reflection_constant_buffer *d = &This->constant_buffers[i]; 441 442 if (!strcmp(d->name, name)) 443 { 444 TRACE("Returning ID3D11ShaderReflectionConstantBuffer %p.\n", d); 445 return &d->ID3D11ShaderReflectionConstantBuffer_iface; 446 } 447 } 448 449 WARN("Invalid name specified\n"); 450 451 return &null_constant_buffer.ID3D11ShaderReflectionConstantBuffer_iface; 452 } 453 454 static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetResourceBindingDesc( 455 ID3D11ShaderReflection *iface, UINT index, D3D11_SHADER_INPUT_BIND_DESC *desc) 456 { 457 struct d3dcompiler_shader_reflection *This = impl_from_ID3D11ShaderReflection(iface); 458 459 TRACE("iface %p, index %u, desc %p\n", iface, index, desc); 460 461 if (!desc || index >= This->bound_resource_count) 462 { 463 WARN("Invalid argument specified\n"); 464 return E_INVALIDARG; 465 } 466 467 *desc = This->bound_resources[index]; 468 469 return S_OK; 470 } 471 472 static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetInputParameterDesc( 473 ID3D11ShaderReflection *iface, UINT index, D3D11_SIGNATURE_PARAMETER_DESC *desc) 474 { 475 struct d3dcompiler_shader_reflection *This = impl_from_ID3D11ShaderReflection(iface); 476 477 TRACE("iface %p, index %u, desc %p\n", iface, index, desc); 478 479 if (!desc || !This->isgn || index >= This->isgn->element_count) 480 { 481 WARN("Invalid argument specified\n"); 482 return E_INVALIDARG; 483 } 484 485 *desc = This->isgn->elements[index]; 486 487 return S_OK; 488 } 489 490 static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetOutputParameterDesc( 491 ID3D11ShaderReflection *iface, UINT index, D3D11_SIGNATURE_PARAMETER_DESC *desc) 492 { 493 struct d3dcompiler_shader_reflection *This = impl_from_ID3D11ShaderReflection(iface); 494 495 TRACE("iface %p, index %u, desc %p\n", iface, index, desc); 496 497 if (!desc || !This->osgn || index >= This->osgn->element_count) 498 { 499 WARN("Invalid argument specified\n"); 500 return E_INVALIDARG; 501 } 502 503 *desc = This->osgn->elements[index]; 504 505 return S_OK; 506 } 507 508 static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetPatchConstantParameterDesc( 509 ID3D11ShaderReflection *iface, UINT index, D3D11_SIGNATURE_PARAMETER_DESC *desc) 510 { 511 struct d3dcompiler_shader_reflection *This = impl_from_ID3D11ShaderReflection(iface); 512 513 TRACE("iface %p, index %u, desc %p\n", iface, index, desc); 514 515 if (!desc || !This->pcsg || index >= This->pcsg->element_count) 516 { 517 WARN("Invalid argument specified\n"); 518 return E_INVALIDARG; 519 } 520 521 *desc = This->pcsg->elements[index]; 522 523 return S_OK; 524 } 525 526 static struct ID3D11ShaderReflectionVariable * STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetVariableByName( 527 ID3D11ShaderReflection *iface, const char *name) 528 { 529 struct d3dcompiler_shader_reflection *This = impl_from_ID3D11ShaderReflection(iface); 530 unsigned int i, k; 531 532 TRACE("iface %p, name %s\n", iface, debugstr_a(name)); 533 534 if (!name) 535 { 536 WARN("Invalid name specified\n"); 537 return &null_variable.ID3D11ShaderReflectionVariable_iface; 538 } 539 540 for (i = 0; i < This->constant_buffer_count; ++i) 541 { 542 struct d3dcompiler_shader_reflection_constant_buffer *cb = &This->constant_buffers[i]; 543 544 for (k = 0; k < cb->variable_count; ++k) 545 { 546 struct d3dcompiler_shader_reflection_variable *v = &cb->variables[k]; 547 548 if (!strcmp(v->name, name)) 549 { 550 TRACE("Returning ID3D11ShaderReflectionVariable %p.\n", v); 551 return &v->ID3D11ShaderReflectionVariable_iface; 552 } 553 } 554 } 555 556 WARN("Invalid name specified\n"); 557 558 return &null_variable.ID3D11ShaderReflectionVariable_iface; 559 } 560 561 static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetResourceBindingDescByName( 562 ID3D11ShaderReflection *iface, const char *name, D3D11_SHADER_INPUT_BIND_DESC *desc) 563 { 564 struct d3dcompiler_shader_reflection *This = impl_from_ID3D11ShaderReflection(iface); 565 unsigned int i; 566 567 TRACE("iface %p, name %s, desc %p\n", iface, debugstr_a(name), desc); 568 569 if (!desc || !name) 570 { 571 WARN("Invalid argument specified\n"); 572 return E_INVALIDARG; 573 } 574 575 for (i = 0; i < This->bound_resource_count; ++i) 576 { 577 D3D11_SHADER_INPUT_BIND_DESC *d = &This->bound_resources[i]; 578 579 if (!strcmp(d->Name, name)) 580 { 581 TRACE("Returning D3D11_SHADER_INPUT_BIND_DESC %p.\n", d); 582 *desc = *d; 583 return S_OK; 584 } 585 } 586 587 WARN("Invalid name specified\n"); 588 589 return E_INVALIDARG; 590 } 591 592 static UINT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetMovInstructionCount( 593 ID3D11ShaderReflection *iface) 594 { 595 struct d3dcompiler_shader_reflection *This = impl_from_ID3D11ShaderReflection(iface); 596 597 TRACE("iface %p\n", iface); 598 599 return This->mov_instruction_count; 600 } 601 602 static UINT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetMovcInstructionCount( 603 ID3D11ShaderReflection *iface) 604 { 605 FIXME("iface %p stub!\n", iface); 606 607 return 0; 608 } 609 610 static UINT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetConversionInstructionCount( 611 ID3D11ShaderReflection *iface) 612 { 613 struct d3dcompiler_shader_reflection *This = impl_from_ID3D11ShaderReflection(iface); 614 615 TRACE("iface %p\n", iface); 616 617 return This->conversion_instruction_count; 618 } 619 620 static UINT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetBitwiseInstructionCount( 621 ID3D11ShaderReflection *iface) 622 { 623 FIXME("iface %p stub!\n", iface); 624 625 return 0; 626 } 627 628 static D3D_PRIMITIVE STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetGSInputPrimitive( 629 ID3D11ShaderReflection *iface) 630 { 631 FIXME("iface %p stub!\n", iface); 632 633 return 0; 634 } 635 636 static BOOL STDMETHODCALLTYPE d3dcompiler_shader_reflection_IsSampleFrequencyShader( 637 ID3D11ShaderReflection *iface) 638 { 639 FIXME("iface %p stub!\n", iface); 640 641 return FALSE; 642 } 643 644 static UINT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetNumInterfaceSlots( 645 ID3D11ShaderReflection *iface) 646 { 647 FIXME("iface %p stub!\n", iface); 648 649 return 0; 650 } 651 652 static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetMinFeatureLevel( 653 ID3D11ShaderReflection *iface, D3D_FEATURE_LEVEL *level) 654 { 655 FIXME("iface %p, level %p stub!\n", iface, level); 656 657 return E_NOTIMPL; 658 } 659 660 static UINT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetThreadGroupSize( 661 ID3D11ShaderReflection *iface, UINT *sizex, UINT *sizey, UINT *sizez) 662 { 663 FIXME("iface %p, sizex %p, sizey %p, sizez %p stub!\n", iface, sizex, sizey, sizez); 664 665 return 0; 666 } 667 668 static const struct ID3D11ShaderReflectionVtbl d3dcompiler_shader_reflection_vtbl = 669 { 670 /* IUnknown methods */ 671 d3dcompiler_shader_reflection_QueryInterface, 672 d3dcompiler_shader_reflection_AddRef, 673 d3dcompiler_shader_reflection_Release, 674 /* ID3D11ShaderReflection methods */ 675 d3dcompiler_shader_reflection_GetDesc, 676 d3dcompiler_shader_reflection_GetConstantBufferByIndex, 677 d3dcompiler_shader_reflection_GetConstantBufferByName, 678 d3dcompiler_shader_reflection_GetResourceBindingDesc, 679 d3dcompiler_shader_reflection_GetInputParameterDesc, 680 d3dcompiler_shader_reflection_GetOutputParameterDesc, 681 d3dcompiler_shader_reflection_GetPatchConstantParameterDesc, 682 d3dcompiler_shader_reflection_GetVariableByName, 683 d3dcompiler_shader_reflection_GetResourceBindingDescByName, 684 d3dcompiler_shader_reflection_GetMovInstructionCount, 685 d3dcompiler_shader_reflection_GetMovcInstructionCount, 686 d3dcompiler_shader_reflection_GetConversionInstructionCount, 687 d3dcompiler_shader_reflection_GetBitwiseInstructionCount, 688 d3dcompiler_shader_reflection_GetGSInputPrimitive, 689 d3dcompiler_shader_reflection_IsSampleFrequencyShader, 690 d3dcompiler_shader_reflection_GetNumInterfaceSlots, 691 d3dcompiler_shader_reflection_GetMinFeatureLevel, 692 d3dcompiler_shader_reflection_GetThreadGroupSize, 693 }; 694 695 /* ID3D11ShaderReflectionConstantBuffer methods */ 696 697 static inline struct d3dcompiler_shader_reflection_constant_buffer *impl_from_ID3D11ShaderReflectionConstantBuffer(ID3D11ShaderReflectionConstantBuffer *iface) 698 { 699 return CONTAINING_RECORD(iface, struct d3dcompiler_shader_reflection_constant_buffer, ID3D11ShaderReflectionConstantBuffer_iface); 700 } 701 702 static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_constant_buffer_GetDesc( 703 ID3D11ShaderReflectionConstantBuffer *iface, D3D11_SHADER_BUFFER_DESC *desc) 704 { 705 struct d3dcompiler_shader_reflection_constant_buffer *This = impl_from_ID3D11ShaderReflectionConstantBuffer(iface); 706 707 TRACE("iface %p, desc %p\n", iface, desc); 708 709 if (This == &null_constant_buffer) 710 { 711 WARN("Null constant buffer specified\n"); 712 return E_FAIL; 713 } 714 715 if (!desc) 716 { 717 WARN("Invalid argument specified\n"); 718 return E_FAIL; 719 } 720 721 desc->Name = This->name; 722 desc->Type = This->type; 723 desc->Variables = This->variable_count; 724 desc->Size = This->size; 725 desc->uFlags = This->flags; 726 727 return S_OK; 728 } 729 730 static ID3D11ShaderReflectionVariable * STDMETHODCALLTYPE d3dcompiler_shader_reflection_constant_buffer_GetVariableByIndex( 731 ID3D11ShaderReflectionConstantBuffer *iface, UINT index) 732 { 733 struct d3dcompiler_shader_reflection_constant_buffer *This = impl_from_ID3D11ShaderReflectionConstantBuffer(iface); 734 735 TRACE("iface %p, index %u\n", iface, index); 736 737 if (index >= This->variable_count) 738 { 739 WARN("Invalid index specified\n"); 740 return &null_variable.ID3D11ShaderReflectionVariable_iface; 741 } 742 743 return &This->variables[index].ID3D11ShaderReflectionVariable_iface; 744 } 745 746 static ID3D11ShaderReflectionVariable * STDMETHODCALLTYPE d3dcompiler_shader_reflection_constant_buffer_GetVariableByName( 747 ID3D11ShaderReflectionConstantBuffer *iface, const char *name) 748 { 749 struct d3dcompiler_shader_reflection_constant_buffer *This = impl_from_ID3D11ShaderReflectionConstantBuffer(iface); 750 unsigned int i; 751 752 TRACE("iface %p, name %s\n", iface, debugstr_a(name)); 753 754 if (!name) 755 { 756 WARN("Invalid argument specified\n"); 757 return &null_variable.ID3D11ShaderReflectionVariable_iface; 758 } 759 760 for (i = 0; i < This->variable_count; ++i) 761 { 762 struct d3dcompiler_shader_reflection_variable *v = &This->variables[i]; 763 764 if (!strcmp(v->name, name)) 765 { 766 TRACE("Returning ID3D11ShaderReflectionVariable %p.\n", v); 767 return &v->ID3D11ShaderReflectionVariable_iface; 768 } 769 } 770 771 WARN("Invalid name specified\n"); 772 773 return &null_variable.ID3D11ShaderReflectionVariable_iface; 774 } 775 776 static const struct ID3D11ShaderReflectionConstantBufferVtbl d3dcompiler_shader_reflection_constant_buffer_vtbl = 777 { 778 /* ID3D11ShaderReflectionConstantBuffer methods */ 779 d3dcompiler_shader_reflection_constant_buffer_GetDesc, 780 d3dcompiler_shader_reflection_constant_buffer_GetVariableByIndex, 781 d3dcompiler_shader_reflection_constant_buffer_GetVariableByName, 782 }; 783 784 /* ID3D11ShaderReflectionVariable methods */ 785 786 static inline struct d3dcompiler_shader_reflection_variable *impl_from_ID3D11ShaderReflectionVariable(ID3D11ShaderReflectionVariable *iface) 787 { 788 return CONTAINING_RECORD(iface, struct d3dcompiler_shader_reflection_variable, ID3D11ShaderReflectionVariable_iface); 789 } 790 791 static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_variable_GetDesc( 792 ID3D11ShaderReflectionVariable *iface, D3D11_SHADER_VARIABLE_DESC *desc) 793 { 794 struct d3dcompiler_shader_reflection_variable *This = impl_from_ID3D11ShaderReflectionVariable(iface); 795 796 TRACE("iface %p, desc %p\n", iface, desc); 797 798 if (This == &null_variable) 799 { 800 WARN("Null variable specified\n"); 801 return E_FAIL; 802 } 803 804 if (!desc) 805 { 806 WARN("Invalid argument specified\n"); 807 return E_FAIL; 808 } 809 810 desc->Name = This->name; 811 desc->StartOffset = This->start_offset; 812 desc->Size = This->size; 813 desc->uFlags = This->flags; 814 desc->DefaultValue = This->default_value; 815 816 return S_OK; 817 } 818 819 static ID3D11ShaderReflectionType * STDMETHODCALLTYPE d3dcompiler_shader_reflection_variable_GetType( 820 ID3D11ShaderReflectionVariable *iface) 821 { 822 struct d3dcompiler_shader_reflection_variable *This = impl_from_ID3D11ShaderReflectionVariable(iface); 823 824 TRACE("iface %p\n", iface); 825 826 return &This->type->ID3D11ShaderReflectionType_iface; 827 } 828 829 static ID3D11ShaderReflectionConstantBuffer * STDMETHODCALLTYPE d3dcompiler_shader_reflection_variable_GetBuffer( 830 ID3D11ShaderReflectionVariable *iface) 831 { 832 struct d3dcompiler_shader_reflection_variable *This = impl_from_ID3D11ShaderReflectionVariable(iface); 833 834 TRACE("iface %p\n", iface); 835 836 return &This->constant_buffer->ID3D11ShaderReflectionConstantBuffer_iface; 837 } 838 839 static UINT STDMETHODCALLTYPE d3dcompiler_shader_reflection_variable_GetInterfaceSlot( 840 ID3D11ShaderReflectionVariable *iface, UINT index) 841 { 842 FIXME("iface %p, index %u stub!\n", iface, index); 843 844 return 0; 845 } 846 847 static const struct ID3D11ShaderReflectionVariableVtbl d3dcompiler_shader_reflection_variable_vtbl = 848 { 849 /* ID3D11ShaderReflectionVariable methods */ 850 d3dcompiler_shader_reflection_variable_GetDesc, 851 d3dcompiler_shader_reflection_variable_GetType, 852 d3dcompiler_shader_reflection_variable_GetBuffer, 853 d3dcompiler_shader_reflection_variable_GetInterfaceSlot, 854 }; 855 856 /* ID3D11ShaderReflectionType methods */ 857 858 static inline struct d3dcompiler_shader_reflection_type *impl_from_ID3D11ShaderReflectionType(ID3D11ShaderReflectionType *iface) 859 { 860 return CONTAINING_RECORD(iface, struct d3dcompiler_shader_reflection_type, ID3D11ShaderReflectionType_iface); 861 } 862 863 static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_type_GetDesc( 864 ID3D11ShaderReflectionType *iface, D3D11_SHADER_TYPE_DESC *desc) 865 { 866 struct d3dcompiler_shader_reflection_type *This = impl_from_ID3D11ShaderReflectionType(iface); 867 868 TRACE("iface %p, desc %p\n", iface, desc); 869 870 if (This == &null_type) 871 { 872 WARN("Null type specified\n"); 873 return E_FAIL; 874 } 875 876 if (!desc) 877 { 878 WARN("Invalid argument specified\n"); 879 return E_FAIL; 880 } 881 882 *desc = This->desc; 883 884 return S_OK; 885 } 886 887 static ID3D11ShaderReflectionType * STDMETHODCALLTYPE d3dcompiler_shader_reflection_type_GetMemberTypeByIndex( 888 ID3D11ShaderReflectionType *iface, UINT index) 889 { 890 struct d3dcompiler_shader_reflection_type *This = impl_from_ID3D11ShaderReflectionType(iface); 891 892 TRACE("iface %p, index %u\n", iface, index); 893 894 if (index >= This->desc.Members) 895 { 896 WARN("Invalid index specified\n"); 897 return &null_type.ID3D11ShaderReflectionType_iface; 898 } 899 900 return &This->members[index].type->ID3D11ShaderReflectionType_iface; 901 } 902 903 static ID3D11ShaderReflectionType * STDMETHODCALLTYPE d3dcompiler_shader_reflection_type_GetMemberTypeByName( 904 ID3D11ShaderReflectionType *iface, const char *name) 905 { 906 struct d3dcompiler_shader_reflection_type *This = impl_from_ID3D11ShaderReflectionType(iface); 907 unsigned int i; 908 909 TRACE("iface %p, name %s\n", iface, debugstr_a(name)); 910 911 if (!name) 912 { 913 WARN("Invalid argument specified\n"); 914 return &null_type.ID3D11ShaderReflectionType_iface; 915 } 916 917 for (i = 0; i < This->desc.Members; ++i) 918 { 919 struct d3dcompiler_shader_reflection_type_member *member = &This->members[i]; 920 921 if (!strcmp(member->name, name)) 922 { 923 TRACE("Returning ID3D11ShaderReflectionType %p.\n", member->type); 924 return &member->type->ID3D11ShaderReflectionType_iface; 925 } 926 } 927 928 WARN("Invalid name specified\n"); 929 930 return &null_type.ID3D11ShaderReflectionType_iface; 931 } 932 933 static const char * STDMETHODCALLTYPE d3dcompiler_shader_reflection_type_GetMemberTypeName( 934 ID3D11ShaderReflectionType *iface, UINT index) 935 { 936 struct d3dcompiler_shader_reflection_type *This = impl_from_ID3D11ShaderReflectionType(iface); 937 938 TRACE("iface %p, index %u\n", iface, index); 939 940 if (This == &null_type) 941 { 942 WARN("Null type specified\n"); 943 return "$Invalid"; 944 } 945 946 if (index >= This->desc.Members) 947 { 948 WARN("Invalid index specified\n"); 949 return NULL; 950 } 951 952 return This->members[index].name; 953 } 954 955 static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_type_IsEqual( 956 ID3D11ShaderReflectionType *iface, ID3D11ShaderReflectionType *type) 957 { 958 struct d3dcompiler_shader_reflection_type *This = impl_from_ID3D11ShaderReflectionType(iface); 959 960 TRACE("iface %p, type %p\n", iface, type); 961 962 if (This == &null_type) 963 { 964 WARN("Null type specified\n"); 965 return E_FAIL; 966 } 967 968 if (iface == type) 969 return S_OK; 970 971 return S_FALSE; 972 } 973 974 static ID3D11ShaderReflectionType * STDMETHODCALLTYPE d3dcompiler_shader_reflection_type_GetSubType( 975 ID3D11ShaderReflectionType *iface) 976 { 977 FIXME("iface %p stub!\n", iface); 978 979 return NULL; 980 } 981 982 static ID3D11ShaderReflectionType * STDMETHODCALLTYPE d3dcompiler_shader_reflection_type_GetBaseClass( 983 ID3D11ShaderReflectionType *iface) 984 { 985 FIXME("iface %p stub!\n", iface); 986 987 return NULL; 988 } 989 990 static UINT STDMETHODCALLTYPE d3dcompiler_shader_reflection_type_GetNumInterfaces( 991 ID3D11ShaderReflectionType *iface) 992 { 993 FIXME("iface %p stub!\n", iface); 994 995 return 0; 996 } 997 998 static ID3D11ShaderReflectionType * STDMETHODCALLTYPE d3dcompiler_shader_reflection_type_GetInterfaceByIndex( 999 ID3D11ShaderReflectionType *iface, UINT index) 1000 { 1001 FIXME("iface %p, index %u stub!\n", iface, index); 1002 1003 return NULL; 1004 } 1005 1006 static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_type_IsOfType( 1007 ID3D11ShaderReflectionType *iface, ID3D11ShaderReflectionType *type) 1008 { 1009 FIXME("iface %p, type %p stub!\n", iface, type); 1010 1011 return E_NOTIMPL; 1012 } 1013 1014 static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_type_ImplementsInterface( 1015 ID3D11ShaderReflectionType *iface, ID3D11ShaderReflectionType *base) 1016 { 1017 FIXME("iface %p, base %p stub!\n", iface, base); 1018 1019 return E_NOTIMPL; 1020 } 1021 1022 static const struct ID3D11ShaderReflectionTypeVtbl d3dcompiler_shader_reflection_type_vtbl = 1023 { 1024 /* ID3D11ShaderReflectionType methods */ 1025 d3dcompiler_shader_reflection_type_GetDesc, 1026 d3dcompiler_shader_reflection_type_GetMemberTypeByIndex, 1027 d3dcompiler_shader_reflection_type_GetMemberTypeByName, 1028 d3dcompiler_shader_reflection_type_GetMemberTypeName, 1029 d3dcompiler_shader_reflection_type_IsEqual, 1030 d3dcompiler_shader_reflection_type_GetSubType, 1031 d3dcompiler_shader_reflection_type_GetBaseClass, 1032 d3dcompiler_shader_reflection_type_GetNumInterfaces, 1033 d3dcompiler_shader_reflection_type_GetInterfaceByIndex, 1034 d3dcompiler_shader_reflection_type_IsOfType, 1035 d3dcompiler_shader_reflection_type_ImplementsInterface, 1036 }; 1037 1038 static HRESULT d3dcompiler_parse_stat(struct d3dcompiler_shader_reflection *r, const char *data, DWORD data_size) 1039 { 1040 const char *ptr = data; 1041 DWORD size = data_size >> 2; 1042 1043 TRACE("Size %u\n", size); 1044 1045 read_dword(&ptr, &r->instruction_count); 1046 TRACE("InstructionCount: %u\n", r->instruction_count); 1047 1048 read_dword(&ptr, &r->temp_register_count); 1049 TRACE("TempRegisterCount: %u\n", r->temp_register_count); 1050 1051 skip_dword_unknown(&ptr, 1); 1052 1053 read_dword(&ptr, &r->dcl_count); 1054 TRACE("DclCount: %u\n", r->dcl_count); 1055 1056 read_dword(&ptr, &r->float_instruction_count); 1057 TRACE("FloatInstructionCount: %u\n", r->float_instruction_count); 1058 1059 read_dword(&ptr, &r->int_instruction_count); 1060 TRACE("IntInstructionCount: %u\n", r->int_instruction_count); 1061 1062 read_dword(&ptr, &r->uint_instruction_count); 1063 TRACE("UintInstructionCount: %u\n", r->uint_instruction_count); 1064 1065 read_dword(&ptr, &r->static_flow_control_count); 1066 TRACE("StaticFlowControlCount: %u\n", r->static_flow_control_count); 1067 1068 read_dword(&ptr, &r->dynamic_flow_control_count); 1069 TRACE("DynamicFlowControlCount: %u\n", r->dynamic_flow_control_count); 1070 1071 skip_dword_unknown(&ptr, 1); 1072 1073 read_dword(&ptr, &r->temp_array_count); 1074 TRACE("TempArrayCount: %u\n", r->temp_array_count); 1075 1076 read_dword(&ptr, &r->array_instruction_count); 1077 TRACE("ArrayInstructionCount: %u\n", r->array_instruction_count); 1078 1079 read_dword(&ptr, &r->cut_instruction_count); 1080 TRACE("CutInstructionCount: %u\n", r->cut_instruction_count); 1081 1082 read_dword(&ptr, &r->emit_instruction_count); 1083 TRACE("EmitInstructionCount: %u\n", r->emit_instruction_count); 1084 1085 read_dword(&ptr, &r->texture_normal_instructions); 1086 TRACE("TextureNormalInstructions: %u\n", r->texture_normal_instructions); 1087 1088 read_dword(&ptr, &r->texture_load_instructions); 1089 TRACE("TextureLoadInstructions: %u\n", r->texture_load_instructions); 1090 1091 read_dword(&ptr, &r->texture_comp_instructions); 1092 TRACE("TextureCompInstructions: %u\n", r->texture_comp_instructions); 1093 1094 read_dword(&ptr, &r->texture_bias_instructions); 1095 TRACE("TextureBiasInstructions: %u\n", r->texture_bias_instructions); 1096 1097 read_dword(&ptr, &r->texture_gradient_instructions); 1098 TRACE("TextureGradientInstructions: %u\n", r->texture_gradient_instructions); 1099 1100 read_dword(&ptr, &r->mov_instruction_count); 1101 TRACE("MovInstructionCount: %u\n", r->mov_instruction_count); 1102 1103 skip_dword_unknown(&ptr, 1); 1104 1105 read_dword(&ptr, &r->conversion_instruction_count); 1106 TRACE("ConversionInstructionCount: %u\n", r->conversion_instruction_count); 1107 1108 skip_dword_unknown(&ptr, 1); 1109 1110 read_dword(&ptr, &r->input_primitive); 1111 TRACE("InputPrimitive: %x\n", r->input_primitive); 1112 1113 read_dword(&ptr, &r->gs_output_topology); 1114 TRACE("GSOutputTopology: %x\n", r->gs_output_topology); 1115 1116 read_dword(&ptr, &r->gs_max_output_vertex_count); 1117 TRACE("GSMaxOutputVertexCount: %u\n", r->gs_max_output_vertex_count); 1118 1119 skip_dword_unknown(&ptr, 3); 1120 1121 /* dx10 stat size */ 1122 if (size == 29) return S_OK; 1123 1124 skip_dword_unknown(&ptr, 1); 1125 1126 read_dword(&ptr, &r->c_control_points); 1127 TRACE("cControlPoints: %u\n", r->c_control_points); 1128 1129 read_dword(&ptr, &r->hs_output_primitive); 1130 TRACE("HSOutputPrimitive: %x\n", r->hs_output_primitive); 1131 1132 read_dword(&ptr, &r->hs_prtitioning); 1133 TRACE("HSPartitioning: %x\n", r->hs_prtitioning); 1134 1135 read_dword(&ptr, &r->tessellator_domain); 1136 TRACE("TessellatorDomain: %x\n", r->tessellator_domain); 1137 1138 skip_dword_unknown(&ptr, 3); 1139 1140 /* dx11 stat size */ 1141 if (size == 37) return S_OK; 1142 1143 FIXME("Unhandled size %u\n", size); 1144 1145 return E_FAIL; 1146 } 1147 1148 static HRESULT d3dcompiler_parse_type_members(struct d3dcompiler_shader_reflection *ref, 1149 struct d3dcompiler_shader_reflection_type_member *member, const char *data, const char **ptr) 1150 { 1151 DWORD offset; 1152 1153 read_dword(ptr, &offset); 1154 if (!copy_name(data + offset, &member->name)) 1155 { 1156 ERR("Failed to copy name.\n"); 1157 return E_OUTOFMEMORY; 1158 } 1159 TRACE("Member name: %s.\n", debugstr_a(member->name)); 1160 1161 read_dword(ptr, &offset); 1162 TRACE("Member type offset: %x\n", offset); 1163 1164 member->type = get_reflection_type(ref, data, offset); 1165 if (!member->type) 1166 { 1167 ERR("Failed to get member type\n"); 1168 HeapFree(GetProcessHeap(), 0, member->name); 1169 return E_FAIL; 1170 } 1171 1172 read_dword(ptr, &member->offset); 1173 TRACE("Member offset %x\n", member->offset); 1174 1175 return S_OK; 1176 } 1177 1178 static HRESULT d3dcompiler_parse_type(struct d3dcompiler_shader_reflection_type *type, const char *data, DWORD offset) 1179 { 1180 const char *ptr = data + offset; 1181 DWORD temp; 1182 D3D11_SHADER_TYPE_DESC *desc; 1183 unsigned int i; 1184 struct d3dcompiler_shader_reflection_type_member *members = NULL; 1185 HRESULT hr; 1186 DWORD member_offset; 1187 1188 desc = &type->desc; 1189 1190 read_dword(&ptr, &temp); 1191 desc->Class = temp & 0xffff; 1192 desc->Type = temp >> 16; 1193 TRACE("Class %s, Type %s\n", debug_d3dcompiler_shader_variable_class(desc->Class), 1194 debug_d3dcompiler_shader_variable_type(desc->Type)); 1195 1196 read_dword(&ptr, &temp); 1197 desc->Rows = temp & 0xffff; 1198 desc->Columns = temp >> 16; 1199 TRACE("Rows %u, Columns %u\n", desc->Rows, desc->Columns); 1200 1201 read_dword(&ptr, &temp); 1202 desc->Elements = temp & 0xffff; 1203 desc->Members = temp >> 16; 1204 TRACE("Elements %u, Members %u\n", desc->Elements, desc->Members); 1205 1206 read_dword(&ptr, &member_offset); 1207 TRACE("Member Offset %u\n", member_offset); 1208 1209 if ((type->reflection->target & D3DCOMPILER_SHADER_TARGET_VERSION_MASK) >= 0x500) 1210 skip_dword_unknown(&ptr, 4); 1211 1212 if (desc->Members) 1213 { 1214 const char *ptr2 = data + member_offset; 1215 1216 members = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*members) * desc->Members); 1217 if (!members) 1218 { 1219 ERR("Failed to allocate type memory.\n"); 1220 return E_OUTOFMEMORY; 1221 } 1222 1223 for (i = 0; i < desc->Members; ++i) 1224 { 1225 hr = d3dcompiler_parse_type_members(type->reflection, &members[i], data, &ptr2); 1226 if (hr != S_OK) 1227 { 1228 FIXME("Failed to parse type members.\n"); 1229 goto err_out; 1230 } 1231 } 1232 } 1233 1234 type->members = members; 1235 1236 return S_OK; 1237 1238 err_out: 1239 for (i = 0; i < desc->Members; ++i) 1240 { 1241 free_type_member(&members[i]); 1242 } 1243 HeapFree(GetProcessHeap(), 0, members); 1244 return hr; 1245 } 1246 1247 static struct d3dcompiler_shader_reflection_type *get_reflection_type(struct d3dcompiler_shader_reflection *reflection, const char *data, DWORD offset) 1248 { 1249 struct d3dcompiler_shader_reflection_type *type; 1250 struct wine_rb_entry *entry; 1251 HRESULT hr; 1252 1253 entry = wine_rb_get(&reflection->types, &offset); 1254 if (entry) 1255 { 1256 TRACE("Returning existing type.\n"); 1257 return WINE_RB_ENTRY_VALUE(entry, struct d3dcompiler_shader_reflection_type, entry); 1258 } 1259 1260 type = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*type)); 1261 if (!type) 1262 return NULL; 1263 1264 type->ID3D11ShaderReflectionType_iface.lpVtbl = &d3dcompiler_shader_reflection_type_vtbl; 1265 type->id = offset; 1266 type->reflection = reflection; 1267 1268 hr = d3dcompiler_parse_type(type, data, offset); 1269 if (FAILED(hr)) 1270 { 1271 ERR("Failed to parse type info, hr %#x.\n", hr); 1272 HeapFree(GetProcessHeap(), 0, type); 1273 return NULL; 1274 } 1275 1276 if (wine_rb_put(&reflection->types, &offset, &type->entry) == -1) 1277 { 1278 ERR("Failed to insert type entry.\n"); 1279 HeapFree(GetProcessHeap(), 0, type); 1280 return NULL; 1281 } 1282 1283 return type; 1284 } 1285 1286 static HRESULT d3dcompiler_parse_variables(struct d3dcompiler_shader_reflection_constant_buffer *cb, 1287 const char *data, DWORD data_size, const char *ptr) 1288 { 1289 struct d3dcompiler_shader_reflection_variable *variables; 1290 unsigned int i; 1291 HRESULT hr; 1292 1293 variables = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cb->variable_count * sizeof(*variables)); 1294 if (!variables) 1295 { 1296 ERR("Failed to allocate variables memory.\n"); 1297 return E_OUTOFMEMORY; 1298 } 1299 1300 for (i = 0; i < cb->variable_count; i++) 1301 { 1302 struct d3dcompiler_shader_reflection_variable *v = &variables[i]; 1303 DWORD offset; 1304 1305 v->ID3D11ShaderReflectionVariable_iface.lpVtbl = &d3dcompiler_shader_reflection_variable_vtbl; 1306 v->constant_buffer = cb; 1307 1308 read_dword(&ptr, &offset); 1309 if (!copy_name(data + offset, &v->name)) 1310 { 1311 ERR("Failed to copy name.\n"); 1312 hr = E_OUTOFMEMORY; 1313 goto err_out; 1314 } 1315 TRACE("Variable name: %s.\n", debugstr_a(v->name)); 1316 1317 read_dword(&ptr, &v->start_offset); 1318 TRACE("Variable offset: %u\n", v->start_offset); 1319 1320 read_dword(&ptr, &v->size); 1321 TRACE("Variable size: %u\n", v->size); 1322 1323 read_dword(&ptr, &v->flags); 1324 TRACE("Variable flags: %u\n", v->flags); 1325 1326 read_dword(&ptr, &offset); 1327 TRACE("Variable type offset: %x\n", offset); 1328 v->type = get_reflection_type(cb->reflection, data, offset); 1329 if (!v->type) 1330 { 1331 ERR("Failed to get type.\n"); 1332 hr = E_FAIL; 1333 goto err_out; 1334 } 1335 1336 read_dword(&ptr, &offset); 1337 TRACE("Variable default value offset: %x\n", offset); 1338 if (!copy_value(data + offset, &v->default_value, offset ? v->size : 0)) 1339 { 1340 ERR("Failed to copy name.\n"); 1341 hr = E_OUTOFMEMORY; 1342 goto err_out; 1343 } 1344 1345 if ((cb->reflection->target & D3DCOMPILER_SHADER_TARGET_VERSION_MASK) >= 0x500) 1346 skip_dword_unknown(&ptr, 4); 1347 } 1348 1349 cb->variables = variables; 1350 1351 return S_OK; 1352 1353 err_out: 1354 for (i = 0; i < cb->variable_count; i++) 1355 { 1356 free_variable(&variables[i]); 1357 } 1358 HeapFree(GetProcessHeap(), 0, variables); 1359 return hr; 1360 } 1361 1362 static HRESULT d3dcompiler_parse_rdef(struct d3dcompiler_shader_reflection *r, const char *data, DWORD data_size) 1363 { 1364 const char *ptr = data; 1365 DWORD size = data_size >> 2; 1366 DWORD offset, cbuffer_offset, resource_offset, creator_offset; 1367 unsigned int i, string_data_offset, string_data_size; 1368 char *string_data = NULL, *creator = NULL; 1369 D3D11_SHADER_INPUT_BIND_DESC *bound_resources = NULL; 1370 struct d3dcompiler_shader_reflection_constant_buffer *constant_buffers = NULL; 1371 HRESULT hr; 1372 1373 TRACE("Size %u\n", size); 1374 1375 read_dword(&ptr, &r->constant_buffer_count); 1376 TRACE("Constant buffer count: %u\n", r->constant_buffer_count); 1377 1378 read_dword(&ptr, &cbuffer_offset); 1379 TRACE("Constant buffer offset: %#x\n", cbuffer_offset); 1380 1381 read_dword(&ptr, &r->bound_resource_count); 1382 TRACE("Bound resource count: %u\n", r->bound_resource_count); 1383 1384 read_dword(&ptr, &resource_offset); 1385 TRACE("Bound resource offset: %#x\n", resource_offset); 1386 1387 read_dword(&ptr, &r->target); 1388 TRACE("Target: %#x\n", r->target); 1389 1390 read_dword(&ptr, &r->flags); 1391 TRACE("Flags: %u\n", r->flags); 1392 1393 read_dword(&ptr, &creator_offset); 1394 TRACE("Creator at offset %#x.\n", creator_offset); 1395 1396 if (!copy_name(data + creator_offset, &creator)) 1397 { 1398 ERR("Failed to copy name.\n"); 1399 return E_OUTOFMEMORY; 1400 } 1401 TRACE("Creator: %s.\n", debugstr_a(creator)); 1402 1403 /* todo: Parse RD11 */ 1404 if ((r->target & D3DCOMPILER_SHADER_TARGET_VERSION_MASK) >= 0x500) 1405 { 1406 skip_dword_unknown(&ptr, 8); 1407 } 1408 1409 if (r->bound_resource_count) 1410 { 1411 /* 8 for each bind desc */ 1412 string_data_offset = resource_offset + r->bound_resource_count * 8 * sizeof(DWORD); 1413 string_data_size = (cbuffer_offset ? cbuffer_offset : creator_offset) - string_data_offset; 1414 1415 string_data = HeapAlloc(GetProcessHeap(), 0, string_data_size); 1416 if (!string_data) 1417 { 1418 ERR("Failed to allocate string data memory.\n"); 1419 hr = E_OUTOFMEMORY; 1420 goto err_out; 1421 } 1422 memcpy(string_data, data + string_data_offset, string_data_size); 1423 1424 bound_resources = HeapAlloc(GetProcessHeap(), 0, r->bound_resource_count * sizeof(*bound_resources)); 1425 if (!bound_resources) 1426 { 1427 ERR("Failed to allocate resources memory.\n"); 1428 hr = E_OUTOFMEMORY; 1429 goto err_out; 1430 } 1431 1432 ptr = data + resource_offset; 1433 for (i = 0; i < r->bound_resource_count; i++) 1434 { 1435 D3D11_SHADER_INPUT_BIND_DESC *desc = &bound_resources[i]; 1436 1437 read_dword(&ptr, &offset); 1438 desc->Name = string_data + (offset - string_data_offset); 1439 TRACE("Input bind Name: %s\n", debugstr_a(desc->Name)); 1440 1441 read_dword(&ptr, &desc->Type); 1442 TRACE("Input bind Type: %#x\n", desc->Type); 1443 1444 read_dword(&ptr, &desc->ReturnType); 1445 TRACE("Input bind ReturnType: %#x\n", desc->ReturnType); 1446 1447 read_dword(&ptr, &desc->Dimension); 1448 TRACE("Input bind Dimension: %#x\n", desc->Dimension); 1449 1450 read_dword(&ptr, &desc->NumSamples); 1451 TRACE("Input bind NumSamples: %u\n", desc->NumSamples); 1452 1453 read_dword(&ptr, &desc->BindPoint); 1454 TRACE("Input bind BindPoint: %u\n", desc->BindPoint); 1455 1456 read_dword(&ptr, &desc->BindCount); 1457 TRACE("Input bind BindCount: %u\n", desc->BindCount); 1458 1459 read_dword(&ptr, &desc->uFlags); 1460 TRACE("Input bind uFlags: %u\n", desc->uFlags); 1461 } 1462 } 1463 1464 if (r->constant_buffer_count) 1465 { 1466 constant_buffers = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, r->constant_buffer_count * sizeof(*constant_buffers)); 1467 if (!constant_buffers) 1468 { 1469 ERR("Failed to allocate constant buffer memory.\n"); 1470 hr = E_OUTOFMEMORY; 1471 goto err_out; 1472 } 1473 1474 ptr = data + cbuffer_offset; 1475 for (i = 0; i < r->constant_buffer_count; i++) 1476 { 1477 struct d3dcompiler_shader_reflection_constant_buffer *cb = &constant_buffers[i]; 1478 1479 cb->ID3D11ShaderReflectionConstantBuffer_iface.lpVtbl = &d3dcompiler_shader_reflection_constant_buffer_vtbl; 1480 cb->reflection = r; 1481 1482 read_dword(&ptr, &offset); 1483 if (!copy_name(data + offset, &cb->name)) 1484 { 1485 ERR("Failed to copy name.\n"); 1486 hr = E_OUTOFMEMORY; 1487 goto err_out; 1488 } 1489 TRACE("Name: %s.\n", debugstr_a(cb->name)); 1490 1491 read_dword(&ptr, &cb->variable_count); 1492 TRACE("Variable count: %u\n", cb->variable_count); 1493 1494 read_dword(&ptr, &offset); 1495 TRACE("Variable offset: %x\n", offset); 1496 1497 hr = d3dcompiler_parse_variables(cb, data, data_size, data + offset); 1498 if (hr != S_OK) 1499 { 1500 FIXME("Failed to parse variables.\n"); 1501 goto err_out; 1502 } 1503 1504 read_dword(&ptr, &cb->size); 1505 TRACE("Cbuffer size: %u\n", cb->size); 1506 1507 read_dword(&ptr, &cb->flags); 1508 TRACE("Cbuffer flags: %u\n", cb->flags); 1509 1510 read_dword(&ptr, &cb->type); 1511 TRACE("Cbuffer type: %#x\n", cb->type); 1512 } 1513 } 1514 1515 r->creator = creator; 1516 r->resource_string = string_data; 1517 r->bound_resources = bound_resources; 1518 r->constant_buffers = constant_buffers; 1519 1520 return S_OK; 1521 1522 err_out: 1523 for (i = 0; i < r->constant_buffer_count; ++i) 1524 { 1525 free_constant_buffer(&constant_buffers[i]); 1526 } 1527 HeapFree(GetProcessHeap(), 0, constant_buffers); 1528 HeapFree(GetProcessHeap(), 0, bound_resources); 1529 HeapFree(GetProcessHeap(), 0, string_data); 1530 HeapFree(GetProcessHeap(), 0, creator); 1531 1532 return hr; 1533 } 1534 1535 static HRESULT d3dcompiler_parse_signature(struct d3dcompiler_shader_signature *s, struct dxbc_section *section, DWORD target) 1536 { 1537 D3D11_SIGNATURE_PARAMETER_DESC *d; 1538 unsigned int string_data_offset; 1539 unsigned int string_data_size; 1540 const char *ptr = section->data; 1541 char *string_data; 1542 unsigned int i; 1543 DWORD count; 1544 enum D3DCOMPILER_SIGNATURE_ELEMENT_SIZE element_size; 1545 1546 switch (section->tag) 1547 { 1548 case TAG_OSG5: 1549 element_size = D3DCOMPILER_SIGNATURE_ELEMENT_SIZE7; 1550 break; 1551 1552 case TAG_ISGN: 1553 case TAG_OSGN: 1554 case TAG_PCSG: 1555 element_size = D3DCOMPILER_SIGNATURE_ELEMENT_SIZE6; 1556 break; 1557 1558 default: 1559 FIXME("Unhandled section %s!\n", debugstr_an((const char *)§ion->tag, 4)); 1560 element_size = D3DCOMPILER_SIGNATURE_ELEMENT_SIZE6; 1561 break; 1562 } 1563 1564 read_dword(&ptr, &count); 1565 TRACE("%u elements\n", count); 1566 1567 skip_dword_unknown(&ptr, 1); 1568 1569 d = HeapAlloc(GetProcessHeap(), 0, count * sizeof(*d)); 1570 if (!d) 1571 { 1572 ERR("Failed to allocate signature memory.\n"); 1573 return E_OUTOFMEMORY; 1574 } 1575 1576 /* 2 DWORDs for the header, element_size for each element. */ 1577 string_data_offset = 2 * sizeof(DWORD) + count * element_size * sizeof(DWORD); 1578 string_data_size = section->data_size - string_data_offset; 1579 1580 string_data = HeapAlloc(GetProcessHeap(), 0, string_data_size); 1581 if (!string_data) 1582 { 1583 ERR("Failed to allocate string data memory.\n"); 1584 HeapFree(GetProcessHeap(), 0, d); 1585 return E_OUTOFMEMORY; 1586 } 1587 memcpy(string_data, section->data + string_data_offset, string_data_size); 1588 1589 for (i = 0; i < count; ++i) 1590 { 1591 UINT name_offset; 1592 DWORD mask; 1593 1594 if (element_size == D3DCOMPILER_SIGNATURE_ELEMENT_SIZE7) 1595 { 1596 read_dword(&ptr, &d[i].Stream); 1597 } 1598 else 1599 { 1600 d[i].Stream = 0; 1601 } 1602 1603 read_dword(&ptr, &name_offset); 1604 d[i].SemanticName = string_data + (name_offset - string_data_offset); 1605 read_dword(&ptr, &d[i].SemanticIndex); 1606 read_dword(&ptr, &d[i].SystemValueType); 1607 read_dword(&ptr, &d[i].ComponentType); 1608 read_dword(&ptr, &d[i].Register); 1609 read_dword(&ptr, &mask); 1610 d[i].ReadWriteMask = (mask >> 8) & 0xff; 1611 d[i].Mask = mask & 0xff; 1612 1613 /* pixel shaders have a special handling for SystemValueType in the output signature */ 1614 if (((target & D3DCOMPILER_SHADER_TARGET_SHADERTYPE_MASK) == 0xffff0000) && (section->tag == TAG_OSG5 || section->tag == TAG_OSGN)) 1615 { 1616 TRACE("Pixelshader output signature fixup.\n"); 1617 1618 if (d[i].Register == 0xffffffff) 1619 { 1620 if (!strcasecmp(d[i].SemanticName, "sv_depth")) d[i].SystemValueType = D3D_NAME_DEPTH; 1621 if (!strcasecmp(d[i].SemanticName, "sv_coverage")) d[i].SystemValueType = D3D_NAME_COVERAGE; 1622 if (!strcasecmp(d[i].SemanticName, "sv_depthgreaterequal")) d[i].SystemValueType = D3D_NAME_DEPTH_GREATER_EQUAL; 1623 if (!strcasecmp(d[i].SemanticName, "sv_depthlessequal")) d[i].SystemValueType = D3D_NAME_DEPTH_LESS_EQUAL; 1624 } 1625 else 1626 { 1627 d[i].SystemValueType = D3D_NAME_TARGET; 1628 } 1629 } 1630 1631 TRACE("semantic: %s, semantic idx: %u, sysval_semantic %#x, " 1632 "type %u, register idx: %u, use_mask %#x, input_mask %#x, stream %u\n", 1633 debugstr_a(d[i].SemanticName), d[i].SemanticIndex, d[i].SystemValueType, 1634 d[i].ComponentType, d[i].Register, d[i].Mask, d[i].ReadWriteMask, d[i].Stream); 1635 } 1636 1637 s->elements = d; 1638 s->element_count = count; 1639 s->string_data = string_data; 1640 1641 return S_OK; 1642 } 1643 1644 static HRESULT d3dcompiler_parse_shdr(struct d3dcompiler_shader_reflection *r, const char *data, DWORD data_size) 1645 { 1646 const char *ptr = data; 1647 1648 read_dword(&ptr, &r->version); 1649 TRACE("Shader version: %u\n", r->version); 1650 1651 /* todo: Check if anything else is needed from the shdr or shex blob. */ 1652 1653 return S_OK; 1654 } 1655 1656 static HRESULT d3dcompiler_shader_reflection_init(struct d3dcompiler_shader_reflection *reflection, 1657 const void *data, SIZE_T data_size) 1658 { 1659 struct dxbc src_dxbc; 1660 HRESULT hr; 1661 unsigned int i; 1662 1663 reflection->ID3D11ShaderReflection_iface.lpVtbl = &d3dcompiler_shader_reflection_vtbl; 1664 reflection->refcount = 1; 1665 1666 wine_rb_init(&reflection->types, d3dcompiler_shader_reflection_type_compare); 1667 1668 hr = dxbc_parse(data, data_size, &src_dxbc); 1669 if (FAILED(hr)) 1670 { 1671 WARN("Failed to parse reflection\n"); 1672 return hr; 1673 } 1674 1675 for (i = 0; i < src_dxbc.count; ++i) 1676 { 1677 struct dxbc_section *section = &src_dxbc.sections[i]; 1678 1679 switch (section->tag) 1680 { 1681 case TAG_RDEF: 1682 hr = d3dcompiler_parse_rdef(reflection, section->data, section->data_size); 1683 if (FAILED(hr)) 1684 { 1685 WARN("Failed to parse RDEF section.\n"); 1686 goto err_out; 1687 } 1688 break; 1689 1690 case TAG_ISGN: 1691 reflection->isgn = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*reflection->isgn)); 1692 if (!reflection->isgn) 1693 { 1694 ERR("Failed to allocate ISGN memory.\n"); 1695 hr = E_OUTOFMEMORY; 1696 goto err_out; 1697 } 1698 1699 hr = d3dcompiler_parse_signature(reflection->isgn, section, reflection->target); 1700 if (FAILED(hr)) 1701 { 1702 WARN("Failed to parse section ISGN.\n"); 1703 goto err_out; 1704 } 1705 break; 1706 1707 case TAG_OSG5: 1708 case TAG_OSGN: 1709 reflection->osgn = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*reflection->osgn)); 1710 if (!reflection->osgn) 1711 { 1712 ERR("Failed to allocate OSGN memory.\n"); 1713 hr = E_OUTOFMEMORY; 1714 goto err_out; 1715 } 1716 1717 hr = d3dcompiler_parse_signature(reflection->osgn, section, reflection->target); 1718 if (FAILED(hr)) 1719 { 1720 WARN("Failed to parse section OSGN.\n"); 1721 goto err_out; 1722 } 1723 break; 1724 1725 case TAG_PCSG: 1726 reflection->pcsg = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*reflection->pcsg)); 1727 if (!reflection->pcsg) 1728 { 1729 ERR("Failed to allocate PCSG memory.\n"); 1730 hr = E_OUTOFMEMORY; 1731 goto err_out; 1732 } 1733 1734 hr = d3dcompiler_parse_signature(reflection->pcsg, section, reflection->target); 1735 if (FAILED(hr)) 1736 { 1737 WARN("Failed to parse section PCSG.\n"); 1738 goto err_out; 1739 } 1740 break; 1741 1742 case TAG_SHEX: 1743 case TAG_SHDR: 1744 hr = d3dcompiler_parse_shdr(reflection, section->data, section->data_size); 1745 if (FAILED(hr)) 1746 { 1747 WARN("Failed to parse SHDR section.\n"); 1748 goto err_out; 1749 } 1750 break; 1751 1752 case TAG_STAT: 1753 hr = d3dcompiler_parse_stat(reflection, section->data, section->data_size); 1754 if (FAILED(hr)) 1755 { 1756 WARN("Failed to parse section STAT.\n"); 1757 goto err_out; 1758 } 1759 break; 1760 1761 default: 1762 FIXME("Unhandled section %s!\n", debugstr_an((const char *)§ion->tag, 4)); 1763 break; 1764 } 1765 } 1766 1767 dxbc_destroy(&src_dxbc); 1768 1769 return hr; 1770 1771 err_out: 1772 reflection_cleanup(reflection); 1773 dxbc_destroy(&src_dxbc); 1774 1775 return hr; 1776 } 1777 1778 HRESULT WINAPI D3DReflect(const void *data, SIZE_T data_size, REFIID riid, void **reflector) 1779 { 1780 struct d3dcompiler_shader_reflection *object; 1781 HRESULT hr; 1782 const DWORD *temp = data; 1783 1784 TRACE("data %p, data_size %lu, riid %s, blob %p\n", data, data_size, debugstr_guid(riid), reflector); 1785 1786 if (!data || data_size < 32) 1787 { 1788 WARN("Invalid argument supplied.\n"); 1789 return D3DERR_INVALIDCALL; 1790 } 1791 1792 if (temp[6] != data_size) 1793 { 1794 WARN("Wrong size supplied.\n"); 1795 return E_FAIL; 1796 } 1797 1798 if (!IsEqualGUID(riid, &IID_ID3D11ShaderReflection)) 1799 { 1800 WARN("Wrong riid %s, accept only %s!\n", debugstr_guid(riid), debugstr_guid(&IID_ID3D11ShaderReflection)); 1801 return E_NOINTERFACE; 1802 } 1803 1804 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)); 1805 if (!object) 1806 return E_OUTOFMEMORY; 1807 1808 hr = d3dcompiler_shader_reflection_init(object, data, data_size); 1809 if (FAILED(hr)) 1810 { 1811 WARN("Failed to initialize shader reflection\n"); 1812 HeapFree(GetProcessHeap(), 0, object); 1813 return hr; 1814 } 1815 1816 *reflector = object; 1817 1818 TRACE("Created ID3D11ShaderReflection %p\n", object); 1819 1820 return S_OK; 1821 } 1822