// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved. #pragma once #if GRAPHICS_API_DIRECTX12 #include "GPUDeviceDX12.h" #include "Engine/Graphics/Shaders/GPUShaderProgram.h" #include "Types.h" #include "../IncludeDirectXHeaders.h" /// /// Shaders base class for DirectX 12 backend. /// template class GPUShaderProgramDX12 : public BaseType { protected: Array _data; public: GPUShaderProgramDX12(const GPUShaderProgramInitializer& initializer, DxShaderHeader* header, byte* cacheBytes, uint32 cacheSize) : Header(*header) { BaseType::Init(initializer); _data.Set(cacheBytes, cacheSize); } public: DxShaderHeader Header; public: // [BaseType] void* GetBufferHandle() const override { return (void*)_data.Get(); } uint32 GetBufferSize() const override { return _data.Count(); } }; /// /// Vertex Shader for DirectX 12 backend. /// class GPUShaderProgramVSDX12 : public GPUShaderProgramDX12 { private: byte _inputLayoutSize; D3D12_INPUT_ELEMENT_DESC _inputLayout[VERTEX_SHADER_MAX_INPUT_ELEMENTS]; public: GPUShaderProgramVSDX12(const GPUShaderProgramInitializer& initializer, DxShaderHeader* header, byte* cacheBytes, uint32 cacheSize, D3D12_INPUT_ELEMENT_DESC* inputLayout, byte inputLayoutSize) : GPUShaderProgramDX12(initializer, header, cacheBytes, cacheSize) , _inputLayoutSize(inputLayoutSize) { for (byte i = 0; i < inputLayoutSize; i++) _inputLayout[i] = inputLayout[i]; } public: // [GPUShaderProgramDX12] void* GetInputLayout() const override { return (void*)_inputLayout; } byte GetInputLayoutSize() const override { return _inputLayoutSize; } }; #if GPU_ALLOW_TESSELLATION_SHADERS /// /// Hull Shader for DirectX 12 backend. /// class GPUShaderProgramHSDX12 : public GPUShaderProgramDX12 { public: GPUShaderProgramHSDX12(const GPUShaderProgramInitializer& initializer, DxShaderHeader* header, byte* cacheBytes, uint32 cacheSize, int32 controlPointsCount) : GPUShaderProgramDX12(initializer, header, cacheBytes, cacheSize) { _controlPointsCount = controlPointsCount; } }; /// /// Domain Shader for DirectX 12 backend. /// class GPUShaderProgramDSDX12 : public GPUShaderProgramDX12 { public: GPUShaderProgramDSDX12(const GPUShaderProgramInitializer& initializer, DxShaderHeader* header, byte* cacheBytes, uint32 cacheSize) : GPUShaderProgramDX12(initializer, header, cacheBytes, cacheSize) { } }; #endif #if GPU_ALLOW_GEOMETRY_SHADERS /// /// Geometry Shader for DirectX 12 backend. /// class GPUShaderProgramGSDX12 : public GPUShaderProgramDX12 { public: GPUShaderProgramGSDX12(const GPUShaderProgramInitializer& initializer, DxShaderHeader* header, byte* cacheBytes, uint32 cacheSize) : GPUShaderProgramDX12(initializer, header, cacheBytes, cacheSize) { } }; #endif /// /// Pixel Shader for DirectX 12 backend. /// class GPUShaderProgramPSDX12 : public GPUShaderProgramDX12 { public: GPUShaderProgramPSDX12(const GPUShaderProgramInitializer& initializer, DxShaderHeader* header, byte* cacheBytes, uint32 cacheSize) : GPUShaderProgramDX12(initializer, header, cacheBytes, cacheSize) { } }; /// /// Compute Shader for DirectX 12 backend. /// class GPUShaderProgramCSDX12 : public GPUShaderProgramDX12 { private: GPUDeviceDX12* _device; Array _data; ID3D12PipelineState* _state; public: GPUShaderProgramCSDX12(GPUDeviceDX12* device, const GPUShaderProgramInitializer& initializer, DxShaderHeader* header, byte* cacheBytes, uint32 cacheSize) : GPUShaderProgramDX12(initializer, header, cacheBytes, cacheSize) , _device(device) , _state(nullptr) { } ~GPUShaderProgramCSDX12() { _device->AddResourceToLateRelease(_state); } public: /// /// Gets DirectX 12 compute pipeline state object /// FORCE_INLINE ID3D12PipelineState* GetState() const { return _state; } /// /// Gets or creates compute pipeline state for that compute shader. /// ID3D12PipelineState* GetOrCreateState(); }; #endif