diff --git a/engine/CMakeLists.txt b/engine/CMakeLists.txt index 67d19379..2bd688e8 100644 --- a/engine/CMakeLists.txt +++ b/engine/CMakeLists.txt @@ -92,6 +92,7 @@ add_library(XCEngine STATIC include/XCEngine/RHI/D3D12/D3D12Buffer.h include/XCEngine/RHI/D3D12/D3D12PipelineState.h include/XCEngine/RHI/D3D12/D3D12Sampler.h + include/XCEngine/RHI/D3D12/D3D12Shader.h include/XCEngine/RHI/D3D12/D3D12Texture.h include/XCEngine/RHI/D3D12/D3D12RootSignature.h include/XCEngine/RHI/D3D12/D3D12SwapChain.h @@ -105,6 +106,7 @@ add_library(XCEngine STATIC src/RHI/D3D12Buffer.cpp src/RHI/D3D12PipelineState.cpp src/RHI/D3D12Sampler.cpp + src/RHI/D3D12Shader.cpp src/RHI/D3D12Texture.cpp src/RHI/D3D12RootSignature.cpp src/RHI/D3D12SwapChain.cpp diff --git a/engine/include/XCEngine/RHI/D3D12/D3D12Shader.h b/engine/include/XCEngine/RHI/D3D12/D3D12Shader.h new file mode 100644 index 00000000..733f2211 --- /dev/null +++ b/engine/include/XCEngine/RHI/D3D12/D3D12Shader.h @@ -0,0 +1,33 @@ +#pragma once + +#include +#include +#include + +#include "D3D12Enum.h" + +using Microsoft::WRL::ComPtr; + +namespace XCEngine { +namespace RHI { + +class D3D12Shader { +public: + D3D12Shader(); + ~D3D12Shader(); + + bool CompileFromFile(const wchar_t* filePath, const char* entryPoint, const char* target); + bool Compile(const void* sourceData, size_t sourceSize, const char* entryPoint, const char* target); + void Shutdown(); + + const D3D12_SHADER_BYTECODE GetBytecode() const; + ShaderType GetType() const { return m_type; } + +private: + ComPtr m_bytecode; + ComPtr m_error; + ShaderType m_type; +}; + +} // namespace RHI +} // namespace XCEngine diff --git a/engine/src/RHI/D3D12Shader.cpp b/engine/src/RHI/D3D12Shader.cpp new file mode 100644 index 00000000..1ff2dcff --- /dev/null +++ b/engine/src/RHI/D3D12Shader.cpp @@ -0,0 +1,70 @@ +#include "XCEngine/RHI/D3D12/D3D12Shader.h" +#include + +namespace XCEngine { +namespace RHI { + +D3D12Shader::D3D12Shader() + : m_type(ShaderType::Vertex) { +} + +D3D12Shader::~D3D12Shader() { + Shutdown(); +} + +bool D3D12Shader::CompileFromFile(const wchar_t* filePath, const char* entryPoint, const char* target) { + HRESULT hResult = D3DCompileFromFile(filePath, nullptr, nullptr, entryPoint, target, + D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION, 0, &m_bytecode, &m_error); + + if (FAILED(hResult)) { + if (m_error) { + const char* errorMsg = static_cast(m_error->GetBufferPointer()); + OutputDebugStringA(errorMsg); + } + return false; + } + + if (strstr(target, "vs_")) { + m_type = ShaderType::Vertex; + } else if (strstr(target, "ps_")) { + m_type = ShaderType::Pixel; + } else if (strstr(target, "gs_")) { + m_type = ShaderType::Geometry; + } else if (strstr(target, "cs_")) { + m_type = ShaderType::Compute; + } + + return true; +} + +bool D3D12Shader::Compile(const void* sourceData, size_t sourceSize, const char* entryPoint, const char* target) { + HRESULT hResult = D3DCompile(sourceData, sourceSize, nullptr, nullptr, nullptr, entryPoint, target, + D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION, 0, &m_bytecode, &m_error); + + if (FAILED(hResult)) { + if (m_error) { + const char* errorMsg = static_cast(m_error->GetBufferPointer()); + OutputDebugStringA(errorMsg); + } + return false; + } + + return true; +} + +void D3D12Shader::Shutdown() { + m_bytecode.Reset(); + m_error.Reset(); +} + +const D3D12_SHADER_BYTECODE D3D12Shader::GetBytecode() const { + D3D12_SHADER_BYTECODE bytecode = {}; + if (m_bytecode) { + bytecode.pShaderBytecode = m_bytecode->GetBufferPointer(); + bytecode.BytecodeLength = m_bytecode->GetBufferSize(); + } + return bytecode; +} + +} // namespace RHI +} // namespace XCEngine