// Copyright (c) Wojciech Figat. All rights reserved. #pragma once #if GRAPHICS_API_DIRECTX12 #include "Engine/Graphics/GPUPipelineState.h" #include "GPUDeviceDX12.h" #include "Types.h" #include "Engine/Core/Collections/Dictionary.h" #include "../IncludeDirectXHeaders.h" #ifdef __ID3D12Device2_FWD_DEFINED__ #define GPU_D3D12_PSO_STREAM 1 #else #define GPU_D3D12_PSO_STREAM 0 #endif class GPUTextureViewDX12; class GPUVertexLayoutDX12; struct GPUPipelineStateKeyDX12 { int32 RTsCount; MSAALevel MSAA; GPUVertexLayout* VertexLayout; PixelFormat DepthFormat; PixelFormat RTVsFormats[GPU_MAX_RT_BINDED]; bool operator==(const GPUPipelineStateKeyDX12& other) const { return Platform::MemoryCompare((void*)this, &other, sizeof(GPUPipelineStateKeyDX12)) == 0; } friend inline uint32 GetHash(const GPUPipelineStateKeyDX12& key) { uint32 hash = (int32)key.MSAA * 11; CombineHash(hash, (uint32)key.DepthFormat * 93473262); CombineHash(hash, key.RTsCount * 136); CombineHash(hash, GetHash(key.VertexLayout)); CombineHash(hash, (uint32)key.RTVsFormats[0]); CombineHash(hash, (uint32)key.RTVsFormats[1]); CombineHash(hash, (uint32)key.RTVsFormats[2]); CombineHash(hash, (uint32)key.RTVsFormats[3]); CombineHash(hash, (uint32)key.RTVsFormats[4]); CombineHash(hash, (uint32)key.RTVsFormats[5]); static_assert(GPU_MAX_RT_BINDED == 6, "Update hash combine code to match RT count (manually inlined loop)."); return hash; } }; /// /// Graphics pipeline state object for DirectX 12 backend. /// class GPUPipelineStateDX12 : public GPUResourceDX12 { private: Dictionary _states; //GraphicsPipelineStateStreamDX12 _desc; #if GPU_D3D12_PSO_STREAM D3D12_DEPTH_STENCIL_DESC1 _depthStencil; #else D3D12_DEPTH_STENCIL_DESC _depthStencil; #endif D3D12_RASTERIZER_DESC _rasterizer; D3D12_BLEND_DESC _blend; D3D12_PRIMITIVE_TOPOLOGY_TYPE _primitiveTopology; #if GPU_ALLOW_TESSELLATION_SHADERS D3D12_SHADER_BYTECODE _shaderHS, _shaderDS; #endif #if GPU_ALLOW_GEOMETRY_SHADERS D3D12_SHADER_BYTECODE _shaderGS; #endif D3D12_SHADER_BYTECODE _shaderVS, _shaderPS; public: GPUPipelineStateDX12(GPUDeviceDX12* device); public: D3D_PRIMITIVE_TOPOLOGY PrimitiveTopology = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED; DxShaderHeader Header; GPUVertexLayoutDX12* VertexBufferLayout = nullptr; GPUVertexLayoutDX12* VertexInputLayout = nullptr; /// /// Gets DirectX 12 graphics pipeline state object for the given rendering state. Uses depth buffer and render targets formats and multi-sample levels to setup a proper PSO. Uses caching. /// /// The depth buffer (can be null). /// The render targets count (can be 0). /// The render target handles array. /// The vertex buffers layout. /// DirectX 12 graphics pipeline state object ID3D12PipelineState* GetState(GPUTextureViewDX12* depth, int32 rtCount, GPUTextureViewDX12** rtHandles, GPUVertexLayoutDX12* vertexLayout); public: // [GPUPipelineState] bool IsValid() const override; bool Init(const Description& desc) override; protected: // [GPUResourceDX12] void OnReleaseGPU() override; }; #endif