├── .gitignore ├── .gitmodules ├── Build Tools └── Independency │ ├── Independency.exe │ └── tools │ ├── 7za.exe │ └── wget.exe ├── Fetch Dependencies.bat ├── Premake ├── corsairengine │ ├── common.lua │ └── dependencies.lua ├── mobdebug.lua ├── premake5-osx └── premake5.exe ├── Source ├── Core │ ├── CrAlignment.h │ ├── CrCommandLine.cpp │ ├── CrCommandLine.h │ ├── CrCoreForwardDeclarations.h │ ├── CrCore_pch.cpp │ ├── CrCore_pch.h │ ├── CrFrameTime.cpp │ ├── CrFrameTime.h │ ├── CrGlobalPaths.cpp │ ├── CrGlobalPaths.h │ ├── CrHash.h │ ├── CrMacros.h │ ├── CrNumericLimits.h │ ├── CrPlatform.h │ ├── CrTypedId.h │ ├── FileSystem │ │ └── CrFixedPath.h │ ├── Input │ │ ├── CrInputManager.cpp │ │ ├── CrInputManager.h │ │ ├── CrPlatformInput.h │ │ └── CrPlatformInputWin32.cpp │ ├── Logging │ │ ├── ICrDebug.h │ │ └── platform │ │ │ └── windows │ │ │ ├── CrDebug_win.cpp │ │ │ └── CrDebug_win.h │ ├── PCH │ │ ├── CrCRSTLPch.h │ │ └── CrWindowsPch.h │ └── Streams │ │ ├── CrFileStream.h │ │ ├── CrMemoryStream.h │ │ └── ICrStream.h ├── CrEntity.cpp ├── CrEntity.h ├── CrEntryPoint.cpp ├── CrFrame.cpp ├── CrFrame.h ├── CrOSWindow.h ├── CrOSWindowWin32.cpp ├── Editor │ ├── CrEditor.cpp │ ├── CrEditor.h │ ├── CrImGuiViewports.cpp │ └── CrImGuiViewports.h ├── Math │ ├── CrHalf.h │ ├── CrHlslppMatrixFloat.h │ ├── CrHlslppMatrixFloatType.h │ ├── CrHlslppQuaternion.h │ ├── CrHlslppQuaternionType.h │ ├── CrHlslppVectorFloat.h │ ├── CrHlslppVectorFloatType.h │ ├── CrHlslppVectorInt.h │ ├── CrHlslppVectorIntType.h │ ├── CrHlslppVectorUint.h │ ├── CrHlslppVectorUintType.h │ ├── CrMath.h │ ├── CrMathPch.h │ ├── CrTransform.h │ └── CrVectorT.h ├── Rendering │ ├── CrBuiltinPipeline.cpp │ ├── CrBuiltinPipeline.h │ ├── CrCPUStackAllocator.cpp │ ├── CrCPUStackAllocator.h │ ├── CrCamera.cpp │ ├── CrCamera.h │ ├── CrCommonVertexLayouts.cpp │ ├── CrCommonVertexLayouts.h │ ├── CrDataFormats.h │ ├── CrGPUBuffer.cpp │ ├── CrGPUBuffer.h │ ├── CrGPUDeletable.cpp │ ├── CrGPUDeletable.h │ ├── CrGPUDeletionQueue.cpp │ ├── CrGPUDeletionQueue.h │ ├── CrGPUStackAllocator.cpp │ ├── CrGPUStackAllocator.h │ ├── CrGPUTimingQueryTracker.cpp │ ├── CrGPUTimingQueryTracker.h │ ├── CrGPUTransferCallbackQueue.cpp │ ├── CrGPUTransferCallbackQueue.h │ ├── CrImage.cpp │ ├── CrImage.h │ ├── CrLight.cpp │ ├── CrLight.h │ ├── CrMaterial.cpp │ ├── CrMaterial.h │ ├── CrMaterialCompiler.cpp │ ├── CrMaterialCompiler.h │ ├── CrRenderGraph.cpp │ ├── CrRenderGraph.h │ ├── CrRenderMesh.cpp │ ├── CrRenderMesh.h │ ├── CrRenderModel.cpp │ ├── CrRenderModel.h │ ├── CrRenderPassDescriptor.h │ ├── CrRendererConfig.cpp │ ├── CrRendererConfig.h │ ├── CrRendering.cpp │ ├── CrRendering.h │ ├── CrRenderingForwardDeclarations.h │ ├── CrRenderingResources.cpp │ ├── CrRenderingResources.h │ ├── CrRenderingStatistics.cpp │ ├── CrRenderingStatistics.h │ ├── CrRenderingVector.h │ ├── CrRendering_pch.cpp │ ├── CrRendering_pch.h │ ├── CrShaderDiskCache.cpp │ ├── CrShaderDiskCache.h │ ├── CrShaderManager.cpp │ ├── CrShaderManager.h │ ├── CrShaderReflectionHeader.h │ ├── CrShaderResourceMetadata.cpp │ ├── CrShaderResourceMetadata.h │ ├── CrShaderSources.cpp │ ├── CrShaderSources.h │ ├── CrShapeBuilder.cpp │ ├── CrShapeBuilder.h │ ├── CrStackAllocator.h │ ├── CrVertexDescriptor.cpp │ ├── CrVertexDescriptor.h │ ├── CrVisibility.cpp │ ├── CrVisibility.h │ ├── Extensions │ │ ├── CrNVAPIHeader.h │ │ └── CrPIXHeader.h │ ├── FrameCapture │ │ ├── CrPIX.cpp │ │ ├── CrPIX.h │ │ ├── CrRenderDoc.cpp │ │ └── CrRenderDoc.h │ ├── ICrCommandBuffer.cpp │ ├── ICrCommandBuffer.h │ ├── ICrGPUQueryPool.cpp │ ├── ICrGPUQueryPool.h │ ├── ICrGPUSynchronization.cpp │ ├── ICrGPUSynchronization.h │ ├── ICrPipeline.cpp │ ├── ICrPipeline.h │ ├── ICrRenderDevice.cpp │ ├── ICrRenderDevice.h │ ├── ICrRenderSystem.cpp │ ├── ICrRenderSystem.h │ ├── ICrSampler.cpp │ ├── ICrSampler.h │ ├── ICrShader.cpp │ ├── ICrShader.h │ ├── ICrShader.inl │ ├── ICrShaderReflection.h │ ├── ICrSwapchain.cpp │ ├── ICrSwapchain.h │ ├── ICrTexture.cpp │ ├── ICrTexture.h │ ├── RenderWorld │ │ ├── CrModelInstance.h │ │ ├── CrRenderWorld.cpp │ │ └── CrRenderWorld.h │ ├── ShaderCompiler │ │ ├── CrBuiltinShaderBuilder.cpp │ │ ├── CrBuiltinShaderBuilder.h │ │ ├── CrCompilerDXC.cpp │ │ ├── CrCompilerDXC.h │ │ ├── CrShaderCompiler.cpp │ │ ├── CrShaderCompiler.h │ │ ├── CrShaderCompilerUtilities.cpp │ │ ├── CrShaderCompilerUtilities.h │ │ ├── CrShaderCompiler_pch.cpp │ │ ├── CrShaderCompiler_pch.h │ │ ├── CrShaderMetadataBuilder.cpp │ │ └── CrShaderMetadataBuilder.h │ ├── Shaders │ │ ├── BSDF.hlsl │ │ ├── Colors.hlsl │ │ ├── Common.hlsl │ │ ├── Compute.hlsl │ │ ├── Compute.shaders │ │ ├── ComputeCommon.hlsl │ │ ├── CopyTexture.hlsl │ │ ├── CopyTexture.shaders │ │ ├── Depth.hlsl │ │ ├── Depth.shaders │ │ ├── DirectLighting.hlsl │ │ ├── DirectLighting.shaders │ │ ├── DirectLightingShared.hlsl │ │ ├── Editor.hlsl │ │ ├── Editor.shaders │ │ ├── GBuffer.hlsl │ │ ├── Imgui.hlsl │ │ ├── Imgui.shaders │ │ ├── IndirectRendering.hlsl │ │ ├── Lighting.hlsl │ │ ├── Metadata.hlsl │ │ ├── PostProcessing.hlsl │ │ ├── PostProcessing.shaders │ │ ├── Surface.hlsl │ │ ├── Ubershader.hlsl │ │ ├── Ubershader.shaders │ │ ├── UbershaderResources.hlsl │ │ └── d3d12 │ │ │ ├── D3D12.hlsl │ │ │ └── D3D12.shaders │ ├── UI │ │ ├── CrImGuiRenderer.cpp │ │ └── CrImGuiRenderer.h │ ├── Vulkan │ │ ├── CrCommandBuffer_vk.cpp │ │ ├── CrCommandBuffer_vk.h │ │ ├── CrGPUBuffer_vk.cpp │ │ ├── CrGPUBuffer_vk.h │ │ ├── CrGPUQueryPool_vk.cpp │ │ ├── CrGPUQueryPool_vk.h │ │ ├── CrGPUSynchronization_vk.cpp │ │ ├── CrGPUSynchronization_vk.h │ │ ├── CrPipeline_vk.cpp │ │ ├── CrPipeline_vk.h │ │ ├── CrRenderDevice_vk.cpp │ │ ├── CrRenderDevice_vk.h │ │ ├── CrRenderSystem_vk.cpp │ │ ├── CrRenderSystem_vk.h │ │ ├── CrSampler_vk.cpp │ │ ├── CrSampler_vk.h │ │ ├── CrShader_vk.cpp │ │ ├── CrShader_vk.h │ │ ├── CrSwapchain_vk.cpp │ │ ├── CrSwapchain_vk.h │ │ ├── CrTexture_vk.cpp │ │ ├── CrTexture_vk.h │ │ ├── CrVMA.h │ │ ├── CrVulkan.cpp │ │ └── CrVulkan.h │ └── d3d12 │ │ ├── CrCommandBuffer_d3d12.cpp │ │ ├── CrCommandBuffer_d3d12.h │ │ ├── CrD3D12.cpp │ │ ├── CrD3D12.h │ │ ├── CrDescriptorHeap_d3d12.cpp │ │ ├── CrDescriptorHeap_d3d12.h │ │ ├── CrGPUBuffer_d3d12.cpp │ │ ├── CrGPUBuffer_d3d12.h │ │ ├── CrGPUQueryPool_d3d12.cpp │ │ ├── CrGPUQueryPool_d3d12.h │ │ ├── CrGPUSynchronization_d3d12.cpp │ │ ├── CrGPUSynchronization_d3d12.h │ │ ├── CrPipeline_d3d12.cpp │ │ ├── CrPipeline_d3d12.h │ │ ├── CrRenderDevice_d3d12.cpp │ │ ├── CrRenderDevice_d3d12.h │ │ ├── CrRenderSystem_d3d12.cpp │ │ ├── CrRenderSystem_d3d12.h │ │ ├── CrSampler_d3d12.cpp │ │ ├── CrSampler_d3d12.h │ │ ├── CrShader_d3d12.cpp │ │ ├── CrShader_d3d12.h │ │ ├── CrSwapchain_d3d12.cpp │ │ ├── CrSwapchain_d3d12.h │ │ ├── CrTexture_d3d12.cpp │ │ └── CrTexture_d3d12.h └── Resource │ ├── CrResourceManager.cpp │ ├── CrResourceManager.h │ ├── CrResource_pch.cpp │ ├── CrResource_pch.h │ ├── Image │ ├── CrImageCodecDDS.cpp │ ├── CrImageCodecDDS.h │ ├── CrImageCodecSTB.cpp │ ├── CrImageCodecSTB.h │ ├── CrImageCodecWuffs.cpp │ ├── CrImageCodecWuffs.h │ ├── CrImageForwardDeclarations.h │ └── ICrImageCodec.h │ └── Model │ ├── CrModelDecoderASSIMP.cpp │ ├── CrModelDecoderASSIMP.h │ ├── CrModelDecoderCGLTF.cpp │ ├── CrModelDecoderCGLTF.h │ ├── CrModelDecoderUFBX.cpp │ ├── CrModelDecoderUFBX.h │ └── ICrModelDecoder.h ├── Visual Studio 2019.bat ├── Visual Studio 2022.bat ├── XCode.command ├── appveyor.yml ├── corsair-dependencies.xml ├── corsairengine.lua └── packages.xml /.gitignore: -------------------------------------------------------------------------------- 1 | Workspace 2 | Build 3 | Dependencies -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "Dependencies/hlslpp/Include"] 2 | path = Dependencies/hlslpp/Include 3 | url = https://github.com/redorav/hlslpp 4 | [submodule "Dependencies/ddspp/Include"] 5 | path = Dependencies/ddspp/Include 6 | url = https://github.com/redorav/ddspp/ 7 | [submodule "Dependencies/crstl/Include"] 8 | path = Dependencies/crstl/Include 9 | url = https://github.com/redorav/crstl 10 | -------------------------------------------------------------------------------- /Build Tools/Independency/Independency.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redorav/corsair-engine/5e96cf5459fcf5f1afaf78074d9c38400755ba13/Build Tools/Independency/Independency.exe -------------------------------------------------------------------------------- /Build Tools/Independency/tools/7za.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redorav/corsair-engine/5e96cf5459fcf5f1afaf78074d9c38400755ba13/Build Tools/Independency/tools/7za.exe -------------------------------------------------------------------------------- /Build Tools/Independency/tools/wget.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redorav/corsair-engine/5e96cf5459fcf5f1afaf78074d9c38400755ba13/Build Tools/Independency/tools/wget.exe -------------------------------------------------------------------------------- /Fetch Dependencies.bat: -------------------------------------------------------------------------------- 1 | "./Build Tools\Independency\Independency.exe" -packages packages.xml -dependencies corsair-dependencies.xml -destination Dependencies -------------------------------------------------------------------------------- /Premake/corsairengine/common.lua: -------------------------------------------------------------------------------- 1 | -- Functionality that is common to all lua scripts in the Corsair Engine 2 | 3 | function GetCopyLibraryPostBuildCommand(action) 4 | 5 | local postBuildCopyCommand = "{copy} %{cfg.buildtarget.abspath} ../../Binaries/%{prj.name}."..action..".%{cfg.buildcfg:lower()}".."%{cfg.buildtarget.extension}" 6 | 7 | if action == "vs2017" then 8 | postBuildCopyCommand = postBuildCopyCommand.."*" 9 | end 10 | 11 | return postBuildCopyCommand 12 | end -------------------------------------------------------------------------------- /Premake/premake5-osx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redorav/corsair-engine/5e96cf5459fcf5f1afaf78074d9c38400755ba13/Premake/premake5-osx -------------------------------------------------------------------------------- /Premake/premake5.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redorav/corsair-engine/5e96cf5459fcf5f1afaf78074d9c38400755ba13/Premake/premake5.exe -------------------------------------------------------------------------------- /Source/Core/CrAlignment.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Core/Logging/ICrDebug.h" 4 | 5 | template 6 | inline T CrAlignUpPow2(T input, uintptr_t pow2) 7 | { 8 | uintptr_t uInput = (uintptr_t)input; 9 | CrAssertMsg(pow2 && ((pow2 & (pow2 - 1)) == 0), "Not a power of 2"); 10 | return (T)((uInput + pow2 - 1) & ~(pow2 - 1)); 11 | } 12 | 13 | template 14 | inline T CrAlignUp256(T input) 15 | { 16 | return CrAlignUpPow2(input, 256); 17 | } -------------------------------------------------------------------------------- /Source/Core/CrCommandLine.cpp: -------------------------------------------------------------------------------- 1 | #include "Core/CrCore_pch.h" 2 | 3 | #include "CrCommandLine.h" 4 | 5 | #if defined(_WIN32) 6 | #include 7 | #include 8 | #endif 9 | 10 | #include "Core/CrMacros.h" 11 | 12 | namespace crcore 13 | { 14 | CrCommandLineParser CommandLine; 15 | } 16 | 17 | CrCommandLineParser::CrCommandLineParser(int argcInput, char* argvInput[]) 18 | { 19 | // Unix systems work in UTF-8 by default and have no problem inputting a properly encoded argv. 20 | // On Windows, however, directories do not come in as UTF-8 so we need to translate the wchar 21 | // version of the parameters to a Unicode (multibyte in Windows parlance) version. Because of 22 | // that, we also need to manage the memory for that fixed command line 23 | #if defined(_WIN32) 24 | 25 | unused_parameter(argvInput); 26 | 27 | int argc = argcInput; 28 | char** argv = new char* [argcInput + 1]; 29 | argv[argcInput] = nullptr; 30 | 31 | // Get the wide command line provided by Windows 32 | int wargc; 33 | wchar_t** wargv = CommandLineToArgvW(GetCommandLineW(), &wargc); 34 | 35 | // Convert to UTF-8 and store locally 36 | for (int i = 0; i < wargc; ++i) 37 | { 38 | // Returns size required for the UTF-8 string 39 | int size = WideCharToMultiByte(CP_UTF8, 0, wargv[i], -1, nullptr, 0, nullptr, nullptr); 40 | 41 | // Allocate new string (taking care to add the null terminator) 42 | argv[i] = new char[size]; 43 | argv[i][size - 1] = 0; 44 | 45 | // Convert wide char to multibyte 46 | WideCharToMultiByte(CP_UTF8, 0, wargv[i], (int)wcslen(wargv[i]), argv[i], size, nullptr, nullptr); 47 | } 48 | 49 | LocalFree(wargv); 50 | 51 | #else 52 | 53 | argc = argcInput; 54 | argv = argvInput; 55 | 56 | #endif 57 | 58 | for (int i = 0; i < argc; ++i) 59 | { 60 | // If it starts with an option character 61 | if (argv[i][0] == '-') 62 | { 63 | // If it has a value and the value is not an option string 64 | if ((i + 1) < argc && argv[i + 1][0] != '-') 65 | { 66 | commandLineArgs.insert(crstl::string(argv[i]), crstl::string(argv[i + 1])); // Insert value option 67 | ++i; // Skip next argument 68 | } 69 | else 70 | { 71 | commandLineArgs.insert(crstl::string(argv[i]), crstl::string()); 72 | } 73 | } 74 | } 75 | 76 | #if defined(_WIN32) 77 | 78 | // Delete each string first 79 | for (int i = 0; i < argc; ++i) 80 | { 81 | delete argv[i]; 82 | } 83 | 84 | // Delete the array 85 | delete[] argv; 86 | 87 | #endif 88 | } -------------------------------------------------------------------------------- /Source/Core/CrCommandLine.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "crstl/open_hashmap.h" 4 | #include "crstl/string.h" 5 | 6 | class CrCommandLineParser 7 | { 8 | public: 9 | 10 | CrCommandLineParser() {} 11 | 12 | CrCommandLineParser(int argc, char* argv[]); 13 | 14 | // Get first value using key 15 | const crstl::string& operator()(const crstl::string& key) 16 | { 17 | auto it = commandLineArgs.find(key); 18 | if (it != commandLineArgs.end()) 19 | { 20 | return it->second; 21 | } 22 | else 23 | { 24 | return invalid; 25 | } 26 | } 27 | 28 | // Get whether key is present 29 | bool operator[](const crstl::string& key) 30 | { 31 | return commandLineArgs.find(key) != commandLineArgs.end(); 32 | } 33 | 34 | // Iterate through the different values of options 35 | template 36 | void for_each(const crstl::string& key, const FunctionT& function) 37 | { 38 | commandLineArgs.for_each(key, function); 39 | } 40 | 41 | private: 42 | 43 | crstl::string invalid; 44 | 45 | // It is unordered with respect to keys, but ordered values for each key 46 | crstl::open_multi_hashmap commandLineArgs; 47 | }; 48 | 49 | namespace crcore 50 | { 51 | extern CrCommandLineParser CommandLine; 52 | } -------------------------------------------------------------------------------- /Source/Core/CrCoreForwardDeclarations.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "stdint.h" 4 | 5 | #include "crstl/forward_declarations.h" 6 | 7 | class CrHash; 8 | 9 | using CrFixedPath = crstl::fixed_path512; 10 | 11 | namespace cr { namespace Platform { enum T : uint32_t; } } -------------------------------------------------------------------------------- /Source/Core/CrCore_pch.cpp: -------------------------------------------------------------------------------- 1 | #include "Core/CrCore_pch.h" -------------------------------------------------------------------------------- /Source/Core/CrCore_pch.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Core/PCH/CrCRSTLPch.h" 4 | #include "Core/PCH/CrWindowsPch.h" 5 | #include "Core/CrHash.h" 6 | 7 | #include "Math/CrMathPch.h" -------------------------------------------------------------------------------- /Source/Core/CrFrameTime.cpp: -------------------------------------------------------------------------------- 1 | #include "Core/CrCore_pch.h" 2 | 3 | #include "CrFrameTime.h" 4 | 5 | #include "Core/Logging/ICrDebug.h" 6 | 7 | #include "crstl/string.h" 8 | 9 | uint64_t CrFrameTime::m_frameCount = 0; 10 | crstl::time CrFrameTime::m_frameDelta; 11 | crstl::time CrFrameTime::m_framePreviousEndTime; 12 | 13 | uint64_t CrFrameTime::m_lastUpdatedFrameCount; 14 | crstl::time CrFrameTime::m_lastUpdatedTime; 15 | crstl::time CrFrameTime::m_frameDeltaAverage; 16 | crstl::time CrFrameTime::m_frameDeltaMin; 17 | crstl::time CrFrameTime::m_frameDeltaMax; 18 | 19 | void CrFrameTime::IncrementFrameCount() 20 | { 21 | crstl::time currentTime = crstl::time::now(); 22 | 23 | if ((currentTime - m_lastUpdatedTime).seconds() > 1.0f) 24 | { 25 | //CrPrintProcessMemory("Frame Memory"); 26 | 27 | m_lastUpdatedTime = currentTime; 28 | m_lastUpdatedFrameCount = m_frameCount; 29 | } 30 | 31 | // If the previous end time hasn't been initialized yet, set it to the current time 32 | if (m_framePreviousEndTime.ticks() == 0) 33 | { 34 | m_framePreviousEndTime = currentTime; 35 | } 36 | 37 | m_frameDelta = currentTime - m_framePreviousEndTime; 38 | m_framePreviousEndTime = currentTime; 39 | 40 | if (m_frameCount > 0) 41 | { 42 | m_frameDeltaMin = m_frameDelta < m_frameDeltaMin ? m_frameDelta : m_frameDeltaMin; 43 | m_frameDeltaMax = m_frameDelta > m_frameDeltaMax ? m_frameDelta : m_frameDeltaMax; 44 | } 45 | 46 | m_frameCount = (m_frameCount + 1) % UINT64_MAX; 47 | 48 | // Update average 49 | m_frameDeltaAverage += (m_frameDelta - m_frameDeltaAverage) / 64; 50 | } 51 | 52 | crstl::time CrFrameTime::GetFrameDelta() 53 | { 54 | return m_frameDelta; 55 | } 56 | 57 | crstl::time CrFrameTime::GetFrameDeltaAverage() 58 | { 59 | return m_frameDeltaAverage; 60 | } 61 | 62 | crstl::time CrFrameTime::GetFrameDeltaMin() 63 | { 64 | return m_frameDeltaMin; 65 | } 66 | 67 | crstl::time CrFrameTime::GetFrameDeltaMax() 68 | { 69 | return m_frameDeltaMax; 70 | } 71 | 72 | uint64_t CrFrameTime::GetFrameIndex() 73 | { 74 | return m_frameCount; 75 | } -------------------------------------------------------------------------------- /Source/Core/CrFrameTime.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "stdint.h" 4 | 5 | #include "crstl/timer.h" 6 | 7 | class CrFrameTime 8 | { 9 | public: 10 | 11 | static void IncrementFrameCount(); 12 | 13 | static crstl::time GetFrameDelta(); 14 | 15 | static crstl::time GetFrameDeltaAverage(); 16 | 17 | static crstl::time GetFrameDeltaMin(); 18 | 19 | static crstl::time GetFrameDeltaMax(); 20 | 21 | static uint64_t GetFrameIndex(); 22 | 23 | private: 24 | 25 | static uint64_t m_frameCount; 26 | 27 | static crstl::time m_frameDelta; 28 | 29 | static crstl::time m_frameDeltaAverage; 30 | 31 | static crstl::time m_frameDeltaMin; 32 | 33 | static crstl::time m_frameDeltaMax; 34 | 35 | static crstl::time m_framePreviousEndTime; 36 | 37 | static crstl::time m_lastUpdatedTime; 38 | 39 | static uint64_t m_lastUpdatedFrameCount; 40 | 41 | static uint32_t m_deltaHistoryIndex; 42 | }; -------------------------------------------------------------------------------- /Source/Core/CrGlobalPaths.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "crstl/string.h" 4 | 5 | class CrGlobalPaths 6 | { 7 | public: 8 | 9 | CrGlobalPaths(); 10 | 11 | static void SetupGlobalPaths 12 | ( 13 | const char* currentExecutableDirectory, 14 | const char* dataRootDirectory 15 | ); 16 | 17 | static const crstl::string& GetAppDataDirectory(); 18 | 19 | static const crstl::string& GetCurrentExecutableDirectory(); 20 | 21 | static const crstl::string& GetCurrentWorkingDirectory(); 22 | 23 | static const crstl::string& GetDataRootDirectory(); 24 | 25 | static const crstl::string& GetShaderCompilerPath(); 26 | 27 | static const crstl::string& GetShaderSourceDirectory(); 28 | 29 | static const crstl::string& GetTempEngineDirectory(); 30 | 31 | static const crstl::string& GetTempDirectory(); 32 | 33 | private: 34 | 35 | // App Data directory. Use for savegames, preferences, etc 36 | static crstl::string AppDataDirectory; 37 | 38 | // Directory where executable is running 39 | static crstl::string CurrentExecutableDirectory; 40 | 41 | // Current working directory (not necessarily the same as the executable) 42 | static crstl::string CurrentWorkingDirectory; 43 | 44 | // Path to root of data 45 | static crstl::string DataRootDirectory; 46 | 47 | // Path to shader compiler 48 | static crstl::string ShaderCompilerPath; 49 | 50 | // Directory where shader source lives 51 | static crstl::string ShaderSourceDirectory; 52 | 53 | // Temporary directory for engine (i.e. subfolder called Corsair Engine) 54 | // The data here needs to be deletable, i.e. if the OS or someone nukes 55 | // the folder the engine must be able to ignore or recreate it 56 | static crstl::string TempEngineDirectory; 57 | 58 | // Generic temporary directory 59 | static crstl::string TempDirectory; 60 | }; -------------------------------------------------------------------------------- /Source/Core/CrHash.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Core/CrMacros.h" 4 | 5 | warnings_off 6 | #define XXH_INLINE_ALL 7 | #include 8 | warnings_on 9 | 10 | class CrHash 11 | { 12 | public: 13 | 14 | static const uint64_t HashSeed = 100; 15 | 16 | CrHash() : m_hash(0) {} 17 | 18 | explicit CrHash(uint64_t hash) : m_hash(hash) {} 19 | 20 | void Reset() 21 | { 22 | m_hash = 0; 23 | } 24 | 25 | uint64_t GetHash() const 26 | { 27 | return m_hash; 28 | } 29 | 30 | template 31 | CrHash(const T& data) 32 | { 33 | m_hash = ComputeHash(&data, sizeof(T)); 34 | } 35 | 36 | template 37 | CrHash(const T* data, uint64_t dataSize) 38 | { 39 | m_hash = ComputeHash(data, dataSize); 40 | } 41 | 42 | CrHash(const char* data, uint32_t length) 43 | { 44 | m_hash = ComputeHash(data, length); 45 | } 46 | 47 | // Streaming operator, incrementally adds hash by combining existing hash with incoming hash 48 | CrHash& operator << (CrHash other) 49 | { 50 | uint64_t hashes[2] = { m_hash, other.m_hash }; 51 | m_hash = ComputeHash(hashes, sizeof(hashes)); 52 | return *this; 53 | } 54 | 55 | bool operator == (const CrHash& other) const 56 | { 57 | return m_hash == other.m_hash; 58 | } 59 | 60 | bool operator != (const CrHash& other) const 61 | { 62 | return m_hash != other.m_hash; 63 | } 64 | 65 | // TODO Select hash function at compile time based on the size of datatype. 66 | // http://aras-p.info/blog/2016/08/09/More-Hash-Function-Tests/ 67 | template 68 | static uint64_t ComputeHash(const T* data) 69 | { 70 | return XXH64(data, sizeof(T), HashSeed); 71 | } 72 | 73 | template 74 | static uint64_t ComputeHash(const T* data, uint64_t dataSize) 75 | { 76 | return XXH64(data, dataSize, HashSeed); 77 | } 78 | 79 | private: 80 | 81 | // Don't hash pointers directly 82 | template CrHash(const T* data); 83 | template CrHash(T* data); 84 | 85 | uint64_t m_hash; 86 | }; 87 | 88 | // Combine two hashes and return the hash of both 89 | inline CrHash operator + (CrHash first, CrHash second) 90 | { 91 | uint64_t hashes[2] = { first.GetHash(), second.GetHash() }; 92 | return CrHash(hashes, sizeof(hashes)); 93 | } 94 | 95 | namespace crstl 96 | { 97 | template struct hash; 98 | 99 | template<> 100 | struct hash 101 | { 102 | size_t operator()(const CrHash& h) const 103 | { 104 | return (size_t)h.GetHash(); 105 | } 106 | }; 107 | }; -------------------------------------------------------------------------------- /Source/Core/CrMacros.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #if defined(__clang__) 4 | 5 | #define optimize_off _Pragma("clang optimize off") 6 | #define optimize_on _Pragma("clang optimize on") 7 | 8 | #define warnings_off \ 9 | _Pragma("clang diagnostic push") \ 10 | _Pragma("clang diagnostic ignored \"-Weverything\"") 11 | 12 | #define warnings_on _Pragma("clang diagnostic pop") 13 | 14 | #elif defined(__GNUC__) 15 | 16 | #error Not implemented 17 | 18 | #define optimize_off _Pragma("GCC push_options") _Pragma("GCC optimize(\"O0\")") 19 | #define optimize_on _Pragma("GCC pop_options") 20 | 21 | #define warnings_off 22 | #define warnings_on 23 | 24 | #elif defined(_MSC_VER) 25 | 26 | #define optimize_off __pragma(optimize("", off)); 27 | #define optimize_on __pragma(optimize("", on)); 28 | 29 | #define warnings_off __pragma(warning(push, 0)); 30 | #define warnings_on __pragma(warning(pop)); 31 | 32 | #else 33 | 34 | #define optimize_off 35 | #define optimize_on 36 | 37 | #endif 38 | 39 | #define unused_parameter(x) (void)(x) 40 | 41 | template struct static_sizeof_dummy; 42 | #define static_sizeof(T) static_sizeof_dummy; 43 | 44 | #define sizeof_array(x) sizeof(x) / sizeof(x[0]) -------------------------------------------------------------------------------- /Source/Core/CrNumericLimits.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "stdint.h" 4 | #include 5 | 6 | template 7 | struct CrNumericLimits 8 | { 9 | static constexpr T max() { return T(0); } 10 | static constexpr T min() { return T(0); } 11 | }; 12 | 13 | template<> 14 | struct CrNumericLimits 15 | { 16 | static constexpr uint8_t max() { return UINT8_MAX; } 17 | static constexpr uint8_t min() { return 0; } 18 | }; 19 | 20 | template<> 21 | struct CrNumericLimits 22 | { 23 | static constexpr int8_t max() { return INT8_MAX; } 24 | static constexpr int8_t min() { return INT8_MIN; } 25 | }; 26 | 27 | template<> 28 | struct CrNumericLimits 29 | { 30 | static constexpr uint16_t max() { return UINT16_MAX; } 31 | static constexpr uint16_t min() { return 0; } 32 | }; 33 | 34 | template<> 35 | struct CrNumericLimits 36 | { 37 | static constexpr int16_t max() { return INT16_MAX; } 38 | static constexpr int16_t min() { return INT16_MIN; } 39 | }; 40 | 41 | template<> 42 | struct CrNumericLimits 43 | { 44 | static constexpr uint32_t max() { return UINT32_MAX; } 45 | static constexpr uint32_t min() { return 0; } 46 | }; 47 | 48 | template<> 49 | struct CrNumericLimits 50 | { 51 | static constexpr int32_t max() { return INT32_MAX; } 52 | static constexpr int32_t min() { return INT32_MIN; } 53 | }; 54 | 55 | template<> 56 | struct CrNumericLimits 57 | { 58 | static constexpr float max() { return FLT_MAX; } 59 | static constexpr float min() { return FLT_MIN; } 60 | }; -------------------------------------------------------------------------------- /Source/Core/CrPlatform.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace cr 4 | { 5 | // Relevant platforms here. The platform and the graphics API are kept separate 6 | namespace Platform 7 | { 8 | enum T : uint32_t 9 | { 10 | Windows, 11 | Count 12 | }; 13 | 14 | constexpr const char* ToString(Platform::T platform, bool lowercase = false) 15 | { 16 | switch (platform) 17 | { 18 | case Windows: return lowercase ? "windows" : "Windows"; 19 | default: return lowercase ? "invalid" : "Invalid"; 20 | } 21 | } 22 | }; 23 | } -------------------------------------------------------------------------------- /Source/Core/CrTypedId.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Core/CrNumericLimits.h" 4 | 5 | template::max()> 6 | class CrTypedId 7 | { 8 | public: 9 | 10 | using type = U; 11 | 12 | enum : U { DefaultValue = DefaultValueT }; 13 | 14 | static const U MaxId = CrNumericLimits::max(); 15 | 16 | CrTypedId() : id(DefaultValue) {} 17 | explicit CrTypedId(U id) : id(id) {} 18 | 19 | CrTypedId operator - (CrTypedId otherId) { return CrTypedId(id - otherId.id); } 20 | CrTypedId operator - (U otherId) { return CrTypedId(id - otherId); } 21 | 22 | bool operator < (CrTypedId otherId) { return id < otherId.id; } 23 | bool operator > (CrTypedId otherId) { return id > otherId.id; } 24 | bool operator == (CrTypedId otherId) { return id == otherId.id; } 25 | bool operator != (CrTypedId otherId) { return id != otherId.id; } 26 | 27 | CrTypedId& operator ++ () { id++; return *this; } // Pre-increment 28 | CrTypedId operator ++ (int) { CrTypedId temp = *this; id++; return temp; } // Post-increment 29 | 30 | U id; 31 | }; -------------------------------------------------------------------------------- /Source/Core/FileSystem/CrFixedPath.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "crstl/fixed_path.h" 4 | typedef crstl::fixed_path512 CrFixedPath; -------------------------------------------------------------------------------- /Source/Core/Input/CrPlatformInput.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class CrPlatformInput 4 | { 5 | public: 6 | 7 | static const unsigned MaxControllers = 4; 8 | 9 | enum class ConnectionStatus 10 | { 11 | Unknown = 0, 12 | Disconnected = 1, 13 | Connected = 2, 14 | Count 15 | }; 16 | 17 | static void Initialize(); 18 | 19 | static void Deinitialize(); 20 | 21 | void RequestRefreshControllers(); 22 | 23 | void Update(); 24 | 25 | private: 26 | 27 | ConnectionStatus m_previousControllerStatus[MaxControllers] = {}; 28 | 29 | ConnectionStatus m_controllerStatus[MaxControllers] = {}; 30 | 31 | bool m_requestControllersRefresh = false; 32 | }; 33 | 34 | extern CrPlatformInput* PlatformInput; -------------------------------------------------------------------------------- /Source/Core/Logging/ICrDebug.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "stdint.h" 4 | 5 | class ICrDebug 6 | { 7 | public: 8 | 9 | virtual ~ICrDebug() {} 10 | 11 | virtual void Log(const char* file, unsigned long line, const char* func, const char* format...) const = 0; 12 | 13 | virtual void AssertMsg(bool condition, const char* file, unsigned long line, const char* func, const char* format...) const = 0; 14 | 15 | virtual void WaitForDebugger() const = 0; 16 | 17 | // TODO Make this a Getter somewhere more appropriate like a memory header 18 | virtual void PrintCurrentProcessMemory(const char* file, unsigned long line, const char* func, const char* format...) const = 0; 19 | 20 | protected: 21 | 22 | static uint64_t ConvertToKilobytes(uint64_t bytes) 23 | { 24 | return bytes / 1024; 25 | } 26 | 27 | static uint64_t ConvertToMegabytes(uint64_t bytes) 28 | { 29 | return bytes / (1024 * 1024); 30 | } 31 | 32 | private: 33 | 34 | void AssertMsg(const char* message) const; // Disallow ugly implicit conversions between const char* and bool 35 | }; 36 | 37 | // We create it in the platform-specific code, which is why we extern it here 38 | const ICrDebug* GetDebug(); 39 | 40 | #define CrLog(format, ...) GetDebug()->Log(__FILE__, __LINE__, __func__, format, __VA_ARGS__) 41 | 42 | #define ERROR_LOG 43 | #define WARNING_LOG 44 | #define INFO_LOG 45 | 46 | #if defined(ERROR_LOG) 47 | #define CrLogError(s) CrLog("[Error] %s", s) 48 | #else 49 | #define CrLogError(s) 50 | #endif 51 | 52 | #if defined(WARNING_LOG) 53 | #define CrLogWarning(s) CrLog("[Warning] %s", s) 54 | #else 55 | #define CrLogWarning(s) 56 | #endif 57 | 58 | #if defined(INFO_LOG) 59 | #define CrLogInfo(s) CrLog("[Info] %s", s) 60 | #endif 61 | 62 | #if defined(CR_CONFIG_FINAL) 63 | 64 | #define CrAssertMsg(condition, message, ...) (void)(condition) 65 | 66 | #define CrAssert(condition) (void)(condition) 67 | 68 | #define CrPrintProcessMemory(message, ...) 69 | 70 | #else 71 | 72 | #define CrAssertMsg(condition, message, ...) GetDebug()->AssertMsg((condition), __FILE__, __LINE__, __func__, (message), __VA_ARGS__) 73 | 74 | #define CrAssert(condition) CrAssertMsg((condition), "") 75 | 76 | #define CrPrintProcessMemory(message, ...) GetDebug()->PrintCurrentProcessMemory(__FILE__, __LINE__, __func__, (message), __VA_ARGS__) 77 | 78 | #endif -------------------------------------------------------------------------------- /Source/Core/Logging/platform/windows/CrDebug_win.cpp: -------------------------------------------------------------------------------- 1 | #include "Core/CrCore_pch.h" 2 | 3 | #include "CrDebug_win.h" 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | // For documentation on Visual Studio friendly output see the following 11 | // https://windowscecleaner.blogspot.com/2013/04/debug-output-tricks-for-visual-studio.html 12 | 13 | CrDebugWindows::CrDebugWindows() 14 | { 15 | 16 | } 17 | 18 | void CrDebugWindows::Log(const char* file, unsigned long line, const char* func, const char* format...) const 19 | { 20 | // Expand variadic arguments 21 | va_list args; 22 | va_start(args, format); 23 | char buffer[2048]; 24 | vsnprintf(buffer, sizeof(buffer), format, args); 25 | va_end(args); 26 | 27 | char finalString[4096]; 28 | sprintf(finalString, "%s (%ld): %s : %s\n", file, line, func, buffer); 29 | 30 | OutputDebugStringA(finalString); 31 | } 32 | 33 | void CrDebugWindows::WaitForDebugger() const 34 | { 35 | while (!IsDebuggerPresent()) 36 | { 37 | int mbResult = MessageBoxA(nullptr, "Waiting For Debugger...", "Waiting For Debugger", MB_RETRYCANCEL | MB_ICONEXCLAMATION); 38 | 39 | if (mbResult == IDCANCEL) 40 | { 41 | _exit(0); 42 | } 43 | } 44 | } 45 | 46 | void CrDebugWindows::AssertMsg(bool condition, const char* file, unsigned long line, const char* func, const char* format...) const 47 | { 48 | if (!condition) 49 | { 50 | if (IsDebuggerPresent()) 51 | { 52 | Log(file, line, func, format); 53 | __debugbreak(); 54 | } 55 | else 56 | { 57 | MessageBoxA(nullptr, format, "Error", MB_RETRYCANCEL | MB_ICONERROR); 58 | } 59 | } 60 | } 61 | 62 | void CrDebugWindows::PrintCurrentProcessMemory(const char* file, unsigned long line, const char* func, const char* format...) const 63 | { 64 | // Expand variadic arguments 65 | va_list args; 66 | va_start(args, format); 67 | char buffer[2048]; 68 | vsnprintf(buffer, sizeof(buffer), format, args); 69 | va_end(args); 70 | 71 | DWORD processID = GetCurrentProcessId(); 72 | HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processID); 73 | 74 | PROCESS_MEMORY_COUNTERS pmc; 75 | if (GetProcessMemoryInfo(hProcess, &pmc, sizeof(pmc))) 76 | { 77 | uint64_t memory = pmc.WorkingSetSize; 78 | const char* units = "bytes"; 79 | 80 | if (pmc.WorkingSetSize > 1024 * 1024) 81 | { 82 | memory = ConvertToMegabytes(pmc.WorkingSetSize); 83 | units = "MB"; 84 | } 85 | else if (pmc.WorkingSetSize > 1024) 86 | { 87 | memory = ConvertToKilobytes(pmc.WorkingSetSize); 88 | units = "KB"; 89 | } 90 | 91 | char finalString[4096]; 92 | sprintf(finalString, "%s (%ld): %s : [%s] Memory: %lld %s\n", file, line, func, buffer, memory, units); 93 | 94 | OutputDebugStringA(finalString); 95 | } 96 | 97 | CloseHandle(hProcess); 98 | } 99 | 100 | static const CrDebugWindows* DebugWindows; 101 | 102 | // Create the global object for debug 103 | const ICrDebug* GetDebug() 104 | { 105 | if (!DebugWindows) 106 | { 107 | DebugWindows = new CrDebugWindows(); 108 | } 109 | 110 | return DebugWindows; 111 | } -------------------------------------------------------------------------------- /Source/Core/Logging/platform/windows/CrDebug_win.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Core/Logging/ICrDebug.h" 4 | 5 | class CrDebugWindows final : public ICrDebug 6 | { 7 | public: 8 | 9 | CrDebugWindows(); 10 | 11 | virtual void Log(const char* file, unsigned long line, const char* func, const char* format...) const override; 12 | 13 | virtual void AssertMsg(bool condition, const char* file, unsigned long line, const char* func, const char* format...) const override; 14 | 15 | virtual void WaitForDebugger() const override; 16 | 17 | virtual void PrintCurrentProcessMemory(const char* file, unsigned long line, const char* func, const char* format...) const override; 18 | }; -------------------------------------------------------------------------------- /Source/Core/PCH/CrCRSTLPch.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "crstl/array.h" 4 | #include "crstl/bitset.h" 5 | #include "crstl/fixed_vector.h" 6 | #include "crstl/fixed_string.h" 7 | #include "crstl/unique_ptr.h" 8 | #include "crstl/intrusive_ptr.h" 9 | #include "crstl/string.h" 10 | #include "crstl/vector.h" 11 | 12 | // Explicit instantiations of commonly used templates 13 | template class crstl::basic_string; 14 | template class crstl::basic_fixed_string; 15 | template class crstl::basic_fixed_string; 16 | template class crstl::basic_fixed_string; 17 | template class crstl::basic_fixed_string; -------------------------------------------------------------------------------- /Source/Core/PCH/CrWindowsPch.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include -------------------------------------------------------------------------------- /Source/CrEntity.cpp: -------------------------------------------------------------------------------- 1 | #include "CrEntity.h" 2 | 3 | #include "Math/CrTransform.h" 4 | 5 | //void GameObject::UpdateTransform() 6 | //{ 7 | //m_worldMatrix = Matrix4::Identity(); 8 | //Matrix3 scaleM = Matrix3::ScaleMatrix(scale.x, scale.y, scale.z); 9 | //Matrix3 RS = rotation * scaleM; 10 | //m_worldMatrix.CopyAffineTransform(RS); 11 | //m_worldMatrix.Translate(position); 12 | //} 13 | 14 | CrEntity::CrEntity() : CrEntity("") 15 | { 16 | 17 | } 18 | 19 | CrEntity::CrEntity(const crstl::string& name) 20 | : m_qrotation(quaternion::identity()) 21 | , m_name(name) 22 | { 23 | 24 | } 25 | 26 | void CrEntity::SetParent(CrEntity* const parent) 27 | { 28 | m_parent = parent; 29 | 30 | // Update matrix to be parented 31 | } 32 | 33 | void CrEntity::SetLocalTransform(const CrTransform& localTransform) 34 | { 35 | *m_localTransform = localTransform; 36 | 37 | // Update world matrix 38 | } 39 | -------------------------------------------------------------------------------- /Source/CrEntity.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Math/CrHlslppVectorFloatType.h" 4 | #include "Math/CrHlslppQuaternionType.h" 5 | 6 | #include "crstl/string.h" 7 | #include "crstl/vector.h" 8 | 9 | class CrTransform; 10 | 11 | class CrEntity 12 | { 13 | public: 14 | 15 | bool isActive = true; 16 | 17 | // TODO Put in transform 18 | float3 m_position; 19 | float3 m_scale; 20 | quaternion m_qrotation; 21 | 22 | crstl::vector gameObjects; 23 | 24 | CrEntity(); 25 | CrEntity(const crstl::string& name); 26 | 27 | const float3& GetPosition() const { return m_position; } 28 | 29 | const float3& GetScale() const { return m_scale; } 30 | 31 | const quaternion& GetRotation() const { return m_qrotation; } 32 | 33 | void SetParent(CrEntity* const parent); 34 | 35 | void SetLocalTransform(const CrTransform& localTransform); 36 | 37 | private: 38 | 39 | crstl::string m_name; 40 | 41 | CrEntity* m_parent; 42 | //CrTransform* m_worldTransform; 43 | CrTransform* m_localTransform; 44 | }; -------------------------------------------------------------------------------- /Source/CrFrame.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Rendering/CrRenderingForwardDeclarations.h" 4 | #include "Rendering/CrRenderGraph.h" 5 | #include "Rendering/CrBuiltinPipeline.h" 6 | #include "Rendering/RenderWorld/CrRenderWorld.h" 7 | 8 | #include "GeneratedShaders/ShaderMetadata.h" 9 | 10 | #include "crstl/unique_ptr.h" 11 | #include "crstl/vector.h" 12 | 13 | namespace GBufferDebugMode { enum T : uint32_t; } 14 | 15 | class CrOSWindow; 16 | 17 | class CrFrame 18 | { 19 | public: 20 | 21 | CrFrame(); 22 | 23 | ~CrFrame(); 24 | 25 | void Initialize(crstl::intrusive_ptr mainWindow); 26 | 27 | void Deinitialize(); 28 | 29 | void Process(); 30 | 31 | void DrawDebugUI(); 32 | 33 | void RecreateRenderTargets(); 34 | 35 | private: 36 | 37 | uint32_t m_currentCommandBuffer = 0; 38 | 39 | crstl::vector m_drawCmdBuffers; // Command buffers used for rendering 40 | 41 | CrComputePipelineHandle m_exampleComputePipeline; 42 | 43 | CrComputePipelineHandle m_depthDownsampleLinearize; 44 | 45 | CrComputePipelineHandle m_postProcessing; 46 | 47 | CrGraphicsPipelineHandle m_copyTexturePipeline; 48 | 49 | // Gets the value of the instance id at the mouse position and stores it in a buffer 50 | CrComputePipelineHandle m_mouseSelectionResolvePipeline; 51 | 52 | CrGraphicsPipelineHandle m_directionalLightPipeline; 53 | 54 | CrGraphicsPipelineHandle m_gbufferDebugPipeline; 55 | 56 | CrComputePipelineHandle m_createIndirectArguments; 57 | 58 | CrTextureHandle m_colorfulVolumeTexture; 59 | 60 | CrTextureHandle m_colorfulTextureArray; 61 | 62 | // Editor Shaders 63 | CrGraphicsPipelineHandle m_editorEdgeSelectionPipeline; 64 | 65 | CrGraphicsPipelineHandle m_editorGridPipeline; 66 | 67 | CrSwapchainHandle m_swapchain; 68 | 69 | CrTextureHandle m_depthStencilTexture; 70 | 71 | // 16-bit linear depth with a min max mip chain 72 | CrTextureHandle m_linearDepth16MinMaxMipChain; 73 | 74 | CrTextureHandle m_preSwapchainTexture; 75 | 76 | CrTextureHandle m_gbufferAlbedoAOTexture; 77 | CrTextureHandle m_gbufferNormalsTexture; 78 | CrTextureHandle m_gbufferMaterialTexture; 79 | 80 | CrTextureHandle m_lightingTexture; 81 | 82 | CrTextureHandle m_debugShaderTexture; 83 | 84 | CrGPUBufferHandle m_mouseSelectionBuffer; 85 | 86 | CrTextureHandle m_colorsRWTexture; 87 | 88 | CrStructuredBufferHandle m_rwStructuredBuffer; 89 | 90 | CrStructuredBufferHandle m_structuredBuffer; 91 | 92 | CrTypedBufferHandle m_colorsRWTypedBuffer; 93 | 94 | CrGPUBufferHandle m_indirectDispatchArguments; 95 | 96 | crstl::intrusive_ptr m_mainWindow; 97 | 98 | // We use these two variables to trigger render target resizing after a window resize 99 | uint32_t m_currentWindowWidth; 100 | 101 | uint32_t m_currentWindowHeight; 102 | 103 | CrCameraHandle m_camera; 104 | 105 | CameraCB m_cameraConstantData; 106 | 107 | CrRenderWorldHandle m_renderWorld; 108 | 109 | CrRenderGraph m_mainRenderGraph; 110 | 111 | crstl::unique_ptr m_timingQueryTracker; 112 | 113 | // This would need to be buffered to account for multiple threads 114 | crstl::intrusive_ptr m_renderingStream; 115 | 116 | #if !defined(CR_CONFIG_FINAL) 117 | GBufferDebugMode::T m_gbufferDebugMode = (GBufferDebugMode::T)0; 118 | #endif 119 | }; -------------------------------------------------------------------------------- /Source/CrOSWindow.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Rendering/ICrSwapchain.h" 4 | #include "Rendering/CrRenderingForwardDeclarations.h" 5 | #include "Rendering/CrDataFormats.h" 6 | 7 | #include "Math/CrMath.h" 8 | 9 | #include "crstl/intrusive_ptr.h" 10 | 11 | struct CrOSWindowDescriptor 12 | { 13 | CrOSWindowDescriptor() 14 | : positionX(0) 15 | , positionY(0) 16 | , width(1) 17 | , height(1) 18 | , parentWindow(nullptr) 19 | , swapchainFormat(cr3d::DataFormat::Invalid) 20 | , decoration(true) 21 | , topMost(false) 22 | { 23 | 24 | } 25 | 26 | uint32_t positionX; 27 | uint32_t positionY; 28 | uint32_t width; 29 | uint32_t height; 30 | CrOSWindow* parentWindow; 31 | crstl::fixed_string128 name; 32 | cr3d::DataFormat::T swapchainFormat; 33 | uint32_t decoration : 1; 34 | uint32_t topMost : 1; 35 | }; 36 | 37 | namespace CursorType 38 | { 39 | enum T 40 | { 41 | Arrow, 42 | TextInput, 43 | ResizeAll, 44 | ResizeEW, 45 | ResizeNS, 46 | ResizeNESW, 47 | ResizeNWSE, 48 | Hand, 49 | NotAllowed, 50 | None, 51 | Count 52 | }; 53 | } 54 | 55 | class CrOSWindow : public crstl::intrusive_ptr_interface_delete 56 | { 57 | public: 58 | 59 | CrOSWindow(const CrOSWindowDescriptor& windowDescriptor); 60 | 61 | ~CrOSWindow(); 62 | 63 | // Initialize the windowing system 64 | static void Initialize(); 65 | 66 | static void SetCursor(CursorType::T cursorType); 67 | 68 | // Destroy the window. A window can be destroyed externally while the object or pointer is still active. For that reason we 69 | // can query whether a window has been destroyed to avoid using its resources in an invalid state. A destroyed window cannot 70 | // be recreated, a new one must be built 71 | void Destroy(); 72 | 73 | bool GetIsMinimized() const; 74 | 75 | bool GetIsFocused() const; 76 | 77 | bool GetIsDestroyed() const; 78 | 79 | void* GetNativeWindowHandle() const; 80 | 81 | void* GetParentWindowHandle() const; 82 | 83 | void* GetNativeInstanceHandle() const; 84 | 85 | void GetPosition(uint32_t& positionX, uint32_t& positionY) const; 86 | 87 | void GetSizePixels(uint32_t& width, uint32_t& height) const; 88 | 89 | void SetPosition(uint32_t positionX, uint32_t positionY); 90 | 91 | void SetSizePixels(uint32_t width, uint32_t height); 92 | 93 | void SetFocus(); 94 | 95 | void SetTitle(const char* title); 96 | 97 | void SetTransparencyAlpha(float alpha); 98 | 99 | void Show(); 100 | 101 | const CrSwapchainHandle& GetSwapchain() { return m_swapchain; } 102 | 103 | private: 104 | 105 | void* m_hwnd = nullptr; 106 | 107 | void* m_parentHwnd = nullptr; 108 | 109 | void* m_hInstance = nullptr; 110 | 111 | uint64_t m_style = 0; 112 | 113 | uint64_t m_exStyle = 0; 114 | 115 | CrSwapchainHandle m_swapchain; 116 | }; -------------------------------------------------------------------------------- /Source/Editor/CrImGuiViewports.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "crstl/intrusive_ptr.h" 4 | 5 | class CrOSWindow; 6 | 7 | struct ImGuiViewportsData 8 | { 9 | CrOSWindow* osWindow; 10 | bool windowOwned; 11 | 12 | ImGuiViewportsData() 13 | { 14 | osWindow = nullptr; 15 | windowOwned = false; 16 | } 17 | }; 18 | 19 | // Imgui Viewports integration 20 | class CrImGuiViewports 21 | { 22 | public: 23 | 24 | static void Initialize(const crstl::intrusive_ptr& mainWindow); 25 | }; -------------------------------------------------------------------------------- /Source/Math/CrHalf.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "hlsl++/half.h" 4 | using hlslpp::half; 5 | using namespace hlslpp::half_literal; -------------------------------------------------------------------------------- /Source/Math/CrHlslppMatrixFloat.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | using namespace hlslpp; -------------------------------------------------------------------------------- /Source/Math/CrHlslppMatrixFloatType.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | using namespace hlslpp; -------------------------------------------------------------------------------- /Source/Math/CrHlslppQuaternion.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | using namespace hlslpp; -------------------------------------------------------------------------------- /Source/Math/CrHlslppQuaternionType.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | using namespace hlslpp; -------------------------------------------------------------------------------- /Source/Math/CrHlslppVectorFloat.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | using namespace hlslpp; -------------------------------------------------------------------------------- /Source/Math/CrHlslppVectorFloatType.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | using namespace hlslpp; -------------------------------------------------------------------------------- /Source/Math/CrHlslppVectorInt.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | using namespace hlslpp; -------------------------------------------------------------------------------- /Source/Math/CrHlslppVectorIntType.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | using namespace hlslpp; -------------------------------------------------------------------------------- /Source/Math/CrHlslppVectorUint.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | using namespace hlslpp; -------------------------------------------------------------------------------- /Source/Math/CrHlslppVectorUintType.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | using namespace hlslpp; -------------------------------------------------------------------------------- /Source/Math/CrMath.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace CrMath 4 | { 5 | constexpr static float Pi = 3.14159265359f; 6 | constexpr static float Rad2Deg = 180.0f / CrMath::Pi; 7 | constexpr static float Deg2Rad = CrMath::Pi / 180.0f; 8 | }; 9 | 10 | template 11 | inline const T& CrMin(const T& a, const T& b) { return a < b ? a : b; } 12 | 13 | template 14 | inline const T& CrMax(const T& a, const T& b) { return a > b ? a : b; } 15 | 16 | template 17 | inline const T& CrClamp(const T& x, const T& min, const T& max) 18 | { 19 | return CrMin(CrMax(x, min), max); 20 | } -------------------------------------------------------------------------------- /Source/Math/CrMathPch.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include -------------------------------------------------------------------------------- /Source/Math/CrTransform.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Math/CrHlslppVectorFloatType.h" 4 | #include "Math/CrHlslppQuaternionType.h" 5 | #include "Math/CrHlslppMatrixFloat.h" 6 | 7 | class CrTransform 8 | { 9 | public: 10 | 11 | float3 position; 12 | float3 scale; 13 | quaternion rotation; 14 | 15 | float4x4 AsMatrix() 16 | { 17 | // float3x3(rotation); // TODO Transform from quaternion to float3x3 18 | // Multiply matrix by scale 19 | // Put position in appropriate row/column 20 | float4x4 dummy; 21 | return dummy; 22 | } 23 | }; -------------------------------------------------------------------------------- /Source/Math/CrVectorT.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | // Templated vector classes. Use mainly as simple structs. 6 | template 7 | struct VectorT 8 | { 9 | VectorT() {} 10 | VectorT(std::initializer_list) {} 11 | static_assert(N < 4, "Do not use this with sizes other than 2, 3 and 4! Specializations are below."); 12 | }; 13 | 14 | template 15 | struct VectorT 16 | { 17 | VectorT() {} 18 | VectorT(std::initializer_list l) : x(*l.begin()), y(*(l.begin() + 1)), z(*(l.begin() + 2)), w(*(l.begin() + 3)) {} 19 | VectorT(T x, T y, T z, T w) : x(x), y(y), z(z), w(w) {} 20 | T x, y, z, w; 21 | }; 22 | 23 | template 24 | struct VectorT 25 | { 26 | VectorT() {} 27 | VectorT(std::initializer_list l) : x(*l.begin()), y(*(l.begin() + 1)), z(*(l.begin() + 2)) {} 28 | VectorT(T x, T y, T z) : x(x), y(y), z(z) {} 29 | T x, y, z; 30 | }; 31 | 32 | template 33 | struct VectorT 34 | { 35 | VectorT() {} 36 | VectorT(std::initializer_list l) : x(*l.begin()), y(*(l.begin() + 1)) {} 37 | VectorT(T x, T y) : x(x), y(y) {} 38 | T x, y; 39 | }; -------------------------------------------------------------------------------- /Source/Rendering/CrBuiltinPipeline.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Rendering/CrRenderingForwardDeclarations.h" 4 | #include "Rendering/ICrPipeline.h" 5 | #include "Rendering/CrVertexDescriptor.h" 6 | 7 | #include "crstl/open_hashmap.h" 8 | 9 | namespace CrBuiltinShaders { enum T : uint32_t; } 10 | 11 | // A collection of all builtin pipelines compiled on boot. They are available to any program that wants them 12 | class CrBuiltinPipelines 13 | { 14 | public: 15 | 16 | static void Initialize(); 17 | 18 | static void Deinitialize(); 19 | 20 | CrGraphicsPipelineHandle GetGraphicsPipeline 21 | ( 22 | const CrGraphicsPipelineDescriptor& graphicsPipelineDescriptor, 23 | const CrVertexDescriptor& vertexDescriptor, 24 | CrBuiltinShaders::T vertexShader, 25 | CrBuiltinShaders::T pixelShader 26 | ); 27 | 28 | CrComputePipelineHandle GetComputePipeline(CrBuiltinShaders::T computeShader); 29 | 30 | void RecompileComputePipelines(); 31 | 32 | // Ubershader builtin pipelines 33 | 34 | CrGraphicsPipelineHandle BasicUbershaderForward; 35 | 36 | CrGraphicsPipelineHandle BasicUbershaderGBuffer; 37 | 38 | CrGraphicsPipelineHandle BasicUbershaderDebug; 39 | 40 | private: 41 | 42 | CrBuiltinPipelines(); 43 | 44 | crstl::open_hashmap m_builtinGraphicsPipelines; 45 | 46 | crstl::open_hashmap m_builtinComputePipelines; 47 | }; 48 | 49 | extern CrBuiltinPipelines* BuiltinPipelines; -------------------------------------------------------------------------------- /Source/Rendering/CrCPUStackAllocator.cpp: -------------------------------------------------------------------------------- 1 | #include "Rendering/CrRendering_pch.h" 2 | 3 | #include "Rendering/CrCPUStackAllocator.h" 4 | 5 | CrCPUStackAllocator::~CrCPUStackAllocator() 6 | { 7 | delete[] m_memoryBasePointer; 8 | } 9 | 10 | void CrCPUStackAllocator::Initialize(size_t size) 11 | { 12 | m_size = size; 13 | m_memoryBasePointer = new uint8_t[size]; 14 | m_currentPointer = m_memoryBasePointer; 15 | } 16 | 17 | void CrCPUStackAllocator::Reset() 18 | { 19 | m_currentPointer = m_memoryBasePointer; 20 | } -------------------------------------------------------------------------------- /Source/Rendering/CrCPUStackAllocator.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Core/CrAlignment.h" 4 | 5 | #include "Rendering/CrStackAllocator.h" 6 | 7 | #include "crstl/intrusive_ptr.h" 8 | 9 | // Manages transient memory allocated per frame for CPU resources 10 | class CrCPUStackAllocator final : public CrStackAllocator, public crstl::intrusive_ptr_interface_delete 11 | { 12 | public: 13 | 14 | ~CrCPUStackAllocator(); 15 | 16 | void Initialize(size_t size); 17 | 18 | void Reset(); 19 | }; -------------------------------------------------------------------------------- /Source/Rendering/CrCommonVertexLayouts.cpp: -------------------------------------------------------------------------------- 1 | #include "Rendering/CrRendering_pch.h" 2 | 3 | #include "Rendering/CrCommonVertexLayouts.h" 4 | 5 | CrVertexDescriptor SimpleVertexDescriptor 6 | ({ 7 | CrVertexAttribute(CrVertexSemantic::Position, cr3d::DataFormat::RGBA16_Float, 0), 8 | CrVertexAttribute(CrVertexSemantic::Color, cr3d::DataFormat::RGBA8_Unorm, 0), 9 | CrVertexAttribute(CrVertexSemantic::Normal, cr3d::DataFormat::RGBA8_Unorm, 0), 10 | CrVertexAttribute(CrVertexSemantic::Tangent, cr3d::DataFormat::RGBA8_Unorm, 0), 11 | CrVertexAttribute(CrVertexSemantic::TexCoord0, cr3d::DataFormat::RG16_Float, 0) 12 | }); 13 | 14 | CrVertexDescriptor NullVertexDescriptor({}); 15 | 16 | CrVertexDescriptor PositionVertexDescriptor 17 | ({ 18 | CrVertexAttribute(CrVertexSemantic::Position, cr3d::DataFormat::RGBA16_Float, 0), 19 | }); 20 | 21 | CrVertexDescriptor AdditionalVertexDescriptor 22 | ({ 23 | CrVertexAttribute(CrVertexSemantic::Color, cr3d::DataFormat::RGBA8_Unorm, 0), 24 | CrVertexAttribute(CrVertexSemantic::Normal, cr3d::DataFormat::RGBA8_Snorm, 0), 25 | CrVertexAttribute(CrVertexSemantic::Tangent, cr3d::DataFormat::RGBA8_Unorm, 0), 26 | CrVertexAttribute(CrVertexSemantic::TexCoord0, cr3d::DataFormat::RG16_Float, 0) 27 | }); 28 | 29 | CrVertexDescriptor ComplexVertexDescriptor 30 | ({ 31 | CrVertexAttribute(CrVertexSemantic::Position, cr3d::DataFormat::RGBA16_Float, 0), 32 | CrVertexAttribute(CrVertexSemantic::Color, cr3d::DataFormat::RGBA8_Unorm, 1), 33 | CrVertexAttribute(CrVertexSemantic::Normal, cr3d::DataFormat::RGBA8_Unorm, 1), 34 | CrVertexAttribute(CrVertexSemantic::Tangent, cr3d::DataFormat::RGBA8_Unorm, 1), 35 | CrVertexAttribute(CrVertexSemantic::TexCoord0, cr3d::DataFormat::RG16_Float, 1) 36 | }); -------------------------------------------------------------------------------- /Source/Rendering/CrCommonVertexLayouts.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Rendering/CrGPUBuffer.h" 4 | 5 | struct SimpleVertex 6 | { 7 | CrVertexElement position; 8 | CrVertexElement color; 9 | CrVertexElement normal; 10 | CrVertexElement tangent; 11 | CrVertexElement uv; 12 | }; 13 | 14 | extern CrVertexDescriptor SimpleVertexDescriptor; 15 | extern CrVertexDescriptor NullVertexDescriptor; 16 | 17 | struct ComplexVertexPosition 18 | { 19 | CrVertexElement position; 20 | }; 21 | 22 | struct ComplexVertexAdditional 23 | { 24 | CrVertexElement color; 25 | CrVertexElement normal; 26 | CrVertexElement tangent; 27 | CrVertexElement uv; 28 | }; 29 | 30 | extern CrVertexDescriptor PositionVertexDescriptor; 31 | 32 | extern CrVertexDescriptor AdditionalVertexDescriptor; 33 | 34 | extern CrVertexDescriptor ComplexVertexDescriptor; -------------------------------------------------------------------------------- /Source/Rendering/CrGPUBuffer.cpp: -------------------------------------------------------------------------------- 1 | #include "Rendering/CrRendering_pch.h" 2 | 3 | #include "Rendering/CrGPUBuffer.h" 4 | #include "Rendering/ICrRenderDevice.h" 5 | 6 | #include "Core/Logging/ICrDebug.h" 7 | 8 | ICrHardwareGPUBuffer::ICrHardwareGPUBuffer(ICrRenderDevice* renderDevice, const CrHardwareGPUBufferDescriptor& descriptor) : CrGPUAutoDeletable(renderDevice) 9 | , m_usage(descriptor.usage) 10 | , m_access(descriptor.access) 11 | , m_dataFormat(descriptor.dataFormat) 12 | , m_mapped(false) 13 | , m_sizeBytes(descriptor.numElements * descriptor.stride) 14 | , m_strideBytes(descriptor.stride) 15 | , m_numElements(descriptor.numElements) 16 | { 17 | CrAssertMsg(m_sizeBytes > 0, "Size must be greater than zero"); 18 | CrAssertMsg(descriptor.initialData ? descriptor.initialDataSize <= m_sizeBytes : true, "Size must be less or equal"); 19 | #if !defined(CR_CONFIG_FINAL) 20 | if (descriptor.name) 21 | { 22 | m_debugName = descriptor.name; 23 | } 24 | #endif 25 | } 26 | 27 | // This constructor takes both a stride and a data format. While this looks like redundant information, this constructor 28 | // is not public, and lives here to cater for the two public-facing constructors 29 | CrGPUBuffer::CrGPUBuffer(ICrRenderDevice* renderDevice, const CrGPUBufferDescriptor& descriptor, uint32_t numElements, uint32_t stride, cr3d::DataFormat::T dataFormat) 30 | : m_usage(descriptor.usage), m_access(descriptor.access) 31 | { 32 | if (descriptor.usage & cr3d::BufferUsage::Index) 33 | { 34 | CrAssertMsg((stride == 2 && dataFormat == cr3d::DataFormat::R16_Uint) || (stride == 4 && dataFormat == cr3d::DataFormat::R32_Uint), "Invalid format for index buffer"); 35 | } 36 | 37 | if (descriptor.usage & cr3d::BufferUsage::Indirect) 38 | { 39 | CrAssertMsg(descriptor.usage & (cr3d::BufferUsage::Structured | cr3d::BufferUsage::Byte), "Must specify structured or byte buffer to write to an indirect buffer"); 40 | } 41 | 42 | CrHardwareGPUBufferDescriptor hardwareGPUBufferDescriptor(descriptor.usage, descriptor.access, numElements, stride); 43 | hardwareGPUBufferDescriptor.dataFormat = dataFormat; 44 | hardwareGPUBufferDescriptor.initialData = descriptor.initialData; 45 | hardwareGPUBufferDescriptor.initialDataSize = descriptor.initialDataSize; 46 | hardwareGPUBufferDescriptor.name = descriptor.name; 47 | m_buffer = renderDevice->CreateHardwareGPUBuffer(hardwareGPUBufferDescriptor); 48 | } 49 | 50 | void* CrGPUBuffer::Lock() 51 | { 52 | return m_buffer->Lock(); 53 | } 54 | 55 | void CrGPUBuffer::Unlock() 56 | { 57 | m_buffer->Unlock(); 58 | } -------------------------------------------------------------------------------- /Source/Rendering/CrGPUDeletable.cpp: -------------------------------------------------------------------------------- 1 | #include "Rendering/CrRendering_pch.h" 2 | 3 | #include "Rendering/CrGPUDeletable.h" 4 | 5 | #include "Rendering/ICrRenderDevice.h" 6 | 7 | void CrGPUDeletable::CrRenderDeviceDeletionFunction(ICrRenderDevice* renderDevice, CrGPUDeletable* deletable) 8 | { 9 | renderDevice->AddToDeletionQueue(deletable); 10 | } -------------------------------------------------------------------------------- /Source/Rendering/CrGPUDeletable.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "crstl/intrusive_ptr.h" 4 | 5 | class ICrRenderDevice; 6 | 7 | class CrGPUDeletable 8 | { 9 | public: 10 | 11 | void CrRenderDeviceDeletionFunction(ICrRenderDevice* renderDevice, CrGPUDeletable* deletable); 12 | 13 | CrGPUDeletable(ICrRenderDevice* renderDevice) : m_renderDevice(renderDevice) {} 14 | 15 | virtual ~CrGPUDeletable() {} 16 | 17 | ICrRenderDevice* m_renderDevice = nullptr; 18 | }; 19 | 20 | class CrGPUAutoDeletable : public crstl::intrusive_ptr_interface_delete, public CrGPUDeletable 21 | { 22 | public: 23 | 24 | CrGPUAutoDeletable(ICrRenderDevice* renderDevice) : CrGPUDeletable(renderDevice) {} 25 | 26 | virtual ~CrGPUAutoDeletable() {} 27 | 28 | template 29 | void intrusive_ptr_delete_callback() 30 | { 31 | CrRenderDeviceDeletionFunction(m_renderDevice, this); 32 | } 33 | }; -------------------------------------------------------------------------------- /Source/Rendering/CrGPUDeletionQueue.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "CrRenderingForwardDeclarations.h" 4 | 5 | #include "Rendering/ICrGPUSynchronization.h" 6 | 7 | #include "crstl/deque.h" 8 | #include "crstl/fixed_vector.h" 9 | 10 | class CrGPUDeletable; 11 | 12 | struct CrDeletionList 13 | { 14 | CrGPUFenceHandle fence; 15 | crstl::vector deletables; 16 | }; 17 | 18 | // A queue that manages deletion of GPU objects. Anything added to this queue 19 | // will eventually get destroyed 20 | class CrGPUDeletionQueue 21 | { 22 | public: 23 | 24 | ~CrGPUDeletionQueue(); 25 | 26 | static const uint32_t MaximumDeletionLists = 4; 27 | 28 | void Initialize(ICrRenderDevice* renderDevice); 29 | 30 | void AddToQueue(CrGPUDeletable* deletable); 31 | 32 | // Processes pending requests and adds current requests so that they're waited on 33 | // This is intended for in-flight resources during the frame 34 | void Process(); 35 | 36 | void Finalize(); 37 | 38 | private: 39 | 40 | ICrRenderDevice* m_renderDevice = nullptr; 41 | 42 | // The current deletion list points to all the resources being deleted 43 | // before we execute the fence. Once we execute the fence, we add it 44 | // to the active deletion lists to be waited on 45 | CrDeletionList* m_currentDeletionList = nullptr; 46 | 47 | // Active deletion lists have had fence signal commands scheduled on 48 | // the GPU, and are waiting to receive that on the CPU. We want to 49 | // push back, but then get front to query the fence 50 | crstl::deque m_activeDeletionLists; 51 | 52 | // Available deletion lists are there to be reused 53 | crstl::fixed_vector m_availableDeletionLists; 54 | 55 | // These are the actual contents of the CrDeletionList 56 | // The other lists point to the contents here. We cannot 57 | // have reallocation on these lists so we use fixed size vectors 58 | crstl::fixed_vector m_deletionLists; 59 | }; -------------------------------------------------------------------------------- /Source/Rendering/CrGPUStackAllocator.cpp: -------------------------------------------------------------------------------- 1 | #include "Rendering/CrRendering_pch.h" 2 | 3 | #include "Rendering/CrGPUStackAllocator.h" 4 | #include "Rendering/ICrRenderDevice.h" 5 | #include "Rendering/CrGPUBuffer.h" 6 | 7 | #include "Core/CrAlignment.h" 8 | 9 | CrGPUStackAllocator::CrGPUStackAllocator(ICrRenderDevice* renderDevice, const CrHardwareGPUBufferDescriptor& gpuBufferDescriptor) 10 | : m_renderDevice(renderDevice) 11 | , m_bufferUsage(gpuBufferDescriptor.usage) 12 | , m_bufferAccess(gpuBufferDescriptor.access) 13 | { 14 | m_size = gpuBufferDescriptor.numElements * gpuBufferDescriptor.stride; 15 | m_hardwareBuffer = m_renderDevice->CreateHardwareGPUBuffer(gpuBufferDescriptor); 16 | } 17 | 18 | CrGPUStackAllocator::~CrGPUStackAllocator() 19 | { 20 | if (m_currentPointer) 21 | { 22 | End(); 23 | } 24 | } 25 | 26 | void CrGPUStackAllocator::Begin() 27 | { 28 | CrAssertMsg(m_currentPointer == nullptr, "Did you call end?"); 29 | void* memoryPointer = m_hardwareBuffer->Lock(); 30 | m_currentPointer = m_memoryBasePointer = reinterpret_cast(memoryPointer); 31 | } 32 | 33 | void CrGPUStackAllocator::End() 34 | { 35 | CrAssertMsg(m_currentPointer != nullptr, "Did you call begin?"); 36 | m_hardwareBuffer->Unlock(); 37 | m_currentPointer = nullptr; 38 | } 39 | -------------------------------------------------------------------------------- /Source/Rendering/CrGPUStackAllocator.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Rendering/CrStackAllocator.h" 4 | #include "Rendering/CrRenderingForwardDeclarations.h" 5 | 6 | class ICrRenderDevice; 7 | class ICrHardwareGPUBuffer; 8 | struct CrHardwareGPUBufferDescriptor; 9 | 10 | // Manages transient memory allocated per frame for GPU resources 11 | class CrGPUStackAllocator : public CrStackAllocator 12 | { 13 | public: 14 | 15 | CrGPUStackAllocator(ICrRenderDevice* renderDevice, const CrHardwareGPUBufferDescriptor& descriptor); 16 | 17 | ~CrGPUStackAllocator(); 18 | 19 | void Begin(); 20 | 21 | void End(); 22 | 23 | ICrHardwareGPUBuffer* GetHardwareGPUBuffer() const; 24 | 25 | cr3d::BufferUsage::T GetUsage() const; 26 | 27 | cr3d::MemoryAccess::T GetAccess() const; 28 | 29 | protected: 30 | 31 | ICrRenderDevice* m_renderDevice = nullptr; 32 | 33 | CrHardwareGPUBufferHandle m_hardwareBuffer; 34 | 35 | cr3d::BufferUsage::T m_bufferUsage; 36 | 37 | cr3d::MemoryAccess::T m_bufferAccess; 38 | }; 39 | 40 | inline ICrHardwareGPUBuffer* CrGPUStackAllocator::GetHardwareGPUBuffer() const 41 | { 42 | return m_hardwareBuffer.get(); 43 | } 44 | 45 | inline cr3d::BufferUsage::T CrGPUStackAllocator::GetUsage() const 46 | { 47 | return m_bufferUsage; 48 | } 49 | 50 | inline cr3d::MemoryAccess::T CrGPUStackAllocator::GetAccess() const 51 | { 52 | return m_bufferAccess; 53 | } -------------------------------------------------------------------------------- /Source/Rendering/CrGPUTimingQueryTracker.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Rendering/CrRenderingForwardDeclarations.h" 4 | #include "Rendering/ICrGPUQueryPool.h" 5 | 6 | #include "Core/CrHash.h" 7 | 8 | #include "crstl/open_hashmap.h" 9 | #include "crstl/vector.h" 10 | 11 | struct CrGPUTimingRequest 12 | { 13 | CrGPUQueryId startQuery; 14 | CrGPUQueryId endQuery; 15 | }; 16 | 17 | struct CrGPUInterval 18 | { 19 | CrGPUInterval() : startTimeNanoseconds(0.0), durationNanoseconds(0.0) {} 20 | 21 | double startTimeNanoseconds; 22 | double durationNanoseconds; 23 | }; 24 | 25 | class CrGPUTimingQueryTracker 26 | { 27 | public: 28 | 29 | void Initialize(ICrRenderDevice* renderDevice, uint32_t maxFrames); 30 | 31 | void BeginFrame(ICrCommandBuffer* commandBuffer, uint64_t frameIndex); 32 | 33 | void EndFrame(ICrCommandBuffer* commandBuffer); 34 | 35 | CrGPUTimingRequest AllocateTimingRequest(CrHash hash); 36 | 37 | CrGPUInterval GetResultForFrame(CrHash hash) const; 38 | 39 | CrGPUInterval GetFrameDuration() const; 40 | 41 | ICrGPUQueryPool* GetCurrentQueryPool() const; 42 | 43 | private: 44 | 45 | ICrGPUQueryPool* GetOldestQueryPool() const; 46 | 47 | uint64_t m_currentFrame; 48 | 49 | // Maximum number of query pools 50 | uint64_t m_maxFrames; 51 | 52 | // Current query pool 53 | uint64_t m_currentPoolIndex; 54 | 55 | // Timing request for the entire frame 56 | CrGPUTimingRequest m_frameTimingRequest; 57 | 58 | // Collection of query pools, ideally one per frame 59 | crstl::vector m_queryPools; 60 | 61 | // There is a hashmap per frame as the query ids change every frame 62 | crstl::vector> m_timingRequests; 63 | 64 | // Data for timings that were resolved this frame. They'll get stomped next frame 65 | // This is the raw data for the timestamps 66 | crstl::vector m_timestampData; 67 | 68 | // Intervals resolved for the current raw data. Starting time is with respect to the 69 | // query inserted by the tracker on Begin() 70 | crstl::open_hashmap m_timingIntervals; 71 | 72 | // Total time this frame took 73 | CrGPUInterval m_totalFrameInterval; 74 | }; -------------------------------------------------------------------------------- /Source/Rendering/CrGPUTransferCallbackQueue.cpp: -------------------------------------------------------------------------------- 1 | #include "Rendering/CrRendering_pch.h" 2 | 3 | #include "Rendering/ICrRenderDevice.h" 4 | #include "Rendering/ICrGPUSynchronization.h" 5 | #include "Rendering/CrGPUBuffer.h" 6 | #include "Rendering/CrGPUTransferCallbackQueue.h" 7 | 8 | #include "Core/Logging/ICrDebug.h" 9 | #include "Core/CrFrameTime.h" 10 | 11 | CrGPUDownloadCallback::~CrGPUDownloadCallback() {} 12 | 13 | CrDownloadCallbackList::~CrDownloadCallbackList() {} 14 | 15 | CrGPUTransferCallbackQueue::~CrGPUTransferCallbackQueue() {} 16 | 17 | void CrGPUTransferCallbackQueue::Initialize(ICrRenderDevice* renderDevice) 18 | { 19 | m_renderDevice = renderDevice; 20 | 21 | // We need as many as the system requests plus an extra one for when they're 22 | // all in flight (and the system reserves "the next one"). We could lazily 23 | // allocate in the AddToQueue function but this is simpler to reason about 24 | m_callbackLists.resize(MaximumCallbackLists); 25 | 26 | for (uint32_t i = 0; i < m_callbackLists.size(); ++i) 27 | { 28 | m_callbackLists[i].fence = m_renderDevice->CreateGPUFence(); 29 | 30 | m_availableCallbackLists.push_back(&m_callbackLists[i]); 31 | } 32 | 33 | // Pop from the vector to get an available list 34 | m_currentCallbackList = m_availableCallbackLists.back(); 35 | m_availableCallbackLists.pop_back(); 36 | } 37 | 38 | void CrGPUTransferCallbackQueue::AddToQueue(const CrGPUDownloadCallback& callback) 39 | { 40 | // TODO Add synchronization for multithreading 41 | m_currentCallbackList->callbacks.push_back(callback); 42 | } 43 | 44 | void CrGPUTransferCallbackQueue::Process() 45 | { 46 | while (!m_activeCallbackLists.empty()) 47 | { 48 | // Get the last list we pushed into the active list 49 | CrDownloadCallbackList* callbackList = m_activeCallbackLists.front(); 50 | 51 | if (m_renderDevice->GetFenceStatus(callbackList->fence.get()) == cr3d::GPUFenceResult::Success) 52 | { 53 | for (const CrGPUDownloadCallback& callback : callbackList->callbacks) 54 | { 55 | callback.callback(callback.buffer); 56 | } 57 | 58 | // Reset the deletion list's properties 59 | callbackList->callbacks.clear(); 60 | m_renderDevice->ResetFence(callbackList->fence.get()); 61 | 62 | // Put back in the available list and remove from active 63 | m_availableCallbackLists.push_back(callbackList); 64 | m_activeCallbackLists.pop_front(); 65 | } 66 | else 67 | { 68 | // Our lists are sequential, i.e. if this one has not been signaled, 69 | // it is guaranteed the others won't have been 70 | break; 71 | } 72 | } 73 | 74 | // 2. If there are any elements to delete, add the current list to the active 75 | // list and submit a fence signal to the queue 76 | if (!m_currentCallbackList->callbacks.empty()) 77 | { 78 | m_activeCallbackLists.push_back(m_currentCallbackList); 79 | m_renderDevice->SignalFence(CrCommandQueueType::Graphics, m_currentCallbackList->fence.get()); 80 | m_currentCallbackList = nullptr; 81 | } 82 | 83 | if (!m_currentCallbackList && !m_availableCallbackLists.empty()) 84 | { 85 | m_currentCallbackList = m_availableCallbackLists.back(); 86 | m_availableCallbackLists.pop_back(); 87 | } 88 | 89 | CrAssertMsg(m_currentCallbackList, "Current callback list cannot be null"); 90 | } -------------------------------------------------------------------------------- /Source/Rendering/CrGPUTransferCallbackQueue.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "CrRenderingForwardDeclarations.h" 4 | 5 | #include "crstl/deque.h" 6 | #include "crstl/fixed_function.h" 7 | #include "crstl/fixed_vector.h" 8 | 9 | struct CrGPUDownloadCallback 10 | { 11 | ~CrGPUDownloadCallback(); 12 | 13 | CrGPUTransferCallbackType callback; 14 | CrHardwareGPUBufferHandle buffer; 15 | }; 16 | 17 | struct CrDownloadCallbackList 18 | { 19 | ~CrDownloadCallbackList(); 20 | 21 | CrGPUFenceHandle fence; 22 | crstl::vector callbacks; 23 | }; 24 | 25 | class CrGPUTransferCallbackQueue 26 | { 27 | public: 28 | 29 | ~CrGPUTransferCallbackQueue(); 30 | 31 | static const uint32_t MaximumCallbackLists = 4; 32 | 33 | void Initialize(ICrRenderDevice* renderDevice); 34 | 35 | void AddToQueue(const CrGPUDownloadCallback& callback); 36 | 37 | void Process(); 38 | 39 | private: 40 | 41 | ICrRenderDevice* m_renderDevice = nullptr; 42 | 43 | // Callbacks to be executed after a successful download operation, copying from GPU to CPU 44 | CrDownloadCallbackList* m_currentCallbackList = nullptr; 45 | 46 | // Active callback lists have had fence signal commands scheduled on 47 | // the GPU, and are waiting to receive that on the CPU. We want to 48 | // push back, but then get front to query the fence 49 | crstl::deque m_activeCallbackLists; 50 | 51 | // Available callback lists are there to be reused 52 | crstl::fixed_vector m_availableCallbackLists; 53 | 54 | crstl::fixed_vector m_callbackLists; 55 | }; -------------------------------------------------------------------------------- /Source/Rendering/CrImage.cpp: -------------------------------------------------------------------------------- 1 | #include "Rendering/CrRendering_pch.h" 2 | 3 | #include "Rendering/CrImage.h" 4 | #include "Rendering/CrRendering.h" 5 | 6 | CrImageDescriptor::CrImageDescriptor() 7 | : width(1) 8 | , height(1) 9 | , depth(1) 10 | , mipmapCount(1) 11 | , data(nullptr) 12 | , dataSize(0) 13 | , format(cr3d::DataFormat::RGBA8_Unorm) 14 | , type(cr3d::TextureType::Tex2D) 15 | { 16 | 17 | } 18 | 19 | CrImage::CrImage() : m_width(1), m_height(1), m_depth(1), m_format(cr3d::DataFormat::RGBA8_Unorm) 20 | { 21 | 22 | } 23 | 24 | CrImage::CrImage(const CrImageDescriptor& descriptor) 25 | : m_width(descriptor.width) 26 | , m_height(descriptor.height) 27 | , m_depth(descriptor.depth) 28 | , m_mipmapCount(descriptor.mipmapCount) 29 | , m_format(descriptor.format) 30 | , m_type(descriptor.type) 31 | { 32 | m_data.resize(descriptor.dataSize); 33 | memcpy(m_data.data(), descriptor.data, m_data.size()); 34 | } 35 | 36 | CrImage::~CrImage() 37 | { 38 | 39 | } -------------------------------------------------------------------------------- /Source/Rendering/CrImage.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Rendering/CrRenderingForwardDeclarations.h" 4 | 5 | #include "crstl/intrusive_ptr.h" 6 | #include "crstl/vector.h" 7 | 8 | namespace CrImageContainerFormat 9 | { 10 | enum T : uint32_t 11 | { 12 | DDS, 13 | PNG, 14 | JPG, 15 | TGA, 16 | BMP, 17 | HDR, 18 | Count, 19 | None, 20 | }; 21 | }; 22 | 23 | struct CrImageDescriptor 24 | { 25 | CrImageDescriptor(); 26 | 27 | uint32_t width; 28 | uint32_t height; 29 | uint32_t depth; 30 | uint32_t mipmapCount; 31 | 32 | uint8_t* data; 33 | uint64_t dataSize; 34 | 35 | cr3d::DataFormat::T format; 36 | cr3d::TextureType type; 37 | }; 38 | 39 | class CrImage final : public crstl::intrusive_ptr_interface_delete 40 | { 41 | public: 42 | 43 | CrImage(); 44 | 45 | CrImage(const CrImageDescriptor& descriptor); 46 | 47 | uint32_t GetWidth() const { return m_width; } 48 | 49 | uint32_t GetHeight() const { return m_height; } 50 | 51 | uint32_t GetDepth() const { return m_depth; } 52 | 53 | cr3d::DataFormat::T GetFormat() const { return m_format; } 54 | 55 | cr3d::TextureType GetType() const { return m_type; } 56 | 57 | const uint8_t* GetData() const { return m_data.data(); } 58 | 59 | uint64_t GetDataSize() const { return m_data.size(); } 60 | 61 | uint32_t GetMipmapCount() const { return m_mipmapCount; } 62 | 63 | ~CrImage(); 64 | 65 | public: // TODO remove 66 | 67 | uint32_t m_width; 68 | uint32_t m_height; 69 | uint32_t m_depth; 70 | uint32_t m_mipmapCount; 71 | 72 | crstl::vector m_data; 73 | cr3d::DataFormat::T m_format; 74 | cr3d::TextureType m_type; 75 | }; -------------------------------------------------------------------------------- /Source/Rendering/CrLight.cpp: -------------------------------------------------------------------------------- 1 | #include "Rendering/CrRendering_pch.h" -------------------------------------------------------------------------------- /Source/Rendering/CrLight.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Core/CrTypedId.h" 4 | 5 | class CrLight; 6 | using CrLightId = CrTypedId; 7 | 8 | namespace LightType 9 | { 10 | enum T 11 | { 12 | Point, 13 | Spot, 14 | Capsule, 15 | Quad, 16 | Directional 17 | }; 18 | }; 19 | 20 | class CrLight 21 | { 22 | CrLight() 23 | : m_colorIntensity(1.0f, 1.0f, 1.0f, 1.0f) 24 | , m_falloffRadius(1.0f) 25 | , m_type(LightType::Point) 26 | { 27 | } 28 | 29 | private: 30 | 31 | float4 m_transform; 32 | 33 | float4 m_colorIntensity; 34 | 35 | float m_falloffRadius; 36 | 37 | LightType::T m_type; 38 | }; -------------------------------------------------------------------------------- /Source/Rendering/CrMaterialCompiler.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Rendering/CrRenderingForwardDeclarations.h" 4 | #include "Rendering/CrShaderDiskCache.h" 5 | 6 | #include "Core/CrCoreForwardDeclarations.h" 7 | 8 | #include "crstl/string.h" 9 | 10 | struct CrMaterialDescriptor; 11 | struct CrMaterialShaderDescriptor; 12 | 13 | // Used to define variables, options, etc 14 | struct CrShaderHeaderGenerator 15 | { 16 | static crstl::string HashDefine; 17 | 18 | // Adds a define, with no value, e.g. #define Example 19 | void Define(const char* define); 20 | 21 | // Adds a define as a character sequence, e.g. #define Example MyExample 22 | void DefineString(const char* define, const char* string); 23 | 24 | // Adds a define with an integer value, e.g. #define Example 2 25 | void DefineInt(const char* define, int value); 26 | 27 | const crstl::string& GetString() const 28 | { 29 | return m_header; 30 | } 31 | 32 | private: 33 | 34 | crstl::string m_header; 35 | }; 36 | 37 | // Creates materials out of a material definition. It takes a descriptor 38 | // and up-to-date shader code, and produces the shaders necessary for 39 | // the material to be then used to pair with a mesh. A material itself 40 | // cannot be used on its own to render things yet, as it needs to be paired 41 | // with a mesh and pipelines produced for it 42 | class CrMaterialCompiler 43 | { 44 | public: 45 | 46 | static void Initialize(); 47 | 48 | static void Deinitialize(); 49 | 50 | // Creates set of defines based on the material shader descriptor 51 | void CreateMaterialShaderDefines(const CrMaterialShaderDescriptor& materialShaderDescriptor, CrShaderCompilerDefines& defines); 52 | 53 | // Compiles a material through its material descriptor 54 | CrMaterialHandle CompileMaterial(const CrMaterialDescriptor& descriptor); 55 | 56 | // Gets a material shader through the internal cache, or if not available, sends it off for compilation 57 | CrShaderBytecodeHandle GetDiskCachedOrCompileShaderBytecode 58 | (const CrFixedPath& shaderSourcePath, const crstl::string& entryPoint, const CrHash& shaderHash, const CrMaterialShaderDescriptor& materialShaderDescriptor); 59 | 60 | private: 61 | 62 | CrMaterialCompiler(); 63 | 64 | CrShaderDiskCache m_bytecodeDiskCache; 65 | }; 66 | 67 | extern CrMaterialCompiler* MaterialCompiler; -------------------------------------------------------------------------------- /Source/Rendering/CrRenderMesh.cpp: -------------------------------------------------------------------------------- 1 | #include "Rendering/CrRendering_pch.h" 2 | 3 | #include "Rendering/CrGPUBuffer.h" 4 | #include "CrRenderMesh.h" 5 | 6 | CrRenderMesh::~CrRenderMesh() 7 | { 8 | 9 | } 10 | 11 | void CrRenderMesh::AddVertexBuffer(const CrVertexBufferHandle& vertexBuffer) 12 | { 13 | m_vertexBuffers.push_back(vertexBuffer); 14 | 15 | MergeVertexDescriptors(); 16 | } 17 | 18 | void CrRenderMesh::SetIndexBuffer(const CrIndexBufferHandle& indexBuffer) 19 | { 20 | m_indexBuffer = indexBuffer; 21 | } 22 | 23 | // TODO Figure out best way of passing multiple references 24 | //void CrMesh::AddVertexBuffers(std::initializer_list vertexBuffers) 25 | //{ 26 | // //auto it = vertexBuffers.begin(); 27 | // //while (it != vertexBuffers.end()) 28 | // //{ 29 | // // m_vertexBuffers.push_back(*it); 30 | // // ++it; 31 | // //} 32 | // // 33 | // //MergeVertexDescriptors(); 34 | //} 35 | 36 | void CrRenderMesh::MergeVertexDescriptors() 37 | { 38 | m_vertexDescriptor = CrVertexDescriptor(); 39 | 40 | for (uint32_t streamId = 0; streamId < m_vertexBuffers.size(); ++streamId) 41 | { 42 | const CrVertexDescriptor& vertexBufferDescriptor = m_vertexBuffers[streamId]->GetVertexDescriptor(); 43 | 44 | for (uint32_t i = 0; i < vertexBufferDescriptor.GetAttributeCount(); ++i) 45 | { 46 | CrVertexAttribute attribute = vertexBufferDescriptor.GetAttribute(i); 47 | attribute.streamId = streamId; 48 | m_vertexDescriptor.AddAttribute(attribute); 49 | } 50 | } 51 | } -------------------------------------------------------------------------------- /Source/Rendering/CrRenderMesh.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Rendering/CrVisibility.h" 4 | #include "Rendering/CrRenderingForwardDeclarations.h" 5 | #include "Rendering/CrVertexDescriptor.h" 6 | 7 | #include "crstl/intrusive_ptr.h" 8 | #include "crstl/vector.h" 9 | 10 | class CrRenderMesh final : public crstl::intrusive_ptr_interface_delete 11 | { 12 | public: 13 | 14 | ~CrRenderMesh(); 15 | 16 | const CrVertexDescriptor& GetVertexDescriptor() const { return m_vertexDescriptor; } 17 | 18 | void AddVertexBuffer(const CrVertexBufferHandle& vertexBuffer); 19 | 20 | const CrVertexBufferHandle& GetVertexBuffer(uint32_t index) const { return m_vertexBuffers[index]; } 21 | 22 | uint32_t GetVertexBufferCount() const { return (uint32_t)m_vertexBuffers.size(); } 23 | 24 | const CrBoundingBox& GetBoundingBox() const { return m_boundingBox; } 25 | 26 | void SetBoundingBox(const CrBoundingBox& boundingBox) { m_boundingBox = boundingBox; } 27 | 28 | const CrIndexBufferHandle& GetIndexBuffer() const { return m_indexBuffer; } 29 | 30 | void SetIndexBuffer(const CrIndexBufferHandle& indexBuffer); 31 | 32 | void SetIsDoubleSided(bool isDoubleSided) { m_isDoubleSided = isDoubleSided; } 33 | 34 | bool GetIsDoubleSided() const { return m_isDoubleSided; } 35 | 36 | private: 37 | 38 | void MergeVertexDescriptors(); 39 | 40 | bool m_isDoubleSided = false; 41 | 42 | crstl::vector m_vertexBuffers; 43 | 44 | CrVertexDescriptor m_vertexDescriptor; 45 | 46 | CrIndexBufferHandle m_indexBuffer; 47 | 48 | CrBoundingBox m_boundingBox; 49 | }; -------------------------------------------------------------------------------- /Source/Rendering/CrRenderModel.cpp: -------------------------------------------------------------------------------- 1 | #include "Rendering/CrRendering_pch.h" 2 | 3 | #include "Rendering/CrRenderModel.h" 4 | #include "Rendering/CrRenderMesh.h" 5 | #include "Rendering/CrMaterial.h" 6 | #include "Rendering/ICrPipeline.h" 7 | #include "Rendering/ICrRenderSystem.h" 8 | #include "Rendering/ICrRenderDevice.h" 9 | 10 | uint32_t CrRenderModelDescriptor::AddMaterial(const CrMaterialHandle& material) 11 | { 12 | uint32_t currentIndex = (uint32_t)m_materials.size(); 13 | m_materials.push_back(material); 14 | return currentIndex; 15 | } 16 | 17 | void CrRenderModelDescriptor::AddRenderMesh(const CrRenderMeshHandle& renderMesh, uint8_t materialIndex) 18 | { 19 | m_meshes.push_back(renderMesh); 20 | m_materialIndices.push_back(materialIndex); 21 | } 22 | 23 | CrRenderModel::CrRenderModel(const CrRenderModelDescriptor& descriptor) 24 | { 25 | // Copy the materials 26 | m_materials.reserve(descriptor.GetMaterialCount()); 27 | for (uint32_t i = 0; i < descriptor.GetMaterialCount(); ++i) 28 | { 29 | const CrMaterialHandle& material = descriptor.GetMaterial(i); 30 | m_materials.push_back(material); 31 | } 32 | 33 | m_renderMeshes.reserve(descriptor.GetRenderMeshCount()); 34 | m_pipelines.resize(descriptor.GetRenderMeshCount()); 35 | 36 | // For every mesh-material combination, create the necessary pipeline objects 37 | for (uint32_t meshIndex = 0; meshIndex < descriptor.GetRenderMeshCount(); ++meshIndex) 38 | { 39 | const CrRenderMeshHandle& mesh = descriptor.GetRenderMesh(meshIndex); 40 | const CrMaterialHandle& material = descriptor.GetMaterial(descriptor.GetRenderMeshMaterial(meshIndex)); 41 | 42 | m_renderMeshes.push_back(mesh); 43 | m_renderMeshMaterialIndex.push_back((uint8_t)descriptor.GetRenderMeshMaterial(meshIndex)); 44 | 45 | for (CrMaterialPipelineVariant::T pipelineVariant = CrMaterialPipelineVariant::First; pipelineVariant < CrMaterialPipelineVariant::Count; ++pipelineVariant) 46 | { 47 | const CrMaterialPassProperties& passProperties = CrMaterialPassProperties::GetMaterialPassProperties(mesh, pipelineVariant); 48 | 49 | const CrGraphicsShaderHandle& graphicsShader = material->GetShader(passProperties.shaderVariant); 50 | 51 | if (graphicsShader) 52 | { 53 | CrGraphicsPipelineHandle pipeline = RenderSystem->GetRenderDevice()->CreateGraphicsPipeline(passProperties.pipelineDescriptor, graphicsShader, mesh->GetVertexDescriptor()); 54 | 55 | m_pipelines[meshIndex][pipelineVariant] = pipeline; 56 | } 57 | } 58 | } 59 | 60 | ComputeBoundingBoxFromMeshes(); 61 | } 62 | 63 | void CrRenderModel::ComputeBoundingBoxFromMeshes() 64 | { 65 | float3 minVertex = float3( FLT_MAX); 66 | float3 maxVertex = float3(-FLT_MAX); 67 | 68 | for (const CrRenderMeshHandle& renderMesh : m_renderMeshes) 69 | { 70 | const CrBoundingBox& meshBox = renderMesh->GetBoundingBox(); 71 | minVertex = min(minVertex, meshBox.center - meshBox.extents); 72 | maxVertex = max(maxVertex, meshBox.center + meshBox.extents); 73 | } 74 | 75 | m_boundingBox.center = (maxVertex + minVertex) * 0.5f; 76 | m_boundingBox.extents = (maxVertex - minVertex) * 0.5f; 77 | } -------------------------------------------------------------------------------- /Source/Rendering/CrRenderModel.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Rendering/CrVisibility.h" 4 | #include "Rendering/CrRenderingForwardDeclarations.h" 5 | #include "Rendering/CrMaterial.h" 6 | #include "Rendering/CrRenderMesh.h" 7 | 8 | #include "crstl/array.h" 9 | #include "crstl/fixed_vector.h" 10 | #include "crstl/intrusive_ptr.h" 11 | #include "crstl/open_hashmap.h" 12 | #include "crstl/pair.h" 13 | #include "crstl/vector.h" 14 | 15 | struct CrRenderModelDescriptor 16 | { 17 | uint32_t AddMaterial(const CrMaterialHandle& material); 18 | 19 | void AddRenderMesh(const CrRenderMeshHandle& renderMesh, uint8_t materialIndex); 20 | 21 | uint32_t GetMaterialCount() const { return (uint32_t)m_materials.size(); } 22 | 23 | uint32_t GetRenderMeshCount() const { return (uint32_t)m_meshes.size(); } 24 | 25 | const CrMaterialHandle& GetMaterial(uint32_t materialIndex) const { return m_materials[materialIndex]; } 26 | 27 | const CrRenderMeshHandle& GetRenderMesh(uint32_t renderMeshIndex) const { return m_meshes[renderMeshIndex]; } 28 | 29 | uint32_t GetRenderMeshMaterial(uint32_t renderMeshIndex) const { return m_materialIndices[renderMeshIndex]; } 30 | 31 | private: 32 | 33 | crstl::fixed_vector m_meshes; 34 | 35 | crstl::fixed_vector m_materialIndices; 36 | 37 | crstl::fixed_vector m_materials; 38 | }; 39 | 40 | class CrRenderModel final : public crstl::intrusive_ptr_interface_delete 41 | { 42 | public: 43 | 44 | CrRenderModel() = default; 45 | 46 | CrRenderModel(const CrRenderModelDescriptor& descriptor); 47 | 48 | const CrBoundingBox& GetBoundingBox() const { return m_boundingBox; } 49 | 50 | const crstl::pair GetRenderMeshMaterial(uint32_t meshIndex) const 51 | { 52 | const CrRenderMeshHandle& renderMesh = m_renderMeshes[meshIndex]; 53 | uint32_t materialIndex = m_renderMeshMaterialIndex[meshIndex]; 54 | const CrMaterialHandle& material = m_materials[materialIndex]; 55 | 56 | return crstl::pair(renderMesh, material); 57 | } 58 | 59 | const CrMaterialHandle& GetMaterial(uint32_t meshIndex) const 60 | { 61 | return m_materials[meshIndex]; 62 | } 63 | 64 | const CrGraphicsPipelineHandle& GetPipeline(uint32_t meshIndex, CrMaterialPipelineVariant::T pipelineVariant) const 65 | { 66 | return m_pipelines[meshIndex][pipelineVariant]; 67 | } 68 | 69 | uint32_t GetRenderMeshCount() const 70 | { 71 | return (uint32_t)m_renderMeshes.size(); 72 | } 73 | 74 | private: 75 | 76 | void ComputeBoundingBoxFromMeshes(); 77 | 78 | CrBoundingBox m_boundingBox; 79 | 80 | crstl::open_hashmap m_pipelineMap; 81 | 82 | // A model has access to a collection of render meshes, each with a material attached. 83 | // To start with we'll make all of these arrays of equal size, but they don't have to 84 | // be. A merging of a material + a render mesh produces a pipeline state. The pipeline 85 | // state knows everything about where it's going to be rendered (it needs to) 86 | 87 | crstl::vector m_renderMeshes; 88 | 89 | crstl::vector m_renderMeshMaterialIndex; 90 | 91 | crstl::vector m_materials; 92 | 93 | crstl::vector> m_pipelines; 94 | }; 95 | -------------------------------------------------------------------------------- /Source/Rendering/CrRendererConfig.cpp: -------------------------------------------------------------------------------- 1 | #include "Rendering/CrRendering_pch.h" 2 | 3 | #include "Rendering/CrRendererConfig.h" 4 | 5 | #include "Rendering/CrDataFormats.h" 6 | 7 | cr3d::DataFormat::T CrRendererConfig::DepthBufferFormat = cr3d::DataFormat::D32_Float_S8_Uint; 8 | 9 | // GBuffer 10 | cr3d::DataFormat::T CrRendererConfig::GBufferAlbedoAOFormat = cr3d::DataFormat::RGBA8_Unorm; 11 | cr3d::DataFormat::T CrRendererConfig::GBufferNormalsFormat = cr3d::DataFormat::RGBA8_Unorm; 12 | cr3d::DataFormat::T CrRendererConfig::GBufferMaterialFormat = cr3d::DataFormat::RGBA8_Unorm; 13 | 14 | cr3d::DataFormat::T CrRendererConfig::LightingFormat = cr3d::DataFormat::RG11B10_Float; 15 | 16 | // Debug Shader 17 | cr3d::DataFormat::T CrRendererConfig::DebugShaderFormat = cr3d::DataFormat::RGBA16_Unorm; 18 | 19 | cr3d::DataFormat::T CrRendererConfig::SwapchainFormat = cr3d::DataFormat::BGRA8_Unorm; -------------------------------------------------------------------------------- /Source/Rendering/CrRendererConfig.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Rendering/CrRenderingForwardDeclarations.h" 4 | 5 | struct CrRendererConfig 6 | { 7 | static cr3d::DataFormat::T DepthBufferFormat; 8 | 9 | static cr3d::DataFormat::T GBufferAlbedoAOFormat; 10 | static cr3d::DataFormat::T GBufferNormalsFormat; 11 | static cr3d::DataFormat::T GBufferMaterialFormat; 12 | 13 | static cr3d::DataFormat::T LightingFormat; 14 | 15 | static cr3d::DataFormat::T DebugShaderFormat; 16 | 17 | static cr3d::DataFormat::T SwapchainFormat; 18 | }; -------------------------------------------------------------------------------- /Source/Rendering/CrRendering.cpp: -------------------------------------------------------------------------------- 1 | #include "Rendering/CrRendering_pch.h" 2 | #include "CrRendering.h" 3 | 4 | #include 5 | 6 | cr3d::GraphicsApi::T cr3d::GraphicsApi::FromString(const char* graphicsApiString) 7 | { 8 | if (strcmp(graphicsApiString, "vulkan") == 0) 9 | { 10 | return cr3d::GraphicsApi::Vulkan; 11 | } 12 | else if (strcmp(graphicsApiString, "d3d12") == 0) 13 | { 14 | return cr3d::GraphicsApi::D3D12; 15 | } 16 | else 17 | { 18 | return cr3d::GraphicsApi::Count; 19 | } 20 | } 21 | 22 | cr3d::GraphicsVendor::T cr3d::GraphicsVendor::FromString(const char* graphicsVendorString) 23 | { 24 | if (strcmp(graphicsVendorString, "nvidia") == 0) 25 | { 26 | return GraphicsVendor::NVIDIA; 27 | } 28 | else if (strcmp(graphicsVendorString, "amd") == 0) 29 | { 30 | return GraphicsVendor::AMD; 31 | } 32 | else if (strcmp(graphicsVendorString, "intel") == 0) 33 | { 34 | return GraphicsVendor::Intel; 35 | } 36 | else 37 | { 38 | return GraphicsVendor::Unknown; 39 | } 40 | } 41 | 42 | cr3d::ShaderStage::T cr3d::ShaderStage::FromString(const char* shaderStageString) 43 | { 44 | if (strcmp(shaderStageString, "vertex") == 0) 45 | { 46 | return ShaderStage::Vertex; 47 | } 48 | else if (strcmp(shaderStageString, "pixel") == 0) 49 | { 50 | return ShaderStage::Pixel; 51 | } 52 | else if (strcmp(shaderStageString, "hull") == 0) 53 | { 54 | return ShaderStage::Hull; 55 | } 56 | else if (strcmp(shaderStageString, "domain") == 0) 57 | { 58 | return ShaderStage::Domain; 59 | } 60 | else if (strcmp(shaderStageString, "geometry") == 0) 61 | { 62 | return ShaderStage::Geometry; 63 | } 64 | else if (strcmp(shaderStageString, "compute") == 0) 65 | { 66 | return ShaderStage::Compute; 67 | } 68 | else if (strcmp(shaderStageString, "rootsignature") == 0) 69 | { 70 | return ShaderStage::RootSignature; 71 | } 72 | else 73 | { 74 | return ShaderStage::Count; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /Source/Rendering/CrRenderingResources.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Rendering/CrRenderingForwardDeclarations.h" 4 | 5 | #include "crstl/intrusive_ptr.h" 6 | 7 | // Rendering resources that are used as default 8 | class CrRenderingResources 9 | { 10 | public: 11 | 12 | static void Initialize(ICrRenderDevice* renderDevice); 13 | 14 | static void Deinitialize(); 15 | 16 | // Global samplers 17 | 18 | CrSamplerHandle AllLinearClampSampler; 19 | 20 | CrSamplerHandle AllLinearWrapSampler; 21 | 22 | CrSamplerHandle AllPointClampSampler; 23 | 24 | CrSamplerHandle AllPointWrapSampler; 25 | 26 | CrTextureHandle WhiteSmallTexture; 27 | 28 | CrTextureHandle BlackSmallTexture; 29 | 30 | // Points up in tangent space 31 | CrTextureHandle NormalsSmallTexture; 32 | 33 | private: 34 | 35 | CrRenderingResources(ICrRenderDevice* renderDevice); 36 | }; 37 | 38 | extern CrRenderingResources* RenderingResources; -------------------------------------------------------------------------------- /Source/Rendering/CrRenderingStatistics.cpp: -------------------------------------------------------------------------------- 1 | #include "Rendering/CrRendering_pch.h" 2 | 3 | #include "CrRenderingStatistics.h" 4 | 5 | uint32_t CrRenderingStatistics::m_drawcallCount; 6 | 7 | uint32_t CrRenderingStatistics::m_vertexCount; 8 | 9 | uint32_t CrRenderingStatistics::m_instanceCount; -------------------------------------------------------------------------------- /Source/Rendering/CrRenderingStatistics.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class CrRenderingStatistics 4 | { 5 | public: 6 | 7 | static void Reset(); 8 | 9 | static void AddDrawcall(); 10 | 11 | static void AddVertices(uint32_t vertexCount); 12 | 13 | static void AddInstances(uint32_t instanceCount); 14 | 15 | static uint32_t GetDrawcallCount(); 16 | 17 | static uint32_t GetVertexCount(); 18 | 19 | static uint32_t GetInstanceCount(); 20 | 21 | private: 22 | 23 | static uint32_t m_drawcallCount; 24 | 25 | static uint32_t m_vertexCount; 26 | 27 | static uint32_t m_instanceCount; 28 | }; 29 | 30 | inline void CrRenderingStatistics::Reset() 31 | { 32 | m_drawcallCount = 0; 33 | m_vertexCount = 0; 34 | m_instanceCount = 0; 35 | } 36 | 37 | inline void CrRenderingStatistics::AddDrawcall() 38 | { 39 | m_drawcallCount++; 40 | } 41 | 42 | inline void CrRenderingStatistics::AddVertices(uint32_t vertexCount) 43 | { 44 | m_vertexCount += vertexCount; 45 | } 46 | 47 | inline void CrRenderingStatistics::AddInstances(uint32_t instanceCount) 48 | { 49 | m_instanceCount += instanceCount; 50 | } 51 | 52 | inline uint32_t CrRenderingStatistics::GetDrawcallCount() 53 | { 54 | return m_drawcallCount; 55 | } 56 | 57 | inline uint32_t CrRenderingStatistics::GetVertexCount() 58 | { 59 | return m_vertexCount; 60 | } 61 | 62 | inline uint32_t CrRenderingStatistics::GetInstanceCount() 63 | { 64 | return m_instanceCount; 65 | } -------------------------------------------------------------------------------- /Source/Rendering/CrRenderingVector.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | // These vectors are simple structs that allow us to interface with shaders. hlsl++ is no good when it comes to this task 9 | // for two reasons: 10 | // 11 | // 1) The hardware vectors are greater in size than the data they're supposed to represent. This is just the nature of SIMD 12 | // 2) Operations on vectors such as multiply or add would cause issues with write-combine memory which is what we normally 13 | // write to when using GPU-visible memory. For that reason it's better to just provide convenience structs that one does 14 | // not read from, even accidentally. 15 | // 16 | // We can still provide conversion operators such that it feels natural to store them using hlsl++ 17 | 18 | namespace cr3d 19 | { 20 | struct float2 21 | { 22 | float2() = default; 23 | float2(hlslpp::float2 f) { hlslpp::store(f, &x); } 24 | float x, y; 25 | }; 26 | 27 | struct float3 28 | { 29 | float3() = default; 30 | float3(hlslpp::float3 f) { hlslpp::store(f, &x); } 31 | float x, y, z; 32 | }; 33 | 34 | struct float4 35 | { 36 | float4() = default; 37 | float4(hlslpp::float4 f) { hlslpp::store(f, &x); } 38 | float x, y, z, w; 39 | }; 40 | 41 | struct float3x4 42 | { 43 | float3x4() = default; 44 | float3x4(hlslpp::float3x4 m) { hlslpp::store(m, &m00); } 45 | float m00, m01, m02, m03, 46 | m10, m11, m12, m13, 47 | m20, m21, m22, m23; 48 | }; 49 | 50 | struct float4x4 51 | { 52 | float4x4() = default; 53 | float4x4(hlslpp::float4x4 m) { hlslpp::store(m, &m00); } 54 | float m00, m01, m02, m03, 55 | m10, m11, m12, m13, 56 | m20, m21, m22, m23, 57 | m30, m31, m32, m33; 58 | }; 59 | 60 | struct int2 61 | { 62 | int2() = default; 63 | int2(hlslpp::int2 u) { hlslpp::store(u, &x); } 64 | 65 | int32_t x, y; 66 | }; 67 | 68 | struct int3 69 | { 70 | int3() = default; 71 | int3(hlslpp::int3 u) { hlslpp::store(u, &x); } 72 | 73 | int32_t x, y, z; 74 | }; 75 | 76 | struct int4 77 | { 78 | int4() = default; 79 | int4(hlslpp::int4 u) { hlslpp::store(u, &x); } 80 | 81 | int32_t x, y, z, w; 82 | }; 83 | 84 | struct uint2 85 | { 86 | uint2() = default; 87 | uint2(hlslpp::uint2 u) { hlslpp::store(u, &x); } 88 | 89 | uint32_t x, y; 90 | }; 91 | 92 | struct uint3 93 | { 94 | uint3() = default; 95 | uint3(hlslpp::uint3 u) { hlslpp::store(u, &x); } 96 | 97 | uint32_t x, y, z; 98 | }; 99 | 100 | struct uint4 101 | { 102 | uint4() = default; 103 | uint4(hlslpp::uint4 u) { hlslpp::store(u, &x); } 104 | 105 | uint32_t x, y, z, w; 106 | }; 107 | } -------------------------------------------------------------------------------- /Source/Rendering/CrRendering_pch.cpp: -------------------------------------------------------------------------------- 1 | #include "Rendering/CrRendering_pch.h" -------------------------------------------------------------------------------- /Source/Rendering/CrRendering_pch.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #if defined(VULKAN_API) 4 | // Vulkan on Windows includes windows.h which defines things like min and max, aside from being very big. 5 | // To counter it we define NOMINMAX, etc. globally 6 | #include 7 | #include "Vulkan/CrVulkan.h" 8 | #include "Vulkan/CrVMA.h" 9 | #endif 10 | 11 | #if defined(D3D12_API) 12 | #include "d3d12.h" 13 | #include 14 | #include 15 | #endif 16 | 17 | #include "Core/PCH/CrCRSTLPch.h" 18 | #include "Core/CrHash.h" 19 | #include "Math/CrMathPch.h" -------------------------------------------------------------------------------- /Source/Rendering/CrShaderDiskCache.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Rendering/CrRenderingForwardDeclarations.h" 4 | 5 | #include "Core/CrCoreForwardDeclarations.h" 6 | #include "Core/FileSystem/CrFixedPath.h" 7 | 8 | struct CrMaterialShaderDescriptor; 9 | 10 | class CrShaderDiskCache 11 | { 12 | public: 13 | 14 | CrShaderDiskCache() {} 15 | 16 | // The current hash is what we want to use this cache with. If the hash doesn't match, we'll delete the cache 17 | CrShaderDiskCache(const CrFixedPath& cachePath, const char* hashFilename, CrHash currentHash); 18 | 19 | CrFixedPath CreateCachedFilePath(const CrHash& hash, cr3d::GraphicsApi::T graphicsApi) const; 20 | 21 | CrShaderBytecodeHandle LoadFromCache(const CrHash& hash, cr3d::GraphicsApi::T graphicsApi) const; 22 | 23 | void SaveToCache(const CrHash& hash, cr3d::GraphicsApi::T graphicsApi, const CrShaderBytecodeHandle& bytecode) const; 24 | 25 | private: 26 | 27 | CrFixedPath m_cachePath; 28 | }; -------------------------------------------------------------------------------- /Source/Rendering/CrShaderManager.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Core/CrCoreForwardDeclarations.h" 4 | 5 | #include "Rendering/CrRenderingForwardDeclarations.h" 6 | 7 | class ICrRenderDevice; 8 | 9 | struct CrShaderCompilationDescriptor; 10 | struct CrShaderBytecodeCompilationDescriptor; 11 | class ICrShaderBindingLayout; 12 | 13 | class CrShaderManager 14 | { 15 | public: 16 | 17 | static const char* GetShaderBytecodeExtension(cr3d::GraphicsApi::T graphicsApi); 18 | 19 | static void Initialize(ICrRenderDevice* renderDevice); 20 | 21 | static void Deinitialize(); 22 | 23 | ICrRenderDevice* GetRenderDevice() const { return m_renderDevice; } 24 | 25 | CrShaderBytecodeHandle CompileShaderBytecode(const CrShaderBytecodeCompilationDescriptor& bytecodeDescriptor) const; 26 | 27 | CrShaderBytecodeHandle CompileShaderBytecode(const CrShaderBytecodeCompilationDescriptor& bytecodeDescriptor, const CrShaderCompilerDefines& defines) const; 28 | 29 | CrGraphicsShaderHandle CompileGraphicsShader(const CrShaderCompilationDescriptor& bytecodeLoadDescriptor) const; 30 | 31 | CrComputeShaderHandle CompileComputeShader(const CrShaderCompilationDescriptor& bytecodeLoadDescriptor) const; 32 | 33 | CrFixedPath GetCompiledShadersPath(cr::Platform::T platform, cr3d::GraphicsApi::T graphicsApi) const; 34 | 35 | protected: 36 | 37 | CrShaderManager(ICrRenderDevice* renderDevice); 38 | 39 | ICrRenderDevice* m_renderDevice; 40 | }; 41 | 42 | extern CrShaderManager* ShaderManager; -------------------------------------------------------------------------------- /Source/Rendering/CrShaderResourceMetadata.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Core/CrCoreForwardDeclarations.h" 4 | #include "Rendering/CrRenderingForwardDeclarations.h" 5 | 6 | class CrShaderMetadata 7 | { 8 | public: 9 | 10 | static const ConstantBufferMetadata& GetConstantBuffer(const crstl::string& name); 11 | 12 | static const ConstantBufferMetadata& GetConstantBuffer(ConstantBuffers::T id); 13 | 14 | static const SamplerMetadata& GetSampler(const crstl::string& name); 15 | 16 | static const SamplerMetadata& GetSampler(Samplers::T id); 17 | 18 | static const TextureMetadata& GetTexture(const crstl::string& name); 19 | 20 | static const TextureMetadata& GetTexture(Textures::T id); 21 | 22 | static const RWTextureMetadata& GetRWTexture(const crstl::string& name); 23 | 24 | static const RWTextureMetadata& GetRWTexture(RWTextures::T id); 25 | 26 | static const StorageBufferMetadata& GetStorageBuffer(const crstl::string& name); 27 | 28 | static const StorageBufferMetadata& GetStorageBuffer(StorageBuffers::T id); 29 | 30 | static const RWStorageBufferMetadata& GetRWStorageBuffer(const crstl::string& name); 31 | 32 | static const RWStorageBufferMetadata& GetRWStorageBuffer(RWStorageBuffers::T id); 33 | 34 | static const RWTypedBufferMetadata& GetRWTypedBuffer(const crstl::string& name); 35 | 36 | static const RWTypedBufferMetadata& GetRWTypedBuffer(RWTypedBuffers::T id); 37 | }; -------------------------------------------------------------------------------- /Source/Rendering/CrShaderSources.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Core/FileSystem/CrFixedPath.h" 4 | #include "Core/CrHash.h" 5 | 6 | #include "crstl/open_hashmap.h" 7 | #include "crstl/string.h" 8 | 9 | // Stores all the sources for our shaders (on a desktop development build) 10 | // so that we can recompile them as necessary. Also has the ability to 11 | // resolve includes. The reason we want to load the shader source is that 12 | // we need to hash the incoming code easily, to determine whether a shader 13 | // needs to be recompiled or not. 14 | // 15 | // TODO File watchers for fast reload. These file watchers will notify other 16 | // systems that their sources have changed and need recompilation 17 | class CrShaderSources 18 | { 19 | public: 20 | 21 | static void Initialize(); 22 | 23 | static void Deinitialize(); 24 | 25 | const crstl::string& GetUbershaderSource() const; 26 | 27 | const CrFixedPath& GetUbershaderTempDirectory() const; 28 | 29 | const CrHash GetUbershaderHash() const; 30 | 31 | private: 32 | 33 | CrShaderSources(); 34 | 35 | crstl::open_hashmap m_shaderPaths; 36 | 37 | crstl::open_hashmap m_shaderSources; 38 | 39 | crstl::open_hashmap m_ubershaderSources; 40 | 41 | // Path to the temp folder for built ubershaders 42 | CrFixedPath m_ubershaderTempDirectory; 43 | 44 | // Ubershader source with resolved includes 45 | crstl::string m_resolvedUbershaderSource; 46 | 47 | // Ubershader source stripped of text elements that cannot affect 48 | // the final binary (in order to hash it) 49 | crstl::string m_hashableUbershaderSource; 50 | 51 | // Ubershader hash computed with current sources (used to determine whether shaders in cache are usable) 52 | CrHash m_ubershaderHash; 53 | }; 54 | 55 | extern CrShaderSources* ShaderSources; -------------------------------------------------------------------------------- /Source/Rendering/CrShapeBuilder.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Rendering/CrRenderingForwardDeclarations.h" 4 | #include "Rendering/CrRenderMesh.h" 5 | 6 | #include "Math/CrHlslppVectorFloatType.h" 7 | 8 | class CrShapeBuilder 9 | { 10 | public: 11 | 12 | // Quad 13 | struct CrQuadDescriptor 14 | { 15 | uint32_t subdivisionX = 0; 16 | uint32_t subdivisionY = 0; 17 | float4x4 transform = float4x4::identity(); 18 | float4 color = 1.0f; 19 | }; 20 | 21 | static CrRenderMeshHandle CreateQuad(const CrQuadDescriptor& descriptor); 22 | 23 | struct CrCubeDescriptor 24 | { 25 | uint32_t subdivisionX = 0; 26 | uint32_t subdivisionY = 0; 27 | uint32_t subdivisionZ = 0; 28 | float4x4 transform = float4x4::identity(); 29 | float4 color = 1.0f; 30 | }; 31 | 32 | static CrRenderMeshHandle CreateCube(const CrCubeDescriptor& descriptor); 33 | 34 | struct CrSphereDescriptor 35 | { 36 | uint32_t subdivision = 0; 37 | float4x4 transform = float4x4::identity(); 38 | float4 color = 1.0f; 39 | }; 40 | 41 | static CrRenderMeshHandle CreateSphere(const CrSphereDescriptor& descriptor); 42 | 43 | struct CrCylinderDescriptor 44 | { 45 | uint32_t subdivisionAxis = 0; 46 | uint32_t subdivisionLength = 0; 47 | float4x4 transform = float4x4::identity(); 48 | float4 color = 1.0f; 49 | }; 50 | 51 | static CrRenderMeshHandle CreateCylinder(const CrCylinderDescriptor& descriptor); 52 | 53 | struct CrConeDescriptor 54 | { 55 | uint32_t subdivisionAxis = 0; 56 | uint32_t subdivisionLength = 0; 57 | float4x4 transform = float4x4::identity(); 58 | float4 color = 1.0f; 59 | }; 60 | 61 | static CrRenderMeshHandle CreateCone(const CrConeDescriptor& descriptor); 62 | }; -------------------------------------------------------------------------------- /Source/Rendering/CrStackAllocator.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Core/CrAlignment.h" 4 | 5 | template 6 | struct CrStackAllocation 7 | { 8 | CrStackAllocation(T* memory, uint32_t offset) : memory(memory), offset(offset) {} 9 | 10 | T* memory = nullptr; 11 | uint32_t offset = 0; 12 | }; 13 | 14 | // Manages transient memory allocated per frame for CPU resources 15 | class CrStackAllocator 16 | { 17 | public: 18 | 19 | CrStackAllocation Allocate(size_t sizeBytes); 20 | 21 | template 22 | CrStackAllocation Allocate(size_t count); 23 | 24 | CrStackAllocation AllocateAligned(size_t size, size_t alignment); 25 | 26 | protected: 27 | 28 | void AllocateAligned(size_t size, size_t alignment, void*& memory, uint32_t& offset); 29 | 30 | uint8_t* m_memoryBasePointer = nullptr; 31 | 32 | uint8_t* m_currentPointer = nullptr; 33 | 34 | size_t m_size = 0; 35 | }; 36 | 37 | inline CrStackAllocation CrStackAllocator::Allocate(size_t sizeBytes) 38 | { 39 | return AllocateAligned(sizeBytes, 1); 40 | } 41 | 42 | template 43 | inline CrStackAllocation CrStackAllocator::Allocate(size_t count) 44 | { 45 | void* bufferPointer; uint32_t offset; 46 | AllocateAligned(sizeof(T) * count, 1, bufferPointer, offset); 47 | return CrStackAllocation((T*)bufferPointer, offset); 48 | } 49 | 50 | inline CrStackAllocation CrStackAllocator::AllocateAligned(size_t sizeBytes, size_t alignment) 51 | { 52 | void* bufferPointer; uint32_t offset; 53 | AllocateAligned(sizeBytes, alignment, bufferPointer, offset); 54 | return CrStackAllocation(bufferPointer, offset); 55 | } 56 | 57 | inline void CrStackAllocator::AllocateAligned(size_t sizeBytes, size_t alignment, void*& memory, uint32_t& offset) 58 | { 59 | uint8_t* bufferPointer = CrAlignUpPow2(m_currentPointer, alignment); // Copy the current pointer, with the correct alignment 60 | m_currentPointer = bufferPointer + sizeBytes; // Reserve as many bytes as needed by the buffer 61 | CrAssertMsg(m_currentPointer < m_memoryBasePointer + m_size, "Ran out of memory in stream"); 62 | 63 | memory = bufferPointer; 64 | offset = static_cast(bufferPointer - m_memoryBasePointer); // Work out the offset 65 | } -------------------------------------------------------------------------------- /Source/Rendering/CrVertexDescriptor.cpp: -------------------------------------------------------------------------------- 1 | #include "Rendering/CrRendering_pch.h" 2 | #include "CrVertexDescriptor.h" 3 | 4 | #include "stdlib.h" 5 | 6 | namespace CrVertexSemantic 7 | { 8 | Data::Data(CrVertexSemantic::T semantic, const char* name) : semantic(semantic), semanticName(name) 9 | { 10 | indexOffset = (uint32_t)semanticName.find_first_of("0123456789"); 11 | if (indexOffset != 0xffffffff) 12 | { 13 | index = atoi(semanticName.substr(indexOffset, semanticName.length()).c_str()); 14 | } 15 | else 16 | { 17 | index = 0; 18 | } 19 | } 20 | 21 | crstl::array VertexSemanticData; 22 | 23 | bool CreateVertexSemanticData() 24 | { 25 | VertexSemanticData[CrVertexSemantic::Position] = Data(CrVertexSemantic::Position, "POSITION"); 26 | VertexSemanticData[CrVertexSemantic::Normal] = Data(CrVertexSemantic::Normal, "NORMAL"); 27 | VertexSemanticData[CrVertexSemantic::Tangent] = Data(CrVertexSemantic::Tangent, "TANGENT"); 28 | VertexSemanticData[CrVertexSemantic::Color] = Data(CrVertexSemantic::Color, "COLOR"); 29 | VertexSemanticData[CrVertexSemantic::TexCoord0] = Data(CrVertexSemantic::TexCoord0, "TEXCOORD0"); 30 | 31 | for (uint32_t s = 0; s < VertexSemanticData.size(); ++s) 32 | { 33 | CrAssertMsg(VertexSemanticData[s].semantic != CrVertexSemantic::Count, "Semantic not initialized"); 34 | } 35 | 36 | return true; 37 | } 38 | 39 | bool DummyCreateVertexSemanticData = CreateVertexSemanticData(); 40 | }; -------------------------------------------------------------------------------- /Source/Rendering/CrVisibility.cpp: -------------------------------------------------------------------------------- 1 | #include "Rendering/CrRendering_pch.h" 2 | 3 | #include "CrVisibility.h" 4 | 5 | #include "Math/CrHlslppVectorFloat.h" 6 | #include "Math/CrHlslppMatrixFloat.h" 7 | 8 | // These projected corners are before the division by w 9 | void CrVisibility::ComputeObbProjection(const CrBoundingBox& obb, const float4x4& worldTransform, const float4x4& view2ProjectionMatrix, CrBoxVertices& projectedCorners) 10 | { 11 | float4x4 worldViewProjectionMatrix = mul(worldTransform, view2ProjectionMatrix); 12 | 13 | float4 cornerMin = float4(obb.center, 1.0f) - float4(obb.extents, 0.0f); 14 | float4 cornerMax = float4(obb.center, 1.0f) + float4(obb.extents, 0.0f); 15 | 16 | crstl::array boxVertices = 17 | { 18 | cornerMax, 19 | float4(cornerMin.x, cornerMax.yzw), 20 | float4(cornerMin.x, cornerMax.y, cornerMin.zw), 21 | float4(cornerMax.xy, cornerMin.zw), 22 | 23 | float4(cornerMax.x, cornerMin.y, cornerMax.zw), 24 | float4(cornerMin.xy, cornerMax.zw), 25 | cornerMin, 26 | float4(cornerMax.x, cornerMin.yzw) 27 | }; 28 | 29 | for (uint32_t i = 0; i < boxVertices.size(); ++i) 30 | { 31 | projectedCorners[i] = mul(boxVertices[i], worldViewProjectionMatrix); 32 | } 33 | } 34 | 35 | bool CrVisibility::AreProjectedPointsOnScreen(const CrBoxVertices& projectedCorners) 36 | { 37 | float3 outsideLeft = float3(1.0f, 1.0f, 1.0f); 38 | float3 outsideRight = float3(1.0f, 1.0f, 1.0f); 39 | 40 | for (uint32_t i = 0; i < projectedCorners.size(); ++i) 41 | { 42 | const float4& projectedPosition = projectedCorners[i]; 43 | outsideLeft = outsideLeft * (projectedPosition.xyz < float3(-projectedPosition.ww, 0.0f)); 44 | outsideRight = outsideRight * (projectedPosition.xyz > float3(projectedPosition.www)); 45 | } 46 | 47 | return !(any(outsideLeft) || any(outsideRight)); 48 | } 49 | 50 | // Calculates the Obb in projection space and effectively does the same calculations as a vertex shader would do 51 | // to determine whether any part of the bounding box is inside the camera. 52 | // TODO This function can be optimized further 53 | bool CrVisibility::IsObbInFrustum 54 | ( 55 | const CrBoundingBox& obb, 56 | const float4x4& worldTransform, 57 | const float4x4& viewProjectionMatrix 58 | ) 59 | { 60 | crstl::array projectedCorners; 61 | ComputeObbProjection(obb, worldTransform, viewProjectionMatrix, projectedCorners); 62 | 63 | return AreProjectedPointsOnScreen(projectedCorners); 64 | } -------------------------------------------------------------------------------- /Source/Rendering/CrVisibility.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Rendering/CrRenderingForwardDeclarations.h" 4 | 5 | #include "Math/CrHlslppVectorFloatType.h" 6 | 7 | struct CrBoundingBox 8 | { 9 | CrBoundingBox() {} 10 | 11 | CrBoundingBox(float3 center, float3 extents) 12 | : center(center) 13 | , extents(extents) 14 | {} 15 | 16 | float3 center; 17 | 18 | float3 extents; // Distance from the center to the corner 19 | }; 20 | 21 | struct CrBoundingSphere 22 | { 23 | float4 centerRadius; 24 | }; 25 | 26 | typedef crstl::array CrBoxVertices; 27 | 28 | class CrVisibility 29 | { 30 | public: 31 | 32 | // Project a bounding box in world space using the view2Projection matrix, and return 8 corners 33 | static void ComputeObbProjection(const CrBoundingBox& obb, const float4x4& worldTransform, const float4x4& view2ProjectionMatrix, CrBoxVertices& projectedCorners); 34 | 35 | // Determine whether the following projected points (without perspective divide) are inside the [-w, w] bounds and [0, w] bounds for z 36 | static bool AreProjectedPointsOnScreen(const CrBoxVertices& projectedCorners); 37 | 38 | // Check whether obb intersects frustum 39 | static bool IsObbInFrustum(const CrBoundingBox& obb, const float4x4& transform, const float4x4& projectionMatrix); 40 | }; -------------------------------------------------------------------------------- /Source/Rendering/Extensions/CrNVAPIHeader.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #if defined(CR_PLATFORM_WINDOWS) 4 | 5 | #define CR_NVAPI_SUPPORTED 6 | 7 | // 5204: class has virtual functions, but its trivial destructor is not virtual; instances of objects derived from this class may not be destructed correctly 8 | #pragma warning(disable:5204) 9 | #include "nvapi.h" 10 | #pragma warning(default:5204) 11 | 12 | #endif -------------------------------------------------------------------------------- /Source/Rendering/Extensions/CrPIXHeader.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #if !defined(CR_CONFIG_FINAL) 4 | #define USE_PIX 5 | #endif 6 | 7 | warnings_off 8 | #include "WinPixEventRuntime/pix3.h" 9 | warnings_on -------------------------------------------------------------------------------- /Source/Rendering/FrameCapture/CrPIX.cpp: -------------------------------------------------------------------------------- 1 | #include "Rendering/CrRendering_pch.h" 2 | 3 | #include "CrPIX.h" 4 | #include "Core/CrMacros.h" 5 | 6 | #include "Rendering/Extensions/CrPIXHeader.h" 7 | 8 | bool CrPIX::Initialize() 9 | { 10 | m_pixHandle = PIXLoadLatestWinPixGpuCapturerLibrary(); 11 | return m_pixHandle != nullptr; 12 | } 13 | 14 | void CrPIX::StartCapture() 15 | { 16 | PIXCaptureParameters captureParameters = {}; 17 | PIXBeginCapture(PIX_CAPTURE_GPU, &captureParameters); 18 | } 19 | 20 | void CrPIX::EndCapture() 21 | { 22 | PIXEndCapture(false); 23 | } 24 | 25 | bool CrPIX::IsFrameCapturing() 26 | { 27 | return PIXGetCaptureState() != 0; 28 | } 29 | 30 | void CrPIX::SetDeviceAndWindow(void* /*device*/, void* window) 31 | { 32 | PIXSetTargetWindow((HWND)window); 33 | } 34 | -------------------------------------------------------------------------------- /Source/Rendering/FrameCapture/CrPIX.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | struct CrRenderSystemDescriptor; 4 | 5 | class CrPIX 6 | { 7 | public: 8 | 9 | bool Initialize(); 10 | 11 | void TriggerCapture(); 12 | 13 | void StartCapture(); 14 | 15 | void EndCapture(); 16 | 17 | bool IsFrameCapturing(); 18 | 19 | void SetDeviceAndWindow(void* device, void* window); 20 | 21 | private: 22 | 23 | void* m_pixHandle; 24 | }; -------------------------------------------------------------------------------- /Source/Rendering/FrameCapture/CrRenderDoc.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | struct CrRenderSystemDescriptor; 4 | struct RENDERDOC_API_1_5_0; 5 | 6 | class CrRenderDoc 7 | { 8 | public: 9 | 10 | void Initialize(const CrRenderSystemDescriptor& renderSystemDescriptor); 11 | 12 | void TriggerCapture(); 13 | 14 | void StartCapture(); 15 | 16 | void EndCapture(); 17 | 18 | bool IsFrameCapturing(); 19 | 20 | void SetDeviceAndWindow(void* device, void* window); 21 | 22 | private: 23 | 24 | void* m_renderDocModule; 25 | 26 | void* m_currentDevice; 27 | 28 | void* m_currentWindow; 29 | 30 | RENDERDOC_API_1_5_0* m_renderDocApi; 31 | }; -------------------------------------------------------------------------------- /Source/Rendering/ICrGPUQueryPool.cpp: -------------------------------------------------------------------------------- 1 | #include "Rendering/CrRendering_pch.h" 2 | 3 | #include "Rendering/ICrGPUQueryPool.h" 4 | #include "Rendering/ICrCommandBuffer.h" 5 | 6 | #include "Math/CrMath.h" 7 | 8 | ICrGPUQueryPool::ICrGPUQueryPool(ICrRenderDevice* renderDevice, const CrGPUQueryPoolDescriptor& descriptor) : CrGPUAutoDeletable(renderDevice) 9 | , m_descriptor(descriptor) 10 | , m_resolved(false) 11 | , m_querySize(0) // Gets calculated by each platform 12 | , m_currentQuery(0) 13 | , m_timestampPeriod(1.0) // Gets calculated per platform 14 | {} 15 | 16 | void ICrGPUQueryPool::Resolve(ICrCommandBuffer* commandBuffer) 17 | { 18 | commandBuffer->ResolveGPUQueries(this, 0, m_currentQuery); 19 | m_resolved = true; 20 | } 21 | 22 | void ICrGPUQueryPool::GetTimestampData(CrGPUTimestamp* timingData, uint32_t timingCount) 23 | { 24 | CrAssertMsg(m_descriptor.type == cr3d::QueryType::Timestamp, "Wrong query type"); 25 | 26 | if (m_resolved) 27 | { 28 | uint32_t resolveCount = CrMin(m_currentQuery, timingCount); 29 | GetTimingDataPS(timingData, resolveCount); 30 | } 31 | } 32 | 33 | void ICrGPUQueryPool::Reset(ICrCommandBuffer* commandBuffer) 34 | { 35 | commandBuffer->ResetGPUQueries(this, 0, m_descriptor.count); 36 | m_currentQuery = 0; 37 | } 38 | 39 | double ICrGPUQueryPool::GetDuration(CrGPUTimestamp startTime, CrGPUTimestamp endTime) const 40 | { 41 | uint64_t tickDelta = 0; 42 | 43 | // Check for overflow 44 | if (endTime.ticks >= startTime.ticks) 45 | { 46 | tickDelta = endTime.ticks - startTime.ticks; 47 | } 48 | else 49 | { 50 | tickDelta = (uint64_t)(-1) - startTime.ticks + endTime.ticks; 51 | } 52 | 53 | return tickDelta * m_timestampPeriod; 54 | } 55 | -------------------------------------------------------------------------------- /Source/Rendering/ICrGPUQueryPool.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Rendering/CrRenderingForwardDeclarations.h" 4 | #include "Rendering/CrGPUDeletable.h" 5 | 6 | #include "Core/CrMacros.h" 7 | #include "Core/Logging/ICrDebug.h" 8 | #include "Core/CrTypedId.h" 9 | 10 | struct CrGPUTimestamp 11 | { 12 | CrGPUTimestamp() { ticks = 0; } 13 | CrGPUTimestamp(uint64_t ticks) : ticks(ticks) {} 14 | 15 | uint64_t ticks; 16 | }; 17 | 18 | struct CrGPUOcclusion 19 | { 20 | uint64_t visibilitySamples; // Number of samples passed by this query 21 | }; 22 | 23 | struct CrGPUQueryPoolDescriptor 24 | { 25 | CrGPUQueryPoolDescriptor(cr3d::QueryType type, uint32_t count) : type(type), count(count) {} 26 | 27 | cr3d::QueryType type; 28 | uint32_t count; 29 | }; 30 | 31 | // Pool that contains queries of the type passed in as a template 32 | // The template must be one of the interfaces provided above 33 | class ICrGPUQueryPool : public CrGPUAutoDeletable 34 | { 35 | public: 36 | 37 | ICrGPUQueryPool(ICrRenderDevice* renderDevice, const CrGPUQueryPoolDescriptor& descriptor); 38 | 39 | virtual ~ICrGPUQueryPool() {} 40 | 41 | uint32_t GetActiveQueryCount() const 42 | { 43 | return m_currentQuery; 44 | } 45 | 46 | uint32_t GetTotalQueryCount() const 47 | { 48 | return m_descriptor.count; 49 | } 50 | 51 | uint32_t GetQuerySize() const 52 | { 53 | return m_querySize; 54 | } 55 | 56 | cr3d::QueryType GetType() const 57 | { 58 | return m_descriptor.type; 59 | } 60 | 61 | // Allocate a GPU query id. We can use this to begin or end a query on a command buffer 62 | CrGPUQueryId Allocate() 63 | { 64 | // TODO Check bounds 65 | uint32_t currentQuery = m_currentQuery; 66 | m_currentQuery++; 67 | return CrGPUQueryId(currentQuery); 68 | } 69 | 70 | // Resolve all pending queries using this command buffer to copy data across 71 | // This doesn't mean the data is available now, it just means the GPU will 72 | // copy it across as soon as it can. Then we can use the GetData() function 73 | // to retrieve it on the CPU 74 | void Resolve(ICrCommandBuffer* commandBuffer); 75 | 76 | void GetTimestampData(CrGPUTimestamp* timingData, uint32_t count); 77 | 78 | void Reset(ICrCommandBuffer* commandBuffer); 79 | 80 | // Computes the duration in nanoseconds between two timestamps 81 | double GetDuration(CrGPUTimestamp startTime, CrGPUTimestamp endTime) const; 82 | 83 | protected: 84 | 85 | virtual void GetTimingDataPS(CrGPUTimestamp* timingData, uint32_t count) = 0; 86 | 87 | virtual void GetOcclusionDataPS(CrGPUOcclusion* data, uint32_t count) = 0; 88 | 89 | CrGPUQueryPoolDescriptor m_descriptor; 90 | 91 | bool m_resolved; 92 | 93 | // Size of each query in bytes 94 | uint32_t m_querySize; 95 | 96 | uint32_t m_currentQuery; 97 | 98 | // Not all platforms work the same way, so this is just a multiplier that takes from 99 | // raw ticks to nanoseconds. In many common cases it will just be 1.0 100 | double m_timestampPeriod; 101 | }; -------------------------------------------------------------------------------- /Source/Rendering/ICrGPUSynchronization.cpp: -------------------------------------------------------------------------------- 1 | #include "Rendering/CrRendering_pch.h" 2 | #include "ICrGPUSynchronization.h" -------------------------------------------------------------------------------- /Source/Rendering/ICrGPUSynchronization.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Core/CrCoreForwardDeclarations.h" 4 | 5 | #include "Rendering/CrGPUDeletable.h" 6 | 7 | // For synchronization primitives we'll use Vulkan nomenclature, as the naming varies between APIs and it's not always 8 | // clear which is which. If unclear refer to the descriptions here for clarity 9 | 10 | // Synchronization between host and device 11 | // Direction is device -> host 12 | // e.g. GPU signals and CPU waits 13 | // Vulkan: vkFence 14 | // D3D12: ID3D12Fence 15 | class ICrGPUFence : public CrGPUAutoDeletable 16 | { 17 | public: 18 | 19 | ICrGPUFence(ICrRenderDevice* renderDevice) : CrGPUAutoDeletable(renderDevice) {} 20 | 21 | virtual ~ICrGPUFence() {} 22 | }; 23 | 24 | // Synchronization between queues 25 | // Direction is device -> device 26 | // e.g. Graphics queue signals, compute queue receives 27 | // e.g. Graphics queue signals, graphics queue receives 28 | // Vulkan: vkSemaphore 29 | // D3D12: ID3D12Fence 30 | class ICrGPUSemaphore : public CrGPUAutoDeletable 31 | { 32 | public: 33 | 34 | ICrGPUSemaphore(ICrRenderDevice* renderDevice) : CrGPUAutoDeletable(renderDevice) {} 35 | 36 | virtual ~ICrGPUSemaphore() {} 37 | }; -------------------------------------------------------------------------------- /Source/Rendering/ICrPipeline.cpp: -------------------------------------------------------------------------------- 1 | #include "Rendering/CrRendering_pch.h" 2 | 3 | #include "Rendering/ICrPipeline.h" 4 | #include "Rendering/ICrShader.h" 5 | #include "Rendering/CrVertexDescriptor.h" 6 | 7 | CrRenderTargetBlendDescriptor CrStandardPipelineStates::OpaqueBlend 8 | { 9 | cr3d::BlendFactor::One, 10 | cr3d::BlendFactor::One, 11 | cr3d::BlendFactor::One, 12 | cr3d::BlendFactor::One, 13 | cr3d::ColorWriteComponent::All, 14 | cr3d::BlendOp::Add, 15 | cr3d::BlendOp::Add, 16 | false 17 | }; 18 | 19 | CrRenderTargetBlendDescriptor CrStandardPipelineStates::AlphaBlend 20 | { 21 | cr3d::BlendFactor::SrcAlpha, 22 | cr3d::BlendFactor::OneMinusSrcAlpha, 23 | cr3d::BlendFactor::One, 24 | cr3d::BlendFactor::Zero, 25 | cr3d::ColorWriteComponent::All, 26 | cr3d::BlendOp::Add, 27 | cr3d::BlendOp::Add, 28 | true 29 | }; 30 | 31 | ICrGraphicsPipeline::ICrGraphicsPipeline(ICrRenderDevice* renderDevice, const CrGraphicsPipelineDescriptor& pipelineDescriptor, const CrGraphicsShaderHandle& graphicsShader, const CrVertexDescriptor& vertexDescriptor) 32 | : CrGPUAutoDeletable(renderDevice) 33 | , m_shader(graphicsShader) 34 | #if !defined(CR_CONFIG_FINAL) 35 | , m_pipelineDescriptor(pipelineDescriptor) 36 | , m_vertexDescriptor(vertexDescriptor) 37 | #endif 38 | { 39 | m_usedVertexStreamCount = vertexDescriptor.GetStreamCount(); 40 | } 41 | 42 | ICrGraphicsPipeline::~ICrGraphicsPipeline() {} 43 | 44 | #if !defined(CR_CONFIG_FINAL) 45 | 46 | void ICrGraphicsPipeline::Recompile(ICrRenderDevice* renderDevice, const CrGraphicsShaderHandle& graphicsShader) 47 | { 48 | RecompilePS(renderDevice, graphicsShader); 49 | m_shader = graphicsShader; 50 | } 51 | 52 | #endif 53 | 54 | ICrComputePipeline::ICrComputePipeline(ICrRenderDevice* renderDevice, const CrComputeShaderHandle& computeShader) 55 | : CrGPUAutoDeletable(renderDevice), m_shader(computeShader) 56 | { 57 | const CrShaderReflectionHeader& reflection = computeShader->GetBytecode()->GetReflection(); 58 | m_threadGroupSizeX = reflection.threadGroupSizeX; 59 | m_threadGroupSizeY = reflection.threadGroupSizeY; 60 | m_threadGroupSizeZ = reflection.threadGroupSizeZ; 61 | } 62 | 63 | ICrComputePipeline::~ICrComputePipeline() {} 64 | 65 | #if !defined(CR_CONFIG_FINAL) 66 | 67 | void ICrComputePipeline::Recompile(ICrRenderDevice* renderDevice, const CrComputeShaderHandle& computeShader) 68 | { 69 | RecompilePS(renderDevice, computeShader); 70 | m_shader = computeShader; 71 | } 72 | 73 | #endif -------------------------------------------------------------------------------- /Source/Rendering/ICrRenderSystem.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Rendering/CrRendering.h" 4 | 5 | #include "Rendering/CrRenderingForwardDeclarations.h" 6 | 7 | #include "Rendering/FrameCapture/CrRenderDoc.h" 8 | #include "Rendering/FrameCapture/CrPIX.h" 9 | 10 | #include "crstl/intrusive_ptr.h" 11 | #include "crstl/vector.h" 12 | 13 | struct CrRenderSystemDescriptor 14 | { 15 | cr3d::GraphicsApi::T graphicsApi = cr3d::GraphicsApi::Count; 16 | 17 | // e.g. Vulkan layers, D3D debug layer 18 | bool enableValidation = false; 19 | 20 | bool enableRenderDoc = false; 21 | 22 | bool enablePIX = false; 23 | 24 | bool enableNVAPI = true; 25 | }; 26 | 27 | namespace CrBuiltinShaders { enum T : uint32_t; }; 28 | 29 | struct CrRenderDeviceDescriptor; 30 | 31 | class ICrRenderSystem 32 | { 33 | public: 34 | 35 | ICrRenderSystem(const CrRenderSystemDescriptor& renderSystemDescriptor); 36 | 37 | virtual ~ICrRenderSystem(); 38 | 39 | static void Initialize(const CrRenderSystemDescriptor& renderSystemDescriptor); 40 | 41 | // Only the render device calls these functions, as it knows what device we are using 42 | 43 | void InitializeRenderdoc(); 44 | 45 | const CrRenderDeviceHandle& GetRenderDevice() const; 46 | 47 | void CreateRenderDevice(const CrRenderDeviceDescriptor& descriptor); 48 | 49 | bool GetIsValidationEnabled() const; 50 | 51 | cr3d::GraphicsApi::T GetGraphicsApi() const; 52 | 53 | const CrShaderBytecodeHandle& GetBuiltinShaderBytecode(CrBuiltinShaders::T builtinShader) const; 54 | 55 | protected: 56 | 57 | crstl::vector m_builtinShaderBytecodes; 58 | 59 | CrRenderDeviceHandle m_mainDevice; 60 | 61 | CrRenderSystemDescriptor m_descriptor; 62 | 63 | CrRenderDoc m_renderDoc; 64 | 65 | CrPIX m_pix; 66 | 67 | virtual ICrRenderDevice* CreateRenderDevicePS(const CrRenderDeviceDescriptor& descriptor) = 0; 68 | }; 69 | 70 | extern crstl::unique_ptr RenderSystem; -------------------------------------------------------------------------------- /Source/Rendering/ICrSampler.cpp: -------------------------------------------------------------------------------- 1 | #include "Rendering/CrRendering_pch.h" 2 | #include "ICrSampler.h" 3 | 4 | #include "Core/CrMacros.h" 5 | 6 | #include "Rendering/CrRendering.h" 7 | 8 | CrSamplerDescriptor::CrSamplerDescriptor() 9 | : minFilter(cr3d::Filter::Linear) 10 | , magFilter(cr3d::Filter::Linear) 11 | , mipmapFilter(cr3d::Filter::Linear) 12 | , addressModeU(cr3d::AddressMode::ClampToEdge) 13 | , addressModeV(cr3d::AddressMode::ClampToEdge) 14 | , addressModeW(cr3d::AddressMode::ClampToEdge) 15 | , enableAnisotropy(false) 16 | , enableCompare(false) 17 | , compareOp(cr3d::CompareOp::Never) 18 | , borderColor(cr3d::BorderColor::OpaqueBlack) 19 | , maxAnisotropy(1) 20 | , mipLodBias(0.0f) 21 | , minLod(0.0f) 22 | , maxLod(1024.0f) // Some arbitrarily big number to mean no clamp 23 | { 24 | 25 | } 26 | 27 | ICrSampler::ICrSampler(ICrRenderDevice* renderDevice) : CrGPUAutoDeletable(renderDevice) 28 | { 29 | m_renderDevice = renderDevice; 30 | } -------------------------------------------------------------------------------- /Source/Rendering/ICrSampler.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Core/CrCoreForwardDeclarations.h" 4 | 5 | #include "Rendering/CrRenderingForwardDeclarations.h" 6 | 7 | #include "CrGPUDeletable.h" 8 | 9 | #include "crstl/fixed_string.h" 10 | 11 | struct CrSamplerDescriptor 12 | { 13 | CrSamplerDescriptor(); 14 | 15 | cr3d::Filter minFilter; 16 | cr3d::Filter magFilter; 17 | cr3d::Filter mipmapFilter; 18 | cr3d::AddressMode addressModeU; 19 | cr3d::AddressMode addressModeV; 20 | cr3d::AddressMode addressModeW; 21 | uint32_t enableAnisotropy; 22 | uint32_t enableCompare; 23 | cr3d::CompareOp compareOp; 24 | cr3d::BorderColor borderColor; 25 | uint32_t maxAnisotropy; 26 | float mipLodBias; 27 | float minLod; 28 | float maxLod; 29 | 30 | crstl::fixed_string128 name; 31 | }; 32 | 33 | class ICrSampler : public CrGPUAutoDeletable 34 | { 35 | public: 36 | 37 | virtual ~ICrSampler() {} 38 | 39 | protected: 40 | 41 | ICrSampler(ICrRenderDevice* renderDevice); 42 | }; -------------------------------------------------------------------------------- /Source/Rendering/ICrShader.cpp: -------------------------------------------------------------------------------- 1 | #include "Rendering/CrRendering_pch.h" 2 | 3 | #include "ICrShader.h" 4 | 5 | #include "Core/Logging/ICrDebug.h" 6 | 7 | CrShaderCompilerDefines CrShaderCompilerDefines::Dummy; 8 | 9 | template 10 | void ICrShaderBindingLayout::ProcessResourceArray(cr3d::ShaderResourceType::T resourceType, const ResourcesT& resources) 11 | { 12 | m_resourceOffsets[resourceType].offset = (uint8_t)m_bindings.size(); 13 | m_resourceOffsets[resourceType].count = (uint8_t)resources.size(); 14 | 15 | cr3d::ShaderStage::T currentStage = cr3d::ShaderStage::Count; 16 | uint32_t currentStageIndex = 0; 17 | uint32_t currentOffset = m_resourceOffsets[resourceType].offset; 18 | 19 | for (const CrShaderBinding& shaderBinding : resources) 20 | { 21 | if (currentStage != shaderBinding.stage) 22 | { 23 | currentStage = (cr3d::ShaderStage::T)shaderBinding.stage; 24 | currentStageIndex = GetStageIndex(currentStage); 25 | m_stageResourceOffsets[resourceType][currentStageIndex].offset = (uint8_t)currentOffset; 26 | } 27 | 28 | m_stageResourceOffsets[resourceType][currentStageIndex].count++; 29 | currentOffset++; 30 | m_bindings.push_back(shaderBinding); 31 | } 32 | 33 | m_totalResourceCount += m_resourceOffsets[resourceType].count; 34 | } 35 | 36 | ICrShaderBindingLayout::ICrShaderBindingLayout(const CrShaderBindingLayoutResources& resources) 37 | { 38 | // We assume shader stages are sequential at this point. That is, any resources are packed 39 | // by shader stage (i.e. all vertex shader constant buffers together) 40 | ProcessResourceArray(cr3d::ShaderResourceType::ConstantBuffer, resources.constantBuffers); 41 | ProcessResourceArray(cr3d::ShaderResourceType::Sampler, resources.samplers); 42 | ProcessResourceArray(cr3d::ShaderResourceType::Texture, resources.textures); 43 | ProcessResourceArray(cr3d::ShaderResourceType::RWTexture, resources.rwTextures); 44 | ProcessResourceArray(cr3d::ShaderResourceType::StorageBuffer, resources.storageBuffers); 45 | ProcessResourceArray(cr3d::ShaderResourceType::RWStorageBuffer, resources.rwStorageBuffers); 46 | ProcessResourceArray(cr3d::ShaderResourceType::RWTypedBuffer, resources.rwTypedBuffers); 47 | } 48 | 49 | ICrGraphicsShader::ICrGraphicsShader(ICrRenderDevice* /*renderDevice*/, const CrGraphicsShaderDescriptor& graphicsShaderDescriptor) 50 | { 51 | for (const CrShaderBytecodeHandle& bytecode : graphicsShaderDescriptor.m_bytecodes) 52 | { 53 | m_bytecodes.push_back(bytecode); 54 | m_hash << bytecode->GetHash(); 55 | m_debugName = graphicsShaderDescriptor.m_debugName; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /Source/Rendering/ICrShader.inl: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Rendering/CrShaderResourceMetadata.h" 4 | #include "GeneratedShaders/ShaderMetadata.h" 5 | 6 | template 7 | inline void ICrShaderBindingLayout::AddResources(const CrShaderReflectionHeader& reflectionHeader, CrShaderBindingLayoutResources& resources, const FunctionT& function) 8 | { 9 | for (const CrShaderReflectionResource& resource : reflectionHeader.constantBuffers) 10 | { 11 | const ConstantBufferMetadata& metadata = CrShaderMetadata::GetConstantBuffer(resource.name); 12 | resources.constantBuffers.push_back(CrShaderBinding(resource.bindPoint, reflectionHeader.shaderStage, metadata.id)); 13 | function(reflectionHeader.shaderStage, resource); 14 | } 15 | 16 | for (const CrShaderReflectionResource& resource : reflectionHeader.samplers) 17 | { 18 | const SamplerMetadata& metadata = CrShaderMetadata::GetSampler(resource.name); 19 | resources.samplers.push_back(CrShaderBinding(resource.bindPoint, reflectionHeader.shaderStage, metadata.id)); 20 | function(reflectionHeader.shaderStage, resource); 21 | } 22 | 23 | for (const CrShaderReflectionResource& resource : reflectionHeader.textures) 24 | { 25 | const TextureMetadata& metadata = CrShaderMetadata::GetTexture(resource.name); 26 | resources.textures.push_back(CrShaderBinding(resource.bindPoint, reflectionHeader.shaderStage, metadata.id)); 27 | function(reflectionHeader.shaderStage, resource); 28 | } 29 | 30 | for (const CrShaderReflectionResource& resource : reflectionHeader.rwTextures) 31 | { 32 | const RWTextureMetadata& metadata = CrShaderMetadata::GetRWTexture(resource.name); 33 | resources.rwTextures.push_back(CrShaderBinding(resource.bindPoint, reflectionHeader.shaderStage, metadata.id)); 34 | function(reflectionHeader.shaderStage, resource); 35 | } 36 | 37 | for (const CrShaderReflectionResource& resource : reflectionHeader.storageBuffers) 38 | { 39 | const StorageBufferMetadata& metadata = CrShaderMetadata::GetStorageBuffer(resource.name); 40 | resources.storageBuffers.push_back(CrShaderBinding(resource.bindPoint, reflectionHeader.shaderStage, metadata.id)); 41 | function(reflectionHeader.shaderStage, resource); 42 | } 43 | 44 | for (const CrShaderReflectionResource& resource : reflectionHeader.rwStorageBuffers) 45 | { 46 | const RWStorageBufferMetadata& metadata = CrShaderMetadata::GetRWStorageBuffer(resource.name); 47 | resources.rwStorageBuffers.push_back(CrShaderBinding(resource.bindPoint, reflectionHeader.shaderStage, metadata.id)); 48 | function(reflectionHeader.shaderStage, resource); 49 | } 50 | 51 | for (const CrShaderReflectionResource& resource : reflectionHeader.rwTypedBuffers) 52 | { 53 | const RWTypedBufferMetadata& metadata = CrShaderMetadata::GetRWTypedBuffer(resource.name); 54 | resources.rwTypedBuffers.push_back(CrShaderBinding(resource.bindPoint, reflectionHeader.shaderStage, metadata.id)); 55 | function(reflectionHeader.shaderStage, resource); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /Source/Rendering/ICrShaderReflection.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Rendering/CrRenderingForwardDeclarations.h" 4 | #include "Core/CrCoreForwardDeclarations.h" 5 | 6 | using bindpoint_t = uint8_t; 7 | 8 | class CrShaderResource 9 | { 10 | public: 11 | 12 | const char* name = nullptr; 13 | bindpoint_t bindPoint = 0; 14 | cr3d::ShaderResourceType::T type = cr3d::ShaderResourceType::Count; 15 | 16 | static CrShaderResource Invalid; 17 | }; 18 | 19 | // Make sure we don't allocate any memory on the heap 20 | using ShaderReflectionFunction = crstl::fixed_function<12, void(cr3d::ShaderStage::T stage, const CrShaderResource&)>; 21 | 22 | // Provides shader reflection functionality. After a shader has been compiled or loaded the shader reflection structure can 23 | // be queried for information regarding resource usage. 24 | 25 | class ICrShaderReflection 26 | { 27 | public: 28 | 29 | virtual ~ICrShaderReflection() {} 30 | 31 | virtual void AddBytecode(const CrShaderBytecodeHandle& bytecode) = 0; 32 | 33 | virtual void ForEachResource(const ShaderReflectionFunction& function) const = 0; 34 | }; 35 | -------------------------------------------------------------------------------- /Source/Rendering/ICrSwapchain.cpp: -------------------------------------------------------------------------------- 1 | #include "Rendering/CrRendering_pch.h" 2 | 3 | #include "ICrSwapchain.h" 4 | 5 | #include "Core/Logging/ICrDebug.h" 6 | 7 | class ICrRenderDevice; 8 | 9 | CrSwapchainDescriptor::CrSwapchainDescriptor() 10 | : name("") 11 | , window(nullptr) 12 | , requestedWidth(0) 13 | , requestedHeight(0) 14 | , requestedBufferCount(0) 15 | , format(cr3d::DataFormat::Invalid) 16 | { 17 | 18 | } 19 | 20 | ICrSwapchain::ICrSwapchain(ICrRenderDevice* renderDevice, const CrSwapchainDescriptor& swapchainDescriptor) : CrGPUAutoDeletable(renderDevice) 21 | , m_name(swapchainDescriptor.name) 22 | , m_imageCount(0) 23 | , m_format(cr3d::DataFormat::Invalid) 24 | , m_width(0) 25 | , m_height(0) 26 | , m_currentBufferIndex(0) 27 | , m_imageAcquired(false) 28 | { 29 | 30 | } 31 | 32 | cr3d::DataFormat::T ICrSwapchain::GetFormat() const 33 | { 34 | return m_format; 35 | } 36 | 37 | uint32_t ICrSwapchain::GetWidth() const 38 | { 39 | return m_width; 40 | } 41 | 42 | uint32_t ICrSwapchain::GetHeight() const 43 | { 44 | return m_height; 45 | } 46 | 47 | uint32_t ICrSwapchain::GetImageCount() const 48 | { 49 | return (uint32_t)m_textures.size(); 50 | } 51 | 52 | uint32_t ICrSwapchain::GetCurrentFrameIndex() const 53 | { 54 | return m_currentBufferIndex; 55 | } 56 | 57 | CrSwapchainResult ICrSwapchain::AcquireNextImage(uint64_t timeoutNanoseconds) 58 | { 59 | return AcquireNextImagePS(timeoutNanoseconds); 60 | } 61 | 62 | void ICrSwapchain::Present() 63 | { 64 | PresentPS(); 65 | } 66 | 67 | void ICrSwapchain::Resize(uint32_t width, uint32_t height) 68 | { 69 | ResizePS(width, height); 70 | m_width = width; 71 | m_height = height; 72 | } 73 | 74 | const CrTextureHandle& ICrSwapchain::GetCurrentTexture() 75 | { 76 | return m_textures[m_currentBufferIndex]; 77 | } 78 | -------------------------------------------------------------------------------- /Source/Rendering/ICrSwapchain.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ICrGPUSynchronization.h" 4 | 5 | #include "Rendering/CrRenderingForwardDeclarations.h" 6 | #include "Rendering/ICrTexture.h" 7 | 8 | #include "crstl/fixed_string.h" 9 | #include "crstl/vector.h" 10 | 11 | class CrOSWindow; 12 | 13 | enum class CrSwapchainResult : uint32_t 14 | { 15 | Success, 16 | Invalid 17 | }; 18 | 19 | struct CrSwapchainDescriptor 20 | { 21 | CrSwapchainDescriptor(); 22 | 23 | const char* name; 24 | CrOSWindow* window; 25 | uint32_t requestedWidth; 26 | uint32_t requestedHeight; 27 | uint32_t requestedBufferCount; // How many surfaces to request for this swapchain 28 | cr3d::DataFormat::T format; 29 | }; 30 | 31 | class ICrSwapchain : public CrGPUAutoDeletable 32 | { 33 | public: 34 | 35 | ICrSwapchain(ICrRenderDevice* renderDevice, const CrSwapchainDescriptor& swapchainDescriptor); 36 | 37 | virtual ~ICrSwapchain() {} 38 | 39 | cr3d::DataFormat::T GetFormat() const; 40 | 41 | uint32_t GetWidth() const; 42 | 43 | uint32_t GetHeight() const; 44 | 45 | uint32_t GetImageCount() const; 46 | 47 | uint32_t GetCurrentFrameIndex() const; 48 | 49 | CrSwapchainResult AcquireNextImage(uint64_t timeoutNanoseconds = UINT64_MAX); 50 | 51 | void Present(); 52 | 53 | void Resize(uint32_t width, uint32_t height); 54 | 55 | const CrTextureHandle& GetCurrentTexture(); 56 | 57 | protected: 58 | 59 | virtual void PresentPS() = 0; 60 | 61 | virtual void ResizePS(uint32_t width, uint32_t height) = 0; 62 | 63 | virtual CrSwapchainResult AcquireNextImagePS(uint64_t timeoutNanoseconds = UINT64_MAX) = 0; 64 | 65 | crstl::vector m_textures; 66 | 67 | crstl::fixed_string32 m_name; 68 | 69 | uint32_t m_imageCount; 70 | 71 | cr3d::DataFormat::T m_format; 72 | 73 | uint32_t m_width; 74 | 75 | uint32_t m_height; 76 | 77 | uint32_t m_currentBufferIndex; // Active frame buffer index 78 | 79 | bool m_imageAcquired; 80 | }; 81 | -------------------------------------------------------------------------------- /Source/Rendering/RenderWorld/CrModelInstance.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Core/CrTypedId.h" 4 | 5 | #include "Rendering/CrVisibility.h" 6 | 7 | #include "Math/CrHlslppMatrixFloatType.h" 8 | 9 | #include "crstl/intrusive_ptr.h" 10 | 11 | class CrModelInstance; 12 | using CrModelInstanceId = CrTypedId; 13 | 14 | class CrModelInstance 15 | { 16 | public: 17 | 18 | CrModelInstance() 19 | : m_instanceId(CrModelInstanceId::MaxId) 20 | , m_visibilityId(0xffffffff) 21 | , m_transform(float4x4::identity()) 22 | {} 23 | 24 | explicit CrModelInstance(CrModelInstanceId instanceId) 25 | : m_instanceId(instanceId) 26 | , m_visibilityId(0xffffffff) 27 | , m_transform(float4x4::identity()) 28 | {} 29 | 30 | void SetTransform(const float4x4& transform) { m_transform = transform; } 31 | const float4x4& GetTransform() const { return m_transform; } 32 | 33 | void SetPosition(float3 position) { m_transform[3].xyz = position; } 34 | float3 GetPosition() const { return m_transform[3].xyz; } 35 | 36 | void SetRenderModel(const CrRenderModelHandle& renderModel) { m_renderModel = renderModel; } 37 | const CrRenderModelHandle& GetRenderModel() const { return m_renderModel; } 38 | 39 | CrModelInstanceId GetId() const { return m_instanceId; } 40 | 41 | void SetVisibilityId(uint32_t visibilityId) { m_visibilityId = visibilityId; } 42 | 43 | private: 44 | 45 | float4x4 m_transform; 46 | 47 | CrRenderModelHandle m_renderModel; 48 | 49 | CrBoundingBox m_boundingBox; 50 | 51 | CrModelInstanceId m_instanceId; 52 | 53 | uint32_t m_visibilityId; 54 | }; 55 | -------------------------------------------------------------------------------- /Source/Rendering/ShaderCompiler/CrBuiltinShaderBuilder.h: -------------------------------------------------------------------------------- 1 | #include "Core/CrCoreForwardDeclarations.h" 2 | #include "Core/FileSystem/CrFixedPath.h" 3 | 4 | #include "Rendering/CrRenderingForwardDeclarations.h" 5 | 6 | struct CrBuiltinShadersDescriptor 7 | { 8 | // Path where .shaders files live 9 | CrFixedPath inputPath; 10 | 11 | // Path where builtin shader binaries are output 12 | CrFixedPath outputPath; 13 | 14 | // We can build builtin shaders for multiple APIs for certain platforms such as Windows 15 | // which builds Vulkan and D3D12 16 | crstl::vector graphicsApis; 17 | 18 | cr::Platform::T platform; 19 | 20 | // Whether to build the headers from the binaries by creating headers and cpp files 21 | // This is useful as part of the main build, but not when live recompiling 22 | bool buildBuiltinHeaders; 23 | }; 24 | 25 | struct CompilationDescriptor; 26 | 27 | struct CrShaderInfo 28 | { 29 | crstl::string name; 30 | }; 31 | 32 | struct CrShaderCompilationJob 33 | { 34 | crstl::string name; 35 | CompilationDescriptor compilationDescriptor; 36 | }; 37 | 38 | class CrBuiltinShaderBuilder 39 | { 40 | public: 41 | 42 | static void ProcessBuiltinShaders(const CrBuiltinShadersDescriptor& builtinShadersDescriptor); 43 | 44 | private: 45 | 46 | static void BuildBuiltinShaderMetadataAndHeaderFiles 47 | ( 48 | const CrBuiltinShadersDescriptor& builtinShadersDescriptor, 49 | const crstl::vector& shaderInfos, 50 | const crstl::vector>& compilationJobs 51 | ); 52 | }; -------------------------------------------------------------------------------- /Source/Rendering/ShaderCompiler/CrCompilerDXC.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Rendering/CrRenderingForwardDeclarations.h" 4 | 5 | struct CompilationDescriptor; 6 | 7 | class CrCompilerDXC 8 | { 9 | public: 10 | 11 | static bool HLSLtoSPIRV(const CompilationDescriptor& compilationDescriptor, crstl::vector& bytecode, crstl::string& compilationStatus); 12 | 13 | static bool HLSLtoSPIRV(const CompilationDescriptor& compilationDescriptor, crstl::string& compilationStatus); 14 | 15 | static bool HLSLtoDXIL(const CompilationDescriptor& compilationDescriptor, crstl::string& compilationStatus); 16 | }; -------------------------------------------------------------------------------- /Source/Rendering/ShaderCompiler/CrShaderCompiler.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Rendering/CrRendering.h" 4 | #include "Core/CrPlatform.h" 5 | #include "Core/FileSystem/CrFixedPath.h" 6 | 7 | #include "crstl/string.h" 8 | #include "crstl/vector.h" 9 | 10 | namespace OptimizationLevel 11 | { 12 | enum T 13 | { 14 | O0, 15 | O1, 16 | O2, 17 | O3, 18 | None 19 | }; 20 | }; 21 | 22 | struct CompilationDescriptor 23 | { 24 | CompilationDescriptor() 25 | : platform(cr::Platform::Count) 26 | , graphicsApi(cr3d::GraphicsApi::Count) 27 | , shaderStage(cr3d::ShaderStage::Count) 28 | , buildReflection(true) 29 | , optimization(OptimizationLevel::O3) 30 | , processed(false) 31 | {} 32 | 33 | void Process() const; 34 | 35 | CrFixedPath inputPath; 36 | CrFixedPath outputPath; 37 | CrFixedPath tempPath; // Filename compiler can use to dump intermediate data 38 | crstl::string entryPoint; 39 | crstl::string uniqueBinaryName; 40 | mutable crstl::vector defines; 41 | cr::Platform::T platform; 42 | cr3d::GraphicsApi::T graphicsApi; 43 | cr3d::ShaderStage::T shaderStage; 44 | bool buildReflection; 45 | OptimizationLevel::T optimization; 46 | 47 | private: 48 | 49 | mutable bool processed; 50 | }; 51 | 52 | class CrShaderCompiler 53 | { 54 | public: 55 | 56 | static const crstl::string& GetExecutableDirectory(); 57 | 58 | static crstl::string ExecutableDirectory; 59 | 60 | static CrFixedPath PDBDirectory; 61 | 62 | static CrFixedPath PDBDirectories[cr::Platform::Count][cr3d::GraphicsApi::Count]; 63 | 64 | static const CrFixedPath& GetPDBDirectory(cr::Platform::T platform, cr3d::GraphicsApi::T graphicsApi); 65 | 66 | static void Initialize(); 67 | 68 | static void Finalize(); 69 | 70 | static bool Compile(const CompilationDescriptor& compilationDescriptor, crstl::string& compilationStatus); 71 | }; -------------------------------------------------------------------------------- /Source/Rendering/ShaderCompiler/CrShaderCompilerUtilities.cpp: -------------------------------------------------------------------------------- 1 | #include "Rendering/ShaderCompiler/CrShaderCompiler_pch.h" 2 | 3 | #include "CrShaderCompilerUtilities.h" 4 | 5 | #include "crstl/string.h" 6 | 7 | // TODO Use file 8 | #include 9 | #include 10 | 11 | void CrShaderCompilerUtilities::WriteToFile(const crstl::string& filename, const crstl::string& text) 12 | { 13 | std::ofstream fileStream; 14 | fileStream.open(filename.c_str(), std::ios::out); 15 | fileStream.write(text.c_str(), text.size()); 16 | fileStream.close(); 17 | printf("Wrote contents of file to %s\n", filename.c_str()); 18 | } 19 | 20 | void CrShaderCompilerUtilities::WriteToFileIfChanged(const crstl::string& filename, const crstl::string& text) 21 | { 22 | std::ifstream originalFile(filename.c_str()); 23 | std::stringstream originalFileStream; 24 | originalFileStream << originalFile.rdbuf(); 25 | originalFile.close(); 26 | 27 | const crstl::string& originalContents = originalFileStream.str().c_str(); 28 | 29 | if (originalContents != text) 30 | { 31 | WriteToFile(filename, text); 32 | } 33 | } 34 | 35 | void CrShaderCompilerUtilities::QuitWithMessage(const crstl::string& errorMessage) 36 | { 37 | // We need a message pump that flushes every message for the shader compiler, otherwise a crash won't allow us to see them 38 | printf("%s", errorMessage.c_str()); 39 | fflush(stdout); 40 | exit(-1); 41 | } -------------------------------------------------------------------------------- /Source/Rendering/ShaderCompiler/CrShaderCompilerUtilities.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Core/CrCoreForwardDeclarations.h" 4 | 5 | class CrShaderCompilerUtilities 6 | { 7 | public: 8 | 9 | static void WriteToFile(const crstl::string& filename, const crstl::string& text); 10 | 11 | static void WriteToFileIfChanged(const crstl::string& filename, const crstl::string& text); 12 | 13 | static void QuitWithMessage(const crstl::string& errorMessage); 14 | }; -------------------------------------------------------------------------------- /Source/Rendering/ShaderCompiler/CrShaderCompiler_pch.cpp: -------------------------------------------------------------------------------- 1 | #include "Rendering/ShaderCompiler/CrShaderCompiler_pch.h" -------------------------------------------------------------------------------- /Source/Rendering/ShaderCompiler/CrShaderCompiler_pch.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Core/PCH/CrCRSTLPch.h" 4 | #include "Math/CrMathPch.h" -------------------------------------------------------------------------------- /Source/Rendering/Shaders/BSDF.hlsl: -------------------------------------------------------------------------------- 1 | #ifndef BRDF_HLSL 2 | #define BRDF_HLSL 3 | 4 | #include "Common.hlsl" 5 | #include "Surface.hlsl" 6 | #include "Lighting.hlsl" 7 | 8 | RWTexture2D BRDFTexture; 9 | Texture2D BRDF_GGX_Texture; 10 | 11 | struct BSDF 12 | { 13 | float3 diffuse; 14 | float3 specular; 15 | }; 16 | 17 | // References 18 | // http://graphicrants.blogspot.com/2013/08/specular-brdf-reference.html 19 | 20 | // N is the normal 21 | // H is the half vector 22 | // alpha is the remapped roughnes (i.e. roughness^2) 23 | float D_TrowbridgeReitzGGX(float NdotH, float alpha) 24 | { 25 | float alpha2 = alpha * alpha; 26 | float denominator = NdotH * NdotH * (alpha2 - 1.0) + 1.0; 27 | return alpha2 / (pi * denominator * denominator); 28 | } 29 | 30 | float G_Smith_Uncorrelated_GGX(float NdotV, float NdotL, float alpha) 31 | { 32 | float alpha2 = alpha * alpha; 33 | float numerator = 2.0 * NdotV * 2.0 * NdotL; 34 | float denominator = (NdotV + sqrt(alpha2 + (1.0 - alpha2) * NdotV * NdotV)) * (NdotL + sqrt(alpha2 + (1.0 - alpha2) * NdotL * NdotL)); 35 | return numerator / denominator; 36 | } 37 | 38 | float3 F_Schlick(float3 F0, float VdotH) 39 | { 40 | return F0 + (1.0 - F0) * pow5(1.0 - VdotH); 41 | } 42 | 43 | // Optimized version of the above 44 | float3 DFG_Trowbridge_SmithU_Schlick(float NdotV, float NdotL, float NdotH, float VdotH, float alpha, float3 F0) 45 | { 46 | float alpha2 = alpha * alpha; 47 | float Ddenominator = NdotH * NdotH * (alpha2 - 1.0) + 1.0; 48 | 49 | float dfgScalarNumerator = NdotL * alpha2; // D * F 50 | float dfgDenominator = 1.0; 51 | dfgDenominator *= (pi * Ddenominator * Ddenominator); // D 52 | dfgDenominator *= (NdotV + sqrt(alpha2 + (1.0 - alpha2) * NdotV * NdotV)) * (NdotL + sqrt(alpha2 + (1.0 - alpha2) * NdotL * NdotL)); // G 53 | 54 | float dfgScalar = dfgScalarNumerator / dfgDenominator; 55 | 56 | return (F0 + (1.0 - F0) * pow5(1.0 - VdotH)) * dfgScalar; 57 | } 58 | 59 | float F0FromIOR(float ior) 60 | { 61 | float sqrf0 = (ior - 1.0) / (ior + 1.0); 62 | return sqrf0 * sqrf0; 63 | } 64 | 65 | float3 EvaluateDiffuseBSDF(Surface surface, Light light) 66 | { 67 | float3 N = surface.pixelNormalWorld; 68 | float3 L = light.directionPosition; 69 | float NdotL = saturate(dot(N, L)); 70 | return surface.diffuseAlbedoLinear * (NdotL / pi); 71 | } 72 | 73 | float3 EvaluateSpecularBRDF(Surface surface, Light light) 74 | { 75 | float3 N = surface.pixelNormalWorld; 76 | float3 V = surface.viewWorld; 77 | float3 L = light.directionPosition; 78 | float3 H = normalize(V + L); 79 | 80 | float NdotL = saturate(dot(N, L)); 81 | float NdotV = saturate(dot(N, V)); 82 | float NdotH = saturate(dot(N, H)); 83 | float VdotH = saturate(dot(V, H)); 84 | 85 | return DFG_Trowbridge_SmithU_Schlick(NdotV, NdotL, NdotH, VdotH, surface.alpha, surface.F0); 86 | } 87 | 88 | BSDF EvaluateBRDF(Surface surface, Light light) 89 | { 90 | BSDF bsdf; 91 | 92 | bsdf.diffuse = EvaluateDiffuseBSDF(surface, light); 93 | 94 | bsdf.specular = EvaluateSpecularBRDF(surface, light); 95 | 96 | return bsdf; 97 | } 98 | 99 | #endif 100 | -------------------------------------------------------------------------------- /Source/Rendering/Shaders/Colors.hlsl: -------------------------------------------------------------------------------- 1 | #ifndef COLORS_HLSL 2 | #define COLORS_HLSL 3 | 4 | namespace Colors 5 | { 6 | static const float3 Red = float3(1.0, 0.0, 0.0); 7 | static const float3 Green = float3(0.0, 1.0, 0.0); 8 | static const float3 Blue = float3(0.0, 0.0, 1.0); 9 | static const float3 Cyan = float3(0.0, 1.0, 1.0); 10 | static const float3 Magenta = float3(1.0, 0.0, 1.0); 11 | static const float3 Yellow = float3(1.0, 1.0, 0.0); 12 | 13 | static const float3 White = float3(1.0, 1.0, 1.0); 14 | static const float3 Grey = float3(0.5, 0.5, 0.5); 15 | static const float3 Black = float3(0.0, 0.0, 0.0); 16 | }; 17 | 18 | #endif -------------------------------------------------------------------------------- /Source/Rendering/Shaders/Compute.hlsl: -------------------------------------------------------------------------------- 1 | #ifndef COMPUTE_HLSL 2 | #define COMPUTE_HLSL 3 | 4 | #include "Common.hlsl" 5 | #include "ComputeCommon.hlsl" 6 | #include "IndirectRendering.hlsl" 7 | 8 | Buffer ExampleTypedBufferCompute; 9 | RWBuffer ExampleRWTypedBufferCompute; 10 | RWTexture2D ExampleRWTextureCompute; 11 | Texture2D ExampleTextureCompute; 12 | Texture3D ExampleTexture3DCompute; 13 | Texture2DArray ExampleTextureArrayCompute; 14 | 15 | RWByteAddressBuffer ExampleIndirectBuffer; 16 | 17 | RWStructuredBuffer ExampleDispatchIndirect; 18 | 19 | struct ComputeStruct 20 | { 21 | float4 a; 22 | int4 b; 23 | }; 24 | 25 | RWStructuredBuffer ExampleRWStructuredBufferCompute; 26 | 27 | StructuredBuffer ExampleStructuredBufferCompute; 28 | 29 | RWStructuredBuffer ExampleRWStructuredPerry; 30 | 31 | [numthreads(8, 8, 1)] 32 | void MainCS(CSInput csInput) 33 | { 34 | float4 volumeTextureSample = ExampleTexture3DCompute.SampleLevel(AllLinearClampSampler, float3(0, 0, 0), 0); 35 | float4 textureArraySample = ExampleTextureArrayCompute.SampleLevel(AllLinearClampSampler, float3(0, 0, 0), 0); 36 | 37 | //ExampleDataBufferCompute[0] = float4(0.0, 0.0, 1.0, 0.0); 38 | ExampleRWTextureCompute[csInput.groupThreadId.xy] = float4(csInput.groupThreadId.xy / 7.0, 0.0, 0.0) + volumeTextureSample + textureArraySample; 39 | 40 | ComputeStruct s; 41 | s.a = 3.0; 42 | s.b = 4; 43 | 44 | //ExampleRWStructuredBufferCompute[0] = ExampleStructuredBufferCompute[0]; 45 | } 46 | 47 | [numthreads(1, 1, 1)] 48 | void CreateIndirectArgumentsCS(CSInput csInput) 49 | { 50 | //ExampleDispatchIndirect[0].dispatchX = 2; 51 | //ExampleDispatchIndirect[0].dispatchY = 2; 52 | //ExampleDispatchIndirect[0].dispatchZ = 2; 53 | WriteDispatchIndirect(ExampleIndirectBuffer, 0, 2, 2, 2); 54 | } 55 | 56 | #endif -------------------------------------------------------------------------------- /Source/Rendering/Shaders/Compute.shaders: -------------------------------------------------------------------------------- 1 | ExampleCompute: 2 | entrypoint: MainCS 3 | stage: Compute 4 | 5 | CreateIndirectArguments: 6 | entrypoint: CreateIndirectArgumentsCS 7 | stage: Compute -------------------------------------------------------------------------------- /Source/Rendering/Shaders/ComputeCommon.hlsl: -------------------------------------------------------------------------------- 1 | #ifndef COMPUTE_COMMON_HLSL 2 | #define COMPUTE_COMMON_HLSL 3 | 4 | struct CSInput 5 | { 6 | uint3 groupId : SV_GroupID; // Index of the thread group a compute shader thread is executing in 7 | uint3 groupThreadId : SV_GroupThreadID; // Index for an individual thread within a thread group (local to the group) 8 | uint groupIndex : SV_GroupIndex; // Flattened version of SV_GroupThreadID 9 | uint3 dispatchThreadId : SV_DispatchThreadID; // SV_GroupID * numthreads + SV_GroupThreadID - The global thread index 10 | }; 11 | 12 | struct DispatchIndirectArguments 13 | { 14 | uint dispatchX; 15 | uint dispatchY; 16 | uint dispatchZ; 17 | }; 18 | 19 | struct DrawIndirectArguments 20 | { 21 | uint vertexCount; 22 | uint instanceCount; 23 | uint firstVertex; 24 | uint firstInstance; 25 | }; 26 | 27 | struct DrawInstancedIndirectArguments 28 | { 29 | uint indexCount; 30 | uint instanceCount; 31 | uint firstIndex; 32 | uint vertexOffset; 33 | uint firstInstance; 34 | }; 35 | 36 | #endif -------------------------------------------------------------------------------- /Source/Rendering/Shaders/CopyTexture.hlsl: -------------------------------------------------------------------------------- 1 | #ifndef COPYTEXTURE_HLSL 2 | #define COPYTEXTURE_HLSL 3 | 4 | #include "Common.hlsl" 5 | 6 | Texture2D CopyTexture; 7 | 8 | VSOutputFullscreen CopyTextureVS(VSInputFullscreen input) 9 | { 10 | VSOutputFullscreen vsOutput = (VSOutputFullscreen) 0; 11 | 12 | if (input.vertexId == 0) // Top left 13 | { 14 | vsOutput.hwPosition = float4(-1.0, 1.0, 1.0, 1.0); 15 | vsOutput.screenUVClip.xy = float2(0.0, 0.0); 16 | vsOutput.screenUVClip.zw = float2(-1.0, 1.0); 17 | } 18 | else if (input.vertexId == 1) // Top right 19 | { 20 | vsOutput.hwPosition = float4(3.0, 1.0, 1.0, 1.0); 21 | vsOutput.screenUVClip.xy = float2(2.0, 0.0); 22 | vsOutput.screenUVClip.zw = float2(3.0, 1.0); 23 | } 24 | else if (input.vertexId == 2) // Bottom left 25 | { 26 | vsOutput.hwPosition = float4(-1.0, -3.0, 1.0, 1.0); 27 | vsOutput.screenUVClip.xy = float2(0.0, 2.0); 28 | vsOutput.screenUVClip.zw = float2(-1.0, -3.0); 29 | } 30 | 31 | // Convert from clip space to view space 32 | vsOutput.screenUVClip.zw = vsOutput.screenUVClip.zw * CameraCB.backprojection.xy + CameraCB.backprojection.zw; 33 | 34 | return vsOutput; 35 | } 36 | 37 | float4 CopyTexturePS(VSOutputFullscreen psInput) : SV_Target0 38 | { 39 | #if defined(DEPTH) 40 | return CopyTexture.Sample(AllPointClampSampler, psInput.screenUVClip.xy); 41 | #else 42 | return CopyTexture.Sample(AllLinearClampSampler, psInput.screenUVClip.xy); 43 | #endif 44 | } 45 | 46 | #endif -------------------------------------------------------------------------------- /Source/Rendering/Shaders/CopyTexture.shaders: -------------------------------------------------------------------------------- 1 | FullscreenTriangle: 2 | entrypoint: CopyTextureVS 3 | stage: Vertex 4 | 5 | CopyTextureColor: 6 | entrypoint: CopyTexturePS 7 | stage: Pixel 8 | 9 | CopyTextureDepth: 10 | entrypoint: CopyTexturePS 11 | stage: Pixel 12 | defines: "DEPTH" 13 | 14 | CopyTextureCubemap: 15 | entrypoint: CopyTexturePS 16 | stage: Pixel 17 | defines: "CUBEMAP" 18 | 19 | CopyTextureCubemapDepth: 20 | entrypoint: CopyTexturePS 21 | stage: Pixel 22 | defines: ["DEPTH", "CUBEMAP"] -------------------------------------------------------------------------------- /Source/Rendering/Shaders/Depth.shaders: -------------------------------------------------------------------------------- 1 | DepthDownsampleLinearizeMinMax: 2 | entrypoint: DepthDownsampleLinearizeMinMaxCS 3 | stage: Compute 4 | -------------------------------------------------------------------------------- /Source/Rendering/Shaders/DirectLighting.hlsl: -------------------------------------------------------------------------------- 1 | #ifndef DIRECT_LIGHTING_HLSL 2 | #define DIRECT_LIGHTING_HLSL 3 | 4 | #include "GBuffer.hlsl" 5 | #include "Common.hlsl" 6 | #include "Lighting.hlsl" 7 | #include "BSDF.hlsl" 8 | #include "DirectLightingShared.hlsl" 9 | 10 | struct DynamicLight 11 | { 12 | float4 positionRadius; 13 | float4 colorIntensity; 14 | }; 15 | 16 | cbuffer DynamicLightCB 17 | { 18 | DynamicLight DynamicLightCB; 19 | }; 20 | 21 | struct LightComponents 22 | { 23 | float intensity; 24 | float3 color; 25 | }; 26 | 27 | Light ReadLight(DynamicLight dynamicLight) 28 | { 29 | Light light = (Light) 0; 30 | 31 | light.directionPosition = dynamicLight.positionRadius.xyz; 32 | light.radius = dynamicLight.positionRadius.w; 33 | light.color = dynamicLight.colorIntensity.rgb; 34 | light.intensity = dynamicLight.colorIntensity.a; 35 | 36 | return light; 37 | } 38 | 39 | float3 DirectionalLighting(Surface surface, Light light) 40 | { 41 | float3 diffuseLighting = EvaluateDiffuseBSDF(surface, light); 42 | 43 | float3 specularLighting = EvaluateSpecularBRDF(surface, light); 44 | 45 | return (diffuseLighting + specularLighting) * light.color; 46 | } 47 | 48 | float4 DeferredLightingPS(VSOutputFullscreen psInput) : SV_Target0 49 | { 50 | uint2 screenPixel = (uint2) psInput.hwPosition.xy; 51 | 52 | Surface surface = DecodeGBufferSurface(screenPixel, psInput.screenUVClip); 53 | 54 | Light light = ReadLight(DynamicLightCB); 55 | 56 | light.directionPosition.xyz = normalize(float3(1, 1, 1)); 57 | 58 | float3 lighting = DirectionalLighting(surface, light); 59 | 60 | if (surface.rawDepth == 0.0) 61 | { 62 | // Temporarily clear to color when depth is far plane 63 | return float4(40.0, 87.0, 220.0, 255.0) / 255.0; 64 | } 65 | else 66 | { 67 | return float4(lighting, 1.0); 68 | } 69 | } 70 | 71 | struct GBufferDebug 72 | { 73 | uint4 decodeOptions; // .x decode target 74 | }; 75 | 76 | cbuffer GBufferDebugCB 77 | { 78 | GBufferDebug GBufferDebugCB; 79 | }; 80 | 81 | float4 GBufferDebugPS(VSOutputFullscreen psInput) : SV_Target0 82 | { 83 | int2 screenPixel = psInput.hwPosition.xy; 84 | 85 | Surface surface = DecodeGBufferSurface(screenPixel, psInput.screenUVClip); 86 | 87 | uint gbufferDebugMode = GBufferDebugCB.decodeOptions.x; 88 | 89 | float3 debugColor = 0.0; 90 | 91 | if(gbufferDebugMode == GBufferDebugMode::Albedo) 92 | { 93 | debugColor = LinearToSRGB(surface.diffuseAlbedoLinear); 94 | } 95 | else if (gbufferDebugMode == GBufferDebugMode::WorldNormals) 96 | { 97 | debugColor = surface.pixelNormalWorld.xyz * 0.5 + 0.5; 98 | } 99 | else if (gbufferDebugMode == GBufferDebugMode::Roughness) 100 | { 101 | debugColor = surface.roughness.xxx; 102 | } 103 | else if(gbufferDebugMode == GBufferDebugMode::F0) 104 | { 105 | debugColor = surface.F0; 106 | } 107 | 108 | return float4(debugColor, 1.0); 109 | } 110 | 111 | #endif -------------------------------------------------------------------------------- /Source/Rendering/Shaders/DirectLighting.shaders: -------------------------------------------------------------------------------- 1 | DirectionalLightPS: 2 | entrypoint: DeferredLightingPS 3 | stage: Pixel 4 | 5 | GBufferDebugPS: 6 | entrypoint: GBufferDebugPS 7 | stage: Pixel -------------------------------------------------------------------------------- /Source/Rendering/Shaders/DirectLightingShared.hlsl: -------------------------------------------------------------------------------- 1 | #ifndef DIRECT_LIGHTING_SHARED_HLSL 2 | #define DIRECT_LIGHTING_SHARED_HLSL 3 | 4 | namespace GBufferDebugMode 5 | { 6 | enum T : uint32_t 7 | { 8 | None, 9 | Albedo, 10 | WorldNormals, 11 | Roughness, 12 | F0, 13 | Depth, 14 | DepthLinear, 15 | Count 16 | }; 17 | }; 18 | 19 | #endif -------------------------------------------------------------------------------- /Source/Rendering/Shaders/Editor.shaders: -------------------------------------------------------------------------------- 1 | EditorEdgeSelectionPS: 2 | entrypoint: EditorEdgeSelectionPS 3 | stage: Pixel 4 | 5 | EditorMouseSelectionResolveCS: 6 | entrypoint: EditorMouseSelectionResolveCS 7 | stage: Compute 8 | 9 | EditorGridVS: 10 | entrypoint: EditorGridVS 11 | stage: Vertex 12 | 13 | EditorGridPS: 14 | entrypoint: EditorGridPS 15 | stage: Pixel -------------------------------------------------------------------------------- /Source/Rendering/Shaders/GBuffer.hlsl: -------------------------------------------------------------------------------- 1 | #ifndef GBUFFER_HLSL 2 | #define GBUFFER_HLSL 3 | 4 | #include "Common.hlsl" 5 | #include "Depth.hlsl" 6 | #include "Surface.hlsl" 7 | 8 | Texture2D GBufferDepthTexture; 9 | Texture2D GBufferAlbedoAOTexture; 10 | Texture2D GBufferNormalsTexture; 11 | Texture2D GBufferMaterialTexture; 12 | 13 | struct GBuffer 14 | { 15 | float4 albedoAO; 16 | float4 worldNormalRoughness; 17 | float4 material; 18 | float rawDepth; 19 | }; 20 | 21 | float3 PackGBufferNormalOctahedral(float3 normal) 22 | { 23 | const float2 normalOctahedral12bits = OctahedralEncode(normal) * 4095.0; 24 | const uint normalOctahedral24bits = uint(normalOctahedral12bits.x) | (uint(normalOctahedral12bits.y) << 12); 25 | return float3(uint3(normalOctahedral24bits, normalOctahedral24bits >> 8, normalOctahedral24bits >> 16) & 0xff) / 255.0; 26 | } 27 | 28 | float3 UnpackGBufferNormalOctahedral(float3 normalPacked) 29 | { 30 | normalPacked *= 255.0; 31 | const uint normalOctahedral24Bits = uint(normalPacked.x) | (uint(normalPacked.y) << 8) | (uint(normalPacked.z) << 16); 32 | const float2 normalOctahedral12bits = float2(uint2(normalOctahedral24Bits, normalOctahedral24Bits >> 12) & 0xfff) / 4095.0; 33 | return OctahedralDecode(normalOctahedral12bits); 34 | } 35 | 36 | GBuffer ReadGBuffer(uint2 screenPixel) 37 | { 38 | GBuffer gBuffer; 39 | gBuffer.albedoAO = GBufferAlbedoAOTexture.Load(int3(screenPixel, 0)); 40 | gBuffer.worldNormalRoughness = GBufferNormalsTexture.Load(int3(screenPixel, 0)); 41 | gBuffer.material = GBufferMaterialTexture.Load(int3(screenPixel, 0)); 42 | gBuffer.rawDepth = GBufferDepthTexture.Load(int3(screenPixel, 0)); 43 | return gBuffer; 44 | } 45 | 46 | Surface DecodeGBufferSurface(uint2 screenPixel, float4 screenUVClip) 47 | { 48 | GBuffer gBuffer = ReadGBuffer(screenPixel); 49 | 50 | Surface surface = CreateDefaultSurface(); 51 | 52 | float linearDepth = LinearizeDepth(gBuffer.rawDepth, CameraCB.linearization); 53 | 54 | surface.rawDepth = gBuffer.rawDepth; 55 | surface.linearDepth = linearDepth; 56 | 57 | surface.screenPixel = screenPixel; 58 | surface.screenUV = screenUVClip.xy; 59 | 60 | surface.positionView = BackprojectView(screenUVClip.zw, linearDepth); 61 | surface.positionCameraWorld = mul(surface.positionView, (float3x3) CameraCB.view2WorldRotation); 62 | surface.viewView = normalize(surface.positionView); 63 | surface.viewWorld = -normalize(surface.positionCameraWorld); 64 | 65 | //surface.viewWorld = GetViewVectorWorld(); 66 | surface.diffuseAlbedoLinear = sRGBToLinear(gBuffer.albedoAO.rgb); 67 | surface.pixelNormalWorld = UnpackGBufferNormalOctahedral(gBuffer.worldNormalRoughness.xyz); 68 | surface.roughness = 0.4; 69 | surface.alpha = surface.roughness * surface.roughness; 70 | 71 | return surface; 72 | } 73 | 74 | #endif -------------------------------------------------------------------------------- /Source/Rendering/Shaders/Imgui.hlsl: -------------------------------------------------------------------------------- 1 | #ifndef IMGUI_HLSL 2 | #define IMGUI_HLSL 3 | 4 | struct VSInputUI 5 | { 6 | float2 position : POSITION; 7 | float2 uv : TEXCOORD0; 8 | float4 color : COLOR; 9 | }; 10 | 11 | struct VSOutputUI 12 | { 13 | float4 hwPosition : SV_Position; 14 | float4 color : COLOR; 15 | float2 uv : TEXCOORD0; 16 | }; 17 | 18 | struct UIData 19 | { 20 | float4x4 projection; 21 | }; 22 | 23 | cbuffer UIDataCB 24 | { 25 | UIData DataCB; 26 | } 27 | 28 | Texture2D UITexture; 29 | SamplerState UISampleState; 30 | 31 | VSOutputUI ImguiVS(VSInputUI vsInput) 32 | { 33 | VSOutputUI output = (VSOutputUI)0; 34 | output.uv = vsInput.uv; 35 | output.color = vsInput.color; 36 | output.hwPosition = mul(DataCB.projection, float4(vsInput.position, 0.0, 1.0)); 37 | return output; 38 | } 39 | 40 | float4 ImguiPS(VSOutputUI psInput) : SV_Target0 41 | { 42 | return UITexture.Sample(UISampleState, psInput.uv) * psInput.color; 43 | } 44 | 45 | #endif -------------------------------------------------------------------------------- /Source/Rendering/Shaders/Imgui.shaders: -------------------------------------------------------------------------------- 1 | ImguiVS: 2 | entrypoint: ImguiVS 3 | stage: Vertex 4 | 5 | ImguiPS: 6 | entrypoint: ImguiPS 7 | stage: Pixel -------------------------------------------------------------------------------- /Source/Rendering/Shaders/IndirectRendering.hlsl: -------------------------------------------------------------------------------- 1 | #ifndef UTILITIES_HLSL 2 | #define UTILITIES_HLSL 3 | 4 | #define DispatchIndirectSize 3 5 | #define DrawIndirectSize 4 6 | #define DrawIndexedIndirectSize 5 7 | 8 | void WriteDrawIndirectInstances(RWByteAddressBuffer indirectArgs, const int indirectDrawIndex, int instanceCount, int firstInstance) 9 | { 10 | const int offset = indirectDrawIndex * DrawIndirectSize; 11 | indirectArgs.Store((offset + 1) * 4, instanceCount); 12 | indirectArgs.Store((offset + 3) * 4, firstInstance); 13 | } 14 | 15 | void WriteIndexedDrawIndirectInstances(RWByteAddressBuffer indirectArgs, int indirectDrawIndex, int instanceCount, int firstInstance) 16 | { 17 | const int offset = indirectDrawIndex * DrawIndexedIndirectSize; 18 | indirectArgs.Store((offset + 1) * 4, instanceCount); 19 | indirectArgs.Store((offset + 4) * 4, firstInstance); 20 | } 21 | 22 | void WriteDrawIndirect(RWByteAddressBuffer indirectArgs, const int indirectDrawIndex, int vertexCount, int instanceCount, int firstVertex, int firstInstance) 23 | { 24 | const int offset = indirectDrawIndex * DrawIndirectSize; 25 | indirectArgs.Store4(offset, uint4(vertexCount, instanceCount, firstVertex, firstInstance)); 26 | } 27 | 28 | void WriteIndexedDrawIndirect(RWByteAddressBuffer indirectArgs, const int indirectDrawIndex, int indexCount, int instanceCount, int firstIndex, int vertexOffset, int firstInstance) 29 | { 30 | const int offset = indirectDrawIndex * DrawIndexedIndirectSize; 31 | indirectArgs.Store4((offset + 0) * 4, indexCount); 32 | indirectArgs.Store((offset + 4) * 4, firstInstance); 33 | } 34 | 35 | void WriteDispatchIndirect(RWByteAddressBuffer indirectArgs, int indirectDrawIndex, int threadGroupCountX, int threadGroupCountY, int threadGroupCountZ) 36 | { 37 | const int offset = indirectDrawIndex * DispatchIndirectSize; 38 | indirectArgs.Store((offset + 0) * 4, max(1, threadGroupCountX)); 39 | indirectArgs.Store((offset + 1) * 4, max(1, threadGroupCountY)); 40 | indirectArgs.Store((offset + 2) * 4, max(1, threadGroupCountZ)); 41 | } 42 | 43 | #endif -------------------------------------------------------------------------------- /Source/Rendering/Shaders/Lighting.hlsl: -------------------------------------------------------------------------------- 1 | #ifndef LIGHTING_HLSL 2 | #define LIGHTING_HLSL 3 | 4 | struct Light 5 | { 6 | float3 directionPosition; 7 | float radius; 8 | float intensity; 9 | float3 color; 10 | }; 11 | 12 | #endif -------------------------------------------------------------------------------- /Source/Rendering/Shaders/Metadata.hlsl: -------------------------------------------------------------------------------- 1 | #include "BSDF.hlsl" 2 | #include "Common.hlsl" 3 | #include "Compute.hlsl" 4 | #include "CopyTexture.hlsl" 5 | #include "Depth.hlsl" 6 | #include "DirectLighting.hlsl" 7 | #include "Imgui.hlsl" 8 | #include "GBuffer.hlsl" 9 | #include "Editor.hlsl" 10 | #include "PostProcessing.hlsl" 11 | 12 | // Never include Ubershader.hlsl. It depends on defines that aren't present during metadata generation 13 | // Instead we include UbershaderResources which has all the type information without the actual shader 14 | // #include "Ubershader.hlsl" 15 | #include "UbershaderResources.hlsl" 16 | 17 | float4 metadata() : SV_Target0 18 | { 19 | return float4(0.0, 0.0, 0.0, 0.0); 20 | } 21 | -------------------------------------------------------------------------------- /Source/Rendering/Shaders/PostProcessing.hlsl: -------------------------------------------------------------------------------- 1 | #ifndef TONEMAPPING_HLSL 2 | #define TONEMAPPING_HLSL 3 | 4 | #include "ComputeCommon.hlsl" 5 | #include "Common.hlsl" 6 | 7 | Texture2D HDRInput; 8 | RWTexture2D RWPostProcessedOutput; 9 | 10 | [numthreads(8, 8, 1)] 11 | void PostProcessingCS(CSInput csInput) 12 | { 13 | RWPostProcessedOutput[csInput.dispatchThreadId.xy].xyz = LinearToSRGB(HDRInput[csInput.dispatchThreadId.xy]); 14 | } 15 | 16 | #endif -------------------------------------------------------------------------------- /Source/Rendering/Shaders/PostProcessing.shaders: -------------------------------------------------------------------------------- 1 | PostProcessingCS: 2 | entrypoint: PostProcessingCS 3 | stage: Compute -------------------------------------------------------------------------------- /Source/Rendering/Shaders/Surface.hlsl: -------------------------------------------------------------------------------- 1 | #ifndef SURFACE_HLSL 2 | #define SURFACE_HLSL 3 | 4 | struct Surface 5 | { 6 | //--------------------- 7 | // Geometric Properties 8 | //--------------------- 9 | 10 | uint2 screenPixel; 11 | float2 screenUV; 12 | 13 | float3 positionView; 14 | 15 | // Position in world space, relative to the camera position 16 | float3 positionCameraWorld; 17 | 18 | // View vector in view space 19 | float3 viewView; 20 | 21 | // View vector in world space 22 | float3 viewWorld; 23 | 24 | float rawDepth; 25 | float linearDepth; 26 | 27 | float3 vertexNormalWorld; 28 | float3 vertexTangentWorld; 29 | float3 vertexBitangentWorld; 30 | 31 | float3 pixelNormalTangent; 32 | 33 | float3 pixelNormalWorld; 34 | 35 | // Material Properties 36 | float3 diffuseAlbedoLinear; 37 | 38 | float roughness; 39 | float alpha; 40 | float3 F0; 41 | }; 42 | 43 | Surface CreateDefaultSurface() 44 | { 45 | Surface surface; 46 | 47 | surface.screenPixel = 0; 48 | surface.screenUV = 0.0; 49 | 50 | surface.positionCameraWorld = 0.0; 51 | surface.viewWorld = float3(0.0, 0.0, 1.0); 52 | 53 | surface.vertexNormalWorld = float3(0, 1, 0); 54 | surface.vertexTangentWorld = float3(1, 0, 0); 55 | surface.vertexBitangentWorld = float3(0, 0, 1); 56 | surface.pixelNormalTangent = float3(0, 0, 1); 57 | surface.pixelNormalWorld = float3(0, 1, 0); 58 | 59 | surface.diffuseAlbedoLinear = 1.0; 60 | 61 | surface.roughness = 1.0; 62 | surface.F0 = 0.02; 63 | 64 | surface.rawDepth = 0.0; 65 | surface.linearDepth = 0.0; 66 | 67 | return surface; 68 | } 69 | 70 | #endif 71 | -------------------------------------------------------------------------------- /Source/Rendering/Shaders/Ubershader.shaders: -------------------------------------------------------------------------------- 1 | BasicUbershaderVS: 2 | entrypoint: UbershaderVS 3 | stage: Vertex 4 | 5 | BasicForwardUbershaderPS: 6 | entrypoint: UbershaderPS 7 | stage: Pixel 8 | 9 | BasicGBufferUbershaderPS: 10 | entrypoint: UbershaderPS 11 | stage: Pixel 12 | defines: "EMaterialShaderVariant_GBuffer" 13 | 14 | BasicDebugUbershaderPS: 15 | entrypoint: UbershaderPS 16 | stage: Pixel 17 | defines: "EMaterialShaderVariant_Debug" -------------------------------------------------------------------------------- /Source/Rendering/Shaders/UbershaderResources.hlsl: -------------------------------------------------------------------------------- 1 | #ifndef UBERSHADER_RESOURCES_HLSL 2 | #define UBERSHADER_RESOURCES_HLSL 3 | 4 | Texture2D DiffuseTexture0; 5 | Texture2D NormalTexture0; 6 | Texture2D SpecularTexture0; 7 | Texture2D EmissiveTexture0; 8 | Texture2D DisplacementTexture0; 9 | Texture2D DisplacementTexture3; 10 | 11 | #endif -------------------------------------------------------------------------------- /Source/Rendering/Shaders/d3d12/D3D12.hlsl: -------------------------------------------------------------------------------- 1 | // This is the most common case of a vertex + pixel shader combination. If tessellation/geometry is needed, 2 | // there is a different root signature for that 3 | #define RootSignatureGraphics \ 4 | "RootFlags(ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT | DENY_HULL_SHADER_ROOT_ACCESS | DENY_DOMAIN_SHADER_ROOT_ACCESS | DENY_GEOMETRY_SHADER_ROOT_ACCESS),"\ 5 | "DescriptorTable(CBV(b0, numDescriptors = unbounded), visibility = SHADER_VISIBILITY_VERTEX),"\ 6 | "DescriptorTable(SRV(t0, numDescriptors = unbounded), visibility = SHADER_VISIBILITY_VERTEX),"\ 7 | "DescriptorTable(UAV(u0, numDescriptors = unbounded), visibility = SHADER_VISIBILITY_VERTEX),"\ 8 | "DescriptorTable(Sampler(s0, numDescriptors = unbounded), visibility = SHADER_VISIBILITY_VERTEX),"\ 9 | "DescriptorTable(CBV(b0, numDescriptors = unbounded), visibility = SHADER_VISIBILITY_PIXEL),"\ 10 | "DescriptorTable(SRV(t0, numDescriptors = unbounded), visibility = SHADER_VISIBILITY_PIXEL),"\ 11 | "DescriptorTable(UAV(u0, numDescriptors = unbounded), visibility = SHADER_VISIBILITY_PIXEL),"\ 12 | "DescriptorTable(Sampler(s0, numDescriptors = unbounded), visibility = SHADER_VISIBILITY_PIXEL)" 13 | 14 | // The compute queue always uses D3D12_SHADER_VISIBILITY_ALL because it has only one active stage. 15 | #define RootSignatureCompute "RootFlags(0),"\ 16 | "DescriptorTable(CBV(b0, numDescriptors = unbounded), visibility = SHADER_VISIBILITY_ALL),"\ 17 | "DescriptorTable(SRV(t0, numDescriptors = unbounded), visibility = SHADER_VISIBILITY_ALL),"\ 18 | "DescriptorTable(UAV(u0, numDescriptors = unbounded), visibility = SHADER_VISIBILITY_ALL),"\ 19 | "DescriptorTable(Sampler(s0, numDescriptors = unbounded), visibility = SHADER_VISIBILITY_ALL)," 20 | -------------------------------------------------------------------------------- /Source/Rendering/Shaders/d3d12/D3D12.shaders: -------------------------------------------------------------------------------- 1 | RootSignatureGraphics: 2 | entrypoint: RootSignatureGraphics 3 | stage: RootSignature 4 | 5 | RootSignatureCompute: 6 | entrypoint: RootSignatureCompute 7 | stage: RootSignature -------------------------------------------------------------------------------- /Source/Rendering/UI/CrImGuiRenderer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Rendering/CrRenderingForwardDeclarations.h" 4 | #include "Rendering/CrBuiltinPipeline.h" 5 | #include "Rendering/ICrTexture.h" 6 | 7 | #include "crstl/intrusive_ptr.h" 8 | 9 | struct ImDrawData; 10 | 11 | struct CrImGuiRendererInitParams 12 | { 13 | cr3d::DataFormat::T m_swapchainFormat; 14 | cr3d::SampleCount m_sampleCount; 15 | }; 16 | 17 | class CrOSWindow; 18 | 19 | class CrImGuiRenderer 20 | { 21 | public: 22 | 23 | static void Initialize(const CrImGuiRendererInitParams& initParams); 24 | 25 | static void Deinitialize(); 26 | 27 | void NewFrame(const crstl::intrusive_ptr& mainWindow); 28 | 29 | void AddRenderPass(CrRenderGraph& renderGraph, const CrTextureHandle& swapchainTexture); 30 | 31 | private: 32 | 33 | CrImGuiRenderer(const CrImGuiRendererInitParams& initParams); 34 | 35 | CrImGuiRenderer(const CrImGuiRenderer& other) = delete; 36 | 37 | CrGraphicsPipelineHandle m_imguiGraphicsPipeline; 38 | 39 | CrTextureHandle m_fontAtlas; 40 | 41 | CrImGuiRendererInitParams m_initParams; 42 | }; 43 | 44 | extern CrImGuiRenderer* ImGuiRenderer; -------------------------------------------------------------------------------- /Source/Rendering/Vulkan/CrGPUBuffer_vk.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Rendering/CrGPUBuffer.h" 4 | #include 5 | 6 | #include "Core/Logging/ICrDebug.h" 7 | 8 | struct CrVkBufferStateInfo 9 | { 10 | VkAccessFlags accessMask = VK_ACCESS_FLAG_BITS_MAX_ENUM; 11 | }; 12 | 13 | class CrRenderDeviceVulkan; 14 | 15 | class CrHardwareGPUBufferVulkan final : public ICrHardwareGPUBuffer 16 | { 17 | public: 18 | 19 | CrHardwareGPUBufferVulkan(CrRenderDeviceVulkan* renderDevice, const CrHardwareGPUBufferDescriptor& descriptor); 20 | 21 | virtual ~CrHardwareGPUBufferVulkan() override; 22 | 23 | static const CrVkBufferStateInfo& GetVkBufferStateInfo(cr3d::BufferState::T bufferState); 24 | 25 | static VkBufferUsageFlags GetVkBufferUsageFlagBits(cr3d::BufferUsage::T usage, cr3d::MemoryAccess::T access); 26 | 27 | static VkPipelineStageFlags GetVkPipelineStageFlags(cr3d::BufferState::T bufferState, cr3d::ShaderStageFlags::T shaderStages); 28 | 29 | VkBuffer GetVkBuffer() const; 30 | 31 | VkBufferView GetVkBufferView() const; 32 | 33 | virtual void* LockPS() override; 34 | 35 | virtual void UnlockPS() override; 36 | 37 | private: 38 | 39 | VkBuffer m_vkBuffer; 40 | 41 | VkBufferView m_vkBufferView = nullptr; 42 | 43 | VmaAllocation m_vmaAllocation; 44 | }; 45 | 46 | inline VkBuffer CrHardwareGPUBufferVulkan::GetVkBuffer() const 47 | { 48 | return m_vkBuffer; 49 | } 50 | 51 | inline VkBufferView CrHardwareGPUBufferVulkan::GetVkBufferView() const 52 | { 53 | return m_vkBufferView; 54 | } -------------------------------------------------------------------------------- /Source/Rendering/Vulkan/CrGPUQueryPool_vk.cpp: -------------------------------------------------------------------------------- 1 | #include "Rendering/CrRendering_pch.h" 2 | 3 | #include "CrRenderDevice_vk.h" 4 | #include "CrGPUQueryPool_vk.h" 5 | #include "CrGPUBuffer_vk.h" 6 | 7 | #include "Core/Logging/ICrDebug.h" 8 | 9 | VkQueryType GetVkQueryType(cr3d::QueryType queryType) 10 | { 11 | switch (queryType) 12 | { 13 | case cr3d::QueryType::Timestamp: return VK_QUERY_TYPE_TIMESTAMP; 14 | case cr3d::QueryType::Occlusion: return VK_QUERY_TYPE_OCCLUSION; 15 | default: return VK_QUERY_TYPE_MAX_ENUM; 16 | } 17 | } 18 | 19 | CrGPUQueryPoolVulkan::CrGPUQueryPoolVulkan(ICrRenderDevice* renderDevice, const CrGPUQueryPoolDescriptor& descriptor) : ICrGPUQueryPool(renderDevice, descriptor) 20 | { 21 | CrRenderDeviceVulkan* vulkanRenderDevice = static_cast(renderDevice); 22 | 23 | m_querySize = sizeof(uint64_t); 24 | 25 | VkQueryPoolCreateInfo poolCreateInfo = {}; 26 | poolCreateInfo.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO; 27 | poolCreateInfo.flags = 0; 28 | poolCreateInfo.queryType = GetVkQueryType(descriptor.type); 29 | poolCreateInfo.queryCount = descriptor.count; 30 | 31 | VkResult vkResult = VK_SUCCESS; 32 | 33 | vkResult = vkCreateQueryPool(vulkanRenderDevice->GetVkDevice(), &poolCreateInfo, nullptr, &m_vkQueryPool); 34 | CrAssertMsg(vkResult == VK_SUCCESS, "Failed to create query pool"); 35 | 36 | CrHardwareGPUBufferDescriptor queryBufferDescriptor 37 | ( 38 | cr3d::BufferUsage::TransferDst, 39 | cr3d::MemoryAccess::GPUWriteCPURead, 40 | descriptor.count, 41 | m_querySize 42 | ); 43 | 44 | m_queryBuffer = vulkanRenderDevice->CreateHardwareGPUBuffer(queryBufferDescriptor); 45 | 46 | m_timestampPeriod = vulkanRenderDevice->GetVkPhysicalDeviceProperties().limits.timestampPeriod; 47 | } 48 | 49 | CrGPUQueryPoolVulkan::~CrGPUQueryPoolVulkan() 50 | { 51 | CrRenderDeviceVulkan* vulkanRenderDevice = static_cast(m_renderDevice); 52 | vkDestroyQueryPool(vulkanRenderDevice->GetVkDevice(), m_vkQueryPool, nullptr); 53 | } 54 | 55 | void CrGPUQueryPoolVulkan::GetTimingDataPS(CrGPUTimestamp* timingData, uint32_t timingCount) 56 | { 57 | uint64_t* memory = (uint64_t*)m_queryBuffer->Lock(); 58 | { 59 | memcpy(timingData, memory, timingCount * sizeof(timingData)); 60 | } 61 | m_queryBuffer->Unlock(); 62 | } 63 | 64 | void CrGPUQueryPoolVulkan::GetOcclusionDataPS(CrGPUOcclusion* occlusionData, uint32_t occlusionCount) 65 | { 66 | uint64_t* memory = (uint64_t*)m_queryBuffer->Lock(); 67 | { 68 | for (uint32_t i = 0; i < occlusionCount; i++) 69 | { 70 | occlusionData[i].visibilitySamples = memory[i]; 71 | } 72 | } 73 | m_queryBuffer->Unlock(); 74 | } 75 | -------------------------------------------------------------------------------- /Source/Rendering/Vulkan/CrGPUQueryPool_vk.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Rendering/ICrGPUQueryPool.h" 4 | #include 5 | 6 | class ICrRenderDevice; 7 | 8 | class CrGPUQueryPoolVulkan final : public ICrGPUQueryPool 9 | { 10 | public: 11 | 12 | CrGPUQueryPoolVulkan(ICrRenderDevice* renderDevice, const CrGPUQueryPoolDescriptor& descriptor); 13 | 14 | ~CrGPUQueryPoolVulkan(); 15 | 16 | VkQueryPool GetVkQueryPool() const { return m_vkQueryPool; } 17 | 18 | const ICrHardwareGPUBuffer* GetResultsBuffer() const { return m_queryBuffer.get(); } 19 | 20 | protected: 21 | 22 | virtual void GetTimingDataPS(CrGPUTimestamp* timingData, uint32_t timingCount) override; 23 | 24 | virtual void GetOcclusionDataPS(CrGPUOcclusion* occlusionData, uint32_t count) override; 25 | 26 | // Use the platform-independent code so we don't have to rewrite it 27 | CrHardwareGPUBufferHandle m_queryBuffer; 28 | 29 | VkQueryPool m_vkQueryPool; 30 | }; -------------------------------------------------------------------------------- /Source/Rendering/Vulkan/CrGPUSynchronization_vk.cpp: -------------------------------------------------------------------------------- 1 | #include "Rendering/CrRendering_pch.h" 2 | 3 | #include "CrGPUSynchronization_vk.h" 4 | #include "CrRenderDevice_vk.h" 5 | 6 | CrGPUFenceVulkan::CrGPUFenceVulkan(ICrRenderDevice* renderDevice, bool signaled) : ICrGPUFence(renderDevice) 7 | { 8 | VkDevice vkDevice = static_cast(renderDevice)->GetVkDevice(); 9 | 10 | VkFenceCreateInfo vkFenceCreateInfo {}; 11 | vkFenceCreateInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; 12 | vkFenceCreateInfo.flags = (signaled ? VK_FENCE_CREATE_SIGNALED_BIT : 0); 13 | 14 | vkCreateFence(vkDevice, &vkFenceCreateInfo, nullptr, &m_vkFence); 15 | } 16 | 17 | CrGPUFenceVulkan::~CrGPUFenceVulkan() 18 | { 19 | vkDestroyFence(static_cast(m_renderDevice)->GetVkDevice(), m_vkFence, nullptr); 20 | } 21 | 22 | CrGPUSemaphoreVulkan::CrGPUSemaphoreVulkan(ICrRenderDevice* renderDevice) : ICrGPUSemaphore(renderDevice) 23 | { 24 | VkDevice vkDevice = static_cast(renderDevice)->GetVkDevice(); 25 | 26 | VkSemaphoreCreateInfo info = {}; 27 | info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; 28 | 29 | vkCreateSemaphore(vkDevice, &info, nullptr, &m_vkSemaphore); 30 | } 31 | 32 | CrGPUSemaphoreVulkan::~CrGPUSemaphoreVulkan() 33 | { 34 | vkDestroySemaphore(static_cast(m_renderDevice)->GetVkDevice(), m_vkSemaphore, nullptr); 35 | } 36 | -------------------------------------------------------------------------------- /Source/Rendering/Vulkan/CrGPUSynchronization_vk.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Rendering/ICrGPUSynchronization.h" 4 | #include 5 | 6 | class ICrRenderDevice; 7 | 8 | class CrGPUFenceVulkan final : public ICrGPUFence 9 | { 10 | public: 11 | 12 | CrGPUFenceVulkan(ICrRenderDevice* renderDevice, bool signaled); 13 | 14 | ~CrGPUFenceVulkan(); 15 | 16 | VkFence GetVkFence() const; 17 | 18 | private: 19 | 20 | VkFence m_vkFence; 21 | }; 22 | 23 | inline VkFence CrGPUFenceVulkan::GetVkFence() const 24 | { 25 | return m_vkFence; 26 | } 27 | 28 | class CrGPUSemaphoreVulkan final : public ICrGPUSemaphore 29 | { 30 | public: 31 | 32 | CrGPUSemaphoreVulkan(ICrRenderDevice* renderDevice); 33 | 34 | ~CrGPUSemaphoreVulkan(); 35 | 36 | VkSemaphore GetVkSemaphore() const; 37 | 38 | private: 39 | 40 | VkSemaphore m_vkSemaphore; 41 | }; 42 | 43 | inline VkSemaphore CrGPUSemaphoreVulkan::GetVkSemaphore() const 44 | { 45 | return m_vkSemaphore; 46 | } -------------------------------------------------------------------------------- /Source/Rendering/Vulkan/CrPipeline_vk.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Rendering/ICrPipeline.h" 4 | 5 | class CrRenderDeviceVulkan; 6 | 7 | class CrGraphicsPipelineVulkan final : public ICrGraphicsPipeline 8 | { 9 | public: 10 | 11 | CrGraphicsPipelineVulkan 12 | ( 13 | CrRenderDeviceVulkan* vulkanRenderDevice, const CrGraphicsPipelineDescriptor& pipelineDescriptor, 14 | const CrGraphicsShaderHandle& graphicsShader, const CrVertexDescriptor& vertexDescriptor 15 | ); 16 | 17 | ~CrGraphicsPipelineVulkan(); 18 | 19 | VkPipeline GetVkPipeline() const { return m_vkPipeline; } 20 | 21 | VkPipelineLayout GetVkPipelineLayout() const { return m_vkPipelineLayout; } 22 | 23 | #if !defined(CR_CONFIG_FINAL) 24 | 25 | virtual void RecompilePS(ICrRenderDevice* renderDevice, const CrGraphicsShaderHandle& graphicsShader) override; 26 | 27 | #endif 28 | 29 | private: 30 | 31 | void Initialize(CrRenderDeviceVulkan* vulkanRenderDevice, const CrGraphicsPipelineDescriptor& pipelineDescriptor, const CrGraphicsShaderHandle& graphicsShader, const CrVertexDescriptor& vertexDescriptor); 32 | 33 | void Deinitialize(); 34 | 35 | // Describes the resource binding layout for this pipeline 36 | // This is later used to bind the descriptor sets 37 | VkPipelineLayout m_vkPipelineLayout; 38 | 39 | VkPipeline m_vkPipeline; 40 | }; 41 | 42 | class CrComputePipelineVulkan final : public ICrComputePipeline 43 | { 44 | public: 45 | 46 | CrComputePipelineVulkan(CrRenderDeviceVulkan* vulkanRenderDevice, const CrComputeShaderHandle& computeShader); 47 | 48 | ~CrComputePipelineVulkan(); 49 | 50 | VkPipeline GetVkPipeline() const { return m_vkPipeline; } 51 | 52 | VkPipelineLayout GetVkPipelineLayout() const { return m_vkPipelineLayout; } 53 | 54 | #if !defined(CR_CONFIG_FINAL) 55 | 56 | virtual void RecompilePS(ICrRenderDevice* renderDevice, const CrComputeShaderHandle& computeShader) override; 57 | 58 | #endif 59 | 60 | private: 61 | 62 | void Initialize(CrRenderDeviceVulkan* vulkanRenderDevice, const CrComputeShaderHandle& computeShader); 63 | 64 | void Deinitialize(); 65 | 66 | VkPipelineLayout m_vkPipelineLayout; 67 | 68 | VkPipeline m_vkPipeline; 69 | }; -------------------------------------------------------------------------------- /Source/Rendering/Vulkan/CrRenderSystem_vk.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Rendering/ICrRenderSystem.h" 4 | 5 | #include "crstl/open_hashmap.h" 6 | #include "crstl/string.h" 7 | #include "crstl/vector.h" 8 | 9 | class CrRenderSystemVulkan final : public ICrRenderSystem 10 | { 11 | public: 12 | 13 | CrRenderSystemVulkan(const CrRenderSystemDescriptor& renderSystemDescriptor); 14 | 15 | VkInstance GetVkInstance() const { return m_vkInstance; } 16 | 17 | bool IsVkInstanceExtensionSupported(const crstl::string& extension); 18 | 19 | bool IsVkInstanceLayerSupported(const crstl::string& layer); 20 | 21 | virtual ICrRenderDevice* CreateRenderDevicePS(const CrRenderDeviceDescriptor& descriptor) override; 22 | 23 | private: 24 | 25 | // Global per-application state https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#VkInstance 26 | VkInstance m_vkInstance; 27 | 28 | VkDebugUtilsMessengerEXT m_vkDebugMessenger; 29 | 30 | crstl::open_hashset m_supportedInstanceExtensions; 31 | 32 | crstl::open_hashset m_supportedInstanceLayers; 33 | 34 | crstl::vector m_instanceLayers; 35 | }; -------------------------------------------------------------------------------- /Source/Rendering/Vulkan/CrSampler_vk.cpp: -------------------------------------------------------------------------------- 1 | #include "Rendering/CrRendering_pch.h" 2 | #include "CrSampler_vk.h" 3 | #include "CrRenderDevice_vk.h" 4 | #include "CrVulkan.h" 5 | 6 | #include "Math/CrMath.h" 7 | 8 | // See https://www.khronos.org/registry/vulkan/specs/1.0/man/html/VkSamplerCreateInfo.html 9 | CrSamplerVulkan::CrSamplerVulkan(ICrRenderDevice* renderDevice, const CrSamplerDescriptor& descriptor) : ICrSampler(renderDevice) 10 | { 11 | CrRenderDeviceVulkan* vulkanRenderDevice = static_cast(renderDevice); 12 | 13 | VkDevice vkDevice = vulkanRenderDevice->GetVkDevice(); 14 | 15 | VkSamplerCreateInfo createInfo = {}; 16 | 17 | createInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; 18 | 19 | createInfo.minFilter = crvk::GetVkFilter(descriptor.minFilter); 20 | createInfo.magFilter = crvk::GetVkFilter(descriptor.magFilter); 21 | 22 | createInfo.mipmapMode = crvk::GetVkMipmapMode(descriptor.mipmapFilter); 23 | 24 | createInfo.addressModeU = crvk::GetVkAddressMode(descriptor.addressModeU); 25 | createInfo.addressModeV = crvk::GetVkAddressMode(descriptor.addressModeV); 26 | createInfo.addressModeW = crvk::GetVkAddressMode(descriptor.addressModeW); 27 | 28 | createInfo.anisotropyEnable = descriptor.enableAnisotropy; 29 | 30 | if (descriptor.enableAnisotropy) 31 | { 32 | createInfo.maxAnisotropy = (float)CrMax(1u, descriptor.maxAnisotropy); // TODO Clamp to hardware max limit 33 | } 34 | 35 | createInfo.compareEnable = descriptor.enableCompare; 36 | createInfo.compareOp = crvk::GetVkCompareOp(descriptor.compareOp); 37 | 38 | createInfo.borderColor = crvk::GetVkBorderColor(descriptor.borderColor); 39 | 40 | createInfo.mipLodBias = descriptor.mipLodBias; 41 | createInfo.minLod = descriptor.minLod; 42 | createInfo.maxLod = descriptor.maxLod; 43 | 44 | createInfo.unnormalizedCoordinates = false; // Not all APIs support it and it has many restrictions in Vulkan (e.g. no anisotropy) 45 | 46 | vkCreateSampler(vkDevice, &createInfo, nullptr, &m_vkSampler); 47 | 48 | vulkanRenderDevice->SetVkObjectName((uint64_t)m_vkSampler, VK_OBJECT_TYPE_SAMPLER, descriptor.name.c_str()); 49 | } 50 | 51 | CrSamplerVulkan::~CrSamplerVulkan() 52 | { 53 | vkDestroySampler(static_cast(m_renderDevice)->GetVkDevice(), m_vkSampler, nullptr); 54 | } 55 | -------------------------------------------------------------------------------- /Source/Rendering/Vulkan/CrSampler_vk.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Rendering/ICrSampler.h" 4 | #include 5 | 6 | class ICrRenderDevice; 7 | 8 | class CrSamplerVulkan final : public ICrSampler 9 | { 10 | public: 11 | 12 | CrSamplerVulkan(ICrRenderDevice* renderDevice, const CrSamplerDescriptor& descriptor); 13 | 14 | ~CrSamplerVulkan(); 15 | 16 | VkSampler GetVkSampler() const { return m_vkSampler; } 17 | 18 | private: 19 | 20 | VkSampler m_vkSampler; 21 | }; -------------------------------------------------------------------------------- /Source/Rendering/Vulkan/CrShader_vk.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Rendering/ICrShader.h" 4 | #include 5 | 6 | class ICrRenderDevice; 7 | 8 | class CrGraphicsShaderVulkan final : public ICrGraphicsShader 9 | { 10 | public: 11 | 12 | CrGraphicsShaderVulkan(ICrRenderDevice* renderDevice, const CrGraphicsShaderDescriptor& graphicsShaderDescriptor); 13 | 14 | ~CrGraphicsShaderVulkan(); 15 | 16 | const crstl::vector& GetVkShaderModules() const { return m_vkShaderModules; } 17 | 18 | VkDescriptorSetLayout GetVkDescriptorSetLayout() const { return m_vkDescriptorSetLayout; } 19 | 20 | private: 21 | 22 | VkDevice m_vkDevice; 23 | 24 | crstl::vector m_vkShaderModules; 25 | 26 | // We store the descriptor set layout to connect it later on to the pipeline resource layout when creating it. 27 | // The layout is also needed when allocating descriptor sets from a pool. 28 | VkDescriptorSetLayout m_vkDescriptorSetLayout; 29 | }; 30 | 31 | class CrComputeShaderVulkan final : public ICrComputeShader 32 | { 33 | public: 34 | 35 | CrComputeShaderVulkan(ICrRenderDevice* renderDevice, const CrComputeShaderDescriptor& computeShaderDescriptor); 36 | 37 | ~CrComputeShaderVulkan(); 38 | 39 | VkShaderModule GetVkShaderModule() const { return m_vkShaderModule; } 40 | 41 | VkDescriptorSetLayout GetVkDescriptorSetLayout() const { return m_vkDescriptorSetLayout; } 42 | 43 | private: 44 | 45 | VkDevice m_vkDevice; 46 | 47 | VkShaderModule m_vkShaderModule; 48 | 49 | VkDescriptorSetLayout m_vkDescriptorSetLayout; 50 | }; -------------------------------------------------------------------------------- /Source/Rendering/Vulkan/CrSwapchain_vk.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Rendering/ICrSwapchain.h" 4 | #include 5 | 6 | class CrSwapchainVulkan final : public ICrSwapchain 7 | { 8 | public: 9 | 10 | CrSwapchainVulkan(ICrRenderDevice* renderDevice, const CrSwapchainDescriptor& swapchainDescriptor); 11 | 12 | ~CrSwapchainVulkan(); 13 | 14 | VkSwapchainKHR GetVkSwapchain() const; 15 | 16 | virtual CrSwapchainResult AcquireNextImagePS(uint64_t timeoutNanoseconds = UINT64_MAX) override; 17 | 18 | virtual void PresentPS() override; 19 | 20 | virtual void ResizePS(uint32_t width, uint32_t height) override; 21 | 22 | private: 23 | 24 | void CreateSwapchainTextures(); 25 | 26 | // Semaphores are signaled when present completes 27 | crstl::vector m_presentCompleteSemaphores; 28 | 29 | crstl::vector m_imageReadyFences; 30 | 31 | // We need to have another index for the semaphore because we don't really know 32 | // the buffer index until we have acquired the image, but we need to signal the 33 | // semaphore during that call 34 | uint32_t m_currentSemaphoreIndex; 35 | 36 | VkSurfaceKHR m_vkSurface = nullptr; 37 | 38 | VkSwapchainKHR m_vkSwapchain = nullptr; 39 | 40 | VkFormat m_vkFormat = VK_FORMAT_UNDEFINED; 41 | 42 | VkColorSpaceKHR m_vkColorSpace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR; 43 | 44 | VkFence m_swapchainRecreationFence = nullptr; 45 | 46 | bool m_acquired = false; 47 | 48 | // We use this mainly to resize the swapchain. There's a couple of things 49 | // we can modify but the rest stays the same 50 | VkSwapchainCreateInfoKHR m_vkSwapchainCreateInfo; 51 | }; 52 | 53 | inline VkSwapchainKHR CrSwapchainVulkan::GetVkSwapchain() const 54 | { 55 | return m_vkSwapchain; 56 | } -------------------------------------------------------------------------------- /Source/Rendering/Vulkan/CrTexture_vk.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Rendering/ICrTexture.h" 4 | 5 | #include 6 | #include "CrVMA.h" 7 | 8 | #include "crstl/array.h" 9 | #include "crstl/vector.h" 10 | 11 | class ICrRenderDevice; 12 | 13 | struct CrVkAdditionalTextureViews 14 | { 15 | crstl::array, cr3d::MaxMipmaps> m_vkImageSingleMipSlice; // Each mipmap can have a variable amount of slices 16 | crstl::array m_vkImageViewSingleMipAllSlices; // Each mipmap can see all slices 17 | 18 | VkImageView m_vkImageViewStencil; 19 | }; 20 | 21 | class CrTextureVulkan final : public ICrTexture 22 | { 23 | public: 24 | 25 | CrTextureVulkan(ICrRenderDevice* renderDevice, const CrTextureDescriptor& descriptor); 26 | 27 | ~CrTextureVulkan(); 28 | 29 | VkImage GetVkImage() const { return m_vkImage; } 30 | 31 | VkImageView GetVkImageViewShaderAllMipsAllSlices() const { return m_vkImageViewAllMipsAllSlices; } 32 | 33 | // Used for depth-stencil images when we want to bind the stencil 34 | // The base image view should be assumed to be depth 35 | VkImageView GetVkImageViewStencil() const { return m_additionalViews->m_vkImageViewStencil; } 36 | 37 | VkImageView GetVkImageViewSingleMipSlice(uint32_t mip, uint32_t slice) const { return m_additionalViews->m_vkImageSingleMipSlice[mip][slice]; } 38 | 39 | VkImageView GetVkImageViewSingleMipAllSlices(uint32_t mip) const { return m_additionalViews->m_vkImageViewSingleMipAllSlices[mip]; } 40 | 41 | private: 42 | 43 | VkImage m_vkImage; 44 | 45 | // Main shader view, can access all mips and slices 46 | VkImageView m_vkImageViewAllMipsAllSlices; 47 | 48 | // This is optional as only render targets and RW textures need them, but can take up 49 | // some memory per texture (almost 512 bytes) 50 | crstl::unique_ptr m_additionalViews; 51 | 52 | // Allocation handle through the VMA allocator 53 | VmaAllocation m_vmaAllocation; 54 | }; -------------------------------------------------------------------------------- /Source/Rendering/Vulkan/CrVMA.h: -------------------------------------------------------------------------------- 1 | // Don't add pragma once here. It needs to be included more than once for the implementation 2 | 3 | #include "Core/CrMacros.h" 4 | #include "Core/Logging/ICrDebug.h" 5 | 6 | warnings_off 7 | 8 | #define VMA_DEBUG_LOG(format, ...) CrLog(format, __VA_ARGS__) 9 | 10 | #include 11 | warnings_on -------------------------------------------------------------------------------- /Source/Rendering/d3d12/CrDescriptorHeap_d3d12.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "CrD3D12.h" 4 | 5 | class CrRenderDeviceD3D12; 6 | 7 | struct CrDescriptorHeapDescriptor 8 | { 9 | const char* name = ""; 10 | uint32_t numDescriptors = 0; 11 | D3D12_DESCRIPTOR_HEAP_TYPE type = D3D12_DESCRIPTOR_HEAP_TYPE_NUM_TYPES; 12 | D3D12_DESCRIPTOR_HEAP_FLAGS flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE; 13 | }; 14 | 15 | class CrDescriptorHeapD3D12 16 | { 17 | public: 18 | 19 | static uint32_t GetMaxDescriptorsPerHeap(const CrDescriptorHeapDescriptor& descriptor); 20 | 21 | void Initialize(CrRenderDeviceD3D12* renderDeviceD3D12, const CrDescriptorHeapDescriptor& descriptor); 22 | 23 | crd3d::DescriptorD3D12 GetHeapStart() const { return m_heapStart; } 24 | 25 | uint32_t GetDescriptorStride() const { return m_descriptorStride; } 26 | 27 | ID3D12DescriptorHeap* GetD3D12DescriptorHeap() const { return m_descriptorHeap; } 28 | 29 | private: 30 | 31 | ID3D12Device* m_d3d12Device; 32 | 33 | // Size of each descriptor 34 | uint32_t m_descriptorStride; 35 | 36 | crd3d::DescriptorD3D12 m_heapStart; 37 | 38 | ID3D12DescriptorHeap* m_descriptorHeap; 39 | }; 40 | 41 | // Pool of descriptors that can be reused. Putting a descriptor back in the pool implicitly assumes that the descriptor can 42 | // be reused, which is often the case for non-shader-visible descriptors. Therefore this caters well for the resource view 43 | // use case, e.g. we create a render target view associated to a resource, and its lifetime is the same as that of the resource 44 | class CrDescriptorPoolD3D12 45 | { 46 | public: 47 | 48 | void Initialize(CrRenderDeviceD3D12* renderDeviceD3D12, const CrDescriptorHeapDescriptor& descriptor); 49 | 50 | crd3d::DescriptorD3D12 Allocate(); 51 | 52 | void Free(crd3d::DescriptorD3D12 descriptor); 53 | 54 | const CrDescriptorHeapD3D12& GetDescriptorHeap() const { return m_descriptorHeap; } 55 | 56 | private: 57 | 58 | CrDescriptorHeapD3D12 m_descriptorHeap; 59 | 60 | crstl::vector m_availableDescriptors; 61 | }; 62 | 63 | // Stream of descriptors that one never returns descriptors to. This is meant to be used throughout the frame, and it's where 64 | // shader-visible descriptors go. Once the frame has been consumed by the GPU, all those descriptors can be reused 65 | class CrDescriptorStreamD3D12 66 | { 67 | public: 68 | 69 | void Initialize(CrRenderDeviceD3D12* renderDeviceD3D12, const CrDescriptorHeapDescriptor& descriptor); 70 | 71 | CrDescriptorStreamD3D12(); 72 | 73 | crd3d::DescriptorD3D12 Allocate(uint32_t count); 74 | 75 | void Reset(); 76 | 77 | const CrDescriptorHeapD3D12& GetDescriptorHeap() const { return m_descriptorHeap; } 78 | 79 | uint32_t GetNumDescriptors() const { return m_currentDescriptor; } 80 | 81 | private: 82 | 83 | CrDescriptorHeapD3D12 m_descriptorHeap; 84 | 85 | uint32_t m_currentDescriptor; 86 | }; -------------------------------------------------------------------------------- /Source/Rendering/d3d12/CrGPUBuffer_d3d12.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Rendering/CrGPUBuffer.h" 4 | #include "d3d12.h" 5 | 6 | #include "Core/Logging/ICrDebug.h" 7 | 8 | class CrRenderDeviceD3D12; 9 | 10 | class CrHardwareGPUBufferD3D12 final : public ICrHardwareGPUBuffer 11 | { 12 | public: 13 | 14 | CrHardwareGPUBufferD3D12(CrRenderDeviceD3D12* renderDevice, const CrHardwareGPUBufferDescriptor& descriptor); 15 | 16 | virtual ~CrHardwareGPUBufferD3D12() override; 17 | 18 | ID3D12Resource* GetD3D12Resource() const { return m_d3d12Resource; } 19 | 20 | D3D12_RESOURCE_STATES GetDefaultResourceState() const { return m_d3d12InitialState; } 21 | 22 | virtual void* LockPS() override; 23 | 24 | virtual void UnlockPS() override; 25 | 26 | private: 27 | 28 | ID3D12Resource* m_d3d12Resource; 29 | 30 | D3D12_RESOURCE_STATES m_d3d12InitialState; 31 | }; -------------------------------------------------------------------------------- /Source/Rendering/d3d12/CrGPUQueryPool_d3d12.cpp: -------------------------------------------------------------------------------- 1 | #include "Rendering/CrRendering_pch.h" 2 | 3 | #include "CrRenderDevice_d3d12.h" 4 | #include "CrGPUQueryPool_d3d12.h" 5 | #include "CrGPUBuffer_d3d12.h" 6 | 7 | #include "Core/Logging/ICrDebug.h" 8 | 9 | D3D12_QUERY_HEAP_TYPE GetD3D12QueryType(cr3d::QueryType queryType) 10 | { 11 | switch (queryType) 12 | { 13 | case cr3d::QueryType::Timestamp: return D3D12_QUERY_HEAP_TYPE_TIMESTAMP; 14 | case cr3d::QueryType::Occlusion: return D3D12_QUERY_HEAP_TYPE_OCCLUSION; 15 | default: return D3D12_QUERY_HEAP_TYPE_OCCLUSION; 16 | } 17 | } 18 | 19 | CrGPUQueryPoolD3D12::CrGPUQueryPoolD3D12(ICrRenderDevice* renderDevice, const CrGPUQueryPoolDescriptor& descriptor) : ICrGPUQueryPool(renderDevice, descriptor) 20 | { 21 | CrRenderDeviceD3D12* d3d12RenderDevice = static_cast(renderDevice); 22 | 23 | m_querySize = sizeof(uint64_t); 24 | 25 | D3D12_QUERY_HEAP_DESC queryHeapDescriptor; 26 | queryHeapDescriptor.Type = GetD3D12QueryType(descriptor.type); 27 | queryHeapDescriptor.Count = descriptor.count; 28 | queryHeapDescriptor.NodeMask = 0; 29 | HRESULT hResult = d3d12RenderDevice->GetD3D12Device()->CreateQueryHeap(&queryHeapDescriptor, IID_PPV_ARGS(&m_d3d12QueryHeap)); 30 | 31 | CrAssertMsg(hResult == S_OK, "Failed to create query pool"); 32 | 33 | CrHardwareGPUBufferDescriptor queryBufferDescriptor(cr3d::BufferUsage::TransferDst, cr3d::MemoryAccess::GPUWriteCPURead, descriptor.count, m_querySize); 34 | 35 | m_queryBuffer = d3d12RenderDevice->CreateHardwareGPUBuffer(queryBufferDescriptor); 36 | } 37 | 38 | CrGPUQueryPoolD3D12::~CrGPUQueryPoolD3D12() 39 | { 40 | m_d3d12QueryHeap->Release(); 41 | } 42 | 43 | void CrGPUQueryPoolD3D12::GetTimingDataPS(CrGPUTimestamp* timingData, uint32_t timingCount) 44 | { 45 | uint64_t* memory = (uint64_t*)m_queryBuffer->Lock(); 46 | { 47 | memcpy(timingData, memory, timingCount * sizeof(timingData)); 48 | } 49 | m_queryBuffer->Unlock(); 50 | } 51 | 52 | void CrGPUQueryPoolD3D12::GetOcclusionDataPS(CrGPUOcclusion* occlusionData, uint32_t occlusionCount) 53 | { 54 | uint64_t* memory = (uint64_t*)m_queryBuffer->Lock(); 55 | { 56 | for (uint32_t i = 0; i < occlusionCount; i++) 57 | { 58 | occlusionData[i].visibilitySamples = memory[i]; 59 | } 60 | } 61 | m_queryBuffer->Unlock(); 62 | } 63 | -------------------------------------------------------------------------------- /Source/Rendering/d3d12/CrGPUQueryPool_d3d12.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Rendering/ICrGPUQueryPool.h" 4 | 5 | class ICrRenderDevice; 6 | 7 | class CrGPUQueryPoolD3D12 final : public ICrGPUQueryPool 8 | { 9 | public: 10 | 11 | CrGPUQueryPoolD3D12(ICrRenderDevice* renderDevice, const CrGPUQueryPoolDescriptor& descriptor); 12 | 13 | ~CrGPUQueryPoolD3D12(); 14 | 15 | ID3D12QueryHeap* GetD3D12QueryHeap() const { return m_d3d12QueryHeap; } 16 | 17 | const ICrHardwareGPUBuffer* GetResultsBuffer() const { return m_queryBuffer.get(); } 18 | 19 | protected: 20 | 21 | virtual void GetTimingDataPS(CrGPUTimestamp* timingData, uint32_t timingCount) override; 22 | 23 | virtual void GetOcclusionDataPS(CrGPUOcclusion* occlusionData, uint32_t count) override; 24 | 25 | // Use the platform-independent code so we don't have to rewrite it 26 | CrHardwareGPUBufferHandle m_queryBuffer; 27 | 28 | ID3D12QueryHeap* m_d3d12QueryHeap; 29 | }; -------------------------------------------------------------------------------- /Source/Rendering/d3d12/CrGPUSynchronization_d3d12.cpp: -------------------------------------------------------------------------------- 1 | #include "Rendering/CrRendering_pch.h" 2 | 3 | #include "CrGPUSynchronization_d3d12.h" 4 | #include "CrRenderDevice_d3d12.h" 5 | 6 | #include "Core/CrMacros.h" 7 | 8 | CrGPUFenceD3D12::CrGPUFenceD3D12(ICrRenderDevice* renderDevice, bool signaled) : ICrGPUFence(renderDevice) 9 | { 10 | CrRenderDeviceD3D12* d3d12RenderDevice = static_cast(renderDevice); 11 | ID3D12Device* d3d12Device = d3d12RenderDevice->GetD3D12Device(); 12 | d3d12Device->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&m_d3d12Fence)); 13 | 14 | m_fenceEvent = CreateEvent(nullptr, TRUE, FALSE, nullptr); 15 | 16 | if (signaled) 17 | { 18 | d3d12RenderDevice->GetD3D12GraphicsCommandQueue()->Signal(m_d3d12Fence, 1); 19 | } 20 | } 21 | 22 | CrGPUFenceD3D12::~CrGPUFenceD3D12() 23 | { 24 | m_d3d12Fence->Release(); 25 | 26 | CloseHandle(m_fenceEvent); 27 | } 28 | 29 | CrGPUSemaphoreD3D12::CrGPUSemaphoreD3D12(ICrRenderDevice* renderDevice) : ICrGPUSemaphore(renderDevice) 30 | { 31 | ID3D12Device* d3d12Device = static_cast(renderDevice)->GetD3D12Device(); 32 | d3d12Device->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&m_d3d12Fence)); 33 | } 34 | 35 | CrGPUSemaphoreD3D12::~CrGPUSemaphoreD3D12() 36 | { 37 | m_d3d12Fence->Release(); 38 | } 39 | -------------------------------------------------------------------------------- /Source/Rendering/d3d12/CrGPUSynchronization_d3d12.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Rendering/ICrGPUSynchronization.h" 4 | #include "d3d12.h" 5 | 6 | class ICrRenderDevice; 7 | 8 | class CrGPUFenceD3D12 final : public ICrGPUFence 9 | { 10 | public: 11 | 12 | CrGPUFenceD3D12(ICrRenderDevice* renderDevice, bool signaled); 13 | 14 | ~CrGPUFenceD3D12(); 15 | 16 | ID3D12Fence* GetD3D12Fence() const { return m_d3d12Fence; } 17 | 18 | HANDLE GetFenceEvent() const { return m_fenceEvent; } 19 | 20 | private: 21 | 22 | HANDLE m_fenceEvent; 23 | 24 | ID3D12Fence* m_d3d12Fence; 25 | }; 26 | 27 | class CrGPUSemaphoreD3D12 final : public ICrGPUSemaphore 28 | { 29 | public: 30 | 31 | CrGPUSemaphoreD3D12(ICrRenderDevice* renderDevice); 32 | 33 | ~CrGPUSemaphoreD3D12(); 34 | 35 | private: 36 | 37 | ID3D12Fence* m_d3d12Fence; 38 | }; -------------------------------------------------------------------------------- /Source/Rendering/d3d12/CrPipeline_d3d12.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Rendering/ICrPipeline.h" 4 | 5 | class CrRenderDeviceD3D12; 6 | 7 | class CrGraphicsPipelineD3D12 final : public ICrGraphicsPipeline 8 | { 9 | public: 10 | 11 | CrGraphicsPipelineD3D12 12 | ( 13 | CrRenderDeviceD3D12* d3d12RenderDevice, const CrGraphicsPipelineDescriptor& pipelineDescriptor, 14 | const CrGraphicsShaderHandle& graphicsShader, const CrVertexDescriptor& vertexDescriptor 15 | ); 16 | 17 | ~CrGraphicsPipelineD3D12(); 18 | 19 | ID3D12PipelineState* GetD3D12PipelineState() const { return m_d3d12PipelineState; } 20 | 21 | ID3D12RootSignature* GetD3D12RootSignature() const { return m_d3d12RootSignature; } 22 | 23 | D3D12_PRIMITIVE_TOPOLOGY GetD3D12PrimitiveTopologyType() const { return m_d3d12PrimitiveTopology; } 24 | 25 | #if !defined(CR_CONFIG_FINAL) 26 | 27 | virtual void RecompilePS(ICrRenderDevice* renderDevice, const CrGraphicsShaderHandle& graphicsShader) override; 28 | 29 | #endif 30 | 31 | private: 32 | 33 | void Initialize(CrRenderDeviceD3D12* d3d12RenderDevice, const CrGraphicsPipelineDescriptor& pipelineDescriptor, const CrGraphicsShaderHandle& graphicsShader, const CrVertexDescriptor& vertexDescriptor); 34 | 35 | void Deinitialize(); 36 | 37 | D3D12_PRIMITIVE_TOPOLOGY m_d3d12PrimitiveTopology; 38 | 39 | ID3D12RootSignature* m_d3d12RootSignature; 40 | 41 | ID3D12PipelineState* m_d3d12PipelineState; 42 | }; 43 | 44 | class CrComputePipelineD3D12 final : public ICrComputePipeline 45 | { 46 | public: 47 | 48 | CrComputePipelineD3D12(CrRenderDeviceD3D12* d3d12RenderDevice, const CrComputeShaderHandle& computeShader); 49 | 50 | ~CrComputePipelineD3D12(); 51 | 52 | ID3D12PipelineState* GetD3D12PipelineState() const { return m_d3d12PipelineState; } 53 | 54 | ID3D12RootSignature* GetD3D12RootSignature() const { return m_d3d12RootSignature; } 55 | 56 | #if !defined(CR_CONFIG_FINAL) 57 | 58 | virtual void RecompilePS(ICrRenderDevice* renderDevice, const CrComputeShaderHandle& computeShader) override; 59 | 60 | #endif 61 | 62 | private: 63 | 64 | void Initialize(CrRenderDeviceD3D12* d3d12RenderDevice, const CrComputeShaderHandle& computeShader); 65 | 66 | void Deinitialize(); 67 | 68 | ID3D12RootSignature* m_d3d12RootSignature; 69 | 70 | ID3D12PipelineState* m_d3d12PipelineState; 71 | }; -------------------------------------------------------------------------------- /Source/Rendering/d3d12/CrRenderSystem_d3d12.cpp: -------------------------------------------------------------------------------- 1 | #include "Rendering/CrRendering_pch.h" 2 | 3 | #include "CrRenderSystem_d3d12.h" 4 | #include "CrRenderDevice_d3d12.h" 5 | 6 | #include "Rendering/Extensions/CrNVAPIHeader.h" 7 | 8 | #include "Core/CrMacros.h" 9 | #include "Core/Logging/ICrDebug.h" 10 | 11 | CrRenderSystemD3D12::CrRenderSystemD3D12(const CrRenderSystemDescriptor& renderSystemDescriptor) : ICrRenderSystem(renderSystemDescriptor) 12 | { 13 | // Load NVAPI or other extension mechanisms before we load Renderdoc or PIX 14 | if (renderSystemDescriptor.enableNVAPI) 15 | { 16 | InitializeNVAPI(); 17 | } 18 | 19 | if (renderSystemDescriptor.enableRenderDoc) 20 | { 21 | InitializeRenderdoc(); 22 | } 23 | else if (renderSystemDescriptor.enablePIX) 24 | { 25 | /*m_pixEnabled = */InitializePIX(); 26 | } 27 | 28 | UINT createFactoryFlags = 0; 29 | HRESULT hResult = S_OK; 30 | 31 | if (renderSystemDescriptor.enableValidation) 32 | { 33 | createFactoryFlags |= DXGI_CREATE_FACTORY_DEBUG; 34 | 35 | hResult = D3D12GetDebugInterface(IID_PPV_ARGS(&m_d3d12DebugController)); 36 | if (SUCCEEDED(hResult)) 37 | { 38 | m_d3d12DebugController->EnableDebugLayer(); 39 | 40 | //ID3D12Debug1* d3d12DebugController1 = nullptr; 41 | //hr = m_d3d12DebugController->QueryInterface(IID_GRAPHICS_PPV_ARGS(&d3d12DebugController1)); 42 | } 43 | } 44 | 45 | // Assume DXGI 1.4 46 | hResult = CreateDXGIFactory2(createFactoryFlags, IID_PPV_ARGS(&m_dxgiFactory4)); 47 | CrAssertMsg(SUCCEEDED(hResult), "Failed to create DXGIFactory"); 48 | 49 | if (m_dxgiFactory4->QueryInterface(IID_PPV_ARGS(&m_dxgiFactory6)) == S_OK) 50 | { 51 | 52 | } 53 | 54 | if (m_dxgiFactory4->QueryInterface(IID_PPV_ARGS(&m_dxgiFactory7)) == S_OK) 55 | { 56 | 57 | } 58 | } 59 | 60 | ICrRenderDevice* CrRenderSystemD3D12::CreateRenderDevicePS(const CrRenderDeviceDescriptor& descriptor) 61 | { 62 | return new CrRenderDeviceD3D12(this, descriptor); 63 | } 64 | 65 | bool CrRenderSystemD3D12::InitializeNVAPI() 66 | { 67 | #if defined(CR_NVAPI_SUPPORTED) 68 | 69 | if(!m_nvapiInitialized) 70 | { 71 | NvAPI_Status result = NvAPI_Initialize(); 72 | m_nvapiInitialized = (result == NVAPI_OK); 73 | } 74 | 75 | #endif 76 | 77 | return m_nvapiInitialized; 78 | } 79 | 80 | bool CrRenderSystemD3D12::InitializePIX() 81 | { 82 | if (!m_pixInitialized) 83 | { 84 | m_pixInitialized = m_pix.Initialize(); 85 | } 86 | 87 | return m_pixInitialized; 88 | } -------------------------------------------------------------------------------- /Source/Rendering/d3d12/CrRenderSystem_d3d12.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Rendering/ICrRenderSystem.h" 4 | 5 | class CrRenderSystemD3D12 final : public ICrRenderSystem 6 | { 7 | public: 8 | 9 | CrRenderSystemD3D12(const CrRenderSystemDescriptor& renderSystemDescriptor); 10 | 11 | virtual ICrRenderDevice* CreateRenderDevicePS(const CrRenderDeviceDescriptor& descriptor) override; 12 | 13 | IDXGIFactory4* GetDXGIFactory4() const { return m_dxgiFactory4; } 14 | 15 | IDXGIFactory6* GetDXGIFactory6() const { return m_dxgiFactory6; } 16 | 17 | IDXGIFactory6* GetDXGIFactory7() const { return m_dxgiFactory7; } 18 | 19 | bool InitializeNVAPI(); 20 | 21 | bool InitializePIX(); 22 | 23 | private: 24 | 25 | ID3D12Debug* m_d3d12DebugController; 26 | 27 | IDXGIFactory4* m_dxgiFactory4 = nullptr; 28 | 29 | IDXGIFactory6* m_dxgiFactory6 = nullptr; 30 | 31 | IDXGIFactory7* m_dxgiFactory7 = nullptr; 32 | 33 | bool m_nvapiInitialized = false; 34 | 35 | bool m_pixInitialized = false; 36 | }; -------------------------------------------------------------------------------- /Source/Rendering/d3d12/CrSampler_d3d12.cpp: -------------------------------------------------------------------------------- 1 | #include "Rendering/CrRendering_pch.h" 2 | #include "CrSampler_d3d12.h" 3 | #include "CrRenderDevice_d3d12.h" 4 | #include "CrD3D12.h" 5 | 6 | #include "Core/Logging/ICrDebug.h" 7 | 8 | CrSamplerD3D12::CrSamplerD3D12(ICrRenderDevice* renderDevice, const CrSamplerDescriptor& descriptor) : ICrSampler(renderDevice) 9 | { 10 | m_d3d12Sampler.Filter = crd3d::GetD3DFilter(descriptor.minFilter, descriptor.magFilter, descriptor.mipmapFilter, descriptor.enableAnisotropy, descriptor.enableCompare); 11 | m_d3d12Sampler.AddressU = crd3d::GetD3DAddressMode(descriptor.addressModeU); 12 | m_d3d12Sampler.AddressV = crd3d::GetD3DAddressMode(descriptor.addressModeV); 13 | m_d3d12Sampler.AddressW = crd3d::GetD3DAddressMode(descriptor.addressModeW); 14 | m_d3d12Sampler.MipLODBias = descriptor.mipLodBias; 15 | m_d3d12Sampler.MaxAnisotropy = descriptor.maxAnisotropy; 16 | m_d3d12Sampler.ComparisonFunc = crd3d::GetD3DCompareOp(descriptor.compareOp); 17 | 18 | switch (descriptor.borderColor) 19 | { 20 | case cr3d::BorderColor::TransparentBlack: 21 | m_d3d12Sampler.BorderColor[0] = 0.0f; 22 | m_d3d12Sampler.BorderColor[1] = 0.0f; 23 | m_d3d12Sampler.BorderColor[2] = 0.0f; 24 | m_d3d12Sampler.BorderColor[3] = 0.0f; 25 | break; 26 | case cr3d::BorderColor::OpaqueBlack: 27 | m_d3d12Sampler.BorderColor[0] = 0.0f; 28 | m_d3d12Sampler.BorderColor[1] = 0.0f; 29 | m_d3d12Sampler.BorderColor[2] = 0.0f; 30 | m_d3d12Sampler.BorderColor[3] = 1.0f; 31 | break; 32 | case cr3d::BorderColor::OpaqueWhite: 33 | m_d3d12Sampler.BorderColor[0] = 1.0f; 34 | m_d3d12Sampler.BorderColor[1] = 1.0f; 35 | m_d3d12Sampler.BorderColor[2] = 1.0f; 36 | m_d3d12Sampler.BorderColor[3] = 1.0f; 37 | break; 38 | } 39 | 40 | m_d3d12Sampler.MinLOD = descriptor.minLod; 41 | m_d3d12Sampler.MaxLOD = descriptor.maxLod; 42 | } 43 | 44 | CrSamplerD3D12::~CrSamplerD3D12() 45 | { 46 | 47 | } 48 | -------------------------------------------------------------------------------- /Source/Rendering/d3d12/CrSampler_d3d12.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Rendering/ICrSampler.h" 4 | 5 | #include "CrD3D12.h" 6 | 7 | class ICrRenderDevice; 8 | 9 | class CrSamplerD3D12 final : public ICrSampler 10 | { 11 | public: 12 | 13 | CrSamplerD3D12(ICrRenderDevice* renderDevice, const CrSamplerDescriptor& descriptor); 14 | 15 | ~CrSamplerD3D12(); 16 | 17 | const D3D12_SAMPLER_DESC& GetD3D12Sampler() const { return m_d3d12Sampler; } 18 | 19 | private: 20 | 21 | D3D12_SAMPLER_DESC m_d3d12Sampler; 22 | }; -------------------------------------------------------------------------------- /Source/Rendering/d3d12/CrShader_d3d12.cpp: -------------------------------------------------------------------------------- 1 | #include "Rendering/CrRendering_pch.h" 2 | #include "CrShader_d3d12.h" 3 | #include "CrRenderDevice_d3d12.h" 4 | 5 | #include "Rendering/CrShaderResourceMetadata.h" 6 | #include "Rendering/ICrShader.inl" 7 | 8 | #include "Core/Logging/ICrDebug.h" 9 | #include "Core/CrMacros.h" 10 | 11 | CrGraphicsShaderD3D12::CrGraphicsShaderD3D12(ICrRenderDevice* renderDevice, const CrGraphicsShaderDescriptor& graphicsShaderDescriptor) 12 | : ICrGraphicsShader(renderDevice, graphicsShaderDescriptor) 13 | { 14 | CrShaderBindingLayoutResources resources; 15 | 16 | // Create the shader modules and parse reflection information 17 | for (const CrShaderBytecodeHandle& shaderBytecode : graphicsShaderDescriptor.m_bytecodes) 18 | { 19 | const CrShaderReflectionHeader& reflectionHeader = shaderBytecode->GetReflection(); 20 | ICrShaderBindingLayout::AddResources(reflectionHeader, resources, [](cr3d::ShaderStage::T, const CrShaderReflectionResource&){}); 21 | } 22 | 23 | m_bindingLayout = crstl::unique_ptr(new ICrShaderBindingLayout(resources)); 24 | } 25 | 26 | CrGraphicsShaderD3D12::~CrGraphicsShaderD3D12() 27 | { 28 | 29 | } 30 | 31 | CrComputeShaderD3D12::CrComputeShaderD3D12(ICrRenderDevice* renderDevice, const CrComputeShaderDescriptor& computeShaderDescriptor) 32 | : ICrComputeShader(renderDevice, computeShaderDescriptor) 33 | { 34 | CrShaderBindingLayoutResources resources; 35 | const CrShaderReflectionHeader& reflectionHeader = computeShaderDescriptor.m_bytecode->GetReflection(); 36 | ICrShaderBindingLayout::AddResources(reflectionHeader, resources, [](cr3d::ShaderStage::T, const CrShaderReflectionResource&){}); 37 | m_bindingLayout = crstl::unique_ptr(new ICrShaderBindingLayout(resources)); 38 | } 39 | -------------------------------------------------------------------------------- /Source/Rendering/d3d12/CrShader_d3d12.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Rendering/ICrShader.h" 4 | #include 5 | 6 | class ICrRenderDevice; 7 | 8 | class CrGraphicsShaderD3D12 final : public ICrGraphicsShader 9 | { 10 | public: 11 | 12 | CrGraphicsShaderD3D12(ICrRenderDevice* renderDevice, const CrGraphicsShaderDescriptor& graphicsShaderDescriptor); 13 | 14 | ~CrGraphicsShaderD3D12(); 15 | 16 | private: 17 | }; 18 | 19 | class CrComputeShaderD3D12 final : public ICrComputeShader 20 | { 21 | public: 22 | 23 | CrComputeShaderD3D12(ICrRenderDevice* renderDevice, const CrComputeShaderDescriptor& computeShaderDescriptor); 24 | 25 | private: 26 | }; -------------------------------------------------------------------------------- /Source/Rendering/d3d12/CrSwapchain_d3d12.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Rendering/ICrSwapchain.h" 4 | 5 | #include "d3d12.h" 6 | 7 | class CrSwapchainD3D12 final : public ICrSwapchain 8 | { 9 | public: 10 | 11 | CrSwapchainD3D12(ICrRenderDevice* renderDevice, const CrSwapchainDescriptor& swapchainDescriptor); 12 | 13 | ~CrSwapchainD3D12(); 14 | 15 | virtual CrSwapchainResult AcquireNextImagePS(uint64_t timeoutNanoseconds = UINT64_MAX) override; 16 | 17 | virtual void PresentPS() override; 18 | 19 | virtual void ResizePS(uint32_t width, uint32_t height) override; 20 | 21 | private: 22 | 23 | void CreateSwapchainTextures(); 24 | 25 | ID3D12Fence* m_d3d12Fence; 26 | 27 | HANDLE m_fenceEvent; 28 | 29 | crstl::vector m_fenceValues; 30 | 31 | DXGI_SWAP_CHAIN_FLAG m_d3d12SwapchainFlags; 32 | 33 | IDXGISwapChain3* m_d3d12Swapchain; 34 | }; 35 | -------------------------------------------------------------------------------- /Source/Rendering/d3d12/CrTexture_d3d12.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Rendering/ICrTexture.h" 4 | 5 | #include "CrD3D12.h" 6 | 7 | #include "crstl/array.h" 8 | #include "crstl/vector.h" 9 | 10 | class ICrRenderDevice; 11 | 12 | struct CrD3D12AdditionalTextureViews 13 | { 14 | // RTVs 15 | crstl::array, cr3d::MaxMipmaps> m_d3d12RTVSingleMipSlice; // Each mipmap can have a variable amount of slices 16 | crstl::array m_d3d12RTVSingleMipAllSlices; // Each mipmap can see all slices (via SV_RenderTargetArrayIndex) 17 | 18 | // DSVs 19 | crd3d::DescriptorD3D12 m_d3d12DSVSingleMipSlice; 20 | 21 | crd3d::DescriptorD3D12 m_d3d12DSVSingleMipSliceReadOnlyDepth; 22 | 23 | crd3d::DescriptorD3D12 m_d3d12DSVSingleMipSliceReadOnlyStencil; 24 | 25 | // UAVs 26 | crstl::array m_d3d12UAVSingleMipAllSlices; // Each mipmap can see all slices 27 | 28 | D3D12_SHADER_RESOURCE_VIEW_DESC m_d3d12StencilSRVDescriptor; 29 | }; 30 | 31 | class CrTextureD3D12 final : public ICrTexture 32 | { 33 | public: 34 | 35 | CrTextureD3D12(ICrRenderDevice* renderDevice, const CrTextureDescriptor& descriptor); 36 | 37 | ~CrTextureD3D12(); 38 | 39 | crd3d::DescriptorD3D12 GetD3D12RenderTargetView(uint32_t mip, uint32_t slice) const 40 | { 41 | return m_additionalViews->m_d3d12RTVSingleMipSlice[mip][slice]; 42 | } 43 | 44 | crd3d::DescriptorD3D12 GetD3D12DepthStencilView() const 45 | { 46 | return m_additionalViews->m_d3d12DSVSingleMipSlice; 47 | } 48 | 49 | ID3D12Resource* GetD3D12Resource() const { return m_d3d12Resource; } 50 | 51 | D3D12_RESOURCE_STATES GetD3D12DefaultLegacyResourceState() const { return m_d3d12LegacyInitialState; } 52 | 53 | D3D12_BARRIER_LAYOUT GetD3D12DefaultTextureLayout() const { return m_d3d12InitialLayout; } 54 | 55 | const D3D12_SHADER_RESOURCE_VIEW_DESC& GetD3D12SRVDescriptor() const { return m_d3d12SRVDescriptor; } 56 | 57 | const D3D12_SHADER_RESOURCE_VIEW_DESC& GetD3D12StencilSRVDescriptor() const { return m_additionalViews->m_d3d12StencilSRVDescriptor; } 58 | 59 | const D3D12_UNORDERED_ACCESS_VIEW_DESC& GetD3D12UAVDescriptor(uint32_t mip) const { return m_additionalViews->m_d3d12UAVSingleMipAllSlices[mip]; } 60 | 61 | uint32_t GetD3D12SubresourceCount() const { return m_d3d12SubresourceCount; } 62 | 63 | private: 64 | 65 | // Main resource view, can access all mips and slices 66 | D3D12_SHADER_RESOURCE_VIEW_DESC m_d3d12SRVDescriptor; 67 | 68 | crstl::unique_ptr m_additionalViews; 69 | 70 | uint32_t m_d3d12SubresourceCount; 71 | 72 | D3D12_RESOURCE_STATES m_d3d12LegacyInitialState; 73 | D3D12_BARRIER_LAYOUT m_d3d12InitialLayout; 74 | 75 | ID3D12Resource* m_d3d12Resource = nullptr; 76 | }; 77 | -------------------------------------------------------------------------------- /Source/Resource/CrResourceManager.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Core/CrCoreForwardDeclarations.h" 4 | #include "Rendering/CrRenderingForwardDeclarations.h" 5 | #include "Image/CrImageForwardDeclarations.h" 6 | 7 | class CrShader; 8 | 9 | class CrResourceManager 10 | { 11 | public: 12 | 13 | static CrRenderModelHandle LoadModel(const CrFixedPath& filePath); 14 | 15 | static CrFixedPath GetFullResourcePath(const CrFixedPath& relativePath); 16 | 17 | // TODO Also allow image loading to take a data pointer, so we can do the upload directly via the map 18 | static CrImageHandle LoadImageFromDisk(const CrFixedPath& filePath); 19 | 20 | static void SaveImageToDisk(const CrImageHandle& image, const CrFixedPath& fullPath); 21 | }; 22 | -------------------------------------------------------------------------------- /Source/Resource/CrResource_pch.cpp: -------------------------------------------------------------------------------- 1 | #include "Resource/CrResource_pch.h" -------------------------------------------------------------------------------- /Source/Resource/CrResource_pch.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Core/PCH/CrCRSTLPch.h" 4 | #include "Math/CrMathPch.h" -------------------------------------------------------------------------------- /Source/Resource/Image/CrImageCodecDDS.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ICrImageCodec.h" 4 | 5 | namespace ddspp 6 | { 7 | struct Descriptor; 8 | } 9 | 10 | class CrImageDecoderDDS final : public ICrImageDecoder 11 | { 12 | public: 13 | 14 | CrImageDecoderDDS(); 15 | 16 | virtual CrImageHandle Decode(crstl::file& file) const override; 17 | 18 | virtual CrImageHandle Decode(void* data, uint64_t dataSize) const override; 19 | 20 | private: 21 | 22 | void SetImageProperties(CrImageHandle& image, const ddspp::Descriptor& desc) const; 23 | }; 24 | 25 | class CrImageEncoderDDS final : public ICrImageEncoder 26 | { 27 | public: 28 | 29 | CrImageEncoderDDS(); 30 | 31 | virtual void Encode(const CrImageHandle& image, CrWriteFileStream& fileStream) const override; 32 | 33 | virtual void Encode(const CrImageHandle& image, void* data, uint64_t dataSize) const override; 34 | 35 | virtual bool IsImageFormatSupported(cr3d::DataFormat::T format) const override; 36 | 37 | private: 38 | 39 | template 40 | void EncodeInternal(const CrImageHandle& image, StreamT& stream) const; 41 | }; -------------------------------------------------------------------------------- /Source/Resource/Image/CrImageCodecSTB.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ICrImageCodec.h" 4 | #include "Rendering/CrImage.h" 5 | 6 | class CrImageDecoderSTB final : public ICrImageDecoder 7 | { 8 | public: 9 | 10 | virtual CrImageHandle Decode(crstl::file& file) const override; 11 | 12 | virtual CrImageHandle Decode(void* data, uint64_t dataSize) const override; 13 | }; 14 | 15 | class CrImageEncoderSTB final : public ICrImageEncoder 16 | { 17 | public: 18 | 19 | CrImageEncoderSTB(CrImageContainerFormat::T containerFormat); 20 | 21 | virtual void Encode(const CrImageHandle& image, CrWriteFileStream& fileStream) const override; 22 | 23 | virtual void Encode(const CrImageHandle& image, void* data, uint64_t dataSize) const override; 24 | 25 | virtual bool IsImageFormatSupported(cr3d::DataFormat::T format) const override; 26 | }; -------------------------------------------------------------------------------- /Source/Resource/Image/CrImageCodecWuffs.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ICrImageCodec.h" 4 | #include "Rendering/CrImage.h" 5 | 6 | class CrImageDecoderWuffs final : public ICrImageDecoder 7 | { 8 | public: 9 | 10 | virtual CrImageHandle Decode(crstl::file& file) const override; 11 | 12 | virtual CrImageHandle Decode(void* data, uint64_t dataSize) const override; 13 | }; 14 | 15 | class CrImageEncoderWuffs final : public ICrImageEncoder 16 | { 17 | public: 18 | 19 | CrImageEncoderWuffs(CrImageContainerFormat::T containerFormat); 20 | 21 | virtual void Encode(const CrImageHandle& image, CrWriteFileStream& fileStream) const override; 22 | 23 | virtual void Encode(const CrImageHandle& image, void* data, uint64_t dataSize) const override; 24 | 25 | virtual bool IsImageFormatSupported(cr3d::DataFormat::T format) const override; 26 | }; -------------------------------------------------------------------------------- /Source/Resource/Image/CrImageForwardDeclarations.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class CrImage; 4 | using CrImageHandle = crstl::intrusive_ptr; 5 | 6 | namespace CrImageContainerFormat { enum T : uint32_t; }; -------------------------------------------------------------------------------- /Source/Resource/Image/ICrImageCodec.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Rendering/CrRenderingForwardDeclarations.h" 4 | #include "Core/CrCoreForwardDeclarations.h" 5 | #include "Resource/Image/CrImageForwardDeclarations.h" 6 | 7 | #include "Core/Streams/CrFileStream.h" // TODO Delete once crstl is good 8 | 9 | #include 10 | 11 | class ICrImageCodec 12 | { 13 | CrImageContainerFormat::T GetContainerFormat() const { return m_containerFormat; } 14 | 15 | protected: 16 | 17 | CrImageContainerFormat::T m_containerFormat; 18 | }; 19 | 20 | class ICrImageDecoder : public ICrImageCodec 21 | { 22 | public: 23 | 24 | virtual ~ICrImageDecoder() {} 25 | 26 | // Decode image in file 27 | virtual CrImageHandle Decode(crstl::file& file) const = 0; 28 | 29 | // Decode image in provided data 30 | virtual CrImageHandle Decode(void* data, uint64_t dataSize) const = 0; 31 | }; 32 | 33 | class ICrImageEncoder : public ICrImageCodec 34 | { 35 | public: 36 | 37 | virtual ~ICrImageEncoder() {} 38 | 39 | // Encode image to file 40 | virtual void Encode(const CrImageHandle& image, CrWriteFileStream& fileStream) const = 0; 41 | 42 | // Encode image in raw data 43 | virtual void Encode(const CrImageHandle& image, void* data, uint64_t dataSize) const = 0; 44 | 45 | // Query whether this encoder can encode this data format 46 | virtual bool IsImageFormatSupported(cr3d::DataFormat::T format) const = 0; 47 | }; -------------------------------------------------------------------------------- /Source/Resource/Model/CrModelDecoderASSIMP.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ICrModelDecoder.h" 4 | 5 | #include "Rendering/CrRenderingForwardDeclarations.h" 6 | 7 | struct aiScene; 8 | struct aiMesh; 9 | struct aiMaterial; 10 | template class aiMatrix4x4t; 11 | typedef aiMatrix4x4t aiMatrix4x4; 12 | 13 | class CrModelDecoderASSIMP final : public ICrModelDecoder 14 | { 15 | public: 16 | 17 | virtual CrRenderModelHandle Decode(const crstl::file& file) override; 18 | 19 | static CrRenderMeshHandle LoadMesh(const aiScene* scene, const aiMesh* mesh, const aiMatrix4x4& transform); 20 | 21 | static CrMaterialHandle LoadMaterial(const aiMaterial* material, const CrFixedPath& relativePath); 22 | }; -------------------------------------------------------------------------------- /Source/Resource/Model/CrModelDecoderCGLTF.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ICrModelDecoder.h" 4 | #include "Core/CrCoreForwardDeclarations.h" 5 | 6 | class CrModelDecoderCGLTF final : public ICrModelDecoder 7 | { 8 | public: 9 | virtual CrRenderModelHandle Decode(const crstl::file& file) override; 10 | }; -------------------------------------------------------------------------------- /Source/Resource/Model/CrModelDecoderUFBX.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ICrModelDecoder.h" 4 | 5 | #include "Rendering/CrRenderingForwardDeclarations.h" 6 | 7 | class CrModelDecoderUFBX final : public ICrModelDecoder 8 | { 9 | public: 10 | 11 | virtual CrRenderModelHandle Decode(const crstl::file& file) override; 12 | }; -------------------------------------------------------------------------------- /Source/Resource/Model/ICrModelDecoder.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Core/CrCoreForwardDeclarations.h" 4 | #include "Resource/CrResourceManager.h" 5 | 6 | class ICrModelDecoder 7 | { 8 | public: 9 | 10 | virtual ~ICrModelDecoder() {} 11 | 12 | virtual CrRenderModelHandle Decode(const crstl::file& file) = 0; 13 | }; -------------------------------------------------------------------------------- /Visual Studio 2019.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | start /B /W Premake/premake5 --file=corsairengine.lua vs2019 3 | rem cd VSFiles 4 | rem CorsairEngine.sln 5 | echo Build finished succesfully 6 | pause -------------------------------------------------------------------------------- /Visual Studio 2022.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | start /B /W Premake/premake5 --file=corsairengine.lua vs2022 3 | rem cd VSFiles 4 | rem CorsairEngine.sln 5 | echo Build finished succesfully 6 | pause -------------------------------------------------------------------------------- /XCode.command: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | cd "`dirname \"$0\"`" 3 | ./premake/premake5-osx --file=corsairengine.lua xcode4 -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | # version format 2 | version: 1.0.{build} 3 | 4 | # Do not build feature branch with open Pull Requests 5 | skip_branch_with_pr: true 6 | 7 | environment: 8 | matrix: 9 | - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 10 | vsversion: 2017 11 | 12 | build: 13 | parallel: true # enable MSBuild parallel builds 14 | project: "Workspace/vs2017/Corsair Engine.sln" 15 | 16 | install: 17 | - git submodule update --init --recursive 18 | - if %vsversion%==2017 start /B /W premake/premake5 --file=corsairengine.lua vs2017 19 | 20 | platform: 21 | - Vulkan Win64 22 | 23 | #matrix: 24 | # exclude: 25 | # - image: Visual Studio 2015 26 | # platform: MSVC ARM64 27 | 28 | configuration: 29 | - Release 30 | 31 | # Disable automatic tests 32 | test: off -------------------------------------------------------------------------------- /corsair-dependencies.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | --------------------------------------------------------------------------------