diff --git a/D3D12Backend/APIWrappers/Resources/Textures/Texture1D.cpp b/D3D12Backend/APIWrappers/Resources/Textures/Texture1D.cpp new file mode 100644 index 0000000..fc420d7 --- /dev/null +++ b/D3D12Backend/APIWrappers/Resources/Textures/Texture1D.cpp @@ -0,0 +1,272 @@ +#include "stdafx.h" + +#include "Texture1D.h" + +#include "APIWrappers/Device.h" +#include "APIWrappers/ResourceHeap.h" + +namespace Boolka +{ + + bool Texture1D::Initialize(ID3D12Resource* resource) + { + BLK_ASSERT(m_Resource == nullptr); +#ifdef BLK_DEBUG + D3D12_RESOURCE_DESC resourceDesc = resource->GetDesc(); + BLK_ASSERT(resourceDesc.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE1D); +#endif + + m_Resource = resource; + + return true; + } + + bool Texture1D::Initialize(Device& device, D3D12_HEAP_TYPE heapType, UINT64 width, + UINT16 mipCount, DXGI_FORMAT format, + D3D12_RESOURCE_FLAGS resourceFlags, D3D12_CLEAR_VALUE* clearValue, + D3D12_RESOURCE_STATES initialState, UINT16 arraySize /*= 1*/) + { + BLK_ASSERT(m_Resource == nullptr); + + D3D12_HEAP_PROPERTIES heapProperties = {}; + heapProperties.Type = heapType; + heapProperties.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN; + heapProperties.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN; + + D3D12_RESOURCE_DESC resourceDesc = + FillDesc(width, mipCount, format, resourceFlags, arraySize); + + HRESULT hr = + device->CreateCommittedResource(&heapProperties, D3D12_HEAP_FLAG_NONE, &resourceDesc, + initialState, clearValue, IID_PPV_ARGS(&m_Resource)); + BLK_ASSERT(SUCCEEDED(hr)); + return SUCCEEDED(hr); + } + + bool Texture1D::Initialize(Device& device, ResourceHeap& resourceHeap, size_t heapOffset, + UINT64 width, UINT16 mipCount, DXGI_FORMAT format, + D3D12_RESOURCE_FLAGS resourceFlags, D3D12_CLEAR_VALUE* clearValue, + D3D12_RESOURCE_STATES initialState, UINT16 arraySize /*= 1*/) + { + D3D12_RESOURCE_DESC resourceDesc = + FillDesc(width, mipCount, format, resourceFlags, arraySize); + + HRESULT hr = + device->CreatePlacedResource(resourceHeap.Get(), heapOffset, &resourceDesc, + initialState, clearValue, IID_PPV_ARGS(&m_Resource)); + BLK_ASSERT(SUCCEEDED(hr)); + return SUCCEEDED(hr); + } + + void Texture1D::GetRequiredSize(size_t& outAlignment, size_t& outSize, Device& device, + UINT64 width, UINT16 mipCount, DXGI_FORMAT format, + D3D12_RESOURCE_FLAGS resourceFlags, UINT16 arraySize /*= 1*/) + { + D3D12_RESOURCE_DESC resourceDesc = + FillDesc(width, mipCount, format, resourceFlags, arraySize); + + D3D12_RESOURCE_ALLOCATION_INFO allocationInfo = + device->GetResourceAllocationInfo(0, 1, &resourceDesc); + outAlignment = allocationInfo.Alignment; + outSize = allocationInfo.SizeInBytes; + } + + size_t Texture1D::GetUploadSize(UINT width, UINT16 mipCount, DXGI_FORMAT format, + D3D12_RESOURCE_FLAGS resourceFlags, UINT16 arraySize /*= 1*/) + { + size_t result = 0; + + UINT bytesPerPixel = GetBPP(format) / 8; + BLK_ASSERT(bytesPerPixel > 0); + + UINT currentWidth = width; + for (UINT16 currentMip = 0; currentMip < mipCount; ++currentMip) + { + BLK_ASSERT(currentWidth != 0); + + size_t rowPitch = BLK_CEIL_TO_POWER_OF_TWO(currentWidth * bytesPerPixel, + D3D12_TEXTURE_DATA_PITCH_ALIGNMENT); + size_t textureSize = BLK_CEIL_TO_POWER_OF_TWO(rowPitch, + D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT); + result += textureSize; + currentWidth >>= 1; + } + + return result * arraySize; + } + + UINT Texture1D::GetBPP(DXGI_FORMAT format) + { + switch (format) + { + case DXGI_FORMAT_R32G32B32A32_TYPELESS: + case DXGI_FORMAT_R32G32B32A32_FLOAT: + case DXGI_FORMAT_R32G32B32A32_UINT: + case DXGI_FORMAT_R32G32B32A32_SINT: + return 128; + + case DXGI_FORMAT_R32G32B32_TYPELESS: + case DXGI_FORMAT_R32G32B32_FLOAT: + case DXGI_FORMAT_R32G32B32_UINT: + case DXGI_FORMAT_R32G32B32_SINT: + return 96; + + case DXGI_FORMAT_R16G16B16A16_TYPELESS: + case DXGI_FORMAT_R16G16B16A16_FLOAT: + case DXGI_FORMAT_R16G16B16A16_UNORM: + case DXGI_FORMAT_R16G16B16A16_UINT: + case DXGI_FORMAT_R16G16B16A16_SNORM: + case DXGI_FORMAT_R16G16B16A16_SINT: + case DXGI_FORMAT_R32G32_TYPELESS: + case DXGI_FORMAT_R32G32_FLOAT: + case DXGI_FORMAT_R32G32_UINT: + case DXGI_FORMAT_R32G32_SINT: + case DXGI_FORMAT_R32G8X24_TYPELESS: + case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: + case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: + case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT: + case DXGI_FORMAT_Y416: + case DXGI_FORMAT_Y210: + case DXGI_FORMAT_Y216: + return 64; + + case DXGI_FORMAT_R10G10B10A2_TYPELESS: + case DXGI_FORMAT_R10G10B10A2_UNORM: + case DXGI_FORMAT_R10G10B10A2_UINT: + case DXGI_FORMAT_R11G11B10_FLOAT: + case DXGI_FORMAT_R8G8B8A8_TYPELESS: + case DXGI_FORMAT_R8G8B8A8_UNORM: + case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: + case DXGI_FORMAT_R8G8B8A8_UINT: + case DXGI_FORMAT_R8G8B8A8_SNORM: + case DXGI_FORMAT_R8G8B8A8_SINT: + case DXGI_FORMAT_R16G16_TYPELESS: + case DXGI_FORMAT_R16G16_FLOAT: + case DXGI_FORMAT_R16G16_UNORM: + case DXGI_FORMAT_R16G16_UINT: + case DXGI_FORMAT_R16G16_SNORM: + case DXGI_FORMAT_R16G16_SINT: + case DXGI_FORMAT_R32_TYPELESS: + case DXGI_FORMAT_D32_FLOAT: + case DXGI_FORMAT_R32_FLOAT: + case DXGI_FORMAT_R32_UINT: + case DXGI_FORMAT_R32_SINT: + case DXGI_FORMAT_R24G8_TYPELESS: + case DXGI_FORMAT_D24_UNORM_S8_UINT: + case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: + case DXGI_FORMAT_X24_TYPELESS_G8_UINT: + case DXGI_FORMAT_R9G9B9E5_SHAREDEXP: + case DXGI_FORMAT_R8G8_B8G8_UNORM: + case DXGI_FORMAT_G8R8_G8B8_UNORM: + case DXGI_FORMAT_B8G8R8A8_UNORM: + case DXGI_FORMAT_B8G8R8X8_UNORM: + case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM: + case DXGI_FORMAT_B8G8R8A8_TYPELESS: + case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: + case DXGI_FORMAT_B8G8R8X8_TYPELESS: + case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: + case DXGI_FORMAT_AYUV: + case DXGI_FORMAT_Y410: + case DXGI_FORMAT_YUY2: + return 32; + + case DXGI_FORMAT_P010: + case DXGI_FORMAT_P016: + return 24; + + case DXGI_FORMAT_R8G8_TYPELESS: + case DXGI_FORMAT_R8G8_UNORM: + case DXGI_FORMAT_R8G8_UINT: + case DXGI_FORMAT_R8G8_SNORM: + case DXGI_FORMAT_R8G8_SINT: + case DXGI_FORMAT_R16_TYPELESS: + case DXGI_FORMAT_R16_FLOAT: + case DXGI_FORMAT_D16_UNORM: + case DXGI_FORMAT_R16_UNORM: + case DXGI_FORMAT_R16_UINT: + case DXGI_FORMAT_R16_SNORM: + case DXGI_FORMAT_R16_SINT: + case DXGI_FORMAT_B5G6R5_UNORM: + case DXGI_FORMAT_B5G5R5A1_UNORM: + case DXGI_FORMAT_A8P8: + case DXGI_FORMAT_B4G4R4A4_UNORM: + return 16; + + case DXGI_FORMAT_NV12: + case DXGI_FORMAT_420_OPAQUE: + case DXGI_FORMAT_NV11: + return 12; + + case DXGI_FORMAT_R8_TYPELESS: + case DXGI_FORMAT_R8_UNORM: + case DXGI_FORMAT_R8_UINT: + case DXGI_FORMAT_R8_SNORM: + case DXGI_FORMAT_R8_SINT: + case DXGI_FORMAT_A8_UNORM: + case DXGI_FORMAT_AI44: + case DXGI_FORMAT_IA44: + case DXGI_FORMAT_P8: + return 8; + + case DXGI_FORMAT_R1_UNORM: + return 1; + + case DXGI_FORMAT_BC1_TYPELESS: + case DXGI_FORMAT_BC1_UNORM: + case DXGI_FORMAT_BC1_UNORM_SRGB: + case DXGI_FORMAT_BC4_TYPELESS: + case DXGI_FORMAT_BC4_UNORM: + case DXGI_FORMAT_BC4_SNORM: + return 4; + + case DXGI_FORMAT_BC2_TYPELESS: + case DXGI_FORMAT_BC2_UNORM: + case DXGI_FORMAT_BC2_UNORM_SRGB: + case DXGI_FORMAT_BC3_TYPELESS: + case DXGI_FORMAT_BC3_UNORM: + case DXGI_FORMAT_BC3_UNORM_SRGB: + case DXGI_FORMAT_BC5_TYPELESS: + case DXGI_FORMAT_BC5_UNORM: + case DXGI_FORMAT_BC5_SNORM: + case DXGI_FORMAT_BC6H_TYPELESS: + case DXGI_FORMAT_BC6H_UF16: + case DXGI_FORMAT_BC6H_SF16: + case DXGI_FORMAT_BC7_TYPELESS: + case DXGI_FORMAT_BC7_UNORM: + case DXGI_FORMAT_BC7_UNORM_SRGB: + return 8; + + default: + BLK_ASSERT(0); + return 0; + } + } + + void Texture1D::Unload() + { + BLK_ASSERT(m_Resource); + + m_Resource->Release(); + m_Resource = nullptr; + } + + D3D12_RESOURCE_DESC Texture1D::FillDesc(UINT64 width, UINT16 mipCount, DXGI_FORMAT format, + D3D12_RESOURCE_FLAGS resourceFlags, UINT16 arraySize) + { + D3D12_RESOURCE_DESC resourceDesc = {}; + resourceDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE1D; + resourceDesc.Alignment = 0; + resourceDesc.Width = width; + resourceDesc.Height = 1; + resourceDesc.DepthOrArraySize = arraySize; + resourceDesc.MipLevels = mipCount; + resourceDesc.Format = format; + resourceDesc.SampleDesc.Count = 1; + resourceDesc.SampleDesc.Quality = 0; + resourceDesc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN; + resourceDesc.Flags = resourceFlags; + + return resourceDesc; + } + +} // namespace Boolka diff --git a/D3D12Backend/APIWrappers/Resources/Textures/Texture1D.h b/D3D12Backend/APIWrappers/Resources/Textures/Texture1D.h new file mode 100644 index 0000000..7e07d75 --- /dev/null +++ b/D3D12Backend/APIWrappers/Resources/Textures/Texture1D.h @@ -0,0 +1,45 @@ +#pragma once +#include "Texture.h" + +namespace Boolka +{ + + class Device; + class ResourceHeap; + + class [[nodiscard]] Texture1D : public Texture + { + public: + Texture1D() = default; + ~Texture1D() = default; + + // Creates committed resource + bool Initialize(Device& device, D3D12_HEAP_TYPE heapType, UINT64 width, UINT16 mipCount, + DXGI_FORMAT format, D3D12_RESOURCE_FLAGS resourceFlags, + D3D12_CLEAR_VALUE* clearValue, D3D12_RESOURCE_STATES initialState, + UINT16 arraySize = 1); + // Creates placed resource + bool Initialize(Device& device, ResourceHeap& resourceHeap, size_t heapOffset, UINT64 width, + UINT16 mipCount, DXGI_FORMAT format, D3D12_RESOURCE_FLAGS resourceFlags, + D3D12_CLEAR_VALUE* clearValue, D3D12_RESOURCE_STATES initialState, + UINT16 arraySize = 1); + static void GetRequiredSize(size_t& outAlignment, size_t& outSize, Device& device, + UINT64 width, UINT16 mipCount, DXGI_FORMAT format, + D3D12_RESOURCE_FLAGS resourceFlags, UINT16 arraySize = 1); + [[nodiscard]] static size_t GetUploadSize(UINT width, UINT16 mipCount, + DXGI_FORMAT format, + D3D12_RESOURCE_FLAGS resourceFlags, + UINT16 arraySize = 1); + [[nodiscard]] static UINT GetBPP(DXGI_FORMAT format); + + // This method don't increment resource's reference count + // You should do it yourself if needed + bool Initialize(ID3D12Resource* resource); + void Unload(); + + private: + static D3D12_RESOURCE_DESC FillDesc(UINT64 width, UINT16 mipCount, DXGI_FORMAT format, + D3D12_RESOURCE_FLAGS resourceFlags, UINT16 arraySize); + }; + +} // namespace Boolka diff --git a/D3D12Backend/APIWrappers/Resources/Textures/Views/ShaderResourceView.cpp b/D3D12Backend/APIWrappers/Resources/Textures/Views/ShaderResourceView.cpp index b74da24..3e0f555 100644 --- a/D3D12Backend/APIWrappers/Resources/Textures/Views/ShaderResourceView.cpp +++ b/D3D12Backend/APIWrappers/Resources/Textures/Views/ShaderResourceView.cpp @@ -8,12 +8,30 @@ namespace Boolka { + void ShaderResourceView::Initialize(Device& device, Texture1D& texture, + D3D12_CPU_DESCRIPTOR_HANDLE destDescriptor) + { + device->CreateShaderResourceView(texture.Get(), nullptr, destDescriptor); + } + void ShaderResourceView::Initialize(Device& device, Texture2D& texture, D3D12_CPU_DESCRIPTOR_HANDLE destDescriptor) { device->CreateShaderResourceView(texture.Get(), nullptr, destDescriptor); } + void ShaderResourceView::Initialize(Device& device, Texture1D& texture, + D3D12_CPU_DESCRIPTOR_HANDLE destDescriptor, + DXGI_FORMAT format) + { + D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc{}; + srvDesc.Format = format; + srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; + srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE1D; + srvDesc.Texture2D.MipLevels = -1; + device->CreateShaderResourceView(texture.Get(), &srvDesc, destDescriptor); + } + void ShaderResourceView::Initialize(Device& device, Texture2D& texture, D3D12_CPU_DESCRIPTOR_HANDLE destDescriptor, DXGI_FORMAT format) diff --git a/D3D12Backend/APIWrappers/Resources/Textures/Views/ShaderResourceView.h b/D3D12Backend/APIWrappers/Resources/Textures/Views/ShaderResourceView.h index 902bb33..137da80 100644 --- a/D3D12Backend/APIWrappers/Resources/Textures/Views/ShaderResourceView.h +++ b/D3D12Backend/APIWrappers/Resources/Textures/Views/ShaderResourceView.h @@ -9,8 +9,12 @@ namespace Boolka class ShaderResourceView { public: + static void Initialize(Device& device, Texture1D& texture, + D3D12_CPU_DESCRIPTOR_HANDLE destDescriptor); static void Initialize(Device& device, Texture2D& texture, D3D12_CPU_DESCRIPTOR_HANDLE destDescriptor); + static void Initialize(Device& device, Texture1D& texture, + D3D12_CPU_DESCRIPTOR_HANDLE destDescriptor, DXGI_FORMAT format); static void Initialize(Device& device, Texture2D& texture, D3D12_CPU_DESCRIPTOR_HANDLE destDescriptor, DXGI_FORMAT format); static void Initialize(Device& device, Buffer& buffer, UINT elementCount, UINT stride, diff --git a/D3D12Backend/APIWrappers/Resources/Textures/Views/UnorderedAccessView.cpp b/D3D12Backend/APIWrappers/Resources/Textures/Views/UnorderedAccessView.cpp index ba5897b..dcc5b0e 100644 --- a/D3D12Backend/APIWrappers/Resources/Textures/Views/UnorderedAccessView.cpp +++ b/D3D12Backend/APIWrappers/Resources/Textures/Views/UnorderedAccessView.cpp @@ -8,6 +8,16 @@ namespace Boolka { + void UnorderedAccessView::Initialize(Device& device, Texture1D& texture, DXGI_FORMAT format, + D3D12_CPU_DESCRIPTOR_HANDLE destDescriptor) + { + D3D12_UNORDERED_ACCESS_VIEW_DESC desc{}; + desc.Format = format; + desc.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE1D; + + device->CreateUnorderedAccessView(texture.Get(), nullptr, &desc, destDescriptor); + } + void UnorderedAccessView::Initialize(Device& device, Texture2D& texture, DXGI_FORMAT format, D3D12_CPU_DESCRIPTOR_HANDLE destDescriptor) { diff --git a/D3D12Backend/APIWrappers/Resources/Textures/Views/UnorderedAccessView.h b/D3D12Backend/APIWrappers/Resources/Textures/Views/UnorderedAccessView.h index 866caf1..30866b5 100644 --- a/D3D12Backend/APIWrappers/Resources/Textures/Views/UnorderedAccessView.h +++ b/D3D12Backend/APIWrappers/Resources/Textures/Views/UnorderedAccessView.h @@ -9,6 +9,8 @@ namespace Boolka class UnorderedAccessView { public: + static void Initialize(Device& device, Texture1D& texture, DXGI_FORMAT format, + D3D12_CPU_DESCRIPTOR_HANDLE destDescriptor); static void Initialize(Device& device, Texture2D& texture, DXGI_FORMAT format, D3D12_CPU_DESCRIPTOR_HANDLE destDescriptor); static void Initialize(Device& device, Buffer& buffer, UINT stride, UINT elementCount, diff --git a/D3D12Backend/APIWrappers/Swapchain.cpp b/D3D12Backend/APIWrappers/Swapchain.cpp index 57e93da..bbc0731 100644 --- a/D3D12Backend/APIWrappers/Swapchain.cpp +++ b/D3D12Backend/APIWrappers/Swapchain.cpp @@ -49,7 +49,7 @@ namespace Boolka DXGI_SWAP_CHAIN_DESC1 desc = {}; desc.Width = 0; desc.Height = 0; - desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + desc.Format = DXGI_FORMAT_R10G10B10A2_UNORM; desc.Stereo = FALSE; desc.SampleDesc.Count = 1; desc.SampleDesc.Quality = 0; @@ -78,10 +78,11 @@ namespace Boolka if (windowState.windowMode == WindowState::WindowMode::Fullscreen) { m_Swapchain->SetFullscreenState(TRUE, NULL); - m_Swapchain->ResizeBuffers(BLK_IN_FLIGHT_FRAMES, 0, 0, DXGI_FORMAT_R8G8B8A8_UNORM, + m_Swapchain->ResizeBuffers(BLK_IN_FLIGHT_FRAMES, 0, 0, DXGI_FORMAT_R10G10B10A2_UNORM, DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT); m_IsFullscreen = true; } + m_Swapchain->SetColorSpace1(DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020); m_PresentFlags = 0; if (windowState.presentInterval == 0 && diff --git a/D3D12Backend/Containers/LightContainer.cpp b/D3D12Backend/Containers/LightContainer.cpp index 25119c8..3970d21 100644 --- a/D3D12Backend/Containers/LightContainer.cpp +++ b/D3D12Backend/Containers/LightContainer.cpp @@ -59,7 +59,7 @@ namespace Boolka void LightContainer::Update(float deltaTime) { - m_CurrentRotation += deltaTime * 0.25f; + //m_CurrentRotation += deltaTime * 0.25f; UpdateLights(); UpdateSun(); } diff --git a/D3D12Backend/Containers/PSOContainer.cpp b/D3D12Backend/Containers/PSOContainer.cpp index 3adceea..8cc8f5f 100644 --- a/D3D12Backend/Containers/PSOContainer.cpp +++ b/D3D12Backend/Containers/PSOContainer.cpp @@ -107,6 +107,12 @@ namespace Boolka BLK_ASSERT_VAR(res); DebugFileReader::FreeMemory(CS); + CS = DebugFileReader::ReadFile("ToneMappingPassCS.cso"); + res = GetPSO(ComputePSO::ToneMappingLUTGeneration) + .Initialize(device, L"ComputePSO::ToneMappingPassCS", defaultRootSig, CS); + BLK_ASSERT_VAR(res); + DebugFileReader::FreeMemory(CS); + if (device.SupportsRaytracing()) { DebugProfileTimer rtpsoTimer; diff --git a/D3D12Backend/Containers/PSOContainer.h b/D3D12Backend/Containers/PSOContainer.h index d83f614..bd7369f 100644 --- a/D3D12Backend/Containers/PSOContainer.h +++ b/D3D12Backend/Containers/PSOContainer.h @@ -27,6 +27,7 @@ namespace Boolka enum class ComputePSO { GPUCulling, + ToneMappingLUTGeneration, Count }; diff --git a/D3D12Backend/Containers/ResourceContainer.cpp b/D3D12Backend/Containers/ResourceContainer.cpp index 0c389b9..afd9cb3 100644 --- a/D3D12Backend/Containers/ResourceContainer.cpp +++ b/D3D12Backend/Containers/ResourceContainer.cpp @@ -14,7 +14,7 @@ namespace Boolka { - BLK_DEFINE_ENUM_OPERATORS(ResourceContainer::Tex); + BLK_DEFINE_ENUM_OPERATORS(ResourceContainer::Tex2D); BLK_DEFINE_ENUM_OPERATORS(ResourceContainer::Buf); BLK_DEFINE_ENUM_OPERATORS(ResourceContainer::SRV); BLK_DEFINE_ENUM_OPERATORS(ResourceContainer::RTV); @@ -61,39 +61,44 @@ namespace Boolka dsvClearValue.Format = DXGI_FORMAT_D32_FLOAT; dsvClearValue.DepthStencil.Depth = 1.0f; - GetTexture(Tex::GBufferAlbedo) + GetTexture(Tex2D::GBufferAlbedo) .Initialize(device, D3D12_HEAP_TYPE_DEFAULT, width, height, 1, gbufferAlbedoFormat, D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET, &rtvClearValue, D3D12_RESOURCE_STATE_RENDER_TARGET); - GetTexture(Tex::GBufferNormal) + GetTexture(Tex2D::GBufferNormal) .Initialize(device, D3D12_HEAP_TYPE_DEFAULT, width, height, 1, gbufferAlbedoFormat, D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET, &rtvClearValue, D3D12_RESOURCE_STATE_RENDER_TARGET); - GetTexture(Tex::GBufferRaytraceResults) + GetTexture(Tex2D::GBufferRaytraceResults) .Initialize(device, D3D12_HEAP_TYPE_DEFAULT, width, height, 1, gbufferAlbedoFormat, D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, nullptr, D3D12_RESOURCE_STATE_UNORDERED_ACCESS); - GetTexture(Tex::LightBuffer) + GetTexture(Tex2D::LightBuffer) .Initialize(device, D3D12_HEAP_TYPE_DEFAULT, width, height, 1, gbufferAlbedoFormat, D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET, &rtvClearValue, D3D12_RESOURCE_STATE_RENDER_TARGET); - GetTexture(Tex::GbufferDepth) + GetTexture(Tex2D::GbufferDepth) .Initialize(device, D3D12_HEAP_TYPE_DEFAULT, width, height, 1, gbufferDepthFormat, D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL, &dsvClearValue, D3D12_RESOURCE_STATE_DEPTH_WRITE); for (size_t i = 0; i < BLK_MAX_LIGHT_COUNT; i++) { - GetTexture(Tex::ShadowMapCube0 + i) + GetTexture(Tex2D::ShadowMapCube0 + i) .Initialize(device, D3D12_HEAP_TYPE_DEFAULT, BLK_LIGHT_SHADOWMAP_SIZE, BLK_LIGHT_SHADOWMAP_SIZE, 1, shadowMapFormat, D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL, &dsvClearValue, D3D12_RESOURCE_STATE_DEPTH_WRITE, 6); } - GetTexture(Tex::ShadowMapSun) + GetTexture(Tex2D::ShadowMapSun) .Initialize(device, D3D12_HEAP_TYPE_DEFAULT, BLK_SUN_SHADOWMAP_SIZE, BLK_SUN_SHADOWMAP_SIZE, 1, shadowMapFormat, D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL, &dsvClearValue, D3D12_RESOURCE_STATE_DEPTH_WRITE); + GetTexture(Tex1D::TonemappingLUT) + .Initialize(device, D3D12_HEAP_TYPE_DEFAULT, BLK_TONEMAPPING_LUT_RESOLUTION, 1, + DXGI_FORMAT_R32_FLOAT, + D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, nullptr, + D3D12_RESOURCE_STATE_UNORDERED_ACCESS); GetDescriptorHeap(DescHeap::RTVHeap) .Initialize(device, rtvHeapDescriptorCount, D3D12_DESCRIPTOR_HEAP_TYPE_RTV, @@ -140,7 +145,7 @@ namespace Boolka m_FlippedResources[i].m_BackBuffer = &displayController.GetBuffer(i); for (UINT i = 0; i < BLK_IN_FLIGHT_FRAMES; ++i) GetBackBufferRTV(i).Initialize(device, *m_FlippedResources[i].m_BackBuffer, - DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R10G10B10A2_UNORM, GetDescriptorHeap(DescHeap::RTVHeap) .GetCPUHandle(static_cast(RTV::Count) + i)); GetBuffer(Buf::Frame) @@ -170,31 +175,35 @@ namespace Boolka const UINT uavOffset = static_cast(MainSRVDescriptorHeapOffsets::UAVHeapOffset); UnorderedAccessView::Initialize( - device, GetTexture(Tex::GBufferRaytraceResults), DXGI_FORMAT_R16G16B16A16_FLOAT, + device, GetTexture(Tex2D::GBufferRaytraceResults), DXGI_FORMAT_R16G16B16A16_FLOAT, + GetDescriptorHeap(DescHeap::MainHeap) + .GetCPUHandle(uavOffset + static_cast(UAV::GBufferRaytraceResults))); + UnorderedAccessView::Initialize( + device, GetTexture(Tex1D::TonemappingLUT), DXGI_FORMAT_R32_FLOAT, GetDescriptorHeap(DescHeap::MainHeap) - .GetCPUHandle(uavOffset + static_cast(SRV::GBufferAlbedo))); + .GetCPUHandle(uavOffset + static_cast(UAV::TonemappingLUT))); const UINT srvOffset = static_cast(MainSRVDescriptorHeapOffsets::SRVHeapOffset); ShaderResourceView::Initialize( - device, GetTexture(Tex::GBufferAlbedo), + device, GetTexture(Tex2D::GBufferAlbedo), GetDescriptorHeap(DescHeap::MainHeap) .GetCPUHandle(srvOffset + static_cast(SRV::GBufferAlbedo))); ShaderResourceView::Initialize( - device, GetTexture(Tex::GBufferNormal), + device, GetTexture(Tex2D::GBufferNormal), GetDescriptorHeap(DescHeap::MainHeap) .GetCPUHandle(srvOffset + static_cast(SRV::GBufferNormal))); ShaderResourceView::Initialize( - device, GetTexture(Tex::GBufferRaytraceResults), + device, GetTexture(Tex2D::GBufferRaytraceResults), GetDescriptorHeap(DescHeap::MainHeap) .GetCPUHandle(srvOffset + static_cast(SRV::GBufferRaytraceResults))); ShaderResourceView::Initialize( - device, GetTexture(Tex::GbufferDepth), + device, GetTexture(Tex2D::GbufferDepth), GetDescriptorHeap(DescHeap::MainHeap) .GetCPUHandle(srvOffset + static_cast(SRV::GbufferDepth)), gbufferDepthSRVFormat); ShaderResourceView::Initialize( - device, GetTexture(Tex::LightBuffer), + device, GetTexture(Tex2D::LightBuffer), GetDescriptorHeap(DescHeap::MainHeap) .GetCPUHandle(srvOffset + static_cast(SRV::LightBuffer))); ShaderResourceView::Initialize( @@ -205,32 +214,37 @@ namespace Boolka for (UINT i = 0; i < BLK_MAX_LIGHT_COUNT; i++) { ShaderResourceView::InitializeCube( - device, GetTexture(Tex::ShadowMapCube0 + i), + device, GetTexture(Tex2D::ShadowMapCube0 + i), GetDescriptorHeap(DescHeap::MainHeap) .GetCPUHandle(srvOffset + static_cast(SRV::ShadowMapCube0 + i)), shadowMapSRVFormat); } ShaderResourceView::Initialize( - device, GetTexture(Tex::ShadowMapSun), + device, GetTexture(Tex2D::ShadowMapSun), GetDescriptorHeap(DescHeap::MainHeap) .GetCPUHandle(srvOffset + static_cast(SRV::ShadowMapSun)), shadowMapSRVFormat); + ShaderResourceView::Initialize( + device, GetTexture(Tex1D::TonemappingLUT), + GetDescriptorHeap(DescHeap::MainHeap) + .GetCPUHandle(srvOffset + static_cast(SRV::TonemappingLUT)), + DXGI_FORMAT_R32_FLOAT); GetRTV(RTV::GBufferAlbedo) - .Initialize(device, GetTexture(Tex::GBufferAlbedo), gbufferAlbedoFormat, + .Initialize(device, GetTexture(Tex2D::GBufferAlbedo), gbufferAlbedoFormat, GetDescriptorHeap(DescHeap::RTVHeap) .GetCPUHandle(static_cast(RTV::GBufferAlbedo))); GetRTV(RTV::GBufferNormal) - .Initialize(device, GetTexture(Tex::GBufferNormal), gbufferAlbedoFormat, + .Initialize(device, GetTexture(Tex2D::GBufferNormal), gbufferAlbedoFormat, GetDescriptorHeap(DescHeap::RTVHeap) .GetCPUHandle(static_cast(RTV::GBufferNormal))); GetRTV(RTV::LightBuffer) - .Initialize(device, GetTexture(Tex::LightBuffer), gbufferAlbedoFormat, + .Initialize(device, GetTexture(Tex2D::LightBuffer), gbufferAlbedoFormat, GetDescriptorHeap(DescHeap::RTVHeap) .GetCPUHandle(static_cast(RTV::LightBuffer))); GetDSV(DSV::GbufferDepth) - .Initialize(device, GetTexture(Tex::GbufferDepth), gbufferDepthFormat, + .Initialize(device, GetTexture(Tex2D::GbufferDepth), gbufferDepthFormat, GetDescriptorHeap(DescHeap::DSVHeap) .GetCPUHandle(static_cast(DSV::GbufferDepth))); for (UINT textureIndex = 0; textureIndex < BLK_MAX_LIGHT_COUNT; textureIndex++) @@ -238,7 +252,7 @@ namespace Boolka for (UINT16 arraySlice = 0; arraySlice < BLK_TEXCUBE_FACE_COUNT; ++arraySlice) { GetDSV(DSV::ShadowMapLight0 + textureIndex * BLK_TEXCUBE_FACE_COUNT + arraySlice) - .Initialize(device, GetTexture(Tex::ShadowMapCube0 + textureIndex), + .Initialize(device, GetTexture(Tex2D::ShadowMapCube0 + textureIndex), shadowMapFormat, GetDescriptorHeap(DescHeap::DSVHeap) .GetCPUHandle(static_cast( @@ -247,7 +261,7 @@ namespace Boolka } } GetDSV(DSV::ShadowMapSun) - .Initialize(device, GetTexture(Tex::ShadowMapSun), gbufferDepthFormat, + .Initialize(device, GetTexture(Tex2D::ShadowMapSun), gbufferDepthFormat, GetDescriptorHeap(DescHeap::DSVHeap) .GetCPUHandle(static_cast(DSV::ShadowMapSun))); @@ -263,6 +277,7 @@ namespace Boolka .GetCPUHandle(static_cast(MainSRVDescriptorHeapOffsets::CBVHeapOffset) + static_cast(CBV::DeferredLighting)), deferredLightingCbSize); + UnorderedAccessView::Initialize( device, GetBuffer(Buf::GPUCullingCommand), gpuCullingCommandBufElementSize, gpuCullingCommandBufElements, GetCPUDescriptor(Buf::GPUCullingCommand)); @@ -298,20 +313,22 @@ namespace Boolka GetFlippableUploadBuffer(i, FlipUploadBuf::GPUCulling) .Initialize(device, gpuCullingCBSize); - resourceTracker.RegisterResource(GetTexture(Tex::GBufferAlbedo), + resourceTracker.RegisterResource(GetTexture(Tex1D::TonemappingLUT), + D3D12_RESOURCE_STATE_UNORDERED_ACCESS); + resourceTracker.RegisterResource(GetTexture(Tex2D::GBufferAlbedo), D3D12_RESOURCE_STATE_RENDER_TARGET); - resourceTracker.RegisterResource(GetTexture(Tex::GBufferNormal), + resourceTracker.RegisterResource(GetTexture(Tex2D::GBufferNormal), D3D12_RESOURCE_STATE_RENDER_TARGET); - resourceTracker.RegisterResource(GetTexture(Tex::GBufferRaytraceResults), + resourceTracker.RegisterResource(GetTexture(Tex2D::GBufferRaytraceResults), D3D12_RESOURCE_STATE_UNORDERED_ACCESS); - resourceTracker.RegisterResource(GetTexture(Tex::LightBuffer), + resourceTracker.RegisterResource(GetTexture(Tex2D::LightBuffer), D3D12_RESOURCE_STATE_RENDER_TARGET); - resourceTracker.RegisterResource(GetTexture(Tex::GbufferDepth), + resourceTracker.RegisterResource(GetTexture(Tex2D::GbufferDepth), D3D12_RESOURCE_STATE_DEPTH_WRITE); for (size_t i = 0; i < BLK_MAX_LIGHT_COUNT; i++) - resourceTracker.RegisterResource(GetTexture(Tex::ShadowMapCube0 + i), + resourceTracker.RegisterResource(GetTexture(Tex2D::ShadowMapCube0 + i), D3D12_RESOURCE_STATE_DEPTH_WRITE); - resourceTracker.RegisterResource(GetTexture(Tex::ShadowMapSun), + resourceTracker.RegisterResource(GetTexture(Tex2D::ShadowMapSun), D3D12_RESOURCE_STATE_DEPTH_WRITE); for (UINT i = 0; i < BLK_IN_FLIGHT_FRAMES; ++i) resourceTracker.RegisterResource(GetBackBuffer(i), D3D12_RESOURCE_STATE_PRESENT); @@ -331,16 +348,17 @@ namespace Boolka D3D12_RESOURCE_STATE_UNORDERED_ACCESS); #ifdef BLK_RENDER_DEBUG - RenderDebug::SetDebugName(GetTexture(Tex::GBufferAlbedo).Get(), L"GBufferAlbedo"); - RenderDebug::SetDebugName(GetTexture(Tex::GBufferNormal).Get(), L"GBufferNormal"); - RenderDebug::SetDebugName(GetTexture(Tex::GBufferRaytraceResults).Get(), + RenderDebug::SetDebugName(GetTexture(Tex1D::TonemappingLUT).Get(), L"TonemappingLUT"); + RenderDebug::SetDebugName(GetTexture(Tex2D::GBufferAlbedo).Get(), L"GBufferAlbedo"); + RenderDebug::SetDebugName(GetTexture(Tex2D::GBufferNormal).Get(), L"GBufferNormal"); + RenderDebug::SetDebugName(GetTexture(Tex2D::GBufferRaytraceResults).Get(), L"GBufferRaytraceResults"); - RenderDebug::SetDebugName(GetTexture(Tex::LightBuffer).Get(), L"LightBuffer"); - RenderDebug::SetDebugName(GetTexture(Tex::GbufferDepth).Get(), L"GbufferDepth"); + RenderDebug::SetDebugName(GetTexture(Tex2D::LightBuffer).Get(), L"LightBuffer"); + RenderDebug::SetDebugName(GetTexture(Tex2D::GbufferDepth).Get(), L"GbufferDepth"); for (size_t i = 0; i < BLK_MAX_LIGHT_COUNT; i++) - RenderDebug::SetDebugName(GetTexture(Tex::ShadowMapCube0 + i).Get(), L"ShadowMapCube%d", - i); - RenderDebug::SetDebugName(GetTexture(Tex::ShadowMapSun).Get(), L"ShadowMapSun"); + RenderDebug::SetDebugName(GetTexture(Tex2D::ShadowMapCube0 + i).Get(), + L"ShadowMapCube%d", i); + RenderDebug::SetDebugName(GetTexture(Tex2D::ShadowMapSun).Get(), L"ShadowMapSun"); RenderDebug::SetDebugName(GetBuffer(Buf::Frame).Get(), L"FrameConstantBuffer"); RenderDebug::SetDebugName(GetBuffer(Buf::DeferredLighting).Get(), @@ -369,7 +387,8 @@ namespace Boolka void ResourceContainer::Unload() { - BLK_UNLOAD_ARRAY(m_Textures); + BLK_UNLOAD_ARRAY(m_Textures1D); + BLK_UNLOAD_ARRAY(m_Textures2D); BLK_UNLOAD_ARRAY(m_Buffers); BLK_UNLOAD_ARRAY(m_DescriptorHeaps); BLK_UNLOAD_ARRAY(m_RTVs); @@ -385,9 +404,14 @@ namespace Boolka BLK_UNLOAD_ARRAY(flippedResource.m_ConstantUploadBuffer); } - Texture2D& ResourceContainer::GetTexture(Tex id) + Texture1D& ResourceContainer::GetTexture(Tex1D id) + { + return m_Textures1D[static_cast(id)]; + } + + Texture2D& ResourceContainer::GetTexture(Tex2D id) { - return m_Textures[static_cast(id)]; + return m_Textures2D[static_cast(id)]; } Buffer& ResourceContainer::GetBuffer(Buf id) diff --git a/D3D12Backend/Containers/ResourceContainer.h b/D3D12Backend/Containers/ResourceContainer.h index a8e285e..e888ff4 100644 --- a/D3D12Backend/Containers/ResourceContainer.h +++ b/D3D12Backend/Containers/ResourceContainer.h @@ -3,6 +3,7 @@ #include "APIWrappers/Resources/Buffers/Buffer.h" #include "APIWrappers/Resources/Buffers/UploadBuffer.h" #include "APIWrappers/Resources/Buffers/Views/ConstantBufferView.h" +#include "APIWrappers/Resources/Textures/Texture1D.h" #include "APIWrappers/Resources/Textures/Texture2D.h" #include "APIWrappers/Resources/Textures/Views/DepthStencilView.h" #include "APIWrappers/Resources/Textures/Views/RenderTargetView.h" @@ -21,7 +22,13 @@ namespace Boolka class [[nodiscard]] ResourceContainer { public: - enum class Tex + enum class Tex1D + { + TonemappingLUT, + Count + }; + + enum class Tex2D { GBufferAlbedo, GBufferNormal, @@ -56,6 +63,7 @@ namespace Boolka GPUCullingMeshletIndices, ShadowMapCube0, ShadowMapSun = ShadowMapCube0 + BLK_MAX_LIGHT_COUNT, + TonemappingLUT, Count }; @@ -80,6 +88,7 @@ namespace Boolka GBufferRaytraceResults, GPUCullingCommand, GPUCullingMeshletIndices, + TonemappingLUT, ProfileMetrics, DebugMarkers, Count @@ -153,7 +162,8 @@ namespace Boolka DisplayController& displayController, ResourceTracker& resourceTracker); void Unload(); - [[nodiscard]] Texture2D& GetTexture(Tex id); + [[nodiscard]] Texture1D& GetTexture(Tex1D id); + [[nodiscard]] Texture2D& GetTexture(Tex2D id); [[nodiscard]] Buffer& GetBuffer(Buf id); [[nodiscard]] DescriptorHeap& GetDescriptorHeap(DescHeap id); [[nodiscard]] RenderTargetView& GetRTV(RTV id); @@ -171,7 +181,8 @@ namespace Boolka private: [[nodiscard]] UINT GetDescriptorHeapOffset(Buf id); - Texture2D m_Textures[static_cast(Tex::Count)]; + Texture1D m_Textures1D[static_cast(Tex1D::Count)]; + Texture2D m_Textures2D[static_cast(Tex2D::Count)]; Buffer m_Buffers[static_cast(Buf::Count)]; DescriptorHeap m_DescriptorHeaps[static_cast(DescHeap::Count)]; RenderTargetView m_RTVs[static_cast(RTV::Count)]; @@ -194,7 +205,8 @@ namespace Boolka FlippedResources m_FlippedResources[BLK_IN_FLIGHT_FRAMES]; }; - BLK_DECLARE_ENUM_OPERATORS(ResourceContainer::Tex); + BLK_DECLARE_ENUM_OPERATORS(ResourceContainer::Tex1D); + BLK_DECLARE_ENUM_OPERATORS(ResourceContainer::Tex2D); BLK_DECLARE_ENUM_OPERATORS(ResourceContainer::Buf); BLK_DECLARE_ENUM_OPERATORS(ResourceContainer::SRV); BLK_DECLARE_ENUM_OPERATORS(ResourceContainer::RTV); diff --git a/D3D12Backend/D3D12Backend.vcxproj b/D3D12Backend/D3D12Backend.vcxproj index 11c5119..6e2bc09 100644 --- a/D3D12Backend/D3D12Backend.vcxproj +++ b/D3D12Backend/D3D12Backend.vcxproj @@ -174,6 +174,7 @@ + @@ -271,6 +272,7 @@ + @@ -427,6 +429,11 @@ Pixel Pixel + + Compute + Compute + Compute + Pixel Pixel @@ -458,6 +465,7 @@ + diff --git a/D3D12Backend/D3D12Backend.vcxproj.filters b/D3D12Backend/D3D12Backend.vcxproj.filters index 0b77ba8..4e683d3 100644 --- a/D3D12Backend/D3D12Backend.vcxproj.filters +++ b/D3D12Backend/D3D12Backend.vcxproj.filters @@ -384,6 +384,9 @@ Containers + + APIWrappers\Resources\Textures + @@ -649,6 +652,9 @@ Containers + + APIWrappers\Resources\Textures + @@ -708,6 +714,9 @@ Shaders\CullingPass + + Shaders\ToneMappingPass + @@ -744,5 +753,8 @@ Shaders\LightingLibrary + + Shaders\ToneMappingPass + \ No newline at end of file diff --git a/D3D12Backend/RenderPasses/DeferredLightingPass.cpp b/D3D12Backend/RenderPasses/DeferredLightingPass.cpp index bd25fb9..709dc5f 100644 --- a/D3D12Backend/RenderPasses/DeferredLightingPass.cpp +++ b/D3D12Backend/RenderPasses/DeferredLightingPass.cpp @@ -13,12 +13,12 @@ namespace Boolka auto& resourceContainer = engineContext.GetResourceContainer(); UINT frameIndex = frameContext.GetFrameIndex(); - Texture2D& albedo = resourceContainer.GetTexture(ResourceContainer::Tex::GBufferAlbedo); - Texture2D& normal = resourceContainer.GetTexture(ResourceContainer::Tex::GBufferNormal); + Texture2D& albedo = resourceContainer.GetTexture(ResourceContainer::Tex2D::GBufferAlbedo); + Texture2D& normal = resourceContainer.GetTexture(ResourceContainer::Tex2D::GBufferNormal); Texture2D& raytraceResults = - resourceContainer.GetTexture(ResourceContainer::Tex::GBufferRaytraceResults); - Texture2D& depth = resourceContainer.GetTexture(ResourceContainer::Tex::GbufferDepth); - Texture2D& lightBuffer = resourceContainer.GetTexture(ResourceContainer::Tex::LightBuffer); + resourceContainer.GetTexture(ResourceContainer::Tex2D::GBufferRaytraceResults); + Texture2D& depth = resourceContainer.GetTexture(ResourceContainer::Tex2D::GbufferDepth); + Texture2D& lightBuffer = resourceContainer.GetTexture(ResourceContainer::Tex2D::LightBuffer); RenderTargetView& lightBufferRTV = resourceContainer.GetRTV(ResourceContainer::RTV::LightBuffer); DescriptorHeap& mainDescriptorHeap = @@ -44,7 +44,7 @@ namespace Boolka for (size_t lightIndex = 0; lightIndex < lights.size(); ++lightIndex) { auto& shadowMap = - resourceContainer.GetTexture(ResourceContainer::Tex::ShadowMapCube0 + lightIndex); + resourceContainer.GetTexture(ResourceContainer::Tex2D::ShadowMapCube0 + lightIndex); resourceTracker.Transition(shadowMap, commandList, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE); } diff --git a/D3D12Backend/RenderPasses/GBufferRenderPass.cpp b/D3D12Backend/RenderPasses/GBufferRenderPass.cpp index 4eb19a6..2b545ea 100644 --- a/D3D12Backend/RenderPasses/GBufferRenderPass.cpp +++ b/D3D12Backend/RenderPasses/GBufferRenderPass.cpp @@ -13,9 +13,9 @@ namespace Boolka auto& resourceContainer = engineContext.GetResourceContainer(); UINT frameIndex = frameContext.GetFrameIndex(); - Texture2D& albedo = resourceContainer.GetTexture(ResourceContainer::Tex::GBufferAlbedo); - Texture2D& normal = resourceContainer.GetTexture(ResourceContainer::Tex::GBufferNormal); - Texture2D& depth = resourceContainer.GetTexture(ResourceContainer::Tex::GbufferDepth); + Texture2D& albedo = resourceContainer.GetTexture(ResourceContainer::Tex2D::GBufferAlbedo); + Texture2D& normal = resourceContainer.GetTexture(ResourceContainer::Tex2D::GBufferNormal); + Texture2D& depth = resourceContainer.GetTexture(ResourceContainer::Tex2D::GbufferDepth); RenderTargetView& albedoRTV = resourceContainer.GetRTV(ResourceContainer::RTV::GBufferAlbedo); RenderTargetView& normalRTV = diff --git a/D3D12Backend/RenderPasses/RaytraceRenderPass.cpp b/D3D12Backend/RenderPasses/RaytraceRenderPass.cpp index f787d55..2eba52f 100644 --- a/D3D12Backend/RenderPasses/RaytraceRenderPass.cpp +++ b/D3D12Backend/RenderPasses/RaytraceRenderPass.cpp @@ -35,10 +35,10 @@ namespace Boolka Buffer& frameConstantBuffer = resourceContainer.GetBuffer(ResourceContainer::Buf::Frame); Buffer& lightingConstantBuffer = resourceContainer.GetBuffer(ResourceContainer::Buf::DeferredLighting); - Texture2D& normal = resourceContainer.GetTexture(ResourceContainer::Tex::GBufferNormal); + Texture2D& normal = resourceContainer.GetTexture(ResourceContainer::Tex2D::GBufferNormal); Texture2D& raytraceResults = - resourceContainer.GetTexture(ResourceContainer::Tex::GBufferRaytraceResults); - Texture2D& depth = resourceContainer.GetTexture(ResourceContainer::Tex::GbufferDepth); + resourceContainer.GetTexture(ResourceContainer::Tex2D::GBufferRaytraceResults); + Texture2D& depth = resourceContainer.GetTexture(ResourceContainer::Tex2D::GbufferDepth); DescriptorHeap& mainDescriptorHeap = resourceContainer.GetDescriptorHeap(ResourceContainer::DescHeap::MainHeap); diff --git a/D3D12Backend/RenderPasses/ShadowMapRenderPass.cpp b/D3D12Backend/RenderPasses/ShadowMapRenderPass.cpp index 2425fc3..4da3242 100644 --- a/D3D12Backend/RenderPasses/ShadowMapRenderPass.cpp +++ b/D3D12Backend/RenderPasses/ShadowMapRenderPass.cpp @@ -59,11 +59,11 @@ namespace Boolka for (size_t lightIndex = 0; lightIndex < lights.size(); ++lightIndex) { auto& shadowMap = - resourceContainer.GetTexture(ResourceContainer::Tex::ShadowMapCube0 + lightIndex); + resourceContainer.GetTexture(ResourceContainer::Tex2D::ShadowMapCube0 + lightIndex); resourceTracker.Transition(shadowMap, commandList, D3D12_RESOURCE_STATE_DEPTH_WRITE); } { - auto& shadowMap = resourceContainer.GetTexture(ResourceContainer::Tex::ShadowMapSun); + auto& shadowMap = resourceContainer.GetTexture(ResourceContainer::Tex2D::ShadowMapSun); resourceTracker.Transition(shadowMap, commandList, D3D12_RESOURCE_STATE_DEPTH_WRITE); } diff --git a/D3D12Backend/RenderPasses/SkyBoxRenderPass.cpp b/D3D12Backend/RenderPasses/SkyBoxRenderPass.cpp index 4f9b8ad..f04016d 100644 --- a/D3D12Backend/RenderPasses/SkyBoxRenderPass.cpp +++ b/D3D12Backend/RenderPasses/SkyBoxRenderPass.cpp @@ -26,7 +26,7 @@ namespace Boolka auto& resourceContainer = engineContext.GetResourceContainer(); UINT frameIndex = frameContext.GetFrameIndex(); - Texture2D& depth = resourceContainer.GetTexture(ResourceContainer::Tex::GbufferDepth); + Texture2D& depth = resourceContainer.GetTexture(ResourceContainer::Tex2D::GbufferDepth); RenderTargetView& lightBufferRTV = resourceContainer.GetRTV(ResourceContainer::RTV::LightBuffer); Buffer& frameConstantBuffer = resourceContainer.GetBuffer(ResourceContainer::Buf::Frame); diff --git a/D3D12Backend/RenderPasses/ToneMappingPass.cpp b/D3D12Backend/RenderPasses/ToneMappingPass.cpp index 9e82251..ea2161d 100644 --- a/D3D12Backend/RenderPasses/ToneMappingPass.cpp +++ b/D3D12Backend/RenderPasses/ToneMappingPass.cpp @@ -26,7 +26,10 @@ namespace Boolka auto& resourceContainer = engineContext.GetResourceContainer(); UINT frameIndex = frameContext.GetFrameIndex(); - Texture2D& lightBuffer = resourceContainer.GetTexture(ResourceContainer::Tex::LightBuffer); + Texture1D& tonemappingLUT = + resourceContainer.GetTexture(ResourceContainer::Tex1D::TonemappingLUT); + Texture2D& lightBuffer = + resourceContainer.GetTexture(ResourceContainer::Tex2D::LightBuffer); Texture2D& backBuffer = resourceContainer.GetBackBuffer(frameIndex); RenderTargetView& backBufferRTV = resourceContainer.GetBackBufferRTV(frameIndex); DescriptorHeap& mainDescriptorHeap = @@ -35,6 +38,28 @@ namespace Boolka GraphicCommandListImpl& commandList = threadContext.GetGraphicCommandList(); + static bool firstTime = true; + +#ifdef BLK_TONEMAPPING_USE_LUT + if (firstTime) + { + firstTime = false; + resourceTracker.Transition(tonemappingLUT, commandList, + D3D12_RESOURCE_STATE_UNORDERED_ACCESS); + engineContext.BindSceneResourcesCompute(commandList); + commandList->SetPipelineState( + engineContext.GetPSOContainer() + .GetPSO(PSOContainer::ComputePSO::ToneMappingLUTGeneration) + .Get()); + static_assert( + BLK_TONEMAPPING_LUT_RESOLUTION % BLK_TONEMAPPING_LUT_GENERATION_GROUP_SIZE == 0); + commandList->Dispatch( + BLK_TONEMAPPING_LUT_RESOLUTION / BLK_TONEMAPPING_LUT_GENERATION_GROUP_SIZE, 1, 1); + resourceTracker.Transition(tonemappingLUT, commandList, + D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE); + } +#endif + resourceTracker.Transition(lightBuffer, commandList, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE); resourceTracker.Transition(backBuffer, commandList, D3D12_RESOURCE_STATE_RENDER_TARGET); @@ -66,7 +91,8 @@ namespace Boolka commandList->SetPipelineState( engineContext.GetPSOContainer().GetPSO(PSOContainer::GraphicPSO::ToneMapping).Get()); - commandList->DrawInstanced(3, 1, 0, 2); + for (int i = 0; i < 10; i++) + commandList->DrawInstanced(3, 1, 0, 2); return true; } diff --git a/D3D12Backend/RenderPasses/TransparentRenderPass.cpp b/D3D12Backend/RenderPasses/TransparentRenderPass.cpp index 36403bf..5c3c53f 100644 --- a/D3D12Backend/RenderPasses/TransparentRenderPass.cpp +++ b/D3D12Backend/RenderPasses/TransparentRenderPass.cpp @@ -24,7 +24,7 @@ namespace Boolka auto& resourceContainer = engineContext.GetResourceContainer(); UINT frameIndex = frameContext.GetFrameIndex(); - Texture2D& depth = resourceContainer.GetTexture(ResourceContainer::Tex::GbufferDepth); + Texture2D& depth = resourceContainer.GetTexture(ResourceContainer::Tex2D::GbufferDepth); RenderTargetView& lightBufferRTV = resourceContainer.GetRTV(ResourceContainer::RTV::LightBuffer); DepthStencilView& depthDSV = resourceContainer.GetDSV(ResourceContainer::DSV::GbufferDepth); diff --git a/D3D12Backend/RenderPasses/ZRenderPass.cpp b/D3D12Backend/RenderPasses/ZRenderPass.cpp index 8c8949f..ebb8977 100644 --- a/D3D12Backend/RenderPasses/ZRenderPass.cpp +++ b/D3D12Backend/RenderPasses/ZRenderPass.cpp @@ -24,7 +24,7 @@ namespace Boolka UINT frameIndex = frameContext.GetFrameIndex(); Texture2D& gbufferDepth = - resourceContainer.GetTexture(ResourceContainer::Tex::GbufferDepth); + resourceContainer.GetTexture(ResourceContainer::Tex2D::GbufferDepth); DepthStencilView& gbufferDSV = resourceContainer.GetDSV(ResourceContainer::DSV::GbufferDepth); Buffer& frameConstantBuffer = resourceContainer.GetBuffer(ResourceContainer::Buf::Frame); diff --git a/D3D12Backend/Shaders/Color.hlsli b/D3D12Backend/Shaders/Color.hlsli index 4f7f9fb..56342f7 100644 --- a/D3D12Backend/Shaders/Color.hlsli +++ b/D3D12Backend/Shaders/Color.hlsli @@ -23,4 +23,17 @@ float3 SRGBToLinear(float3 srgbColor) return float3(SRGBToLinear(srgbColor.r), SRGBToLinear(srgbColor.g), SRGBToLinear(srgbColor.b)); } +float LinearToPQ(float linearColor) +{ + linearColor = linearColor / 100.0f; + float m1 = 2610.0 / 4096.0 / 4; + float m2 = 2523.0 / 4096.0 * 128; + float c1 = 3424.0 / 4096.0; + float c2 = 2413.0 / 4096.0 * 32; + float c3 = 2392.0 / 4096.0 * 32; + float Lp = pow(linearColor, m1); + return pow((c1 + c2 * Lp) / (1 + c3 * Lp), m2); +} + + #endif diff --git a/D3D12Backend/Shaders/CppShared.hlsli b/D3D12Backend/Shaders/CppShared.hlsli index 742043b..d25d128 100644 --- a/D3D12Backend/Shaders/CppShared.hlsli +++ b/D3D12Backend/Shaders/CppShared.hlsli @@ -10,7 +10,7 @@ using float4 = Vector4; using uint2 = Vector2u; using uint3 = Vector3u; using uint4 = Vector4u; -// Frustum and AABB is types in Boolka namespace +// Frustum and AABB are types in Boolka namespace #else @@ -38,6 +38,12 @@ struct AABB #define BLK_RT_MAX_RECURSION_DEPTH 4 +// Only used for performance/quality testing +// Undefining this doesn't prevent resource creation +#define BLK_TONEMAPPING_USE_LUT +#define BLK_TONEMAPPING_LUT_RESOLUTION 32 +#define BLK_TONEMAPPING_LUT_GENERATION_GROUP_SIZE 32 + #define BLK_DEBUG_DATA_ELEMENT_COUNT 4096 #define BLK_PROFILING_DATA_GPU_CULLING_OFFSET 0 diff --git a/D3D12Backend/Shaders/ResourceBindings.hlsli b/D3D12Backend/Shaders/ResourceBindings.hlsli index de0ec4f..7108228 100644 --- a/D3D12Backend/Shaders/ResourceBindings.hlsli +++ b/D3D12Backend/Shaders/ResourceBindings.hlsli @@ -20,8 +20,9 @@ ConstantBuffer GPUCulling : register(b2, space1); RWTexture2D raytraceUAV : register(u0); RWStructuredBuffer gpuCullingCommandUAV : register(u1); RWStructuredBuffer gpuCullingMeshletIndicesUAV : register(u2); -RWStructuredBuffer profileMetrics : register(u3); -RWStructuredBuffer debugMarkers : register(u4); +RWTexture1D tonemappingLUTUAV : register(u3); +RWStructuredBuffer profileMetrics : register(u4); +RWStructuredBuffer debugMarkers : register(u5); // Pipeline resources Texture2D albedo : register(t0); @@ -32,6 +33,7 @@ Texture2D lightBuffer : register(t4); StructuredBuffer gpuCullingMeshletIndices : register(t5); TextureCube shadowMapCube[4] : register(t6); Texture2D shadowMapSun : register(t10); +Texture1D tonemappingLUT : register(t11); // Meshlet data StructuredBuffer vertexBuffer1 : register(t0, space1); diff --git a/D3D12Backend/Shaders/RootSig.hlsl b/D3D12Backend/Shaders/RootSig.hlsl index 047cf3f..8b3e6ac 100644 --- a/D3D12Backend/Shaders/RootSig.hlsl +++ b/D3D12Backend/Shaders/RootSig.hlsl @@ -8,8 +8,8 @@ "RootConstants(num32BitConstants=1, b2), " /* CPU constant */ \ "RootConstants(num32BitConstants=1, b3), " /* GPU indirect constant */ \ "DescriptorTable(CBV(b0, space=1, numDescriptors = 3, flags = DATA_VOLATILE)," /* CBVs */ \ - "UAV(u0, numDescriptors = 5, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE), " /* UAVs */ \ - "SRV(t0, space=0, numDescriptors = 11, flags = DATA_VOLATILE), " /* Dynamic resources */ \ + "UAV(u0, numDescriptors = 6, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE), " /* UAVs */ \ + "SRV(t0, space=0, numDescriptors = 12, flags = DATA_VOLATILE), " /* Dynamic resources */ \ "SRV(t0, space=1, numDescriptors = 8, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE), " /* Meshlet data */ \ "SRV(t0, space=2, numDescriptors = 3, flags = DATA_STATIC), " /* RT data */ \ "SRV(t0, space=3, numDescriptors = 1, flags = DATA_STATIC), " /* Sky box */ \ diff --git a/D3D12Backend/Shaders/ToneMappingPass/ToneMappingPassCS.hlsl b/D3D12Backend/Shaders/ToneMappingPass/ToneMappingPassCS.hlsl new file mode 100644 index 0000000..289ff1a --- /dev/null +++ b/D3D12Backend/Shaders/ToneMappingPass/ToneMappingPassCS.hlsl @@ -0,0 +1,10 @@ +#include "ToneMappingPassCommon.hlsli" + +[numthreads(BLK_TONEMAPPING_LUT_GENERATION_GROUP_SIZE, 1, 1)] +void main(uint3 DTid : SV_DispatchThreadID) +{ + uint idx = DTid.x; + float lutU = float(idx + 0.5f) / float(BLK_TONEMAPPING_LUT_RESOLUTION); + float inputValue = TonemapLUTRemapBackward(lutU); + tonemappingLUTUAV[idx] = TonemapViaCompute(inputValue); +} diff --git a/D3D12Backend/Shaders/ToneMappingPass/ToneMappingPassCommon.hlsli b/D3D12Backend/Shaders/ToneMappingPass/ToneMappingPassCommon.hlsli new file mode 100644 index 0000000..cc71206 --- /dev/null +++ b/D3D12Backend/Shaders/ToneMappingPass/ToneMappingPassCommon.hlsli @@ -0,0 +1,67 @@ +#include "../Color.hlsli" +#include "../FullScreen/FullScreenCommon.hlsli" + +struct PSOut +{ + float4 color : SV_Target; +}; + +// https://www.desmos.com/calculator/gslcdxvipg +float GTTonemap(float x) +{ + float P = 1.0f; + float a = 1.0f; + float m = 0.22f; + float l = 0.4f; + float c = 1.33f; + float b = 0.0f; + float l0 = (P - m) * l / a; + float Lx = m + a * (x - m); + float Tx = m * pow(x / m, c) + b; + float S0 = m + l0; + float S1 = m + a * l0; + float C2 = a * P / (P - S1); + float Sx = P - (P - S1) * exp(-C2 * (x - S0) / P); + float w0 = 1.0f - smoothstep(0, m, x); + float w2 = step(m + l0, x); + float w1 = 1.0f - w0 - w2; + return Tx * w0 + Lx * w1 + Sx * w2; +} + +float TonemapViaCompute(float c) +{ + return LinearToPQ(GTTonemap(c)); +} + +float3 TonemapViaCompute(float3 c) +{ + return float3(TonemapViaCompute(c.r), TonemapViaCompute(c.g), TonemapViaCompute(c.b)); +} + +float TonemapLUTRemapForward(float c) +{ + c = c / 5.0f; + c = sqrt(c); + c = c * (float(BLK_TONEMAPPING_LUT_RESOLUTION - 1) / BLK_TONEMAPPING_LUT_RESOLUTION); + c = c + 0.5f / BLK_TONEMAPPING_LUT_RESOLUTION; + return saturate(c); +} + +float TonemapLUTRemapBackward(float c) +{ + c = saturate(c); + c = c - 0.5f / BLK_TONEMAPPING_LUT_RESOLUTION; + c = c * (BLK_TONEMAPPING_LUT_RESOLUTION / float(BLK_TONEMAPPING_LUT_RESOLUTION - 1)); + c = c * c; + return c * 5.0f; +} + +float TonemapViaLUT(float c) +{ + return tonemappingLUT.SampleLevel(linearSingleMipSampler, TonemapLUTRemapForward(c), 0); +} + +float3 TonemapViaLUT(float3 c) +{ + return float3(TonemapViaLUT(c.r), TonemapViaLUT(c.g), TonemapViaLUT(c.b)); +} diff --git a/D3D12Backend/Shaders/ToneMappingPass/ToneMappingPassPS.hlsl b/D3D12Backend/Shaders/ToneMappingPass/ToneMappingPassPS.hlsl index b98b31a..6e6dc55 100644 --- a/D3D12Backend/Shaders/ToneMappingPass/ToneMappingPassPS.hlsl +++ b/D3D12Backend/Shaders/ToneMappingPass/ToneMappingPassPS.hlsl @@ -1,43 +1,4 @@ -#include "../Color.hlsli" -#include "../FullScreen/FullScreenCommon.hlsli" - -struct PSOut -{ - float4 color : SV_Target; -}; - -// https://www.desmos.com/calculator/gslcdxvipg -float GTTonemap(float x) -{ - float P = 1.0f; - float a = 1.0f; - float m = 0.22f; - float l = 0.4f; - float c = 1.33f; - float b = 0.0f; - float l0 = (P - m) * l / a; - float Lx = m + a * (x - m); - float Tx = m * pow(x / m, c) + b; - float S0 = m + l0; - float S1 = m + a * l0; - float C2 = a * P / (P - S1); - float Sx = P - (P - S1) * exp(-C2 * (x - S0) / P); - float w0 = 1.0f - smoothstep(0, m, x); - float w2 = step(m + l0, x); - float w1 = 1.0f - w0 - w2; - return Tx * w0 + Lx * w1 + Sx * w2; -} - -float3 GTTonemap(float3 c) -{ - // Another option is to tonemap max from rgb components and scale others accordingly - return float3(GTTonemap(c.r), GTTonemap(c.g), GTTonemap(c.b)); -} - -float3 Tonemap(float3 c) -{ - return LinearToSRGB(GTTonemap(c)); -} +#include "ToneMappingPassCommon.hlsli" PSOut main(VSOut In) { @@ -45,6 +6,11 @@ PSOut main(VSOut In) uint2 vpos = uint2(In.position.xy); float4 light = lightBuffer.Load(uint3(vpos, 0)); - Out.color = float4(Tonemap(light.rgb), 0.0f); +#ifdef BLK_TONEMAPPING_USE_LUT + float3 tonemapped = TonemapViaLUT(light.rgb); +#else + float3 tonemapped = TonemapViaCompute(light.rgb); +#endif + Out.color = float4(tonemapped, 0.0f); return Out; }