D3D11VertexDeclaration.cpp 3.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. // Copyright (c) 2008-2023 the Urho3D project
  2. // License: MIT
  3. #include "../../Precompiled.h"
  4. #include "../../Graphics/Graphics.h"
  5. #include "../../GraphicsAPI/Direct3D11/D3D11GraphicsImpl.h"
  6. #include "../../GraphicsAPI/ShaderVariation.h"
  7. #include "../../GraphicsAPI/VertexBuffer.h"
  8. #include "../../IO/Log.h"
  9. #include "D3D11VertexDeclaration.h"
  10. #include "../../DebugNew.h"
  11. namespace Urho3D
  12. {
  13. static const DXGI_FORMAT d3dElementFormats[] =
  14. {
  15. DXGI_FORMAT_R32_SINT,
  16. DXGI_FORMAT_R32_FLOAT,
  17. DXGI_FORMAT_R32G32_FLOAT,
  18. DXGI_FORMAT_R32G32B32_FLOAT,
  19. DXGI_FORMAT_R32G32B32A32_FLOAT,
  20. DXGI_FORMAT_R8G8B8A8_UINT,
  21. DXGI_FORMAT_R8G8B8A8_UNORM
  22. };
  23. VertexDeclaration_D3D11::VertexDeclaration_D3D11(Graphics* graphics, ShaderVariation* vertexShader, VertexBuffer** vertexBuffers) :
  24. inputLayout_(nullptr)
  25. {
  26. Vector<D3D11_INPUT_ELEMENT_DESC> elementDescs;
  27. i32 prevBufferDescs = 0;
  28. for (i32 i = 0; i < MAX_VERTEX_STREAMS; ++i)
  29. {
  30. if (!vertexBuffers[i])
  31. continue;
  32. const Vector<VertexElement>& srcElements = vertexBuffers[i]->GetElements();
  33. bool isExisting = false;
  34. for (const VertexElement& srcElement : srcElements)
  35. {
  36. const char* semanticName = ShaderVariation::elementSemanticNames_D3D11[srcElement.semantic_];
  37. // Override existing element if necessary
  38. for (i32 k = 0; k < prevBufferDescs; ++k)
  39. {
  40. if (elementDescs[k].SemanticName == semanticName && elementDescs[k].SemanticIndex == srcElement.index_)
  41. {
  42. isExisting = true;
  43. elementDescs[k].InputSlot = (UINT)i;
  44. elementDescs[k].AlignedByteOffset = (UINT)srcElement.offset_;
  45. elementDescs[k].InputSlotClass = srcElement.perInstance_ ? D3D11_INPUT_PER_INSTANCE_DATA : D3D11_INPUT_PER_VERTEX_DATA;
  46. elementDescs[k].InstanceDataStepRate = srcElement.perInstance_ ? 1 : 0;
  47. break;
  48. }
  49. }
  50. if (isExisting)
  51. continue;
  52. D3D11_INPUT_ELEMENT_DESC newDesc;
  53. newDesc.SemanticName = semanticName;
  54. newDesc.SemanticIndex = srcElement.index_;
  55. newDesc.Format = d3dElementFormats[srcElement.type_];
  56. newDesc.InputSlot = (UINT)i;
  57. newDesc.AlignedByteOffset = (UINT)srcElement.offset_;
  58. newDesc.InputSlotClass = srcElement.perInstance_ ? D3D11_INPUT_PER_INSTANCE_DATA : D3D11_INPUT_PER_VERTEX_DATA;
  59. newDesc.InstanceDataStepRate = srcElement.perInstance_ ? 1 : 0;
  60. elementDescs.Push(newDesc);
  61. }
  62. prevBufferDescs = elementDescs.Size();
  63. }
  64. if (elementDescs.Empty())
  65. return;
  66. const Vector<u8>& byteCode = vertexShader->GetByteCode();
  67. HRESULT hr = graphics->GetImpl_D3D11()->GetDevice()->CreateInputLayout(&elementDescs[0], (UINT)elementDescs.Size(), &byteCode[0],
  68. (SIZE_T)byteCode.Size(), (ID3D11InputLayout**)&inputLayout_);
  69. if (FAILED(hr))
  70. {
  71. URHO3D_SAFE_RELEASE(inputLayout_);
  72. URHO3D_LOGERRORF("Failed to create input layout for shader %s due to missing vertex element(s) (HRESULT %x)",
  73. vertexShader->GetFullName().CString(), (unsigned)hr);
  74. }
  75. }
  76. VertexDeclaration_D3D11::~VertexDeclaration_D3D11()
  77. {
  78. URHO3D_SAFE_RELEASE(inputLayout_);
  79. }
  80. }