PipelineStateDX12.cpp 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. // Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
  2. // SPDX-FileCopyrightText: 2024 Jorrit Rouwe
  3. // SPDX-License-Identifier: MIT
  4. #include <TestFramework.h>
  5. #include <Renderer/DX12/PipelineStateDX12.h>
  6. #include <Renderer/DX12/RendererDX12.h>
  7. #include <Renderer/DX12/VertexShaderDX12.h>
  8. #include <Renderer/DX12/PixelShaderDX12.h>
  9. #include <Renderer/DX12/FatalErrorIfFailedDX12.h>
  10. PipelineStateDX12::PipelineStateDX12(RendererDX12 *inRenderer, const VertexShaderDX12 *inVertexShader, const EInputDescription *inInputDescription, uint inInputDescriptionCount, const PixelShaderDX12 *inPixelShader, EDrawPass inDrawPass, EFillMode inFillMode, ETopology inTopology, EDepthTest inDepthTest, EBlendMode inBlendMode, ECullMode inCullMode) :
  11. mRenderer(inRenderer)
  12. {
  13. D3D12_PRIMITIVE_TOPOLOGY_TYPE topology = inTopology == ETopology::Triangle? D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE : D3D12_PRIMITIVE_TOPOLOGY_TYPE_LINE;
  14. Array<D3D12_INPUT_ELEMENT_DESC> input_description;
  15. uint vertex_offset = 0, instance_offset = 0;
  16. for (uint i = 0; i < inInputDescriptionCount; ++i)
  17. switch (inInputDescription[i])
  18. {
  19. case EInputDescription::Position:
  20. input_description.push_back({ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, vertex_offset, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 });
  21. vertex_offset += 3 * sizeof(float);
  22. break;
  23. case EInputDescription::Color:
  24. input_description.push_back({ "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, vertex_offset, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 });
  25. vertex_offset += 4 * sizeof(uint8);
  26. break;
  27. case EInputDescription::Normal:
  28. input_description.push_back({ "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, vertex_offset, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 });
  29. vertex_offset += 3 * sizeof(float);
  30. break;
  31. case EInputDescription::TexCoord:
  32. input_description.push_back({ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, vertex_offset, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 });
  33. vertex_offset += 2 * sizeof(float);
  34. break;
  35. case EInputDescription::InstanceColor:
  36. input_description.push_back({ "INSTANCE_COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 1, instance_offset, D3D12_INPUT_CLASSIFICATION_PER_INSTANCE_DATA, 1 });
  37. instance_offset += 4 * sizeof(uint8);
  38. break;
  39. case EInputDescription::InstanceTransform:
  40. {
  41. for (uint j = 0; j < 4; ++j)
  42. {
  43. input_description.push_back({ "INSTANCE_TRANSFORM", j, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, instance_offset, D3D12_INPUT_CLASSIFICATION_PER_INSTANCE_DATA, 1 });
  44. instance_offset += 4 * sizeof(float);
  45. }
  46. break;
  47. }
  48. case EInputDescription::InstanceInvTransform:
  49. {
  50. for (uint j = 0; j < 4; ++j)
  51. {
  52. input_description.push_back({ "INSTANCE_INV_TRANSFORM", j, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, instance_offset, D3D12_INPUT_CLASSIFICATION_PER_INSTANCE_DATA, 1 });
  53. instance_offset += 4 * sizeof(float);
  54. }
  55. break;
  56. }
  57. }
  58. D3D12_GRAPHICS_PIPELINE_STATE_DESC pso_desc = {};
  59. pso_desc.InputLayout = { input_description.data(), (UINT)input_description.size() };
  60. pso_desc.pRootSignature = mRenderer->GetRootSignature();
  61. pso_desc.VS = { inVertexShader->mShader->GetBufferPointer(), inVertexShader->mShader->GetBufferSize() };
  62. pso_desc.PS = { inPixelShader->mShader->GetBufferPointer(), inPixelShader->mShader->GetBufferSize() };
  63. pso_desc.RasterizerState.FillMode = inFillMode == EFillMode::Solid? D3D12_FILL_MODE_SOLID : D3D12_FILL_MODE_WIREFRAME;
  64. pso_desc.RasterizerState.CullMode = inCullMode == ECullMode::Backface? D3D12_CULL_MODE_FRONT : D3D12_CULL_MODE_BACK; // DX uses left handed system so we reverse the options
  65. pso_desc.RasterizerState.FrontCounterClockwise = FALSE;
  66. pso_desc.RasterizerState.DepthBias = D3D12_DEFAULT_DEPTH_BIAS;
  67. pso_desc.RasterizerState.DepthBiasClamp = D3D12_DEFAULT_DEPTH_BIAS_CLAMP;
  68. pso_desc.RasterizerState.SlopeScaledDepthBias = D3D12_DEFAULT_SLOPE_SCALED_DEPTH_BIAS;
  69. pso_desc.RasterizerState.DepthClipEnable = TRUE;
  70. pso_desc.RasterizerState.MultisampleEnable = FALSE;
  71. pso_desc.RasterizerState.AntialiasedLineEnable = FALSE;
  72. pso_desc.RasterizerState.ForcedSampleCount = 0;
  73. pso_desc.RasterizerState.ConservativeRaster = D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF;
  74. pso_desc.BlendState.AlphaToCoverageEnable = FALSE;
  75. pso_desc.BlendState.IndependentBlendEnable = FALSE;
  76. D3D12_RENDER_TARGET_BLEND_DESC &blend_desc = pso_desc.BlendState.RenderTarget[0];
  77. blend_desc.LogicOpEnable = FALSE;
  78. blend_desc.LogicOp = D3D12_LOGIC_OP_NOOP;
  79. blend_desc.RenderTargetWriteMask = D3D12_COLOR_WRITE_ENABLE_ALL;
  80. switch (inBlendMode)
  81. {
  82. case EBlendMode::Write:
  83. blend_desc.BlendEnable = FALSE;
  84. break;
  85. case EBlendMode::AlphaBlend:
  86. blend_desc.BlendEnable = TRUE;
  87. blend_desc.SrcBlend = D3D12_BLEND_SRC_ALPHA;
  88. blend_desc.DestBlend = D3D12_BLEND_INV_SRC_ALPHA;
  89. blend_desc.BlendOp = D3D12_BLEND_OP_ADD;
  90. blend_desc.SrcBlendAlpha = D3D12_BLEND_ZERO;
  91. blend_desc.DestBlendAlpha = D3D12_BLEND_ZERO;
  92. blend_desc.BlendOpAlpha = D3D12_BLEND_OP_ADD;
  93. break;
  94. }
  95. pso_desc.DepthStencilState.DepthEnable = inDepthTest == EDepthTest::On? TRUE : FALSE;
  96. pso_desc.DepthStencilState.DepthWriteMask = inDepthTest == EDepthTest::On? D3D12_DEPTH_WRITE_MASK_ALL : D3D12_DEPTH_WRITE_MASK_ZERO;
  97. pso_desc.DepthStencilState.DepthFunc = D3D12_COMPARISON_FUNC_GREATER;
  98. pso_desc.DepthStencilState.StencilEnable = FALSE;
  99. pso_desc.SampleMask = UINT_MAX;
  100. pso_desc.PrimitiveTopologyType = topology;
  101. pso_desc.NumRenderTargets = 1;
  102. pso_desc.RTVFormats[0] = DXGI_FORMAT_R8G8B8A8_UNORM;
  103. pso_desc.DSVFormat = DXGI_FORMAT_D32_FLOAT;
  104. pso_desc.SampleDesc.Count = 1;
  105. FatalErrorIfFailed(mRenderer->GetDevice()->CreateGraphicsPipelineState(&pso_desc, IID_PPV_ARGS(&mPSO)));
  106. }
  107. PipelineStateDX12::~PipelineStateDX12()
  108. {
  109. if (mPSO != nullptr)
  110. mRenderer->RecycleD3DObject(mPSO.Get());
  111. }
  112. void PipelineStateDX12::Activate()
  113. {
  114. mRenderer->GetCommandList()->SetPipelineState(mPSO.Get());
  115. }