Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions Engine/common_dx/include/DXMipmapGenerator.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
//Author: JEYOON YU
//Project: CubeEngine
//File: DXMipmapGenerator.hpp
#pragma once
#define NOMINMAX
#include <d3dx12/d3dx12.h>
#include <wrl.h>

using Microsoft::WRL::ComPtr;

class DXMipmapGenerator
{
public:
DXMipmapGenerator(const ComPtr<ID3D12Device>& device);
~DXMipmapGenerator() = default;

DXMipmapGenerator(const DXMipmapGenerator&) = delete;
DXMipmapGenerator& operator=(const DXMipmapGenerator&) = delete;
DXMipmapGenerator(const DXMipmapGenerator&&) = delete;
DXMipmapGenerator& operator=(const DXMipmapGenerator&&) = delete;

void Generate(const ComPtr<ID3D12Device>& device, const ComPtr<ID3D12GraphicsCommandList>& commandList, const ComPtr<ID3D12Resource>& texture) const;
private:
ComPtr<ID3D12RootSignature> m_rootSignature;
ComPtr<ID3D12PipelineState> m_pipelineState;
ComPtr<ID3D12DescriptorHeap> m_descriptorHeap;
UINT m_descriptorSize;
};
2 changes: 2 additions & 0 deletions Engine/common_dx/include/DXSkybox.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

#include "DXVertexBuffer.hpp"
#include "DXPipeLine.hpp"
#include "DXMipmapGenerator.hpp"

#include <filesystem>
#include <functional>
Expand Down Expand Up @@ -79,6 +80,7 @@ class DXSkybox

ComPtr<ID3D12Device> m_device;
ComPtr<ID3D12CommandQueue> m_commandQueue;
std::unique_ptr<DXMipmapGenerator> m_mipmapGenerator;

ComPtr<ID3D12CommandAllocator> m_commandAllocator;
ComPtr<ID3D12GraphicsCommandList> m_commandList;
Expand Down
137 changes: 137 additions & 0 deletions Engine/common_dx/source/DXMipmapGenerator.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
//Author: JEYOON YU
//Project: CubeEngine
//File: DXMipmapGenerator.cpp
#include "DXMipmapGenerator.hpp"

#include <stdexcept>
#include <algorithm>
#include <vector>
#include <d3dcompiler.h>

DXMipmapGenerator::DXMipmapGenerator(const ComPtr<ID3D12Device>& device)
{
// Create root signature
CD3DX12_DESCRIPTOR_RANGE1 srvRange(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 1, 0, 0, D3D12_DESCRIPTOR_RANGE_FLAG_DATA_VOLATILE);
CD3DX12_DESCRIPTOR_RANGE1 uavRange(D3D12_DESCRIPTOR_RANGE_TYPE_UAV, 1, 0, 0, D3D12_DESCRIPTOR_RANGE_FLAG_DATA_VOLATILE);

CD3DX12_ROOT_PARAMETER1 rootParameters[3];
rootParameters[0].InitAsConstants(2, 0);
rootParameters[1].InitAsDescriptorTable(1, &srvRange);
rootParameters[2].InitAsDescriptorTable(1, &uavRange);

D3D12_STATIC_SAMPLER_DESC sampler = {};
sampler.Filter = D3D12_FILTER_MIN_MAG_MIP_LINEAR;
sampler.AddressU = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
sampler.AddressV = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
sampler.AddressW = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
sampler.MipLODBias = 0.0f;
sampler.MaxAnisotropy = 1;
sampler.ComparisonFunc = D3D12_COMPARISON_FUNC_ALWAYS;
sampler.MinLOD = 0.0f;
sampler.MaxLOD = D3D12_FLOAT32_MAX;
sampler.ShaderRegister = 0;
sampler.RegisterSpace = 0;
sampler.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;

CD3DX12_VERSIONED_ROOT_SIGNATURE_DESC rootSignatureDesc;
rootSignatureDesc.Init_1_1(_countof(rootParameters), rootParameters, 1, &sampler, D3D12_ROOT_SIGNATURE_FLAG_NONE);

ComPtr<ID3DBlob> signature, error;
if (FAILED(D3D12SerializeVersionedRootSignature(&rootSignatureDesc, &signature, &error)))
{
throw std::runtime_error("Failed to serialize mipmap root signature.\n" + std::string((char*)error->GetBufferPointer()));
}
device->CreateRootSignature(0, signature->GetBufferPointer(), signature->GetBufferSize(), IID_PPV_ARGS(&m_rootSignature));

// Compile compute shader
ComPtr<ID3DBlob> computeShader;
HRESULT hr = D3DCompileFromFile(L"../Engine/shaders/hlsl/MipmapGen.comp.hlsl", nullptr, D3D_COMPILE_STANDARD_FILE_INCLUDE, "computeMain", "cs_5_1", 0, 0, &computeShader, &error);
if (FAILED(hr)) throw std::runtime_error("Failed to compile MipmapGen compute shader.\n" + std::string(static_cast<char*>(error->GetBufferPointer())));

D3D12_COMPUTE_PIPELINE_STATE_DESC psoDesc = {};
psoDesc.pRootSignature = m_rootSignature.Get();
psoDesc.CS = CD3DX12_SHADER_BYTECODE(computeShader.Get());
device->CreateComputePipelineState(&psoDesc, IID_PPV_ARGS(&m_pipelineState));

// Create descriptor heap for SRV/UAV
D3D12_DESCRIPTOR_HEAP_DESC heapDesc = {};
heapDesc.NumDescriptors = 256;
heapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV;
heapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE;
device->CreateDescriptorHeap(&heapDesc, IID_PPV_ARGS(&m_descriptorHeap));
m_descriptorSize = device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
}

void DXMipmapGenerator::Generate(const ComPtr<ID3D12Device>& device, const ComPtr<ID3D12GraphicsCommandList>& commandList, const ComPtr<ID3D12Resource>& texture) const
{
D3D12_RESOURCE_DESC texDesc = texture->GetDesc();

if (texDesc.MipLevels <= 1 || !(texDesc.Flags & D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS)) return;

commandList->SetPipelineState(m_pipelineState.Get());
commandList->SetComputeRootSignature(m_rootSignature.Get());

ID3D12DescriptorHeap* ppHeaps[] = { m_descriptorHeap.Get() };
commandList->SetDescriptorHeaps(_countof(ppHeaps), ppHeaps);

CD3DX12_CPU_DESCRIPTOR_HANDLE cpuHandle(m_descriptorHeap->GetCPUDescriptorHandleForHeapStart());
CD3DX12_GPU_DESCRIPTOR_HANDLE gpuHandle(m_descriptorHeap->GetGPUDescriptorHandleForHeapStart());

for (uint32_t mip = 0; mip < texDesc.MipLevels - 1; ++mip)
{
uint32_t srcMip = mip;
uint32_t dstMip = mip + 1;

uint32_t dstWidth = std::max(1u, static_cast<uint32_t>(texDesc.Width >> dstMip));
uint32_t dstHeight = std::max(1u, static_cast<uint32_t>(texDesc.Height >> dstMip));

std::vector<D3D12_RESOURCE_BARRIER> barriers;
for (uint32_t arraySlice = 0; arraySlice < texDesc.DepthOrArraySize; ++arraySlice)
{
uint32_t dstSubresource = D3D12CalcSubresource(dstMip, arraySlice, 0, texDesc.MipLevels, texDesc.DepthOrArraySize);
barriers.push_back(CD3DX12_RESOURCE_BARRIER::Transition(texture.Get(), D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, D3D12_RESOURCE_STATE_UNORDERED_ACCESS, dstSubresource));
}
commandList->ResourceBarrier(static_cast<UINT>(barriers.size()), barriers.data());

// Create SRV for source mip level
D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = {};
srvDesc.Format = texDesc.Format;
srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2DARRAY;
srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
srvDesc.Texture2DArray.MostDetailedMip = srcMip;
srvDesc.Texture2DArray.MipLevels = 1;
srvDesc.Texture2DArray.FirstArraySlice = 0;
srvDesc.Texture2DArray.ArraySize = texDesc.DepthOrArraySize;

device->CreateShaderResourceView(texture.Get(), &srvDesc, cpuHandle);
commandList->SetComputeRootDescriptorTable(1, gpuHandle);
cpuHandle.Offset(1, m_descriptorSize);
gpuHandle.Offset(1, m_descriptorSize);

// Create UAV for destination mip level
D3D12_UNORDERED_ACCESS_VIEW_DESC uavDesc = {};
uavDesc.Format = texDesc.Format;
uavDesc.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE2DARRAY;
uavDesc.Texture2DArray.MipSlice = dstMip;
uavDesc.Texture2DArray.FirstArraySlice = 0;
uavDesc.Texture2DArray.ArraySize = texDesc.DepthOrArraySize;

device->CreateUnorderedAccessView(texture.Get(), nullptr, &uavDesc, cpuHandle);
commandList->SetComputeRootDescriptorTable(2, gpuHandle);
cpuHandle.Offset(1, m_descriptorSize);
gpuHandle.Offset(1, m_descriptorSize);

float texelSize[2] = { 1.0f / dstWidth, 1.0f / dstHeight };
commandList->SetComputeRoot32BitConstants(0, 2, texelSize, 0);

UINT dispatchX = (dstWidth + 7) / 8;
UINT dispatchY = (dstHeight + 7) / 8;
commandList->Dispatch(dispatchX, dispatchY, texDesc.DepthOrArraySize);

for (auto& b : barriers)
{
std::swap(b.Transition.StateBefore, b.Transition.StateAfter);
}
commandList->ResourceBarrier(static_cast<UINT>(barriers.size()), barriers.data());
}
}
14 changes: 11 additions & 3 deletions Engine/common_dx/source/DXSkybox.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ DXSkybox::DXSkybox(const ComPtr<ID3D12Device>& device,
m_srvDescriptorSize = m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);

m_skyboxVertexBuffer = std::make_unique<DXVertexBuffer>(m_device, m_commandQueue, static_cast<UINT>(sizeof(glm::vec3)), static_cast<UINT>(sizeof(glm::vec3) * m_skyboxVertices.size()), m_skyboxVertices.data());

m_mipmapGenerator = std::make_unique<DXMipmapGenerator>(m_device);
}

DXSkybox::~DXSkybox()
Expand Down Expand Up @@ -91,10 +93,11 @@ void DXSkybox::EquirectangularToCube()
texDesc.Width = static_cast<UINT64>(faceSize);
texDesc.Height = static_cast<UINT>(faceSize);
texDesc.DepthOrArraySize = 6;
texDesc.MipLevels = 1;
UINT16 maxMipLevels = static_cast<UINT16>(std::log2(faceSize)) + 1;
texDesc.MipLevels = maxMipLevels;
texDesc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
texDesc.SampleDesc.Count = 1;
texDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET;
texDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET | D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS;

D3D12_CLEAR_VALUE clearValue = {};
clearValue.Format = texDesc.Format;
Expand Down Expand Up @@ -213,13 +216,15 @@ void DXSkybox::EquirectangularToCube()
barrier = CD3DX12_RESOURCE_BARRIER::Transition(m_cubemap.Get(), D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
m_commandList->ResourceBarrier(1, &barrier);

m_mipmapGenerator->Generate(m_device, m_commandList, m_cubemap.Get());

ExecuteCommandList();

D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = {};
srvDesc.Format = texDesc.Format;
srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURECUBE;
srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
srvDesc.TextureCube.MipLevels = 1;
srvDesc.TextureCube.MipLevels = maxMipLevels;

// Store Cubemap texture in second array of m_srvDescriptorIndices offset
m_device->CreateShaderResourceView(m_cubemap.Get(), &srvDesc, m_srvHandles[1].first);
Expand Down Expand Up @@ -411,6 +416,9 @@ void DXSkybox::PrefilteredEnvironmentMap()
sampler.AddressU = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
sampler.AddressV = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
sampler.AddressW = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
// MinLOD and MaxLOD are set to allow sampling across all mip levels of the cubemap, which is essential for accurate prefiltering results
sampler.MinLOD = 0.0f;
sampler.MaxLOD = D3D12_FLOAT32_MAX;
sampler.ShaderRegister = 0;
sampler.RegisterSpace = 1;
sampler.ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;
Expand Down
2 changes: 1 addition & 1 deletion Engine/include/Interface/IComponent.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class IComponent

Object* GetOwner() const { return owner; }
void SetOwner(Object* owner_) { this->owner = owner_; }
ComponentTypes GetType() { return componentType; }
ComponentTypes GetType() const { return componentType; }

private:
Object* owner = nullptr;
Expand Down
101 changes: 101 additions & 0 deletions Engine/shaders/hlsl/MipmapGen.comp.hlsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
#pragma pack_matrix(column_major)
#ifdef SLANG_HLSL_ENABLE_NVAPI
#include "nvHLSLExtns.h"
#endif

#ifndef __DXC_VERSION_MAJOR
// warning X3557: loop doesn't seem to do anything, forcing loop to unroll
#pragma warning(disable : 3557)
#endif


#line 2 "slang/MipmapGen.slang"
RWTexture2DArray<float4 > dstTexture_0 : register(u0);


struct MipGenConstants_0
{
float2 texelSize_0;
};


#line 9
cbuffer cb_0 : register(b0)
{
MipGenConstants_0 cb_0;
}

#line 1
Texture2DArray<float4 > srcTexture_0 : register(t0);

SamplerState LinearClampSampler_0 : register(s0);


#line 12
[numthreads(8, 8, 1)]
void computeMain(uint3 dispatchThreadID_0 : SV_DispatchThreadID)
{

#line 12
uint3 _S1 = dispatchThreadID_0;

uint dstWidth_0;

#line 14
uint dstHeight_0;

#line 14
uint elements_0;
dstTexture_0.GetDimensions(dstWidth_0, dstHeight_0, elements_0);

#line 15
bool _S2;

if((_S1.x) >= dstWidth_0)
{

#line 17
_S2 = true;

#line 17
}
else
{

#line 17
_S2 = (_S1.y) >= dstHeight_0;

#line 17
}

#line 17
if(_S2)
{

#line 17
_S2 = true;

#line 17
}
else
{

#line 17
_S2 = (_S1.z) >= elements_0;

#line 17
}

#line 17
if(_S2)
{

#line 17
return;
}


dstTexture_0[_S1] = srcTexture_0.SampleLevel(LinearClampSampler_0, float3((float2(_S1.xy) + 0.5f) * cb_0.texelSize_0, float(_S1.z)), 0.0f);
return;
}

22 changes: 22 additions & 0 deletions Engine/shaders/slang/MipmapGen.slang
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
Texture2DArray<float4> srcTexture : register(t0);
RWTexture2DArray<float4> dstTexture : register(u0);
SamplerState LinearClampSampler : register(s0);

struct MipGenConstants
{
float2 texelSize;
};
ConstantBuffer<MipGenConstants> cb : register(b0);

[numthreads(8, 8, 1)]
void computeMain(uint3 dispatchThreadID : SV_DispatchThreadID)
{
uint dstWidth, dstHeight, elements;
dstTexture.GetDimensions(dstWidth, dstHeight, elements);

if (dispatchThreadID.x >= dstWidth || dispatchThreadID.y >= dstHeight || dispatchThreadID.z >= elements) return;

float2 uv = (float2(dispatchThreadID.xy) + 0.5f) * cb.texelSize;
float4 color = srcTexture.SampleLevel(LinearClampSampler, float3(uv, dispatchThreadID.z), 0);
dstTexture[dispatchThreadID] = color;
}
Binary file added Engine/shaders/spirv/Compute.comp.spv
Binary file not shown.
Binary file added Engine/shaders/spirv/ConvolutionBlur.comp.spv
Binary file not shown.
Binary file added Engine/shaders/spirv/MipmapGen.comp.spv
Binary file not shown.
2 changes: 1 addition & 1 deletion Engine/source/DXShadowMapContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ void DXShadowMapContext::Initialize()
m_computeRootSignature->SetName(L"Shadow Blur Compute Root Signature");

ComPtr<ID3DBlob> computeShader, errorMessages;
HRESULT hr = D3DCompileFromFile(L"../Engine/shaders/hlsl/ConvolutionBlur.compute.hlsl", nullptr, nullptr, "computeMain", "cs_5_1", 0, 0, &computeShader, &errorMessages);
HRESULT hr = D3DCompileFromFile(L"../Engine/shaders/hlsl/ConvolutionBlur.comp.hlsl", nullptr, nullptr, "computeMain", "cs_5_1", 0, 0, &computeShader, &errorMessages);
if (FAILED(hr) && errorMessages) OutputDebugStringA(static_cast<const char*>(errorMessages->GetBufferPointer()));

D3D12_COMPUTE_PIPELINE_STATE_DESC computePsoDesc = {};
Expand Down
6 changes: 4 additions & 2 deletions shader_compiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
# Shadow Map Pass
{ "file": "ShadowMapPass.slang", "entry": "vertexMain", "stage": "vertex", "profile_hlsl": "sm_5_1", "out_name": "ShadowMapPass.vert" },
{ "file": "ShadowMapPass.slang", "entry": "fragmentMain", "stage": "fragment", "profile_hlsl": "sm_5_1", "out_name": "ShadowMapPass.frag" },
{ "file": "ConvolutionBlur.slang", "entry": "computeMain", "stage": "compute", "profile_hlsl": "sm_5_1", "out_name": "ConvolutionBlur.compute" },
{ "file": "ConvolutionBlur.slang", "entry": "computeMain", "stage": "compute", "profile_hlsl": "sm_5_1", "out_name": "ConvolutionBlur.comp" },
# Geometry Pass, Use totally same vertex and mesh shader but different pixel shader
{ "file": "GBuffer.slang", "entry": "fragmentMain", "stage": "fragment", "profile_hlsl": "sm_5_1", "out_name": "GBuffer.frag" },
{ "file": "GBuffer.slang", "entry": "fragmentMain", "stage": "fragment", "profile_hlsl": "sm_6_5", "out_name": "GBufferMesh.frag" }, # Also need to convert to DXIL
Expand Down Expand Up @@ -66,7 +66,9 @@
{ "file": "ToneMapping.slang", "entry": "vertexMain", "stage": "vertex", "profile_hlsl": "sm_5_1", "out_name": "ToneMapping.vert" },
{ "file": "ToneMapping.slang", "entry": "fragmentMain", "stage": "fragment", "profile_hlsl": "sm_5_1", "out_name": "ToneMapping.frag" },
# Compute
{ "file": "Compute.slang", "entry": "computeMain", "stage": "compute", "profile_hlsl": "sm_5_1", "out_name": "Compute.compute" }
{ "file": "Compute.slang", "entry": "computeMain", "stage": "compute", "profile_hlsl": "sm_5_1", "out_name": "Compute.comp" },
# Mipmap
{ "file": "MipmapGen.slang", "entry": "computeMain", "stage": "compute", "profile_hlsl": "sm_5_1", "out_name": "MipmapGen.comp" }
]

# DXC Shader List
Expand Down
Loading