diff --git a/.vscode/settings.json b/.vscode/settings.json index dc4ef5c..2691ea7 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -10,7 +10,6 @@ }, "git.ignoreSubmodules": true, "cmake.parallelJobs": 0, - "cmake.buildDirectory": "${workspaceFolder}/build", "C_Cpp.files.exclude": { "**/.vs": true, "**/.vscode": true, @@ -23,7 +22,7 @@ "lldb.showDisassembly": "auto", "lldb.dereferencePointers": true, "lldb.consoleMode": "commands", - "cmake.generator": "Xcode", + "cmake.generator": "Ninja", "editor.tabSize": 4, "slang.additionalSearchPaths": [ "res/shaders/", diff --git a/CMakeLists.txt b/CMakeLists.txt index f1e4683..0dbea35 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -23,7 +23,7 @@ set(CMAKE_TOOLCHAIN_FILE ${EXTERNAL_ROOT}/vcpkg/scripts/buildsystems/vcpkg.cmake set(CRCPP_ROOT ${EXTERNAL_ROOT}/CRCpp) set(METAL_ROOT ${EXTERNAL_ROOT}/metal-cpp) if(WIN32) - set(VCPKG_BASE_FOLDER ${VCPKG_INSTALLED_DIR}/x64-windows/) + set(VCPKG_BASE_FOLDER ${CMAKE_BINARY_DIR}/vcpkg_installed/x64-windows/) elseif(APPLE) set(VCPKG_BASE_FOLDER ${CMAKE_CURRENT_SOURCE_DIR}/build/vcpkg_installed/arm64-osx/) endif() @@ -34,18 +34,6 @@ project (Seele) include(cmake/SuperBuild.cmake) -set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/build) -set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/build) -#Workaround for vs, because it places artifacts into an additional subfolder -set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${CMAKE_CURRENT_SOURCE_DIR}/build) -set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${CMAKE_CURRENT_SOURCE_DIR}/build) -set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELWITHDEBINFO ${CMAKE_CURRENT_SOURCE_DIR}/build) -set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_MINSIZEREL ${CMAKE_CURRENT_SOURCE_DIR}/build) -set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_CURRENT_SOURCE_DIR}/build) -set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_CURRENT_SOURCE_DIR}/build) -set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO ${CMAKE_CURRENT_SOURCE_DIR}/build) -set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_MINSIZEREL ${CMAKE_CURRENT_SOURCE_DIR}/build) - find_package(Vulkan REQUIRED) find_package(assimp CONFIG REQUIRED) find_package(Stb REQUIRED) @@ -57,7 +45,7 @@ find_package(glm CONFIG REQUIRED) find_package(Ktx CONFIG REQUIRED) find_package(nlohmann_json CONFIG REQUIRED) find_package(fmt CONFIG REQUIRED) -find_package(unofficial-lunasvg CONFIG REQUIRED) +find_package(lunasvg CONFIG REQUIRED) find_package(VulkanMemoryAllocator CONFIG REQUIRED) if(UNIX) @@ -85,7 +73,7 @@ target_link_libraries(Engine PUBLIC KTX::ktx) target_link_libraries(Engine PUBLIC nlohmann_json::nlohmann_json) target_link_libraries(Engine PUBLIC crcpp) target_link_libraries(Engine PUBLIC fmt::fmt) -target_link_libraries(Engine PUBLIC unofficial::lunasvg::lunasvg) +target_link_libraries(Engine PUBLIC lunasvg::lunasvg) target_link_libraries(Engine PUBLIC GPUOpen::VulkanMemoryAllocator) if(WIN32) target_link_libraries(Engine PUBLIC ${VCPKG_BASE_FOLDER}/lib/slang.lib) diff --git a/CMakeSettings.json b/CMakeSettings.json index 6f611fc..a95c7d1 100644 --- a/CMakeSettings.json +++ b/CMakeSettings.json @@ -1,65 +1,65 @@ { - "configurations": [ - { - "name": "Debug", - "buildCommandArgs": "", - "ctestCommandArgs": "", - "configurationType": "Debug", - "generator": "Ninja", - "intelliSenseMode": "windows-msvc-x64", - "inheritEnvironments": [ "msvc_x64" ], - "cmakeCommandArgs": "-DCMAKE_DEBUG_POSTFIX=\"\" -DCMAKE_PLATFORM=x64", - "buildRoot": "${workspaceRoot}/build", - "installRoot": "C:/Program Files/Seele" - }, - { - "name": "Release", - "generator": "Ninja", - "configurationType": "Release", - "buildRoot": "${workspaceRoot}/build", - "cmakeCommandArgs": "-DCMAKE_DEBUG_POSTFIX=\"\" -DCMAKE_PLATFORM=x64", - "buildCommandArgs": "", - "ctestCommandArgs": "", - "inheritEnvironments": [ "msvc_x64" ], - "intelliSenseMode": "windows-msvc-x64", - "installRoot": "C:/Program Files/Seele" - }, - { - "name": "RelWithDebInfo", - "generator": "Ninja", - "configurationType": "RelWithDebInfo", - "buildRoot": "${workspaceRoot}/build", - "installRoot": "C:/Program Files/Seele", - "cmakeCommandArgs": "-DCMAKE_DEBUG_POSTFIX=\"\" -DCMAKE_PLATFORM=x64", - "buildCommandArgs": "", - "ctestCommandArgs": "", - "inheritEnvironments": [ "msvc_x64" ], - "intelliSenseMode": "windows-msvc-x64" - }, - { - "name": "AddressSanitizer", - "buildCommandArgs": "", - "ctestCommandArgs": "", - "configurationType": "Debug", - "generator": "Ninja", - "intelliSenseMode": "windows-msvc-x64", - "inheritEnvironments": [ "msvc_x64" ], - "cmakeCommandArgs": "-DCMAKE_DEBUG_POSTFIX=\"\" -DCMAKE_PLATFORM=x64", - "buildRoot": "${workspaceRoot}/build", - "installRoot": "C:/Program Files/Seele", - "addressSanitizerEnabled": true - }, - { - "name": "MinSizeRel", - "generator": "Ninja", - "configurationType": "MinSizeRel", - "buildRoot": "${workspaceRoot}/build", - "installRoot": "C:/Program Files/Seele", - "cmakeCommandArgs": "-DCMAKE_DEBUG_POSTFIX=\"\" -DCMAKE_PLATFORM=x64", - "buildCommandArgs": "", - "ctestCommandArgs": "", - "inheritEnvironments": [ "msvc_x64" ], - "intelliSenseMode": "windows-msvc-x64" - } - ] + "configurations": [ + { + "name": "Debug", + "buildCommandArgs": "", + "ctestCommandArgs": "", + "configurationType": "Debug", + "generator": "Ninja", + "intelliSenseMode": "windows-msvc-x64", + "inheritEnvironments": [ "msvc_x64" ], + "cmakeCommandArgs": "-DCMAKE_DEBUG_POSTFIX=\"\" -DCMAKE_PLATFORM=x64", + "buildRoot": "${workspaceRoot}/build", + "installRoot": "C:/Program Files/Seele" + }, + { + "name": "Release", + "generator": "Ninja Multi-Config", + "configurationType": "Release", + "buildRoot": "${workspaceRoot}/build/", + "cmakeCommandArgs": "-DCMAKE_DEBUG_POSTFIX=\"\" -DCMAKE_PLATFORM=x64", + "buildCommandArgs": "", + "ctestCommandArgs": "", + "inheritEnvironments": [ "msvc_x64" ], + "intelliSenseMode": "windows-msvc-x64", + "installRoot": "C:/Program Files/Seele" + }, + { + "name": "RelWithDebInfo", + "generator": "Ninja", + "configurationType": "RelWithDebInfo", + "buildRoot": "${workspaceRoot}/build", + "installRoot": "C:/Program Files/Seele", + "cmakeCommandArgs": "-DCMAKE_DEBUG_POSTFIX=\"\" -DCMAKE_PLATFORM=x64", + "buildCommandArgs": "", + "ctestCommandArgs": "", + "inheritEnvironments": [ "msvc_x64" ], + "intelliSenseMode": "windows-msvc-x64" + }, + { + "name": "AddressSanitizer", + "buildCommandArgs": "", + "ctestCommandArgs": "", + "configurationType": "Debug", + "generator": "Ninja Multi-Config", + "intelliSenseMode": "windows-msvc-x64", + "inheritEnvironments": [ "msvc_x64" ], + "cmakeCommandArgs": "-DCMAKE_DEBUG_POSTFIX=\"\" -DCMAKE_PLATFORM=x64", + "buildRoot": "${workspaceRoot}/build", + "installRoot": "C:/Program Files/Seele", + "addressSanitizerEnabled": true + }, + { + "name": "MinSizeRel", + "generator": "Ninja Multi-Config", + "configurationType": "MinSizeRel", + "buildRoot": "${workspaceRoot}/build", + "installRoot": "C:/Program Files/Seele", + "cmakeCommandArgs": "-DCMAKE_DEBUG_POSTFIX=\"\" -DCMAKE_PLATFORM=x64", + "buildCommandArgs": "", + "ctestCommandArgs": "", + "inheritEnvironments": [ "msvc_x64" ], + "intelliSenseMode": "windows-msvc-x64" + } + ] } \ No newline at end of file diff --git a/WRITEUP.md b/WRITEUP.md index c4a01f4..7d88c34 100644 --- a/WRITEUP.md +++ b/WRITEUP.md @@ -146,7 +146,6 @@ Here is the material generated from the above JSON example: ```cpp import VERTEX_INPUT_IMPORT; import Material; -import BRDF; import MaterialParameter; struct Placeholder: IMaterial { diff --git a/external/vcpkg b/external/vcpkg index ab42fb3..f9a99aa 160000 --- a/external/vcpkg +++ b/external/vcpkg @@ -1 +1 @@ -Subproject commit ab42fb3032acd29dd12cea7897f85025526a60e6 +Subproject commit f9a99aa79c1309001e36572fa42d7d8edebfc451 diff --git a/res/shaders/BasePass.slang b/res/shaders/BasePass.slang index 3c7d1b1..9c7b74a 100644 --- a/res/shaders/BasePass.slang +++ b/res/shaders/BasePass.slang @@ -30,6 +30,6 @@ float4 fragmentMain(in FragmentParameter params) : SV_Target uint lightIndex = pLightCullingData.lightIndexList[startOffset + i]; result += pLightEnv.pointLights[lightIndex].illuminate(lightingParams, brdf); } - result += brdf.evaluateAmbient(); + result += brdf.evaluateAmbient(lightingParams.viewDir_WS); return float4(result, brdf.getAlpha()); } \ No newline at end of file diff --git a/res/shaders/EnvironmentMapping.slang b/res/shaders/EnvironmentMapping.slang new file mode 100644 index 0000000..3545fc6 --- /dev/null +++ b/res/shaders/EnvironmentMapping.slang @@ -0,0 +1,125 @@ +const static float3 vertices[] = { + // Right + float3( 1, -1, 1), + float3( 1, 1, 1), + float3( 1, -1, -1), + + float3( 1, -1, -1), + float3( 1, 1, 1), + float3( 1, 1, -1), + + // Left + float3(-1, -1, -1), + float3(-1, 1, -1), + float3(-1, -1, 1), + + float3(-1, -1, 1), + float3(-1, 1, -1), + float3(-1, 1, 1), + + // Bottom + float3(-1, 1, 1), + float3(-1, 1, -1), + float3( 1, 1, 1), + + float3( 1, 1, 1), + float3(-1, 1, -1), + float3( 1, 1, -1), + + // Top + float3(-1, -1, -1), + float3(-1, -1, 1), + float3( 1, -1, -1), + + float3( 1, -1, -1), + float3(-1, -1, 1), + float3( 1, -1, 1), + + // Back + float3(-1, -1, 1), + float3(-1, 1, 1), + float3( 1, -1, 1), + + float3( 1, -1, 1), + float3(-1, 1, 1), + float3( 1, 1, 1), + + // Front + float3( 1, -1, -1), + float3( 1, 1, -1), + float3(-1, -1, -1), + + float3(-1, -1, -1), + float3( 1, 1, -1), + float3(-1, 1, -1), +}; + +struct ViewParams +{ + float4x4 view[6]; + float4x4 projection; + Texture2D equirectangularMap; + SamplerState sampler; + TextureCube cubeMap; +}; +ParameterBlock pViewParams; +struct VertexOutput +{ + float4 svPos : SV_Position; + float3 localPos : LOCALPOS; +}; +[shader("vertex")] +VertexOutput vertMain(uint vertexIndex : SV_VertexID, uint viewIndex : SV_ViewID) +{ + VertexOutput output; + output.localPos = vertices[vertexIndex]; + output.svPos = mul(pViewParams.projection, mul(pViewParams.view[viewIndex], float4(output.localPos, 1))); + return output; +} + +const static float2 invAtan = float2(0.1591, 0.3183); +float2 sampleSphericalMap(float3 v) +{ + float2 uv = float2(atan2(v.z, v.x), asin(v.y)); + uv *= invAtan; + uv += 0.5; + return uv; +} + +[shader("pixel")] +float4 computeCubemap(float3 localPos : LOCALPOS) : SV_Target +{ + float2 uv = sampleSphericalMap(normalize(localPos)); + float3 color = pViewParams.equirectangularMap.Sample(pViewParams.sampler, uv).rgb; + return float4(color, 1); +} + +static const float PI = 3.14159265359; +[shader("pixel")] +float4 convolveCubemap(float3 localPos : LOCALPOS) : SV_Target +{ + float3 normal = normalize(localPos); + + float3 irradiance = float3(0); + + float3 up = float3(0, 1, 0); + float3 right = normalize(cross(up, normal)); + up = normalize(cross(normal, right)); + + float sampleDelta = 0.025; + float nrSamples = 0.0f; + for(float phi = 0; phi < 2.0 * PI; phi += sampleDelta) + { + for(float theta = 0; theta < 0.5 * PI; theta += sampleDelta) + { + float3 tangentSample = float3(sin(theta) * cos(phi), sin(theta) * sin(phi), cos(theta)); + float3 sampleVec = tangentSample.x * right + tangentSample.y * up + tangentSample.z * normal; + + irradiance += pViewParams.cubeMap.Sample(pViewParams.sampler, sampleVec).rgb * cos(theta) * sin(theta); + nrSamples++; + } + } + irradiance = PI * irradiance * (1.0 / nrSamples); + + return float4(irradiance, 1); +} \ No newline at end of file diff --git a/res/shaders/Placeholder.json b/res/shaders/Placeholder.json new file mode 100644 index 0000000..08d2e12 --- /dev/null +++ b/res/shaders/Placeholder.json @@ -0,0 +1,15 @@ +{ + "name": "Placeholder", + "params": { + }, + "code": [ + { + "exp": "BRDF", + "profile": "BlinnPhong", + "values": { + "baseColor": "float3(0, 1, 0)", + "normal": "float3(0, 0, 1)" + } + } + ] +} \ No newline at end of file diff --git a/res/shaders/Skybox.slang b/res/shaders/Skybox.slang index def3e3a..ff07380 100644 --- a/res/shaders/Skybox.slang +++ b/res/shaders/Skybox.slang @@ -12,66 +12,66 @@ struct SkyboxData }; ParameterBlock pSkyboxData; +const static float3 vertices[] = { + // Back + float3(-512, -512, 512), + float3(-512, 512, 512), + float3( 512, -512, 512), + + float3( 512, -512, 512), + float3(-512, 512, 512), + float3( 512, 512, 512), + + // Front + float3( 512, -512, -512), + float3( 512, 512, -512), + float3(-512, -512, -512), + + float3(-512, -512, -512), + float3( 512, 512, -512), + float3(-512, 512, -512), + + // Top + float3(-512, -512, -512), + float3(-512, -512, 512), + float3( 512, -512, -512), + + float3( 512, -512, -512), + float3(-512, -512, 512), + float3( 512, -512, 512), + + // Bottom + float3(-512, 512, 512), + float3(-512, 512, -512), + float3( 512, 512, 512), + + float3( 512, 512, 512), + float3(-512, 512, -512), + float3( 512, 512, -512), + + // Left + float3(-512, -512, -512), + float3(-512, 512, -512), + float3(-512, -512, 512), + + float3(-512, -512, 512), + float3(-512, 512, -512), + float3(-512, 512, 512), + + // Right + float3( 512, -512, 512), + float3( 512, 512, 512), + float3( 512, -512, -512), + + float3( 512, -512, -512), + float3( 512, 512, 512), + float3( 512, 512, -512), +}; + [shader("vertex")] VertexShaderOutput vertexMain( uint vertexIndex : SV_VertexId) { - const float3 vertices[] = { - // Back - float3(-512, -512, 512), - float3(-512, 512, 512), - float3( 512, -512, 512), - - float3( 512, -512, 512), - float3(-512, 512, 512), - float3( 512, 512, 512), - - // Front - float3( 512, -512, -512), - float3( 512, 512, -512), - float3(-512, -512, -512), - - float3(-512, -512, -512), - float3( 512, 512, -512), - float3(-512, 512, -512), - - // Top - float3(-512, -512, -512), - float3(-512, -512, 512), - float3( 512, -512, -512), - - float3( 512, -512, -512), - float3(-512, -512, 512), - float3( 512, -512, 512), - - // Bottom - float3(-512, 512, 512), - float3(-512, 512, -512), - float3( 512, 512, 512), - - float3( 512, 512, 512), - float3(-512, 512, -512), - float3( 512, 512, -512), - - // Left - float3(-512, -512, -512), - float3(-512, 512, -512), - float3(-512, -512, 512), - - float3(-512, -512, 512), - float3(-512, 512, -512), - float3(-512, 512, 512), - - // Right - float3( 512, -512, 512), - float3( 512, 512, 512), - float3( 512, -512, -512), - - float3( 512, -512, -512), - float3( 512, 512, 512), - float3( 512, 512, -512), - }; - VertexShaderOutput output; float3x3 cameraRotation = float3x3(pViewParams.viewMatrix); float4 worldPos = float4(mul(cameraRotation, vertices[vertexIndex]), 1.0f); @@ -101,5 +101,5 @@ float4 fragmentMain( float factor = (output.texCoords.y - lowerLimit) / (upperLimit - lowerLimit); factor = clamp(factor, 0.0, 1.0); - return lerp(float4(pSkyboxData.fogBlend.xyz, 1), finalColor, factor) * 100; + return lerp(float4(pSkyboxData.fogBlend.xyz, 1), finalColor, factor); } \ No newline at end of file diff --git a/res/shaders/TextPass.slang b/res/shaders/TextPass.slang index a3144b0..cd2642f 100644 --- a/res/shaders/TextPass.slang +++ b/res/shaders/TextPass.slang @@ -1,23 +1,5 @@ import Common; -struct GlyphInstanceData -{ - float x; - float y; - float z; - float width; - float height; - uint glyphIndex; -}; - -struct TextData -{ - StructuredBuffer glyphs; - SamplerState glyphSampler; - Texture2D glyphTextures[]; -}; -ParameterBlock pText; - struct VertexInput { uint vertexId : SV_VertexID; @@ -31,6 +13,24 @@ struct VertexOutput uint glyphIndex : GLYPHINDEX; }; +struct GlyphInstanceData +{ + float x; + float y; + float z; + float width; + float height; + uint glyphIndex; +}; +struct TextData +{ + StructuredBuffer glyphs; + SamplerState glyphSampler; + Texture2D glyphTextures[]; +}; +ParameterBlock pText; + + [shader("vertex")] VertexOutput vertexMain(VertexInput input) { diff --git a/res/shaders/ToneMapping.slang b/res/shaders/ToneMapping.slang index 3608110..b4dd02a 100644 --- a/res/shaders/ToneMapping.slang +++ b/res/shaders/ToneMapping.slang @@ -109,7 +109,7 @@ float4 toneMapping(float2 uv : UV) : SV_Target { float3 hdrValue = pToneMappingParams.hdrInputTexture.Sample(pToneMappingParams.hdrSampler, uv).rgb; - float3 value = agx(hdrValue / 1000); + float3 value = agx(hdrValue); value = agxLook(value); value = agxEotf(value); diff --git a/res/shaders/lib/BRDF.slang b/res/shaders/lib/BRDF.slang deleted file mode 100644 index 612496d..0000000 --- a/res/shaders/lib/BRDF.slang +++ /dev/null @@ -1,291 +0,0 @@ -import Common; - -interface IBRDF -{ - float3 evaluate(float3 viewDir_WS, float3 lightDir_WS, float3 lightColor); - [mutating] void transformNormal(float3x3 tangentToWorld); - float3 getNormal(); - float3 getBaseColor(); - float3 evaluateAmbient(); - float getAlpha(); - float3 getEmissive(); -}; - -struct Phong : IBRDF -{ - float3 baseColor; - float alpha; - float3 specular; - float3 normal; - float3 ambient; - float shininess; - float3 emissive; - - __init() - { - baseColor = float3(0, 0, 0); - alpha = 1; - specular = float3(0, 0, 0); - normal = float3(0, 0, 1); - ambient = float3(0, 0, 0); - shininess = 0; - emissive = float3(0, 0, 0); - } - - float3 evaluate(float3 viewDir_WS, float3 lightDir_WS, float3 lightColor) - { - float3 normal_WS = normal; - float3 nDotL = dot(normal_WS, lightDir_WS); - float3 r = 2 * (nDotL) * normal_WS - lightDir_WS; - float rDotV = dot(r, viewDir_WS); - - return lightColor * (baseColor * max(nDotL, 0.0)) + specular * pow(max(rDotV, 0.0), max(shininess, 1)); - } - [mutating] - void transformNormal(float3x3 tangentToWorld) - { - normal = normalize(mul(tangentToWorld, normal)); - } - float3 getNormal() - { - return normal; - } - float3 getBaseColor() - { - return baseColor; - } - float3 evaluateAmbient() - { - return ambient; - } - float getAlpha() - { - return alpha; - } - float3 getEmissive() - { - return emissive; - } -}; - -struct BlinnPhong : IBRDF -{ - float3 baseColor; - float alpha; - float3 specularColor; - float3 normal; - float shininess; - float3 ambient; - float3 emissive; - - __init() - { - baseColor = float3(0, 0, 0); - alpha = 1; - specularColor = float3(0, 0, 0); - normal = float3(0, 0, 1); - shininess = 4; - ambient = float3(0, 0, 0); - emissive = float3(0, 0, 0); - } - - float3 evaluate(float3 viewDir_WS, float3 lightDir_WS, float3 lightColor) - { - float3 normal_WS = normal; - float diffuse = max(dot(normal_WS, lightDir_WS), 0); - float3 h = normalize(lightDir_WS + viewDir_WS); - float specular = pow(saturate(dot(normal_WS, h)), shininess); - - return (baseColor * diffuse * lightColor) + (specularColor * specular); - } - [mutating] - void transformNormal(float3x3 tangentToWorld) - { - normal = normalize(mul(tangentToWorld, normal)); - } - float3 getNormal() - { - return normal; - } - float3 getBaseColor() - { - return baseColor; - } - float3 evaluateAmbient() - { - return ambient; - } - float getAlpha() - { - return alpha; - } - float3 getEmissive() - { - return emissive; - } -}; - -struct CelShading : IBRDF -{ - float3 baseColor; - float alpha; - float3 normal; - float3 emissive; - - __init() - { - baseColor = float3(0, 0, 0); - alpha = 1; - normal = float3(0, 0, 1); - emissive = float3(0, 0, 0); - } - float3 evaluate(float3 viewDir_WS, float3 lightDir_WS, float3 lightColor) - { - float3 normal_WS = normal; - float nDotL = dot(normal_WS, lightDir_WS); - float diffuse = max(nDotL, 0); - - float3 darkenedBase = baseColor * 0.8; - if(diffuse > 0.5) - { - return baseColor * lightColor; - } - else - { - return darkenedBase * lightColor; - } - } - [mutating] - void transformNormal(float3x3 tangentToWorld) - { - normal = normalize(mul(tangentToWorld, normal)); - } - float3 getNormal() - { - return normal; - } - float3 getBaseColor() - { - return baseColor; - } - float3 evaluateAmbient() - { - return float3(0, 0, 0); - } - float getAlpha() - { - return alpha; - } - float3 getEmissive() - { - return emissive; - } -}; - -// https://learnopengl.com/PBR/Theory -struct CookTorrance : IBRDF -{ - float3 baseColor; - float alpha; - float3 normal; - float roughness; - float metallic; - float ambientOcclusion; - float3 emissive; - - __init() - { - baseColor = float3(0, 0, 0); - alpha = 1; - normal = float3(0, 0, 1); - roughness = 0; - metallic = 0; - ambientOcclusion = 1; - emissive = float3(0, 0, 0); - } - - float TrowbridgeReitzGGX(float3 normal, float3 halfway) - { - float a_sqr = roughness * roughness; - float nDotH = max(dot(normal, halfway), 0.0); - float nDotH_sqr = nDotH * nDotH; - - float denom = (nDotH_sqr * (a_sqr - 1.0) + 1.0); - - return a_sqr / (PI * denom * denom); - } - - float SchlickGGX(float nDotV, float k) - { - return nDotV / (nDotV * (1.0 - k) + k); - } - - float Smith(float3 normal, float3 view, float3 light) - { - float k = (roughness + 1); - k = (k * k) / 8; - float nDotV = max(dot(normal, view), 0.0); - float nDotL = max(dot(normal, light), 0.0); - float ggx1 = SchlickGGX(nDotV, k); - float ggx2 = SchlickGGX(nDotL, k); - return ggx1 * ggx2; - } - - float3 FresnelSchlick(float cosTheta, float3 F0) - { - return F0 + (1.0 - F0) * pow(clamp(1.0 - cosTheta, 0.0, 1.0), 5.0); - } - - float3 evaluate(float3 viewDir_WS, float3 lightDir_WS, float3 lightColor) - { - float3 n = normal; - float3 h = normalize(lightDir_WS + viewDir_WS); - - float3 F0 = float3(0.04); - F0 = lerp(F0, baseColor, metallic); - - float3 F = FresnelSchlick(max(dot(h, viewDir_WS), 0.0), F0); - - float NDF = TrowbridgeReitzGGX(n, h); - float G = Smith(n, viewDir_WS, lightDir_WS); - - float3 num = NDF * G * F; - float denom = 4.0 * max(dot(n, viewDir_WS), 0.0) * max(dot(n, lightDir_WS), 0.0) + 0.000001; - float3 specular = num / denom; - - float3 k_s = F; - float3 k_d = float3(1.0) - k_s; - - k_d *= 1.0 - metallic; - - float nDotL = max(dot(n, lightDir_WS), 0.0); - - float3 result = (k_d * baseColor / PI + specular) * nDotL * lightColor; - return result * ambientOcclusion; - } - [mutating] - void transformNormal(float3x3 tangentToWorld) - { - normal = normalize(mul(tangentToWorld, normal)); - } - float3 getNormal() - { - return normal; - } - float3 getBaseColor() - { - return baseColor; - } - float3 evaluateAmbient() - { - return float3(0.03) * baseColor * ambientOcclusion; - } - float getAlpha() - { - return alpha; - } - float3 getEmissive() - { - return emissive; - } -}; diff --git a/res/shaders/lib/LightEnv.slang b/res/shaders/lib/LightEnv.slang index 393987c..dd8fd7d 100644 --- a/res/shaders/lib/LightEnv.slang +++ b/res/shaders/lib/LightEnv.slang @@ -1,5 +1,4 @@ import Common; -import BRDF; import MaterialParameter; interface ILightEnv @@ -28,7 +27,7 @@ struct PointLight : ILightEnv { float3 lightDir_WS = position_WS.xyz - params.position_WS; float d = length(lightDir_WS); - float illuminance = max(1 - d / colorRange.w, 0); + float illuminance = max(1 / (d * d), 0); return illuminance * brdf.evaluate(params.viewDir_WS, normalize(lightDir_WS), colorRange.xyz * position_WS.w); } @@ -65,6 +64,312 @@ struct LightEnv uint numDirectionalLights; StructuredBuffer pointLights; uint numPointLights; + TextureCube irradianceMap; + SamplerState irradianceSampler; }; layout(set=3) ParameterBlock pLightEnv; + +[Differentiable] +float polynomial(float a, float b, float c, float x) { + return a * x * x + b * x + c; +} + +interface IBRDF +{ + float3 evaluate(float3 viewDir_WS, float3 lightDir_WS, float3 lightColor); + [mutating] void transformNormal(float3x3 tangentToWorld); + float3 getNormal(); + float3 getBaseColor(); + float3 evaluateAmbient(float3 viewDir_WS); + float getAlpha(); + float3 getEmissive(); +}; + +struct Phong : IBRDF +{ + float3 baseColor; + float alpha; + float3 specular; + float3 normal; + float3 ambient; + float shininess; + float3 emissive; + + __init() + { + baseColor = float3(0, 0, 0); + alpha = 1; + specular = float3(0, 0, 0); + normal = float3(0, 0, 1); + ambient = float3(0, 0, 0); + shininess = 0; + emissive = float3(0, 0, 0); + } + + float3 evaluate(float3 viewDir_WS, float3 lightDir_WS, float3 lightColor) + { + float3 normal_WS = normal; + float3 nDotL = dot(normal_WS, lightDir_WS); + float3 r = 2 * (nDotL) * normal_WS - lightDir_WS; + float rDotV = dot(r, viewDir_WS); + + return lightColor * (baseColor * max(nDotL, 0.0)) + specular * pow(max(rDotV, 0.0), max(shininess, 1)); + } + [mutating] + void transformNormal(float3x3 tangentToWorld) + { + normal = normalize(mul(tangentToWorld, normal)); + } + float3 getNormal() + { + return normal; + } + float3 getBaseColor() + { + return baseColor; + } + float3 evaluateAmbient(float3 viewDir_WS) + { + return ambient; + } + float getAlpha() + { + return alpha; + } + float3 getEmissive() + { + return emissive; + } +}; + +struct BlinnPhong : IBRDF +{ + float3 baseColor; + float alpha; + float3 specularColor; + float3 normal; + float shininess; + float3 ambient; + float3 emissive; + + __init() + { + baseColor = float3(0, 0, 0); + alpha = 1; + specularColor = float3(0, 0, 0); + normal = float3(0, 0, 1); + shininess = 4; + ambient = float3(0, 0, 0); + emissive = float3(0, 0, 0); + } + + float3 evaluate(float3 viewDir_WS, float3 lightDir_WS, float3 lightColor) + { + float3 normal_WS = normal; + float diffuse = max(dot(normal_WS, lightDir_WS), 0); + float3 h = normalize(lightDir_WS + viewDir_WS); + float specular = pow(saturate(dot(normal_WS, h)), shininess); + + return (baseColor * diffuse * lightColor) + (specularColor * specular); + } + [mutating] + void transformNormal(float3x3 tangentToWorld) + { + normal = normalize(mul(tangentToWorld, normal)); + } + float3 getNormal() + { + return normal; + } + float3 getBaseColor() + { + return baseColor; + } + float3 evaluateAmbient(float3 viewDir_WS) + { + return ambient; + } + float getAlpha() + { + return alpha; + } + float3 getEmissive() + { + return emissive; + } +}; + +struct CelShading : IBRDF +{ + float3 baseColor; + float alpha; + float3 normal; + float3 emissive; + + __init() + { + baseColor = float3(0, 0, 0); + alpha = 1; + normal = float3(0, 0, 1); + emissive = float3(0, 0, 0); + } + float3 evaluate(float3 viewDir_WS, float3 lightDir_WS, float3 lightColor) + { + float3 normal_WS = normal; + float nDotL = dot(normal_WS, lightDir_WS); + float diffuse = max(nDotL, 0); + + float3 darkenedBase = baseColor * 0.8; + if(diffuse > 0.5) + { + return baseColor * lightColor; + } + else + { + return darkenedBase * lightColor; + } + } + [mutating] + void transformNormal(float3x3 tangentToWorld) + { + normal = normalize(mul(tangentToWorld, normal)); + } + float3 getNormal() + { + return normal; + } + float3 getBaseColor() + { + return baseColor; + } + float3 evaluateAmbient(float3 viewDir_WS) + { + return float3(0, 0, 0); + } + float getAlpha() + { + return alpha; + } + float3 getEmissive() + { + return emissive; + } +}; + +// https://learnopengl.com/PBR/Theory +struct CookTorrance : IBRDF +{ + float3 baseColor; + float alpha; + float3 normal; + float roughness; + float metallic; + float ambientOcclusion; + float3 emissive; + + __init() + { + baseColor = float3(0, 0, 0); + alpha = 1; + normal = float3(0, 0, 1); + roughness = 0; + metallic = 0; + ambientOcclusion = 1; + emissive = float3(0, 0, 0); + } + + float TrowbridgeReitzGGX(float3 normal, float3 halfway) + { + float a = roughness * roughness; + float a2 = a * a; + float nDotH = max(dot(normal, halfway), 0.0); + float nDotH2 = nDotH * nDotH; + + float nom = a2; + float denom = (nDotH * (a2 - 1.0) + 1.0); + + return nom / (PI * denom * denom); + } + + float SchlickGGX(float nDotV, float k) + { + return nDotV / (nDotV * (1.0 - k) + k); + } + + float Smith(float3 normal, float3 view, float3 light) + { + float k = (roughness + 1); + k = (k * k) / 8; + float nDotV = max(dot(normal, view), 0.0); + float nDotL = max(dot(normal, light), 0.0); + float ggx1 = SchlickGGX(nDotV, k); + float ggx2 = SchlickGGX(nDotL, k); + return ggx1 * ggx2; + } + + float3 FresnelSchlick(float cosTheta, float3 F0) + { + return F0 + (1.0 - F0) * pow(clamp(1.0 - cosTheta, 0.0, 1.0), 5.0); + } + + float3 evaluate(float3 viewDir_WS, float3 lightDir_WS, float3 lightColor) + { + float3 n = normal; + float3 h = normalize(lightDir_WS + viewDir_WS); + + float3 F0 = float3(0.04); + F0 = lerp(F0, baseColor, metallic); + + float NDF = TrowbridgeReitzGGX(n, h); + float G = Smith(n, viewDir_WS, lightDir_WS); + float3 F = FresnelSchlick(max(dot(h, viewDir_WS), 0.0), F0); + + float3 num = NDF * G * F; + float denom = 4.0 * max(dot(n, viewDir_WS), 0.0) * max(dot(n, lightDir_WS), 0.0) + 0.000001; + float3 specular = num / denom; + + float3 k_s = F; + float3 k_d = float3(1.0) - k_s; + + k_d *= 1.0 - metallic; + + float nDotL = max(dot(n, lightDir_WS), 0.0); + + float3 result = (k_d * baseColor / PI + specular) * nDotL * lightColor; + return result; + } + [mutating] + void transformNormal(float3x3 tangentToWorld) + { + normal = normalize(mul(tangentToWorld, normal)); + } + float3 getNormal() + { + return normal; + } + float3 getBaseColor() + { + return baseColor; + } + float3 evaluateAmbient(float3 viewDir_WS) + { + float3 F0 = float3(0.04); + F0 = lerp(F0, baseColor, metallic); + float3 k_s = FresnelSchlick(max(dot(normal, viewDir_WS), 0.0), F0); + float3 k_d = 1 - k_s; + k_d *= 1 - metallic; + float3 irradiance = pLightEnv.irradianceMap.Sample(pLightEnv.irradianceSampler, normal).rgb; + float3 diffuse = irradiance * baseColor; + return (k_d * diffuse) * ambientOcclusion; + } + float getAlpha() + { + return alpha; + } + float3 getEmissive() + { + return emissive; + } +}; + diff --git a/res/shaders/lib/Material.slang b/res/shaders/lib/Material.slang index a3bcd2e..6669f0a 100644 --- a/res/shaders/lib/Material.slang +++ b/res/shaders/lib/Material.slang @@ -1,5 +1,4 @@ import Common; -import BRDF; import MaterialParameter; import Scene; diff --git a/res/shaders/lib/StaticMeshVertexData.slang b/res/shaders/lib/StaticMeshVertexData.slang index f597dc3..eee80af 100644 --- a/res/shaders/lib/StaticMeshVertexData.slang +++ b/res/shaders/lib/StaticMeshVertexData.slang @@ -16,8 +16,9 @@ struct StaticMeshVertexData #ifndef POS_ONLY //attributes.qTangent = qTangent[index]; attributes.normal_MS = float3(normals[index * 3 + 0], normals[index * 3 + 1], normals[index * 3 + 2]); - attributes.tangent_MS = float3(tangents[index * 3 + 0], tangents[index * 3 + 1], tangents[index * 3 + 2]); - attributes.biTangent_MS = float3(biTangents[index * 3 + 0], biTangents[index * 3 + 1], biTangents[index * 3 + 2]); + float4 tangentSign = float4(tangents[index * 4 + 0], tangents[index * 4 + 1], tangents[index * 4 + 2], tangents[index * 4 + 3]); + attributes.tangent_MS = tangentSign.xyz; + attributes.biTangent_MS = cross(attributes.normal_MS, attributes.tangent_MS) * -tangentSign.w; for(uint i = 0; i < MAX_TEXCOORDS; ++i) { attributes.texCoords[i] = float2(uint16ToFloat(texCoords[i][index * 2 + 0]), uint16ToFloat(texCoords[i][index * 2 + 1])); @@ -27,9 +28,9 @@ struct StaticMeshVertexData return attributes; } StructuredBuffer positions; + //StructuredBuffer qTangents; StructuredBuffer normals; StructuredBuffer tangents; - StructuredBuffer biTangents; StructuredBuffer color; StructuredBuffer texCoords[MAX_TEXCOORDS]; }; diff --git a/res/shaders/raytracing/ClosestHit.slang b/res/shaders/raytracing/ClosestHit.slang index aa595ce..e0c71d4 100644 --- a/res/shaders/raytracing/ClosestHit.slang +++ b/res/shaders/raytracing/ClosestHit.slang @@ -147,7 +147,7 @@ void closestHit(inout RayPayload hitValue, in BuiltInTriangleIntersectionAttribu if (rnd.z >= p) return; } - hitValue.light += brdf.getEmissive() * hitValue.emissive + brdf.evaluateAmbient(); + hitValue.light += brdf.getEmissive() * hitValue.emissive + brdf.evaluateAmbient(lightingParams.viewDir_WS); //-- Ideal DIFFUSE reflection //if(bool(useNEE)) { // accrad += nextEventEstimation(accmat, r.d, params.x, params.nl, kt, false, rnd); diff --git a/res/shaders/raytracing/RayTracingData.slang b/res/shaders/raytracing/RayTracingData.slang index 3d5acdc..276b97a 100644 --- a/res/shaders/raytracing/RayTracingData.slang +++ b/res/shaders/raytracing/RayTracingData.slang @@ -1,5 +1,4 @@ import MaterialParameter; -import BRDF; struct RayTracingParams { diff --git a/src/AssetViewer/main.cpp b/src/AssetViewer/main.cpp index 090fc24..b8d1493 100644 --- a/src/AssetViewer/main.cpp +++ b/src/AssetViewer/main.cpp @@ -36,7 +36,7 @@ int main(int, char**) { Array texCoords1(mesh->mNumVertices); if (mesh->HasTextureCoords(2)) abort(); - for (int32 i = 0; i < mesh->mNumVertices; ++i) { + for (uint32 i = 0; i < mesh->mNumVertices; ++i) { positions[i] = Vector(mesh->mVertices[i].x, mesh->mVertices[i].y, mesh->mVertices[i].z); if (mesh->mTextureCoords[0] != nullptr) @@ -65,7 +65,7 @@ int main(int, char**) { return 0.5 * glm::length(glm::cross(p2 - p1, p3 - p1)); }; Array tris(mesh->mNumFaces); - for (int32 faceIndex = 0; faceIndex < mesh->mNumFaces; ++faceIndex) { + for (uint32 faceIndex = 0; faceIndex < mesh->mNumFaces; ++faceIndex) { tris[faceIndex].p[0] = mesh->mFaces[faceIndex].mIndices[0]; tris[faceIndex].p[1] = mesh->mFaces[faceIndex].mIndices[1]; tris[faceIndex].p[2] = mesh->mFaces[faceIndex].mIndices[2]; @@ -74,7 +74,7 @@ int main(int, char**) { uint32 p0 = tris[i].p[0]; uint32 p1 = tris[i].p[1]; uint32 p2 = tris[i].p[2]; - uint32 p3 = positions.size(); + uint32 p3 = (uint32)positions.size(); positions.add(interpolate(positions[p0], positions[p1], positions[p2])); if (mesh->mTextureCoords[0] != nullptr) @@ -102,7 +102,7 @@ int main(int, char**) { //for (uint32 i = 0; i < tris.size(); ++i) { // stats << calcArea(tris[i]) << std::endl; //} - bool tess = false; + //bool tess = false; //while (!tess) { // tess = true; // for (uint32 i = 0; i < tris.size(); ++i) { @@ -143,7 +143,7 @@ int main(int, char**) { mesh->mBitangents = newBit; } - uint32 numFaces = tris.size(); + uint32 numFaces = (uint32)tris.size(); aiFace* newFaces = new aiFace[numFaces]; for (uint32 i = 0; i < numFaces; ++i) { newFaces[i].mNumIndices = 3; @@ -153,10 +153,10 @@ int main(int, char**) { newFaces[i].mIndices[2] = tris[i].p[2]; } - mesh->mNumVertices = positions.size(); + mesh->mNumVertices = (uint32)positions.size(); mesh->mVertices = newPos; mesh->mFaces = newFaces; - mesh->mNumFaces = tris.size(); + mesh->mNumFaces = (uint32)tris.size(); } Assimp::Exporter exporter; diff --git a/src/Benchmark/PlayView.cpp b/src/Benchmark/PlayView.cpp index 3f6cf97..5e7fdfc 100644 --- a/src/Benchmark/PlayView.cpp +++ b/src/Benchmark/PlayView.cpp @@ -28,7 +28,6 @@ PlayView::PlayView(Gfx::PGraphics graphics, PWindow window, const ViewportCreate "VisibilityMS," << std::endl; uint64 start = 0; - uint64 prevBegin = 0; std::this_thread::sleep_for(std::chrono::milliseconds(500)); stats << std::fixed << std::setprecision(0); while (getGlobals().running) { @@ -37,8 +36,8 @@ PlayView::PlayView(Gfx::PGraphics graphics, PWindow window, const ViewportCreate auto baseResults = baseQuery->getResults(); auto lightCullResults = lightCullQuery->getResults(); auto visiblityResults = visibilityQuery->getResults(); - int64 renderBegin = renderTimestamp->getResult().time; - int64 renderEnd = renderTimestamp->getResult().time; + //int64 renderBegin = renderTimestamp->getResult().time; + //int64 renderEnd = renderTimestamp->getResult().time; Map results; for (uint32 i = 0; i < 11; ++i) { auto ts = timestamps->getResult(); diff --git a/src/Editor/Asset/AssetImporter.cpp b/src/Editor/Asset/AssetImporter.cpp index d7de0e9..8400d2a 100644 --- a/src/Editor/Asset/AssetImporter.cpp +++ b/src/Editor/Asset/AssetImporter.cpp @@ -4,7 +4,7 @@ #include "MaterialLoader.h" #include "MeshLoader.h" #include "TextureLoader.h" - +#include "EnvironmentLoader.h" using namespace Seele; @@ -40,12 +40,21 @@ void AssetImporter::importMaterial(MaterialImportArgs args) { get().materialLoader->importAsset(args); } +void Seele::AssetImporter::importEnvironmentMap(EnvironmentImportArgs args) { + if (get().registry->getOrCreateFolder(args.importPath)->materials.contains(args.filePath.stem().string())) { + // skip importing duplicates + return; + } + get().environmentLoader->importAsset(args); +} + void AssetImporter::init(Gfx::PGraphics graphics) { get().registry = AssetRegistry::getInstance(); get().meshLoader = new MeshLoader(graphics); get().textureLoader = new TextureLoader(graphics); get().materialLoader = new MaterialLoader(graphics); get().fontLoader = new FontLoader(graphics); + get().environmentLoader = new EnvironmentLoader(graphics); } AssetImporter& AssetImporter::get() { diff --git a/src/Editor/Asset/AssetImporter.h b/src/Editor/Asset/AssetImporter.h index 6f3fb22..2202386 100644 --- a/src/Editor/Asset/AssetImporter.h +++ b/src/Editor/Asset/AssetImporter.h @@ -1,6 +1,6 @@ #pragma once -#include "Asset/AssetRegistry.h" #include "MinimalEngine.h" +#include "Asset/AssetRegistry.h" namespace Seele { @@ -8,12 +8,14 @@ DECLARE_REF(TextureLoader) DECLARE_REF(FontLoader) DECLARE_REF(MeshLoader) DECLARE_REF(MaterialLoader) +DECLARE_REF(EnvironmentLoader) class AssetImporter { public: static void importMesh(struct MeshImportArgs args); static void importTexture(struct TextureImportArgs args); static void importFont(struct FontImportArgs args); static void importMaterial(struct MaterialImportArgs args); + static void importEnvironmentMap(struct EnvironmentImportArgs args); static void init(Gfx::PGraphics graphics); private: @@ -22,6 +24,7 @@ class AssetImporter { UPFontLoader fontLoader; UPMeshLoader meshLoader; UPMaterialLoader materialLoader; + UPEnvironmentLoader environmentLoader; AssetRegistry* registry; }; } // namespace Seele \ No newline at end of file diff --git a/src/Editor/Asset/CMakeLists.txt b/src/Editor/Asset/CMakeLists.txt index 240cb8f..58d56c5 100644 --- a/src/Editor/Asset/CMakeLists.txt +++ b/src/Editor/Asset/CMakeLists.txt @@ -2,6 +2,8 @@ target_sources(Editor PRIVATE AssetImporter.h AssetImporter.cpp + EnvironmentLoader.h + EnvironmentLoader.cpp FontLoader.h FontLoader.cpp MaterialLoader.h diff --git a/src/Editor/Asset/EnvironmentLoader.cpp b/src/Editor/Asset/EnvironmentLoader.cpp new file mode 100644 index 0000000..be4a2bc --- /dev/null +++ b/src/Editor/Asset/EnvironmentLoader.cpp @@ -0,0 +1,210 @@ +#include "EnvironmentLoader.h" +#include "Asset/AssetRegistry.h" +#include "Asset/EnvironmentMapAsset.h" +#include "Graphics/Descriptor.h" +#include "stb_image.h" + +using namespace Seele; + +static constexpr uint32 SOURCE_RESOLUTION = 2048; +static constexpr uint32 CONVOLUTED_RESOLUTION = 64; + +EnvironmentLoader::EnvironmentLoader(Gfx::PGraphics graphics) : graphics(graphics) { + cubeRenderViewport = graphics->createViewport(nullptr, ViewportCreateInfo{ + .dimensions = + { + .size = {SOURCE_RESOLUTION, SOURCE_RESOLUTION}, + .offset = {0, 0}, + }, + }); + convolutionViewport = graphics->createViewport(nullptr, ViewportCreateInfo{ + .dimensions = + { + .size = {CONVOLUTED_RESOLUTION, CONVOLUTED_RESOLUTION}, + .offset = {0, 0}, + }, + }); + cubeSampler = graphics->createSampler({ + .magFilter = Gfx::SE_FILTER_LINEAR, + .minFilter = Gfx::SE_FILTER_LINEAR, + .addressModeU = Gfx::SE_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, + .addressModeV = Gfx::SE_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, + .addressModeW = Gfx::SE_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, + }); + + cubeRenderLayout = graphics->createDescriptorLayout("pViewParams"); + cubeRenderLayout->addDescriptorBinding(Gfx::DescriptorBinding{ + .name = "view", + .uniformLength = sizeof(Matrix4) * 6, + }); + cubeRenderLayout->addDescriptorBinding(Gfx::DescriptorBinding{ + .name = "projection", + .uniformLength = sizeof(Matrix4), + }); + cubeRenderLayout->addDescriptorBinding(Gfx::DescriptorBinding{ + .name = "equirectangularMap", + .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE, + }); + cubeRenderLayout->addDescriptorBinding(Gfx::DescriptorBinding{ + .name = "sampler", + .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLER, + }); + cubeRenderLayout->addDescriptorBinding(Gfx::DescriptorBinding{ + .name = "cubeMap", + .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE, + }); + cubeRenderLayout->create(); + + cubePipelineLayout = graphics->createPipelineLayout("CubeRenderLayout"); + cubePipelineLayout->addDescriptorLayout(cubeRenderLayout); + + graphics->beginShaderCompilation(ShaderCompilationInfo{ + .name = "CubeRenderPipeline", + .modules = {"EnvironmentMapping"}, + .entryPoints = + { + {"vertMain", "EnvironmentMapping"}, + {"computeCubemap", "EnvironmentMapping"}, + {"convolveCubemap", "EnvironmentMapping"}, + }, + .rootSignature = cubePipelineLayout, + }); + cubePipelineLayout->create(); + + cubeRenderVertex = graphics->createVertexShader({0}); + cubeRenderFrag = graphics->createFragmentShader({1}); + convolutionFrag = graphics->createFragmentShader({2}); +} + +EnvironmentLoader::~EnvironmentLoader() {} + +void EnvironmentLoader::importAsset(EnvironmentImportArgs args) { + std::filesystem::path assetPath = args.filePath.filename(); + assetPath.replace_extension("asset"); + OEnvironmentMapAsset asset = new EnvironmentMapAsset(args.importPath, assetPath.stem().string()); + asset->setStatus(Asset::Status::Loading); + // the registry takes ownership, but we need to edit the reference + PEnvironmentMapAsset ref = asset; + AssetRegistry::get().registerEnvironmentMap(std::move(asset)); + import(args, ref); +} + +void EnvironmentLoader::import(EnvironmentImportArgs args, PEnvironmentMapAsset asset) { + stbi_set_flip_vertically_on_load(true); + int width, height, nrComponents; + float* data = stbi_loadf(args.filePath.string().c_str(), &width, &height, &nrComponents, 4); + stbi_set_flip_vertically_on_load(false); + assert(data); + Gfx::OTexture2D hdrTexture = graphics->createTexture2D(TextureCreateInfo{ + .sourceData = + { + .size = width * height * 4 * sizeof(float), + .data = (uint8*)data, + }, + .format = Gfx::SE_FORMAT_R32G32B32A32_SFLOAT, + .width = (uint32)width, + .height = (uint32)height, + .name = "HDRRaw", + }); + Matrix4 captureProjection = glm::perspective(glm::radians(90.0f), 1.0f, 0.1f, 10.0f); + Matrix4 captureViews[] = { + glm::lookAt(Vector(0.0f, 0.0f, 0.0f), Vector(1.0f, 0.0f, 0.0f), Vector(0.0f, 1.0f, 0.0f)), + glm::lookAt(Vector(0.0f, 0.0f, 0.0f), Vector(-1.0f, 0.0f, 0.0f), Vector(0.0f, 1.0f, 0.0f)), + glm::lookAt(Vector(0.0f, 0.0f, 0.0f), Vector(0.0f, 1.0f, 0.0f), Vector(0.0f, 0.0f, 1.0f)), + glm::lookAt(Vector(0.0f, 0.0f, 0.0f), Vector(0.0f, -1.0f, 0.0f), Vector(0.0f, 0.0f, -1.0f)), + glm::lookAt(Vector(0.0f, 0.0f, 0.0f), Vector(0.0f, 0.0f, 1.0f), Vector(0.0f, 1.0f, 0.0f)), + glm::lookAt(Vector(0.0f, 0.0f, 0.0f), Vector(0.0f, 0.0f, -1.0f), Vector(0.0f, 1.0f, 0.0f)), + }; + Gfx::PDescriptorSet set = cubeRenderLayout->allocateDescriptorSet(); + set->updateConstants("view", 0, captureViews); + set->updateConstants("projection", 0, &captureProjection); + set->updateTexture("equirectangularMap", 0, Gfx::PTexture2D(hdrTexture)); + set->updateSampler("sampler", 0, cubeSampler); + set->writeChanges(); + Gfx::OTextureCube cubeMap = graphics->createTextureCube(TextureCreateInfo{ + .format = Gfx::SE_FORMAT_R32G32B32A32_SFLOAT, + .width = SOURCE_RESOLUTION, + .height = SOURCE_RESOLUTION, + .usage = Gfx::SE_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | Gfx::SE_IMAGE_USAGE_SAMPLED_BIT, + }); + Gfx::ORenderPass cubeRenderPass = graphics->createRenderPass( + Gfx::RenderTargetLayout{ + .colorAttachments = {Gfx::RenderTargetAttachment(cubeMap, Gfx::SE_IMAGE_LAYOUT_UNDEFINED, + Gfx::SE_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, + Gfx::SE_ATTACHMENT_LOAD_OP_DONT_CARE, Gfx::SE_ATTACHMENT_STORE_OP_STORE)}, + }, + {}, + URect{ + .size = {SOURCE_RESOLUTION, SOURCE_RESOLUTION}, + .offset = {0, 0}, + }, + "EnvironmentRenderPass", {0b111111}, {0b111111}); + cubeRenderPipeline = graphics->createGraphicsPipeline(Gfx::LegacyPipelineCreateInfo{ + .vertexShader = cubeRenderVertex, + .fragmentShader = cubeRenderFrag, + .renderPass = cubeRenderPass, + .pipelineLayout = cubePipelineLayout, + .colorBlend = + { + .attachmentCount = 1, + }, + }); + graphics->beginRenderPass(cubeRenderPass); + Gfx::ORenderCommand renderCommand = graphics->createRenderCommand("CubeMapRender"); + renderCommand->bindPipeline(cubeRenderPipeline); + renderCommand->bindDescriptor({set}); + renderCommand->setViewport(cubeRenderViewport); + renderCommand->draw(36, 1, 0, 0); + graphics->executeCommands(std::move(renderCommand)); + graphics->endRenderPass(); + + Gfx::OTextureCube convolutedMap = graphics->createTextureCube(TextureCreateInfo{ + .format = Gfx::SE_FORMAT_R32G32B32A32_SFLOAT, + .width = CONVOLUTED_RESOLUTION, + .height = CONVOLUTED_RESOLUTION, + .usage = Gfx::SE_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, + }); + Gfx::ORenderPass convolutionPass = graphics->createRenderPass( + Gfx::RenderTargetLayout{ + .colorAttachments = {Gfx::RenderTargetAttachment(convolutedMap, Gfx::SE_IMAGE_LAYOUT_UNDEFINED, + Gfx::SE_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, + Gfx::SE_ATTACHMENT_LOAD_OP_DONT_CARE, Gfx::SE_ATTACHMENT_STORE_OP_STORE)}, + }, + {}, + URect{ + .size = {CONVOLUTED_RESOLUTION, CONVOLUTED_RESOLUTION}, + .offset = {0, 0}, + }, + "EnvironmentRenderPass", {0b111111}, {0b111111}); + convolutionPipeline = graphics->createGraphicsPipeline(Gfx::LegacyPipelineCreateInfo{ + .vertexShader = cubeRenderVertex, + .fragmentShader = convolutionFrag, + .renderPass = convolutionPass, + .pipelineLayout = cubePipelineLayout, + .colorBlend = + { + .attachmentCount = 1, + }, + }); + + set = cubeRenderLayout->allocateDescriptorSet(); + set->updateConstants("view", 0, captureViews); + set->updateConstants("projection", 0, &captureProjection); + set->updateSampler("sampler", 0, cubeSampler); + set->updateTexture("cubeMap", 0, Gfx::PTextureCube(cubeMap)); + set->writeChanges(); + + graphics->beginRenderPass(convolutionPass); + Gfx::ORenderCommand cmd = graphics->createRenderCommand("ConvolutionPass"); + cmd->bindPipeline(convolutionPipeline); + cmd->bindDescriptor({set}); + cmd->setViewport(convolutionViewport); + cmd->draw(36, 1, 0, 0); + graphics->executeCommands(std::move(cmd)); + graphics->endRenderPass(); + + asset->skybox = std::move(cubeMap); + asset->irradianceMap = std::move(convolutedMap); + asset->specularMap = std::move(cubeMap); + graphics->waitDeviceIdle(); +} diff --git a/src/Editor/Asset/EnvironmentLoader.h b/src/Editor/Asset/EnvironmentLoader.h new file mode 100644 index 0000000..968b018 --- /dev/null +++ b/src/Editor/Asset/EnvironmentLoader.h @@ -0,0 +1,34 @@ +#pragma once +#include "MinimalEngine.h" +#include "Graphics/Graphics.h" +#include "Graphics/Shader.h" +#include + +namespace Seele +{ +DECLARE_REF(EnvironmentMapAsset) +struct EnvironmentImportArgs { + std::filesystem::path filePath; + std::string importPath; +}; +class EnvironmentLoader { + public: + EnvironmentLoader(Gfx::PGraphics graphic); + ~EnvironmentLoader(); + void importAsset(EnvironmentImportArgs args); + + private: + void import(EnvironmentImportArgs args, PEnvironmentMapAsset asset); + Gfx::PGraphics graphics; + Gfx::OVertexShader cubeRenderVertex; + Gfx::OFragmentShader cubeRenderFrag; + Gfx::ODescriptorLayout cubeRenderLayout; + Gfx::OPipelineLayout cubePipelineLayout; + Gfx::PGraphicsPipeline cubeRenderPipeline; + Gfx::OFragmentShader convolutionFrag; + Gfx::PGraphicsPipeline convolutionPipeline; + Gfx::OViewport cubeRenderViewport; + Gfx::OViewport convolutionViewport; + Gfx::OSampler cubeSampler; +}; +} \ No newline at end of file diff --git a/src/Editor/Asset/MeshLoader.cpp b/src/Editor/Asset/MeshLoader.cpp index a39e896..c8bb68b 100644 --- a/src/Editor/Asset/MeshLoader.cpp +++ b/src/Editor/Asset/MeshLoader.cpp @@ -151,7 +151,7 @@ void MeshLoader::loadMaterials(const aiScene* scene, const Array& uint32 uvIndex = 0; aiTextureMapMode mapMode = aiTextureMapMode_Clamp; float blend = std::numeric_limits::max(); - aiTextureOp op; + aiTextureOp op = aiTextureOp_Add; if (material->GetTexture(type, index, &texPath, &mapping, &uvIndex, nullptr, nullptr, nullptr) != AI_SUCCESS) { std::cout << "fuck" << std::endl; } @@ -488,23 +488,23 @@ Vector4 MeshLoader::encodeQTangent(Matrix3 m) { Vector4 r; if (t > 2.9999999) { r = Vector4(0.0, 0.0, 0.0, 1.0); - } else if (t > 0.0000001) { - float s = sqrt(1.0 + t) * 2.0; - r = Vector4(Vector(m[1][2] - m[2][1], m[2][0] - m[0][2], m[0][1] - m[1][0]) / s, s * 0.25); + } else if (t > 0.0000001f) { + float s = sqrt(1.0f + t) * 2.0f; + r = Vector4(Vector(m[1][2] - m[2][1], m[2][0] - m[0][2], m[0][1] - m[1][0]) / s, s * 0.25f); } else if ((m[0][0] > m[1][1]) && (m[0][0] > m[2][2])) { - float s = sqrt(1.0 + (m[0][0] - (m[1][1] + m[2][2]))) * 2.0; + float s = sqrt(1.0f + (m[0][0] - (m[1][1] + m[2][2]))) * 2.0; r = Vector4(s * 0.25, Vector(m[1][0] - m[0][1], m[2][0] - m[0][2], m[0][2] - m[2][1]) / s); } else if (m[1][1] > m[2][2]) { - float s = sqrt(1.0 + (m[1][1] - (m[0][0] + m[2][2]))) * 2.0; - r = Vector4(Vector(m[1][0] + m[0][1], m[2][1] + m[1][2], m[2][0] - m[0][2]) / s, s * 0.25); + float s = sqrt(1.0f + (m[1][1] - (m[0][0] + m[2][2]))) * 2.0f; + r = Vector4(Vector(m[1][0] + m[0][1], m[2][1] + m[1][2], m[2][0] - m[0][2]) / s, s * 0.25f); r = Vector4(r.x, r.w, r.y, r.z); } else { - float s = sqrt(1.0 + (m[2][2] - (m[0][0] + m[1][1]))) * 2.0; - r = Vector4(Vector(m[2][0] + m[0][2], m[2][1] + m[1][2], m[0][1] - m[1][0]) / s, s * 0.25); + float s = sqrt(1.0f + (m[2][2] - (m[0][0] + m[1][1]))) * 2.0f; + r = Vector4(Vector(m[2][0] + m[0][2], m[2][1] + m[1][2], m[0][1] - m[1][0]) / s, s * 0.25f); r = Vector4(r.x, r.y, r.w, r.z); } r = normalize(r); - const float threshold = 1.0 / 32767.0; + const float threshold = 1.0f / 32767.0f; if (r.w <= threshold) { r = Vector4(Vector(r) * (float)sqrt(1.0 - (threshold * threshold)), (r.w > 0.0) ? threshold : -threshold); } @@ -516,7 +516,7 @@ Vector4 MeshLoader::encodeQTangent(Matrix3 m) { void MeshLoader::loadGlobalMeshes(const aiScene* scene, const Array& materials, Array& globalMeshes, Component::Collider& collider) { List> work; - for (int32 meshIndex = 0; meshIndex < scene->mNumMeshes; ++meshIndex) { + for (uint32 meshIndex = 0; meshIndex < scene->mNumMeshes; ++meshIndex) { aiMesh* mesh = scene->mMeshes[meshIndex]; if (!(mesh->mPrimitiveTypes & aiPrimitiveType_TRIANGLE)) continue; @@ -536,12 +536,12 @@ void MeshLoader::loadGlobalMeshes(const aiScene* scene, const Array normals(mesh->mNumVertices); Array tangents(mesh->mNumVertices); - Array biTangents(mesh->mNumVertices); + //Array biTangents(mesh->mNumVertices); Array colors(mesh->mNumVertices); - for (int32 i = 0; i < mesh->mNumVertices; ++i) { + for (uint32 i = 0; i < mesh->mNumVertices; ++i) { positions[i] = Vector(mesh->mVertices[i].x, mesh->mVertices[i].y, mesh->mVertices[i].z); - for (size_t j = 0; j < MAX_TEXCOORDS; ++j) { + for (uint32 j = 0; j < MAX_TEXCOORDS; ++j) { if (mesh->HasTextureCoords(j)) { texCoords[j][i] = U16Vector2(mesh->mTextureCoords[j][i].x * 65535, mesh->mTextureCoords[j][i].y * 65535); } else { @@ -555,10 +555,15 @@ void MeshLoader::loadGlobalMeshes(const aiScene* scene, const ArraymTangents[i].x, mesh->mTangents[i].y, mesh->mTangents[i].z); biTangent = Vector(mesh->mBitangents[i].x, mesh->mBitangents[i].y, mesh->mBitangents[i].z); } - normals[i] = normal; // encodeQTangent(Matrix3(tangent, biTangent, normal)); - tangents[i] = tangent; - biTangents[i] = biTangent; + normals[i] = normal; // encodeQTangent(Matrix3(tangent, biTangent, normal)); + // the fourth component encodes the sign of the bitangent. + // in the shader we calc n x t, and b = (n x t) * sign + // so we try to cross the two, and see what is the result, and if it is + // the same as b, the dot product is 1, and if they are inverse, the dot product is + // -1, which is the sign we need + tangents[i] = Vector4(tangent, dot(glm::cross(normal, tangent), biTangent)); + if (mesh->HasVertexColors(0)) { colors[i] = StaticMeshVertexData::ColorType(mesh->mColors[0][i].r * 65535, mesh->mColors[0][i].g * 65535, mesh->mColors[0][i].b * 65535); } else { @@ -572,7 +577,7 @@ void MeshLoader::loadGlobalMeshes(const aiScene* scene, const ArrayloadNormals(offset, normals); vertexData->loadTangents(offset, tangents); - vertexData->loadBitangents(offset, biTangents); + //vertexData->loadBitangents(offset, biTangents); vertexData->loadColors(offset, colors); Array indices(mesh->mNumFaces * 3); diff --git a/src/Editor/Asset/TextureLoader.cpp b/src/Editor/Asset/TextureLoader.cpp index bf24c20..6c0bc94 100644 --- a/src/Editor/Asset/TextureLoader.cpp +++ b/src/Editor/Asset/TextureLoader.cpp @@ -42,7 +42,7 @@ void TextureLoader::importAsset(TextureImportArgs args) { PTextureAsset ref = asset; asset->setStatus(Asset::Status::Loading); AssetRegistry::get().registerTexture(std::move(asset)); - import(args, ref); + getThreadPool().runAsync([=]() { import(args, ref); }); } PTextureAsset TextureLoader::getPlaceholderTexture() { return placeholderAsset; } @@ -67,7 +67,7 @@ void TextureLoader::import(TextureImportArgs args, PTextureAsset textureAsset) { .numLevels = 1, .numLayers = 1, .isArray = false, - .generateMipmaps = false, + .generateMipmaps = true, }; if (args.type == TextureImportType::TEXTURE_CUBEMAP) { @@ -110,13 +110,14 @@ void TextureLoader::import(TextureImportArgs args, PTextureAsset textureAsset) { } ktxBasisParams basisParams = { .structSize = sizeof(ktxBasisParams), - .uastc = true, + .uastc = false, .threadCount = 1, - .uastcFlags = KTX_PACK_UASTC_LEVEL_FASTEST, + .compressionLevel = KTX_ETC1S_DEFAULT_COMPRESSION_LEVEL, + .uastcFlags = KTX_PACK_UASTC_LEVEL_DEFAULT, .uastcRDO = true, }; - // KTX_ASSERT(ktxTexture2_CompressBasisEx(kTexture, &basisParams)); - // KTX_ASSERT(ktxTexture2_DeflateZstd(kTexture, 20)); + KTX_ASSERT(ktxTexture2_CompressBasisEx(kTexture, &basisParams)); + //KTX_ASSERT(ktxTexture2_DeflateZstd(kTexture, 10)); char writer[100]; snprintf(writer, sizeof(writer), "%s version %s", "SeeleEngine", "0.0.1"); @@ -148,4 +149,5 @@ void TextureLoader::import(TextureImportArgs args, PTextureAsset textureAsset) { AssetRegistry::saveAsset(textureAsset, TextureAsset::IDENTIFIER, textureAsset->getFolderPath(), textureAsset->getName()); textureAsset->setStatus(Asset::Status::Ready); + std::cout << "Done importing " << textureAsset->getName() << std::endl; } diff --git a/src/Editor/Window/InspectorView.cpp b/src/Editor/Window/InspectorView.cpp index 37dcb25..16ea243 100644 --- a/src/Editor/Window/InspectorView.cpp +++ b/src/Editor/Window/InspectorView.cpp @@ -36,7 +36,7 @@ void InspectorView::prepareRender() {} void InspectorView::render() { renderGraph.render(Component::Camera()); } -void InspectorView::applyArea(URect area) {} +void InspectorView::applyArea(URect ) {} void InspectorView::keyCallback(KeyCode, InputAction, KeyModifier) {} diff --git a/src/Editor/Window/PlayView.cpp b/src/Editor/Window/PlayView.cpp index 75506f2..c0627e9 100644 --- a/src/Editor/Window/PlayView.cpp +++ b/src/Editor/Window/PlayView.cpp @@ -49,6 +49,7 @@ void PlayView::keyCallback(KeyCode code, InputAction action, KeyModifier modifie if (code == KeyCode::KEY_R && action == InputAction::RELEASE) { getGlobals().useRayTracing = !getGlobals().useRayTracing; } - //if (code == KeyCode::KEY_B && action == InputAction::RELEASE && modifier & KeyModifier::MOD_CONTROL) { - //} + if (code == KeyCode::KEY_H && action == InputAction::RELEASE) { + MemoryManager::printAllocations(); + } } diff --git a/src/Editor/Window/ViewportControl.cpp b/src/Editor/Window/ViewportControl.cpp index 1c5b22c..8cf7bbc 100644 --- a/src/Editor/Window/ViewportControl.cpp +++ b/src/Editor/Window/ViewportControl.cpp @@ -13,7 +13,7 @@ ViewportControl::ViewportControl(const URect& viewportDimensions, Vector initial ViewportControl::~ViewportControl() {} -void ViewportControl::update(Component::Camera& camera, float deltaTime) { +void ViewportControl::update(Component::Camera&, float deltaTime) { float cameraMove = deltaTime * 20; if (keys[KeyCode::KEY_LEFT_SHIFT]) { cameraMove *= 4; diff --git a/src/Editor/main.cpp b/src/Editor/main.cpp index 5f0053f..2fa89f7 100644 --- a/src/Editor/main.cpp +++ b/src/Editor/main.cpp @@ -4,6 +4,7 @@ #include "Asset/MaterialLoader.h" #include "Asset/MeshLoader.h" #include "Asset/TextureLoader.h" +#include "Asset/EnvironmentLoader.h" #include "Graphics/Initializer.h" #ifdef __APPLE__ #include "Graphics/Metal/Graphics.h" @@ -23,54 +24,11 @@ using namespace Seele::Editor; // make it global so it gets deleted last and automatically static Gfx::OGraphics graphics; -struct Halfedge { - uint32 vertexID; - uint32 nextID; - uint32 prevID; - uint32 twinID; -}; -Array generateEdges() { - Array indices = {UVector(0, 1, 4), UVector(4, 1, 5), UVector(1, 2, 5), UVector(5, 2, 6), UVector(2, 3, 6), - UVector(6, 3, 7), UVector(4, 5, 8), UVector(8, 5, 9), UVector(5, 6, 9), UVector(9, 6, 10), - UVector(6, 7, 10), UVector(10, 7, 11), UVector(8, 9, 12), UVector(12, 9, 13), UVector(9, 10, 13), - UVector(13, 10, 14), UVector(10, 11, 14), UVector(14, 11, 15)}; - Array edges; - for (auto ind : indices) { - uint32 baseIndex = edges.size(); - edges.add(Halfedge{ind.x, baseIndex + 1, baseIndex + 2, UINT32_MAX}); - edges.add(Halfedge{ind.y, baseIndex + 2, baseIndex, UINT32_MAX}); - edges.add(Halfedge{ind.z, baseIndex, baseIndex + 1, UINT32_MAX}); - } - for (uint32 i = 0; i < edges.size(); ++i) { - if (edges[i].twinID == UINT32_MAX) { - for (uint32 j = 0; j < edges.size(); ++j) { - if (edges[i].vertexID == edges[edges[j].nextID].vertexID && edges[edges[i].nextID].vertexID == edges[j].vertexID) { - edges[i].twinID = j; - edges[j].twinID = i; - } - } - } - } - return edges; -} - -Array generateArray() { return Array(); } - int main() { - std::string gameName = "MeshShadingDemo"; -#ifdef WIN32 - std::filesystem::path outputPath = "C:/Users/Dynamitos/MeshShadingDemoGame"; - std::filesystem::path sourcePath = "C:/Users/Dynamitos/MeshShadingDemo"; - std::filesystem::path binaryPath = sourcePath / "bin" / "MeshShadingDemo.dll"; -#elif __APPLE__ - std::filesystem::path outputPath = "/Users/dynamitos/MeshShadingDemoGame"; - std::filesystem::path sourcePath = "/Users/dynamitos/MeshShadingDemo"; - std::filesystem::path binaryPath = sourcePath / "cmake" / "libMeshShadingDemo.dylib"; -#else - std::filesystem::path outputPath = "/home/dynamitos/MeshShadingDemoGame"; - std::filesystem::path sourcePath = "/home/dynamitos/MeshShadingDemo"; - std::filesystem::path binaryPath = sourcePath / "cmake" / "libMeshShadingDemo.so"; -#endif + std::string gameName = "MinecraftClone"; + std::filesystem::path outputPath = fmt::format("../../{0}Game", gameName); + std::filesystem::path sourcePath = fmt::format("../../{0}", gameName); + std::filesystem::path binaryPath = sourcePath / "bin" / fmt::format("{0}.dll", gameName); std::filesystem::path cmakePath = outputPath / "cmake"; if (true) { #ifdef __APPLE__ @@ -89,45 +47,12 @@ int main() { AssetImporter::importFont(FontImportArgs{ .filePath = "./fonts/arial.ttf", }); - AssetImporter::importMesh(MeshImportArgs{ - .filePath = sourcePath / "import/models/cube.fbx", + AssetImporter::importEnvironmentMap(EnvironmentImportArgs{ + .filePath = sourcePath / "import" / "textures" / "newport_loft.hdr", }); - // AssetImporter::importMesh(MeshImportArgs{ - // .filePath = sourcePath / "import/models/culling.fbx", - //}); - AssetImporter::importTexture(TextureImportArgs{ - .filePath = sourcePath / "import/textures/skybox.jpg", - .type = TextureImportType::TEXTURE_CUBEMAP, - }); - // AssetImporter::importMesh(MeshImportArgs{ - // .filePath = sourcePath / "import/models/ship.fbx", - // .importPath = "ship", - // }); - // AssetImporter::importTexture(TextureImportArgs{ - // .filePath = sourcePath / "import/textures/azeroth.png", - //}); - // AssetImporter::importTexture(TextureImportArgs{ - // .filePath = sourcePath / "import/textures/azeroth_height.png", - //}); - // AssetImporter::importTexture(TextureImportArgs{ - // .filePath = sourcePath / "import/textures/wgen.png", - //}); - AssetImporter::importMesh(MeshImportArgs{ - .filePath = sourcePath / "import/models/after-the-rain-vr-sound/source/Whitechapel.glb", - .importPath = "Whitechapel", - }); - //AssetImporter::importMesh(MeshImportArgs{ - // .filePath = sourcePath / "import/models/box.glb", - // .importPath = "", - //}); - AssetImporter::importMesh(MeshImportArgs{ - .filePath = sourcePath / "import/models/rttest.glb", - .importPath = "", - }); - //AssetImporter::importMesh(MeshImportArgs{ - // .filePath = sourcePath / "import/models/town_hall.glb", - // .importPath = "", - //}); + AssetImporter::importTexture(TextureImportArgs{.filePath = sourcePath / "import" / "texture" / "Dirt.png", .importPath = ""}); + + getThreadPool().waitIdle(); vd->commitMeshes(); WindowCreateInfo mainWindowInfo = { @@ -146,16 +71,16 @@ int main() { }; OGameView sceneView = new Editor::PlayView(graphics, window, sceneViewInfo, binaryPath.generic_string()); sceneView->setFocused(); - //OInspectorView inspectorView = new Editor::InspectorView(graphics, window, - // ViewportCreateInfo{ - // .dimensions = - // { - // .size = {1920, 1080}, - // .offset = {0, 0}, - // }, - // .fieldOfView = 0, - // .numSamples = Gfx::SE_SAMPLE_COUNT_1_BIT, - // }); + // OInspectorView inspectorView = new Editor::InspectorView(graphics, window, + // ViewportCreateInfo{ + // .dimensions = + // { + // .size = {1920, 1080}, + // .offset = {0, 0}, + // }, + // .fieldOfView = 0, + // .numSamples = Gfx::SE_SAMPLE_COUNT_1_BIT, + // }); // window->show(); while (windowManager->isActive() && getGlobals().running) { diff --git a/src/Engine/Asset/AssetRegistry.cpp b/src/Engine/Asset/AssetRegistry.cpp index 2b563b4..1dc9714 100644 --- a/src/Engine/Asset/AssetRegistry.cpp +++ b/src/Engine/Asset/AssetRegistry.cpp @@ -1,12 +1,14 @@ #include "AssetRegistry.h" +#include "Asset/FontAsset.h" +#include "Asset/MaterialAsset.h" +#include "Asset/MaterialInstanceAsset.h" +#include "Asset/MeshAsset.h" +#include "Asset/EnvironmentMapAsset.h" +#include "Asset/SVGAsset.h" +#include "Asset/TextureAsset.h" #include "FontAsset.h" #include "Graphics/Graphics.h" #include "Graphics/Mesh.h" -#include "MaterialAsset.h" -#include "MaterialInstanceAsset.h" -#include "MeshAsset.h" -#include "SVGAsset.h" -#include "TextureAsset.h" #include "Window/WindowManager.h" #include #include @@ -56,6 +58,15 @@ PSVGAsset AssetRegistry::findSVG(std::string_view folderPath, std::string_view f return folder->svgs.at(std::string(filePath)); } +PEnvironmentMapAsset AssetRegistry::findEnvironmentMap(std::string_view folderPath, std::string_view filePath) { + std::unique_lock l(get().assetLock); + AssetFolder* folder = get().assetRoot; + if (!folderPath.empty()) { + folder = get().getOrCreateFolder(folderPath); + } + return folder->envs.at(std::string(filePath)); +} + PMaterialAsset AssetRegistry::findMaterial(std::string_view folderPath, std::string_view filePath) { std::unique_lock l(get().assetLock); AssetFolder* folder = get().assetRoot; @@ -94,6 +105,11 @@ void AssetRegistry::registerSVG(OSVGAsset svg) { get().registerSVGInternal(std::move(svg)); } +void AssetRegistry::registerEnvironmentMap(OEnvironmentMapAsset env) { + std::unique_lock l(get().assetLock); + get().registerEnvironmentMapInternal(std::move(env)); +} + void AssetRegistry::registerMaterial(OMaterialAsset material) { std::unique_lock l(get().assetLock); get().registerMaterialInternal(std::move(material)); @@ -146,6 +162,9 @@ void AssetRegistry::loadAsset(ArchiveBuffer& buffer) { case SVGAsset::IDENTIFIER: asset = PSVGAsset(folder->svgs.at(name)); break; + case EnvironmentMapAsset::IDENTIFIER: + asset = PEnvironmentMapAsset(folder->envs.at(name)); + break; default: throw new std::logic_error("Unknown Identifier"); } @@ -176,13 +195,9 @@ AssetRegistry::AssetRegistry() : assetRoot(nullptr) {} AssetRegistry* AssetRegistry::getInstance() { return _instance; } -void AssetRegistry::loadRegistry() { - get().loadRegistryInternal(); -} +void AssetRegistry::loadRegistry() { get().loadRegistryInternal(); } -void AssetRegistry::saveRegistry() { - get().saveRegistryInternal(); -} +void AssetRegistry::saveRegistry() { get().saveRegistryInternal(); } AssetRegistry::AssetFolder* AssetRegistry::getOrCreateFolder(std::string_view fullPath) { AssetFolder* result = assetRoot; @@ -209,11 +224,19 @@ void AssetRegistry::initialize(const std::filesystem::path& _rootFolder, Gfx::PG this->graphics = _graphics; this->rootFolder = _rootFolder; this->assetRoot = new AssetFolder(""); + if (!std::filesystem::exists(rootFolder)) + { + std::filesystem::create_directories(rootFolder); + } + else if (!std::filesystem::is_directory(rootFolder)) + { + throw std::logic_error("Asset Folder is not a directory!!"); + } loadRegistryInternal(); } void AssetRegistry::loadRegistryInternal() { - Array> peeked; + Array> peeked; { std::unique_lock l(get().assetLock); peeked = peekFolder(assetRoot); @@ -295,13 +318,16 @@ Pair AssetRegistry::peekAsset(ArchiveBuffer& buffer) { folder->svgs[name] = new SVGAsset(folderPath, name); asset = PSVGAsset(folder->svgs[name]); break; + case EnvironmentMapAsset::IDENTIFIER: + folder->envs[name] = new EnvironmentMapAsset(folderPath, name); + asset = PEnvironmentMapAsset(folder->envs[name]); + break; default: throw new std::logic_error("Unknown Identifier"); } return {asset, std::move(buffer)}; } - void AssetRegistry::saveRegistryInternal() { saveFolder("", assetRoot); } void AssetRegistry::saveFolder(const std::filesystem::path& folderPath, AssetFolder* folder) { @@ -324,6 +350,9 @@ void AssetRegistry::saveFolder(const std::filesystem::path& folderPath, AssetFol for (const auto& [name, svg] : folder->svgs) { saveAsset(PSVGAsset(svg), SVGAsset::IDENTIFIER, folderPath, name); } + for (const auto& [name, env] : folder->envs) { + saveAsset(PEnvironmentMapAsset(env), EnvironmentMapAsset::IDENTIFIER, folderPath, name); + } for (auto& [name, child] : folder->children) { saveFolder(folderPath / name, child); } @@ -351,6 +380,11 @@ void AssetRegistry::registerSVGInternal(OSVGAsset svg) { folder->svgs[svg->getName()] = std::move(svg); } +void AssetRegistry::registerEnvironmentMapInternal(OEnvironmentMapAsset env) { + AssetFolder* folder = getOrCreateFolder(env->getFolderPath()); + folder->envs[env->getName()] = std::move(env); +} + void AssetRegistry::registerMaterialInternal(OMaterialAsset material) { AssetFolder* folder = getOrCreateFolder(material->getFolderPath()); folder->materials[material->getName()] = std::move(material); diff --git a/src/Engine/Asset/AssetRegistry.h b/src/Engine/Asset/AssetRegistry.h index e9a1424..00ad6ba 100644 --- a/src/Engine/Asset/AssetRegistry.h +++ b/src/Engine/Asset/AssetRegistry.h @@ -12,6 +12,7 @@ DECLARE_REF(TextureAsset) DECLARE_REF(FontAsset) DECLARE_REF(SVGAsset) DECLARE_REF(MeshAsset) +DECLARE_REF(EnvironmentMapAsset) DECLARE_REF(MaterialAsset) DECLARE_REF(MaterialInstanceAsset) DECLARE_NAME_REF(Gfx, Graphics) @@ -26,6 +27,7 @@ class AssetRegistry { static PTextureAsset findTexture(std::string_view folderPath, std::string_view filePath); static PFontAsset findFont(std::string_view folderPath, std::string_view name); static PSVGAsset findSVG(std::string_view folderPath, std::string_view name); + static PEnvironmentMapAsset findEnvironmentMap(std::string_view folder, std::string_view name); static PMaterialAsset findMaterial(std::string_view folderPath, std::string_view filePath); static PMaterialInstanceAsset findMaterialInstance(std::string_view folderPath, std::string_view filePath); @@ -33,6 +35,7 @@ class AssetRegistry { static void registerTexture(OTextureAsset texture); static void registerFont(OFontAsset font); static void registerSVG(OSVGAsset svg); + static void registerEnvironmentMap(OEnvironmentMapAsset env); static void registerMaterial(OMaterialAsset material); static void registerMaterialInstance(OMaterialInstanceAsset instance); @@ -52,6 +55,7 @@ class AssetRegistry { Map textures; Map fonts; Map svgs; + Map envs; Map meshes; Map materials; Map instances; @@ -75,6 +79,7 @@ class AssetRegistry { void registerTextureInternal(OTextureAsset texture); void registerFontInternal(OFontAsset font); void registerSVGInternal(OSVGAsset svg); + void registerEnvironmentMapInternal(OEnvironmentMapAsset env); void registerMaterialInternal(OMaterialAsset material); void registerMaterialInstanceInternal(OMaterialInstanceAsset instance); diff --git a/src/Engine/Asset/CMakeLists.txt b/src/Engine/Asset/CMakeLists.txt index 24ecfd4..c57326e 100644 --- a/src/Engine/Asset/CMakeLists.txt +++ b/src/Engine/Asset/CMakeLists.txt @@ -4,6 +4,8 @@ target_sources(Engine Asset.cpp AssetRegistry.h AssetRegistry.cpp + EnvironmentMapAsset.h + EnvironmentMapAsset.cpp FontAsset.h FontAsset.cpp LevelAsset.h diff --git a/src/Engine/Asset/EnvironmentMapAsset.cpp b/src/Engine/Asset/EnvironmentMapAsset.cpp new file mode 100644 index 0000000..58cdd32 --- /dev/null +++ b/src/Engine/Asset/EnvironmentMapAsset.cpp @@ -0,0 +1,13 @@ +#include "EnvironmentMapAsset.h" + +using namespace Seele; + +EnvironmentMapAsset::EnvironmentMapAsset() {} + +EnvironmentMapAsset::EnvironmentMapAsset(std::string_view folderPath, std::string_view name) : Asset(folderPath, name) {} + +EnvironmentMapAsset::~EnvironmentMapAsset() {} + +void EnvironmentMapAsset::save(ArchiveBuffer& buffer) const {} + +void EnvironmentMapAsset::load(ArchiveBuffer& buffer) {} diff --git a/src/Engine/Asset/EnvironmentMapAsset.h b/src/Engine/Asset/EnvironmentMapAsset.h new file mode 100644 index 0000000..2f3116a --- /dev/null +++ b/src/Engine/Asset/EnvironmentMapAsset.h @@ -0,0 +1,23 @@ +#pragma once +#include "Asset.h" +#include "Graphics/Texture.h" + +namespace Seele { +class EnvironmentMapAsset : public Asset { + public: + static constexpr uint64 IDENTIFIER = 0x80; + EnvironmentMapAsset(); + EnvironmentMapAsset(std::string_view folderPath, std::string_view name); + virtual ~EnvironmentMapAsset(); + virtual void save(ArchiveBuffer& buffer) const override; + virtual void load(ArchiveBuffer& buffer) override; + Gfx::PTextureCube getSkybox() const { return skybox; } + Gfx::PTextureCube getIrradianceMap() const { return irradianceMap; } + Gfx::PTextureCube getSpecularMap() const { return specularMap; } + private: + Gfx::OTextureCube skybox; + Gfx::OTextureCube irradianceMap; + Gfx::OTextureCube specularMap; + friend class EnvironmentLoader; +}; +} // namespace Seele \ No newline at end of file diff --git a/src/Engine/Asset/FontAsset.cpp b/src/Engine/Asset/FontAsset.cpp index 4d6709c..8498c9e 100644 --- a/src/Engine/Asset/FontAsset.cpp +++ b/src/Engine/Asset/FontAsset.cpp @@ -28,16 +28,16 @@ void FontAsset::load(ArchiveBuffer& buffer) { } void FontAsset::loadFace() { - FT_Error error = FT_New_Memory_Face(ft, (unsigned char*)ttfFile.data(), ttfFile.size(), 0, &ft_face); + FT_Error error = FT_New_Memory_Face(ft, (unsigned char*)ttfFile.data(), (uint32)ttfFile.size(), 0, &ft_face); assert(!error); - blob = hb_blob_create(ttfFile.data(), ttfFile.size(), HB_MEMORY_MODE_DUPLICATE, nullptr, nullptr); + blob = hb_blob_create(ttfFile.data(), (uint32)ttfFile.size(), HB_MEMORY_MODE_DUPLICATE, nullptr, nullptr); hb_face = hb_face_create(blob, 0); hb_font = hb_font_create(hb_face); } UVector2 FontAsset::shapeText(std::string_view view, uint32 fontSize, Array& render) { loadGlyphs(fontSize); hb_buffer_t* buf = hb_buffer_create(); - hb_buffer_add_utf8(buf, view.data(), view.size(), 0, -1); + hb_buffer_add_utf8(buf, view.data(), (uint32)view.size(), 0, -1); hb_buffer_set_language(buf, hb_language_from_string("en", -1)); hb_buffer_set_script(buf, HB_SCRIPT_LATIN); hb_buffer_set_direction(buf, HB_DIRECTION_LTR); @@ -52,10 +52,10 @@ UVector2 FontAsset::shapeText(std::string_view view, uint32 fontSize, Arraynum_glyphs; ++i) { + for (int i = 0; i < ft_face->num_glyphs; ++i) { assert(FT_Load_Glyph(ft_face, i, FT_LOAD_RENDER) == 0); FontAsset::Glyph& glyph = fontSizes[fontSize].glyphs[i]; glyph.size = IVector2(ft_face->glyph->bitmap.width, ft_face->glyph->bitmap.rows); diff --git a/src/Engine/Asset/LevelAsset.cpp b/src/Engine/Asset/LevelAsset.cpp index 27ce4c8..c0d5a5e 100644 --- a/src/Engine/Asset/LevelAsset.cpp +++ b/src/Engine/Asset/LevelAsset.cpp @@ -9,6 +9,6 @@ LevelAsset::LevelAsset(std::string_view folderPath, std::string_view name) : Ass LevelAsset::~LevelAsset() {} -void LevelAsset::save(ArchiveBuffer& buffer) const { } +void LevelAsset::save(ArchiveBuffer&) const { } -void LevelAsset::load(ArchiveBuffer& buffer) { } +void LevelAsset::load(ArchiveBuffer&) { } diff --git a/src/Engine/Asset/LevelAsset.h b/src/Engine/Asset/LevelAsset.h index 1d34ec5..ece286c 100644 --- a/src/Engine/Asset/LevelAsset.h +++ b/src/Engine/Asset/LevelAsset.h @@ -5,7 +5,7 @@ namespace Seele { class LevelAsset : public Asset { public: - static constexpr uint64 IDENTIFIER = 0x20; + static constexpr uint64 IDENTIFIER = 0x40; LevelAsset(); LevelAsset(std::string_view folderPath, std::string_view name); virtual ~LevelAsset(); diff --git a/src/Engine/Asset/MaterialAsset.cpp b/src/Engine/Asset/MaterialAsset.cpp index 9a058a7..b90c64f 100644 --- a/src/Engine/Asset/MaterialAsset.cpp +++ b/src/Engine/Asset/MaterialAsset.cpp @@ -30,6 +30,6 @@ PMaterialInstanceAsset MaterialAsset::instantiate(const InstantiationParameter& asset->setBase(this); PMaterialInstanceAsset ref = asset; AssetRegistry::registerMaterialInstance(std::move(asset)); - AssetRegistry::saveAsset(ref, MaterialInstanceAsset::IDENTIFIER, ref->getFolderPath(), ref->getName()); + AssetRegistry::saveAsset(PAsset(ref), MaterialInstanceAsset::IDENTIFIER, ref->getFolderPath(), ref->getName()); return ref; } diff --git a/src/Engine/Asset/TextureAsset.cpp b/src/Engine/Asset/TextureAsset.cpp index 6517525..88118c5 100644 --- a/src/Engine/Asset/TextureAsset.cpp +++ b/src/Engine/Asset/TextureAsset.cpp @@ -31,9 +31,7 @@ void TextureAsset::load(ArchiveBuffer& buffer) { Serialization::load(buffer, ktxData); KTX_ASSERT( ktxTexture_CreateFromMemory(ktxData.data(), ktxData.size(), KTX_TEXTURE_CREATE_LOAD_IMAGE_DATA_BIT, (ktxTexture**)&ktxHandle)); - ktxTexture2_TranscodeBasis(ktxHandle, KTX_TTF_RGBA32, 0); - // ktxTexture2_DeflateZstd(ktxHandle, 0); Gfx::PGraphics graphics = buffer.getGraphics(); TextureCreateInfo createInfo = { @@ -47,7 +45,6 @@ void TextureAsset::load(ArchiveBuffer& buffer) { .width = ktxHandle->baseWidth, .height = ktxHandle->baseHeight, .depth = ktxHandle->baseDepth, - .layers = ktxHandle->numFaces, .elements = ktxHandle->numLayers, .useMip = true, .usage = Gfx::SE_IMAGE_USAGE_SAMPLED_BIT, diff --git a/src/Engine/Component/KeyboardInput.h b/src/Engine/Component/KeyboardInput.h index 9146c08..d11766c 100644 --- a/src/Engine/Component/KeyboardInput.h +++ b/src/Engine/Component/KeyboardInput.h @@ -5,14 +5,14 @@ namespace Seele { namespace Component { struct KeyboardInput { Seele::StaticArray(Seele::KeyCode::KEY_LAST)> keys; - bool mouse1; - bool mouse2; - float mouseX; - float mouseY; - float deltaX; - float deltaY; - float scrollX; - float scrollY; + bool mouse1 = false; + bool mouse2 = false; + float mouseX = 0.0f; + float mouseY = 0.0f; + float deltaX = 0.0f; + float deltaY = 0.0f; + float scrollX = 0.0f; + float scrollY = 0.0f; }; } // namespace Component } // namespace Seele \ No newline at end of file diff --git a/src/Engine/Containers/Array.h b/src/Engine/Containers/Array.h index 14482dd..be9e799 100644 --- a/src/Engine/Containers/Array.h +++ b/src/Engine/Containers/Array.h @@ -1,6 +1,7 @@ #pragma once -#include "EngineTypes.h" #include "Concepts.h" +#include "EngineTypes.h" +#include "MemoryResource.h" #include #include #include @@ -12,7 +13,7 @@ #endif namespace Seele { -template > struct Array { +template struct Array { public: template class IteratorBase { public: @@ -67,7 +68,7 @@ template > s }; using value_type = T; - using allocator_type = Allocator; + using allocator_type = std::pmr::polymorphic_allocator; using size_type = std::size_t; using difference_type = std::ptrdiff_t; using pointer = T*; @@ -82,12 +83,8 @@ template > s using reverse_iterator = std::reverse_iterator; using const_reverse_iterator = std::reverse_iterator; - constexpr Array() noexcept(noexcept(Allocator())) : arraySize(0), allocated(DEFAULT_ALLOC_SIZE), allocator(Allocator()) { - _data = allocateArray(DEFAULT_ALLOC_SIZE); - assert(_data != nullptr); - } - - constexpr explicit Array(const allocator_type& alloc) noexcept : arraySize(0), allocated(DEFAULT_ALLOC_SIZE), allocator(alloc) { + constexpr Array(const allocator_type& alloc = allocator_type()) noexcept + : arraySize(0), allocated(DEFAULT_ALLOC_SIZE), allocator(alloc) { _data = allocateArray(DEFAULT_ALLOC_SIZE); assert(_data != nullptr); } @@ -138,7 +135,8 @@ template > s assert(_data != nullptr); std::uninitialized_copy(other.begin(), other.end(), begin()); } - constexpr Array(const Array& other, const Allocator& alloc) : arraySize(other.arraySize), allocated(other.allocated), allocator(alloc) { + constexpr Array(const Array& other, const allocator_type& alloc) + : arraySize(other.arraySize), allocated(other.allocated), allocator(alloc) { _data = allocateArray(other.allocated); assert(_data != nullptr); std::uninitialized_copy(other.begin(), other.end(), begin()); @@ -150,7 +148,7 @@ template > s other.allocated = 0; other.arraySize = 0; } - constexpr Array(Array&& other, const Allocator& alloc) noexcept + constexpr Array(Array&& other, const allocator_type& alloc) noexcept : arraySize(std::move(other.arraySize)), allocated(std::move(other.allocated)), allocator(alloc) { _data = allocateArray(other.allocated); std::uninitialized_move(other.begin(), other.end(), begin()); @@ -179,8 +177,8 @@ template > s } return *this; } - Array& operator=(Array&& other) noexcept(std::allocator_traits::propagate_on_container_move_assignment::value || - std::allocator_traits::is_always_equal::value) { + Array& operator=(Array&& other) noexcept(std::allocator_traits::propagate_on_container_move_assignment::value || + std::allocator_traits::is_always_equal::value) { if (this != &other) { if (_data != nullptr) { clear(); @@ -294,7 +292,7 @@ template > s requires std::predicate constexpr void remove_if(Pred&& pred, bool keepOrder = true) { Iterator it; - while((it = find(pred)) != end()) { + while ((it = find(pred)) != end()) { erase(it, keepOrder); } } @@ -389,7 +387,11 @@ template > s assert(result != nullptr); return result; } - void deallocateArray(T* ptr, size_type size) { if(ptr == nullptr) return; allocator.deallocate(ptr, size); } + void deallocateArray(T* ptr, size_type size) { + if (ptr == nullptr) + return; + allocator.deallocate(ptr, size); + } template T& addInternal(Type&& t) noexcept { if (arraySize == allocated) { size_type newSize = arraySize + 1; @@ -449,7 +451,7 @@ template > s allocator_type allocator; }; -template constexpr bool operator==(const Array& lhs, const Array& rhs) { +template constexpr bool operator==(const Array& lhs, const Array& rhs) { if (lhs.size() != rhs.size()) { return false; } @@ -461,7 +463,7 @@ template constexpr bool operator==(const Array constexpr auto operator<=>(const Array& lhs, const Array& rhs) { +template constexpr auto operator<=>(const Array& lhs, const Array& rhs) { return std::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end()); } diff --git a/src/Engine/Containers/CMakeLists.txt b/src/Engine/Containers/CMakeLists.txt index 75715e1..a0bb38e 100644 --- a/src/Engine/Containers/CMakeLists.txt +++ b/src/Engine/Containers/CMakeLists.txt @@ -3,6 +3,8 @@ target_sources(Engine Array.h List.h Map.h + MemoryResource.h + MemoryResource.cpp Pair.h Set.h Tree.h) @@ -13,6 +15,7 @@ target_sources(Engine Array.h List.h Map.h + MemoryResource.h Pair.h Set.h Tree.h) \ No newline at end of file diff --git a/src/Engine/Containers/Map.h b/src/Engine/Containers/Map.h index 6a17412..566ed4b 100644 --- a/src/Engine/Containers/Map.h +++ b/src/Engine/Containers/Map.h @@ -5,12 +5,11 @@ #include "Tree.h" #include - namespace Seele { template struct _KeyFun { const KeyType& operator()(const PairType& pair) const { return pair.key; } }; -template , typename Allocator = std::pmr::polymorphic_allocator>> +template , typename Allocator = std::pmr::polymorphic_allocator>> struct Map : public Tree, _KeyFun>, Compare, Allocator> { using Super = Tree, _KeyFun>, Compare, Allocator>; using key_type = Super::key_type; @@ -35,8 +34,8 @@ struct Map : public Tree, _KeyFun>, Compare, Allocat : Super(comp, alloc) {} constexpr explicit Map(const Allocator& alloc) noexcept(noexcept(Compare())) : Super(alloc) {} constexpr Map(std::initializer_list> init) : Super(init) {} - constexpr mapped_type& operator[](const key_type& key) { - auto [it, inserted] = Super::insert(Pair(key, V())); + constexpr mapped_type& operator[](const key_type& key) { + auto [it, _] = Super::insert(Pair(key)); return it->value; } constexpr const mapped_type& operator[](const key_type& key) const { return Super::find(key)->value; } diff --git a/src/Engine/Containers/MemoryResource.cpp b/src/Engine/Containers/MemoryResource.cpp new file mode 100644 index 0000000..5fb97fc --- /dev/null +++ b/src/Engine/Containers/MemoryResource.cpp @@ -0,0 +1,40 @@ +#include "MemoryResource.h" +#include "Map.h" +#include + +using namespace Seele; + + +RefPtr MemoryManager::getAllocationCounter(const std::string& name) { + std::unique_lock l(getInstance().allocationMutex); + if (!getInstance().allocationCounters.contains(name)) { + getInstance().allocationCounters[name] = new uint64(0); + } + return getInstance().allocationCounters[name]; +} + +void MemoryManager::printAllocations() { + std::unique_lock l(getInstance().allocationMutex); + for (const auto& [name, counter] : getInstance().allocationCounters) { + if (name.empty()) { + std::cout << name << ": " << **counter << std::endl; + } else { + std::cout << name << ": " << **counter << std::endl; + } + } +} + +MemoryManager& MemoryManager::getInstance() { + static MemoryManager instance; + return instance; +} + +debug_resource* debug_resource::get(const std::string& name) { + static std::mutex resourcesMutex; + static std::map debugResources; + std::unique_lock l(resourcesMutex); + if (!debugResources.count(name)) { + debugResources.emplace(std::pair(name, debug_resource(name))); + } + return &debugResources[name]; +} \ No newline at end of file diff --git a/src/Engine/Containers/MemoryResource.h b/src/Engine/Containers/MemoryResource.h new file mode 100644 index 0000000..5e58fae --- /dev/null +++ b/src/Engine/Containers/MemoryResource.h @@ -0,0 +1,48 @@ +#pragma once +#include +#include +#include "MinimalEngine.h" + +namespace Seele { +class MemoryManager { + public: + static RefPtr getAllocationCounter(const std::string& name); + static void printAllocations(); + + private: + static MemoryManager& getInstance(); + std::mutex allocationMutex; + std::map> allocationCounters; +}; + +class debug_resource : public std::pmr::memory_resource { + public: + static debug_resource* get(const std::string& name); + debug_resource() : name(""), upstream(std::pmr::get_default_resource()), counter(MemoryManager::getAllocationCounter(name)) {} + debug_resource(std::string name, std::pmr::memory_resource* up = std::pmr::get_default_resource()) + : name(name), upstream(up), counter(MemoryManager::getAllocationCounter(name)) {} + debug_resource(const debug_resource& other) = delete; + debug_resource(debug_resource&& other) = default; + debug_resource& operator=(const debug_resource& other) = delete; + debug_resource& operator=(debug_resource&& other) = default; + + void* do_allocate(size_t bytes, size_t alignment) override { +// std::cout << name << " + " << bytes << std::endl; + *counter.getHandle() += bytes; + return upstream->allocate(bytes, alignment); + } + + void do_deallocate(void* ptr, size_t bytes, size_t alignment) override { + upstream->deallocate(ptr, bytes, alignment); +// std::cout << name << " - " << bytes << std::endl; + *counter.getHandle() -= bytes; + } + + bool do_is_equal(const std::pmr::memory_resource& other) const noexcept override { return this == &other; } + + private: + std::string name; + std::pmr::memory_resource* upstream; + RefPtr counter; +}; +} // namespace Seele \ No newline at end of file diff --git a/src/Engine/Containers/Pair.h b/src/Engine/Containers/Pair.h index 45cb210..ac9121d 100644 --- a/src/Engine/Containers/Pair.h +++ b/src/Engine/Containers/Pair.h @@ -3,14 +3,6 @@ namespace Seele { template struct Pair { public: - constexpr Pair() : key(K()), value(V()) {} - constexpr Pair(const K& key, const V& value) : key(key), value(value) {} - template constexpr Pair(U1&& x, U2&& y) : key(std::forward(x)), value(std::forward(y)) {} - Pair(const Pair& other) = default; - Pair(Pair&& other) = default; - ~Pair() {} - Pair& operator=(const Pair& other) = default; - Pair& operator=(Pair&& other) = default; constexpr friend bool operator<(const Pair& left, const Pair& right) { return left.key < right.key || (!(right.key < left.key) && left.value < right.value); } diff --git a/src/Engine/Containers/Tree.h b/src/Engine/Containers/Tree.h index 5daf90a..253feb5 100644 --- a/src/Engine/Containers/Tree.h +++ b/src/Engine/Containers/Tree.h @@ -1,18 +1,31 @@ #pragma once -#include "Pair.h" #include "Array.h" -#include - +#include "List.h" +#include "Pair.h" namespace Seele { template struct Tree { protected: struct Node { + Node() {} Node(Node* left, Node* right, const NodeData& nodeData) : leftChild(left), rightChild(right), data(nodeData) {} Node(Node* left, Node* right, NodeData&& nodeData) : leftChild(left), rightChild(right), data(std::move(nodeData)) {} - Node* leftChild; - Node* rightChild; + Node* leftChild = nullptr; + Node* rightChild = nullptr; + Node* parent = nullptr; NodeData data; + void setLeftChild(Node* child) { + leftChild = child; + if (child != nullptr) { + child->parent = this; + } + } + void setRightChild(Node* child) { + rightChild = child; + if (child != nullptr) { + child->parent = this; + } + } }; using NodeAlloc = std::allocator_traits::template rebind_alloc; @@ -25,49 +38,65 @@ template && beginIt = Array()) : node(x), traversal(std::move(beginIt)) {} - constexpr IteratorBase(const IteratorBase& i) : node(i.node), traversal(i.traversal) {} - constexpr IteratorBase(IteratorBase&& i) noexcept : node(std::move(i.node)), traversal(std::move(i.traversal)) {} + constexpr IteratorBase(Node* x = nullptr) : node(x) {} + constexpr IteratorBase(const IteratorBase& i) : node(i.node) {} + constexpr IteratorBase(IteratorBase&& i) noexcept : node(std::move(i.node)) {} constexpr IteratorBase& operator=(const IteratorBase& other) { if (this != &other) { node = other.node; - traversal = other.traversal; } return *this; } constexpr IteratorBase& operator=(IteratorBase&& other) noexcept { if (this != &other) { node = std::move(other.node); - traversal = std::move(other.traversal); } return *this; } constexpr reference operator*() const { return node->data; } - constexpr pointer operator->() const { return &(node->data); } + constexpr pointer operator->() const { return std::pointer_traits::pointer_to(**this); } constexpr bool operator!=(const IteratorBase& other) { return node != other.node; } constexpr bool operator==(const IteratorBase& other) { return node == other.node; } constexpr std::strong_ordering operator<=>(const IteratorBase& other) { return node <=> other.node; } constexpr IteratorBase& operator++() { - node = node->rightChild; - while (node != nullptr && node->leftChild != nullptr) { - traversal.add(node); - node = node->leftChild; - } - if (node == nullptr && traversal.size() > 0) { - node = traversal.back(); - traversal.pop(); + // if current node has no right subtree + if (node->rightChild == nullptr) { + Node* temp = node; + node = node->parent; + // walk up hierarchy until we were the left subtree of any parent + // this means that that parent is the correct next element + while (node->rightChild == temp) { + temp = node; + node = node->parent; + } + } else { + // if there is a right subtree, descend there + node = node->rightChild; + // and find the leftmost node in that tree + while (node->leftChild != nullptr) { + node = node->leftChild; + } } return *this; } constexpr IteratorBase& operator--() { - node = node->leftChild; - while (node != nullptr && node->rightChild != nullptr) { - traversal.add(node); - node = node->rightchild; - } - if (node == nullptr && traversal.size() > 0) { - node = traversal.back(); - traversal.pop(); + // if current node has no left subtree + if (node->leftChild == nullptr) { + Node* temp = node; + node = node->parent; + // walk up hierarchy until we were the right subtree of any parent + // this means that that parent is the correct next element + while (node->leftChild == temp) { + temp = node; + node = node->parent; + } + } else { + // if there is a left subtree, descend there + node = node->leftChild; + // and find the rightmost node in that tree + while (node->rightChild != nullptr) { + node = node->rightChild; + } } return *this; } @@ -81,11 +110,10 @@ template traversal; }; using Iterator = IteratorBase; using ConstIterator = IteratorBase; @@ -123,8 +151,8 @@ template data)); } root = nullptr; + pseudoRoot.setLeftChild(nullptr); markIteratorsDirty(); } constexpr iterator begin() { @@ -192,6 +222,7 @@ template data, key)) { return end(); } @@ -214,15 +245,18 @@ template insert(const NodeData& data) { auto [r, inserted] = _insert(root, data); root = r; + pseudoRoot.setLeftChild(root); return Pair(iterator(root), inserted); } constexpr Pair insert(NodeData&& data) { auto [r, inserted] = _insert(root, std::move(data)); root = r; + pseudoRoot.setLeftChild(root); return Pair(iterator(root), inserted); } constexpr iterator remove(const key_type& key) { root = _remove(root, key); + pseudoRoot.setLeftChild(root); return iterator(root); } @@ -241,29 +275,18 @@ template beginTraversal; - while (begin != nullptr) { - beginTraversal.add(begin); + // start at pseudoroot so that if no regular nodes exist begin == end + Node* begin = const_cast(&pseudoRoot); + while (begin != nullptr && begin->leftChild != nullptr) { begin = begin->leftChild; } - if (!beginTraversal.empty()) { - begin = beginTraversal.back(); - beginTraversal.pop(); - } - return Iterator(begin, std::move(beginTraversal)); - } - constexpr Iterator calcEndIterator() const { - Node* endIndex = root; - Array endTraversal; - while (endIndex != nullptr) { - endTraversal.add(endIndex); - endIndex = endIndex->rightChild; - } - return Iterator(endIndex, std::move(endTraversal)); + return Iterator(begin); } + constexpr Iterator calcEndIterator() const { return Iterator(const_cast(&pseudoRoot)); } NodeAlloc alloc; Node* root; + // where the end iterator points to + Node pseudoRoot; Iterator beginIt; Iterator endIt; bool iteratorsDirty; @@ -272,14 +295,14 @@ template rightChild; - x->rightChild = y->leftChild; - y->leftChild = x; + x->setRightChild(y->leftChild); + y->setLeftChild(x); return y; } Node* rotateRight(Node* x) { Node* y = x->leftChild; - x->leftChild = y->rightChild; - y->rightChild = x; + x->setLeftChild(y->rightChild); + y->setRightChild(x); return y; } template Pair _insert(Node* r, NodeDataType&& data) { @@ -299,13 +322,13 @@ template ::construct(alloc, newNode, nullptr, nullptr, std::forward(data)); if (comp(keyFun(newNode->data), keyFun(r->data))) { - newNode->rightChild = r; - newNode->leftChild = r->leftChild; - r->leftChild = nullptr; + newNode->setRightChild(r); + newNode->setLeftChild(r->leftChild); + r->setLeftChild(nullptr); } else { - newNode->leftChild = r; - newNode->rightChild = r->rightChild; - r->rightChild = nullptr; + newNode->setLeftChild(r); + newNode->setRightChild(r->rightChild); + r->setRightChild(nullptr); } _size++; return Pair(newNode, true); @@ -328,7 +351,7 @@ template leftChild, key); - r->rightChild = temp->rightChild; + r->setRightChild(temp->rightChild); } std::allocator_traits::destroy(alloc, temp); alloc.deallocate(temp, 1); @@ -345,11 +368,11 @@ template leftChild->data))) { - r->leftChild->leftChild = _splay(r->leftChild->leftChild, key); + r->leftChild->setLeftChild(_splay(r->leftChild->leftChild, key)); r = rotateRight(r); } else if (comp(keyFun(r->leftChild->data), key)) { - r->leftChild->rightChild = _splay(r->leftChild->rightChild, key); + r->leftChild->setRightChild(_splay(r->leftChild->rightChild, key)); if (r->leftChild->rightChild != nullptr) { r->leftChild = rotateLeft(r->leftChild); @@ -361,13 +384,13 @@ template rightChild->data))) { - r->rightChild->leftChild = _splay(r->rightChild->leftChild, key); + r->rightChild->setLeftChild(_splay(r->rightChild->leftChild, key)); if (r->rightChild->leftChild != nullptr) { - r->rightChild = rotateRight(r->rightChild); + r->setRightChild(rotateRight(r->rightChild)); } } else if (comp(keyFun(r->rightChild->data), key)) { - r->rightChild->rightChild = _splay(r->rightChild->rightChild, key); + r->rightChild->setRightChild(_splay(r->rightChild->rightChild, key)); r = rotateLeft(r); } diff --git a/src/Engine/Graphics/Buffer.h b/src/Engine/Graphics/Buffer.h index 0daf8ea..9043cc3 100644 --- a/src/Engine/Graphics/Buffer.h +++ b/src/Engine/Graphics/Buffer.h @@ -52,7 +52,7 @@ class IndexBuffer : public Buffer { virtual void executePipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage, SeAccessFlags dstAccess, SePipelineStageFlags dstStage) = 0; Gfx::SeIndexType indexType; - uint64 numIndices; + uint64 numIndices = 0; }; DEFINE_REF(IndexBuffer) @@ -81,7 +81,7 @@ class ShaderBuffer : public Buffer { virtual void updateContents(uint64 offset, uint64 size, void* data) = 0; virtual void* map() = 0; virtual void unmap() = 0; - constexpr uint32 getNumElements() const { return numElements; } + constexpr uint64 getNumElements() const { return numElements; } virtual void clear() = 0; @@ -91,7 +91,7 @@ class ShaderBuffer : public Buffer { virtual void executePipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage, SeAccessFlags dstAccess, SePipelineStageFlags dstStage) = 0; - uint32 numElements; + uint64 numElements; }; DEFINE_REF(ShaderBuffer) } // namespace Gfx diff --git a/src/Engine/Graphics/CBT/CBT.cpp b/src/Engine/Graphics/CBT/CBT.cpp index 46c7484..33baffc 100644 --- a/src/Engine/Graphics/CBT/CBT.cpp +++ b/src/Engine/Graphics/CBT/CBT.cpp @@ -120,7 +120,7 @@ uint32_t find_msb_64(uint64_t x) { CPUMesh Seele::generateCPUMesh(uint32 cbtNumElements) { CPUMesh result; - result.totalNumElements = edges.size() + cbtNumElements; + result.totalNumElements = (uint32)edges.size() + cbtNumElements; result.heapIDArray.resize(result.totalNumElements); result.neighborsArray.resize(result.totalNumElements); @@ -193,7 +193,6 @@ Matrix3 decodeSubdivisionMatrix(uint64 heapID) { void LebMatrixCache::init(Gfx::PGraphics graphics, uint32 depth) { cacheDepth = depth; uint32 matrixCount = 2ULL << cacheDepth; - Matrix3 m; std::vector table(matrixCount); table[0] = Matrix3({1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f}); for (uint64 heapID = 1ULL; heapID < (2ULL << cacheDepth); ++heapID) { @@ -799,7 +798,7 @@ void MeshUpdater::update(CBTMesh& mesh, Gfx::PDescriptorSet viewParamsSet, Gfx:: } void MeshUpdater::validation(CBTMesh& mesh, Gfx::PUniformBuffer geometryCB) { - uint32 numGroups = (mesh.totalNumElements + WORKGROUP_SIZE - 1) / WORKGROUP_SIZE; + //uint32 numGroups = (mesh.totalNumElements + WORKGROUP_SIZE - 1) / WORKGROUP_SIZE; /*Gfx::PDescriptorSet set = layout->allocateDescriptorSet(); set->updateBuffer(GEOMETRY_CB, 0, geometryCB); diff --git a/src/Engine/Graphics/CMakeLists.txt b/src/Engine/Graphics/CMakeLists.txt index c619c3d..2290016 100644 --- a/src/Engine/Graphics/CMakeLists.txt +++ b/src/Engine/Graphics/CMakeLists.txt @@ -1,4 +1,4 @@ -add_subdirectory(CBT/) +#add_subdirectory(CBT/) target_sources(Engine PRIVATE diff --git a/src/Engine/Graphics/Descriptor.cpp b/src/Engine/Graphics/Descriptor.cpp index db557dc..4d81705 100644 --- a/src/Engine/Graphics/Descriptor.cpp +++ b/src/Engine/Graphics/Descriptor.cpp @@ -38,6 +38,4 @@ void PipelineLayout::addDescriptorLayout(PDescriptorLayout layout) { descriptorS void PipelineLayout::addPushConstants(const SePushConstantRange& pushConstant) { pushConstants.add(pushConstant); } -void PipelineLayout::addMapping(std::string name, uint32 index) { - parameterMapping[name] = index; -} +void PipelineLayout::addMapping(std::string mappingName, uint32 index) { parameterMapping[mappingName] = index; } diff --git a/src/Engine/Graphics/Descriptor.h b/src/Engine/Graphics/Descriptor.h index 818d743..b454d9b 100644 --- a/src/Engine/Graphics/Descriptor.h +++ b/src/Engine/Graphics/Descriptor.h @@ -68,9 +68,7 @@ class DescriptorSet { virtual void updateBuffer(const std::string& name, uint32 index, Gfx::PVertexBuffer indexBuffer) = 0; virtual void updateBuffer(const std::string& name, uint32 index, Gfx::PIndexBuffer indexBuffer) = 0; virtual void updateSampler(const std::string& name, uint32 index, Gfx::PSampler samplerState) = 0; - virtual void updateTexture(const std::string& name, uint32 index, Gfx::PTexture2D texture) = 0; - virtual void updateTexture(const std::string& name, uint32 index, Gfx::PTexture3D texture) = 0; - virtual void updateTexture(const std::string& name, uint32 index, Gfx::PTextureCube texture) = 0; + virtual void updateTexture(const std::string& name, uint32 index, Gfx::PTexture texture) = 0; virtual void updateAccelerationStructure(const std::string& name, uint32 index, Gfx::PTopLevelAS as) = 0; bool operator<(PDescriptorSet other); diff --git a/src/Engine/Graphics/Graphics.h b/src/Engine/Graphics/Graphics.h index a585f45..b673a91 100644 --- a/src/Engine/Graphics/Graphics.h +++ b/src/Engine/Graphics/Graphics.h @@ -55,8 +55,8 @@ class Graphics { virtual OWindow createWindow(const WindowCreateInfo& createInfo) = 0; virtual OViewport createViewport(PWindow owner, const ViewportCreateInfo& createInfo) = 0; - virtual ORenderPass createRenderPass(RenderTargetLayout layout, Array dependencies, PViewport renderArea, - std::string name = "") = 0; + virtual ORenderPass createRenderPass(RenderTargetLayout layout, Array dependencies, URect renderArea, + std::string name = "", Array viewMasks = {0}, Array correlationMasks = {}) = 0; virtual void beginRenderPass(PRenderPass renderPass) = 0; virtual void endRenderPass() = 0; virtual void waitDeviceIdle() = 0; diff --git a/src/Engine/Graphics/Initializer.h b/src/Engine/Graphics/Initializer.h index 4889cb8..9eb4bfc 100644 --- a/src/Engine/Graphics/Initializer.h +++ b/src/Engine/Graphics/Initializer.h @@ -49,7 +49,6 @@ struct TextureCreateInfo { uint32 width = 1; uint32 height = 1; uint32 depth = 1; - uint32 layers = 1; uint32 elements = 1; uint32 samples = 1; bool useMip = false; diff --git a/src/Engine/Graphics/Meshlet.cpp b/src/Engine/Graphics/Meshlet.cpp index 88fb9d1..f3e2cee 100644 --- a/src/Engine/Graphics/Meshlet.cpp +++ b/src/Engine/Graphics/Meshlet.cpp @@ -25,7 +25,7 @@ void buildAdjacency(const uint32 numVerts, const Array& indices, Adjacen triangleOffset += info.trianglesPerVertex[j]; } - uint32 numTriangles = indices.size() / 3; + uint32 numTriangles = (uint32)indices.size() / 3; info.triangleData.resize(triangleOffset); Array offsets = info.indexBufferOffset; for (uint32 k = 0; k < numTriangles; ++k) { diff --git a/src/Engine/Graphics/RayTracing.cpp b/src/Engine/Graphics/RayTracing.cpp index 454277e..79998c9 100644 --- a/src/Engine/Graphics/RayTracing.cpp +++ b/src/Engine/Graphics/RayTracing.cpp @@ -1,5 +1,4 @@ #include "RayTracing.h" -#include "RayTracing.h" using namespace Seele::Gfx; diff --git a/src/Engine/Graphics/RayTracing.h b/src/Engine/Graphics/RayTracing.h index adcc474..ac0d89b 100644 --- a/src/Engine/Graphics/RayTracing.h +++ b/src/Engine/Graphics/RayTracing.h @@ -1,5 +1,6 @@ #pragma once #include "Resources.h" +#include "Graphics/Descriptor.h" namespace Seele { namespace Gfx { diff --git a/src/Engine/Graphics/RenderPass/BasePass.cpp b/src/Engine/Graphics/RenderPass/BasePass.cpp index 561a9b4..9cc43ab 100644 --- a/src/Engine/Graphics/RenderPass/BasePass.cpp +++ b/src/Engine/Graphics/RenderPass/BasePass.cpp @@ -1,6 +1,7 @@ #include "BasePass.h" #include "Actor/CameraActor.h" #include "Asset/AssetRegistry.h" +#include "Asset/EnvironmentMapAsset.h" #include "Component/Camera.h" #include "Component/Mesh.h" #include "Component/WaterTile.h" @@ -78,8 +79,8 @@ BasePass::BasePass(Gfx::PGraphics graphics, PScene scene) : RenderPass(graphics) }); } skybox = Seele::Component::Skybox{ - .day = AssetRegistry::findTexture("", "skybox")->getTexture().cast(), - .night = AssetRegistry::findTexture("", "skybox")->getTexture().cast(), + .day = scene->getLightEnvironment()->getEnvironmentMap()->getIrradianceMap(), + .night = scene->getLightEnvironment()->getEnvironmentMap()->getIrradianceMap(), .fogColor = Vector(0.1, 0.1, 0.8), .blendFactor = 0, }; @@ -156,8 +157,7 @@ void BasePass::render() { vertexData->getInstanceDataSet()->updateBuffer(VertexData::CULLINGDATA_NAME, 0, cullingBuffer); vertexData->getInstanceDataSet()->writeChanges(); permutation.setVertexData(vertexData->getTypeName()); - const auto& materials = vertexData->getMaterialData(); - for (const auto& materialData : materials) { + for (const auto& materialData : vertexData->getMaterialData()) { // material not used for any active meshes, skip if (materialData.instances.size() == 0) continue; @@ -200,8 +200,7 @@ void BasePass::render() { .attachmentCount = 1, }, }; - Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo)); - command->bindPipeline(pipeline); + command->bindPipeline(graphics->createGraphicsPipeline(std::move(pipelineInfo))); } else { Gfx::LegacyPipelineCreateInfo pipelineInfo = { .vertexShader = collection->vertexShader, @@ -221,8 +220,7 @@ void BasePass::render() { .attachmentCount = 1, }, }; - Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo)); - command->bindPipeline(pipeline); + command->bindPipeline(graphics->createGraphicsPipeline(std::move(pipelineInfo))); } command->bindDescriptor({viewParamsSet, vertexData->getVertexDataSet(), vertexData->getInstanceDataSet(), scene->getLightEnvironment()->getDescriptorSet(), Material::getDescriptorSet(), opaqueCulling}); @@ -231,7 +229,7 @@ void BasePass::render() { Gfx::SE_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(VertexData::DrawCallOffsets), &drawCall.offsets); if (graphics->supportMeshShading()) { - command->drawMesh(drawCall.instanceMeshData.size(), 1, 1); + command->drawMesh((uint32)drawCall.instanceMeshData.size(), 1, 1); } else { command->bindIndexBuffer(vertexData->getIndexBuffer()); for (const auto& meshData : drawCall.instanceMeshData) { @@ -252,7 +250,7 @@ void BasePass::render() { { Gfx::ORenderCommand skyboxCommand = graphics->createRenderCommand("SkyboxRender"); skyboxCommand->setViewport(viewport); - skyboxCommand->bindPipeline(pipeline); + skyboxCommand->bindPipeline(skyboxPipeline); skyboxCommand->bindDescriptor({viewParamsSet, skyboxDataSet, textureSet}); skyboxCommand->draw(36, 1, 0, 0); graphics->executeCommands(std::move(skyboxCommand)); @@ -409,8 +407,8 @@ void BasePass::publishOutputs() { }); depthAttachment = - Gfx::RenderTargetAttachment(basePassDepth, Gfx::SE_IMAGE_LAYOUT_UNDEFINED, Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, - Gfx::SE_ATTACHMENT_LOAD_OP_DONT_CARE, Gfx::SE_ATTACHMENT_STORE_OP_DONT_CARE); + Gfx::RenderTargetAttachment(Gfx::PTexture2D(basePassDepth), Gfx::SE_IMAGE_LAYOUT_UNDEFINED, Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, + Gfx::SE_ATTACHMENT_LOAD_OP_DONT_CARE, Gfx::SE_ATTACHMENT_STORE_OP_STORE); msDepthAttachment = Gfx::RenderTargetAttachment(msBasePassDepth, Gfx::SE_IMAGE_LAYOUT_UNDEFINED, Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, @@ -474,7 +472,7 @@ void BasePass::createRenderPass() { Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, }, }; - renderPass = graphics->createRenderPass(std::move(layout), std::move(dependency), viewport, "BasePass"); + renderPass = graphics->createRenderPass(std::move(layout), std::move(dependency), viewport->getRenderArea(), "BasePass"); oLightIndexList = resources->requestBuffer("LIGHTCULLING_OLIGHTLIST"); tLightIndexList = resources->requestBuffer("LIGHTCULLING_TLIGHTLIST"); oLightGrid = resources->requestTexture("LIGHTCULLING_OLIGHTGRID"); @@ -623,6 +621,6 @@ void BasePass::createRenderPass() { .attachmentCount = 1, }, }; - pipeline = graphics->createGraphicsPipeline(std::move(gfxInfo)); + skyboxPipeline = graphics->createGraphicsPipeline(std::move(gfxInfo)); } } diff --git a/src/Engine/Graphics/RenderPass/BasePass.h b/src/Engine/Graphics/RenderPass/BasePass.h index 81507cc..7a2305f 100644 --- a/src/Engine/Graphics/RenderPass/BasePass.h +++ b/src/Engine/Graphics/RenderPass/BasePass.h @@ -2,7 +2,6 @@ #include "MinimalEngine.h" #include "RenderPass.h" #include "WaterRenderer.h" -#include "TerrainRenderer.h" namespace Seele { DECLARE_REF(CameraActor) @@ -56,7 +55,7 @@ class BasePass : public RenderPass { Gfx::PShaderBuffer cullingBuffer; //OWaterRenderer waterRenderer; - OTerrainRenderer terrainRenderer; + //OTerrainRenderer terrainRenderer; // Debug rendering Gfx::OVertexInput debugVertexInput; @@ -74,7 +73,7 @@ class BasePass : public RenderPass { Gfx::OVertexShader vertexShader; Gfx::OFragmentShader fragmentShader; Gfx::OPipelineLayout pipelineLayout; - Gfx::PGraphicsPipeline pipeline; + Gfx::PGraphicsPipeline skyboxPipeline; Gfx::OSampler skyboxSampler; struct SkyboxData { Matrix4 transformMatrix; diff --git a/src/Engine/Graphics/RenderPass/CMakeLists.txt b/src/Engine/Graphics/RenderPass/CMakeLists.txt index 7102259..a5fd61a 100644 --- a/src/Engine/Graphics/RenderPass/CMakeLists.txt +++ b/src/Engine/Graphics/RenderPass/CMakeLists.txt @@ -15,8 +15,8 @@ target_sources(Engine RenderGraphResources.cpp RenderPass.h RenderPass.cpp - TerrainRenderer.h - TerrainRenderer.cpp + #TerrainRenderer.h + #TerrainRenderer.cpp ToneMappingPass.h ToneMappingPass.cpp UIPass.h @@ -38,6 +38,6 @@ target_sources(Engine RenderGraph.h RenderGraphResources.h RenderPass.h - TerrainRenderer.h + #TerrainRenderer.h UIPass.h VisibilityPass.h) \ No newline at end of file diff --git a/src/Engine/Graphics/RenderPass/CachedDepthPass.cpp b/src/Engine/Graphics/RenderPass/CachedDepthPass.cpp index 8b0b44a..f6f717c 100644 --- a/src/Engine/Graphics/RenderPass/CachedDepthPass.cpp +++ b/src/Engine/Graphics/RenderPass/CachedDepthPass.cpp @@ -1,5 +1,6 @@ #include "CachedDepthPass.h" #include "Graphics/Shader.h" +#include "Graphics/Pipeline.h" using namespace Seele; @@ -111,7 +112,7 @@ void CachedDepthPass::render() { command->pushConstants(Gfx::SE_SHADER_STAGE_TASK_BIT_EXT | Gfx::SE_SHADER_STAGE_VERTEX_BIT, 0, sizeof(VertexData::DrawCallOffsets), &offsets); if (graphics->supportMeshShading()) { - command->drawMesh(vertexData->getNumInstances(), 1, 1); + command->drawMesh((uint32)vertexData->getNumInstances(), 1, 1); } else { const auto& materials = vertexData->getMaterialData(); for (const auto& materialData : materials) { @@ -202,5 +203,5 @@ void CachedDepthPass::createRenderPass() { Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, }, }; - renderPass = graphics->createRenderPass(std::move(layout), std::move(dependency), viewport, "CachedDepthPass"); + renderPass = graphics->createRenderPass(std::move(layout), std::move(dependency), viewport->getRenderArea(), "CachedDepthPass"); } diff --git a/src/Engine/Graphics/RenderPass/DepthCullingPass.cpp b/src/Engine/Graphics/RenderPass/DepthCullingPass.cpp index 0e6190d..d111540 100644 --- a/src/Engine/Graphics/RenderPass/DepthCullingPass.cpp +++ b/src/Engine/Graphics/RenderPass/DepthCullingPass.cpp @@ -185,7 +185,7 @@ void DepthCullingPass::render() { command->pushConstants(Gfx::SE_SHADER_STAGE_TASK_BIT_EXT | Gfx::SE_SHADER_STAGE_VERTEX_BIT, 0, sizeof(VertexData::DrawCallOffsets), &offsets); if (graphics->supportMeshShading()) { - command->drawMesh(vertexData->getNumInstances(), 1, 1); + command->drawMesh((uint32)vertexData->getNumInstances(), 1, 1); } else { const auto& materials = vertexData->getMaterialData(); for (const auto& materialData : materials) { @@ -306,5 +306,5 @@ void DepthCullingPass::createRenderPass() { Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, }, }; - renderPass = graphics->createRenderPass(std::move(layout), std::move(dependency), viewport, "DepthCullingPass"); + renderPass = graphics->createRenderPass(std::move(layout), std::move(dependency), viewport->getRenderArea(), "DepthCullingPass"); } diff --git a/src/Engine/Graphics/RenderPass/LightCullingPass.cpp b/src/Engine/Graphics/RenderPass/LightCullingPass.cpp index 099031d..4835692 100644 --- a/src/Engine/Graphics/RenderPass/LightCullingPass.cpp +++ b/src/Engine/Graphics/RenderPass/LightCullingPass.cpp @@ -3,6 +3,7 @@ #include "Component/Camera.h" #include "Graphics/Command.h" #include "Graphics/Graphics.h" +#include "Graphics/Pipeline.h" #include "Math/Vector.h" #include "RenderGraph.h" #include "Scene/Scene.h" @@ -48,8 +49,8 @@ void LightCullingPass::render() { cullingDescriptorSet->updateBuffer(TLIGHTINDEXCOUNTER_NAME, 0, tLightIndexCounter); cullingDescriptorSet->updateBuffer(OLIGHTINDEXLIST_NAME, 0, oLightIndexList); cullingDescriptorSet->updateBuffer(TLIGHTINDEXLIST_NAME, 0, tLightIndexList); - cullingDescriptorSet->updateTexture(OLIGHTGRID_NAME, 0, oLightGrid); - cullingDescriptorSet->updateTexture(TLIGHTGRID_NAME, 0, tLightGrid); + cullingDescriptorSet->updateTexture(OLIGHTGRID_NAME, 0, Gfx::PTexture2D(oLightGrid)); + cullingDescriptorSet->updateTexture(TLIGHTGRID_NAME, 0, Gfx::PTexture2D(tLightGrid)); cullingDescriptorSet->writeChanges(); Gfx::OComputeCommand computeCommand = graphics->createComputeCommand("CullingCommand"); if (getGlobals().useLightCulling) { @@ -278,7 +279,7 @@ void LightCullingPass::setupFrustums() { frustumBuffer->pipelineBarrier(Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT, Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT); - Gfx::PDescriptorSet dispatchParamsSet = dispatchParamsLayout->allocateDescriptorSet(); + dispatchParamsSet = dispatchParamsLayout->allocateDescriptorSet(); dispatchParamsSet->updateConstants("numThreadGroups", 0, &numThreadGroups); dispatchParamsSet->updateConstants("numThreads", 0, &numThreads); dispatchParamsSet->updateBuffer(FRUSTUMBUFFER_NAME, 0, frustumBuffer); @@ -292,8 +293,5 @@ void LightCullingPass::setupFrustums() { commands.add(std::move(command)); graphics->executeCommands(std::move(commands)); frustumBuffer->pipelineBarrier(Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT, - Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT); - Frustum* frustums = (Frustum*)frustumBuffer->map(); - graphics->waitDeviceIdle(); - + Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT); } diff --git a/src/Engine/Graphics/RenderPass/RayTracingPass.cpp b/src/Engine/Graphics/RenderPass/RayTracingPass.cpp index 8b6bb0a..c2587c8 100644 --- a/src/Engine/Graphics/RenderPass/RayTracingPass.cpp +++ b/src/Engine/Graphics/RenderPass/RayTracingPass.cpp @@ -1,6 +1,7 @@ #include "RayTracingPass.h" #include "Asset/AssetRegistry.h" #include "Asset/MeshAsset.h" +#include "Asset/EnvironmentMapAsset.h" #include "Graphics/Mesh.h" #include "Graphics/RayTracing.h" #include "Graphics/Shader.h" @@ -59,7 +60,7 @@ RayTracingPass::RayTracingPass(Gfx::PGraphics graphics, PScene scene) : RenderPa .useMaterial = true, .rayTracing = true, }); - skyBox = AssetRegistry::findTexture("", "skybox")->getTexture().cast(); + skyBox = AssetRegistry::findEnvironmentMap("", "newport_loft")->getIrradianceMap(); skyBoxSampler = graphics->createSampler({}); } @@ -74,6 +75,8 @@ void RayTracingPass::beginFrame(const Component::Camera& cam) { } void RayTracingPass::render() { + texture->changeLayout(Gfx::SE_IMAGE_LAYOUT_GENERAL, Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, + Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR); Array callableGroups; Array accelerationStructures; Array instanceData; @@ -129,7 +132,18 @@ void RayTracingPass::render() { } } pipeline = graphics->createRayTracingPipeline(Gfx::RayTracingPipelineCreateInfo{ - .pipelineLayout = pipelineLayout, .rayGenGroup = {.shader = rayGen}, .hitGroups = callableGroups, .missGroups = {{.shader = miss}}, + .pipelineLayout = pipelineLayout, + .rayGenGroup = + { + .shader = rayGen, + }, + .hitGroups = callableGroups, + .missGroups = + { + { + .shader = miss, + }, + }, //.callableGroups = callableGroups, }); tlas = graphics->createTopLevelAccelerationStructure(Gfx::TopLevelASCreateInfo{ @@ -138,8 +152,8 @@ void RayTracingPass::render() { }); Gfx::PDescriptorSet desc = paramsLayout->allocateDescriptorSet(); desc->updateAccelerationStructure(TLAS_NAME, 0, tlas); - desc->updateTexture(ACCUMULATOR_NAME, 0, radianceAccumulator); - desc->updateTexture(TEXTURE_NAME, 0, texture); + desc->updateTexture(ACCUMULATOR_NAME, 0, Gfx::PTexture2D(radianceAccumulator)); + desc->updateTexture(TEXTURE_NAME, 0, Gfx::PTexture2D(texture)); desc->updateBuffer(INDEXBUFFER_NAME, 0, StaticMeshVertexData::getInstance()->getIndexBuffer()); desc->updateTexture(SKYBOX_NAME, 0, skyBox); desc->updateSampler(SKYSAMPLER_NAME, 0, skyBoxSampler); @@ -168,15 +182,9 @@ void RayTracingPass::render() { } pass++; std::cout << pass << std::endl; - texture->pipelineBarrier(Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR, - Gfx::SE_ACCESS_TRANSFER_READ_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT); Array commands; commands.add(std::move(command)); graphics->executeCommands(std::move(commands)); - viewport->getOwner()->getBackBuffer()->changeLayout(Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, Gfx::SE_ACCESS_NONE, - Gfx::SE_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, - Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT); - graphics->copyTexture(Gfx::PTexture2D(texture), viewport->getOwner()->getBackBuffer()); } void RayTracingPass::endFrame() {} @@ -200,6 +208,8 @@ void RayTracingPass::publishOutputs() { texture->changeLayout(Gfx::SE_IMAGE_LAYOUT_GENERAL, Gfx::SE_ACCESS_NONE, Gfx::SE_PIPELINE_STAGE_TOP_OF_PIPE_BIT, Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT | Gfx::SE_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR); + resources->registerRenderPassOutput("BASEPASS_COLOR", Gfx::RenderTargetAttachment(texture, Gfx::SE_IMAGE_LAYOUT_UNDEFINED, + Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)); ShaderCompilationInfo compileInfo = { .name = "RayGenMiss", .modules = {"RayGen", "AnyHit", "Miss"}, diff --git a/src/Engine/Graphics/RenderPass/TerrainRenderer.cpp b/src/Engine/Graphics/RenderPass/TerrainRenderer.cpp index 045a2b4..fdb89ea 100644 --- a/src/Engine/Graphics/RenderPass/TerrainRenderer.cpp +++ b/src/Engine/Graphics/RenderPass/TerrainRenderer.cpp @@ -25,7 +25,7 @@ TerrainRenderer::TerrainRenderer(Gfx::PGraphics graphics, PScene scene, Gfx::PDe plainMesh.gpuCBT.bufferCount = 2; for (uint32 i = 0; i < 2; ++i) { uint32 bufferSize = cbt.bufferSize(i); - uint32 elementSize = cbt.elementSize(i); + //uint32 elementSize = cbt.elementSize(i); plainMesh.gpuCBT.bufferArray[i] = graphics->createShaderBuffer(ShaderBufferCreateInfo{ .sourceData = { @@ -189,7 +189,7 @@ TerrainRenderer::TerrainRenderer(Gfx::PGraphics graphics, PScene scene, Gfx::PDe baseMesh.vertexBuffer->pipelineBarrier(Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT, Gfx::SE_ACCESS_SHADER_READ_BIT | Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT); - uint32 indexBufferSize = cpuMesh.totalNumElements * sizeof(UVector); + //uint32 indexBufferSize = cpuMesh.totalNumElements * sizeof(UVector); Array indices; for (uint32 i = 0; i < cpuMesh.totalNumElements * 3; ++i) indices.add(i); diff --git a/src/Engine/Graphics/RenderPass/ToneMappingPass.cpp b/src/Engine/Graphics/RenderPass/ToneMappingPass.cpp index b1808ad..8b343df 100644 --- a/src/Engine/Graphics/RenderPass/ToneMappingPass.cpp +++ b/src/Engine/Graphics/RenderPass/ToneMappingPass.cpp @@ -131,7 +131,7 @@ void ToneMappingPass::render() { Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT); histogramLayout->reset(); - Gfx::PDescriptorSet histogramSet = histogramLayout->allocateDescriptorSet(); + histogramSet = histogramLayout->allocateDescriptorSet(); histogramSet->updateConstants("minLogLum", 0, &minLogLum); histogramSet->updateConstants("inverseLogLumRange", 0, &inverseLogLumRange); histogramSet->updateConstants("timeCoeff", 0, &timeCoeff); @@ -216,7 +216,7 @@ void ToneMappingPass::createRenderPass() { .dstAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, }, }; - renderPass = graphics->createRenderPass(targetLayout, dependency, viewport, "ToneMappingPass"); + renderPass = graphics->createRenderPass(targetLayout, dependency, viewport->getRenderArea(), "ToneMappingPass"); pipeline = graphics->createGraphicsPipeline(Gfx::LegacyPipelineCreateInfo{ .vertexShader = vert, .fragmentShader = frag, diff --git a/src/Engine/Graphics/RenderPass/UIPass.cpp b/src/Engine/Graphics/RenderPass/UIPass.cpp index d019e03..0d64159 100644 --- a/src/Engine/Graphics/RenderPass/UIPass.cpp +++ b/src/Engine/Graphics/RenderPass/UIPass.cpp @@ -62,9 +62,9 @@ void UIPass::beginFrame(const Component::Camera& cam) { float x = render.position.x; float y = render.position.y; //todo: convert using actual tree depth - uint32 textureIndex = -1ul; + uint32 textureIndex = std::numeric_limits::max(); if (render.backgroundTexture != nullptr) { - textureIndex = usedTextures.size(); + textureIndex = (uint32)usedTextures.size(); usedTextures.add(render.backgroundTexture); } elements.add(RenderElementStyle{ @@ -112,7 +112,7 @@ void UIPass::render() { command->setViewport(viewport); command->bindPipeline(uiPipeline); command->bindDescriptor({viewParamsSet, uiDescriptorSet}); - command->draw(4, elements.size(), 0, 0); + command->draw(4, (uint32)elements.size(), 0, 0); commands.add(std::move(command)); graphics->executeCommands(std::move(commands)); graphics->endRenderPass(); @@ -170,7 +170,7 @@ void UIPass::createRenderPass() { Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, }, }; - renderPass = graphics->createRenderPass(std::move(layout), dependency, viewport, "TextPass"); + renderPass = graphics->createRenderPass(std::move(layout), dependency, viewport->getRenderArea(), "TextPass"); graphics->beginShaderCompilation(ShaderCompilationInfo{ .name = "TextVertex", diff --git a/src/Engine/Graphics/RenderPass/UIPass.h b/src/Engine/Graphics/RenderPass/UIPass.h index 55a94ac..2162202 100644 --- a/src/Engine/Graphics/RenderPass/UIPass.h +++ b/src/Engine/Graphics/RenderPass/UIPass.h @@ -42,7 +42,7 @@ class UIPass : public RenderPass { Vector color; float opacity = 1; float z = 0; - uint32 textureIndex = -1ul; + uint32 textureIndex = std::numeric_limits::max(); uint32 pad0; uint32 pad1; }; diff --git a/src/Engine/Graphics/RenderPass/WaterRenderer.cpp b/src/Engine/Graphics/RenderPass/WaterRenderer.cpp index 785b0a2..7468c3d 100644 --- a/src/Engine/Graphics/RenderPass/WaterRenderer.cpp +++ b/src/Engine/Graphics/RenderPass/WaterRenderer.cpp @@ -10,8 +10,8 @@ WaterRenderer::WaterRenderer(Gfx::PGraphics graphics, PScene scene, Gfx::PDescri : graphics(graphics), scene(scene) { skyBox = AssetRegistry::findTexture("", "skyboxsun5deg_tn")->getTexture().cast(); logN = (int)log2(params.N); - threadGroupsX = ceil(params.N / 8.0f); - threadGroupsY = ceil(params.N / 8.0f); + threadGroupsX = (uint32)ceil(params.N / 8.0f); + threadGroupsY = (uint32)ceil(params.N / 8.0f); materialUniforms = graphics->createUniformBuffer(UniformBufferCreateInfo{ .sourceData = @@ -263,7 +263,7 @@ WaterRenderer::WaterRenderer(Gfx::PGraphics graphics, PScene scene, Gfx::PDescri .windSpeed = 2, .windDirection = 22, .fetch = 100000, - .spreadBlend = 0.642, + .spreadBlend = 0.642f, .swell = 1, .peakEnhancement = 1, .shortWavesFade = 0.25f, @@ -523,8 +523,8 @@ void WaterRenderer::updateFFTDescriptor() { spectrumBuffer->pipelineBarrier(Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT, Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT); - params.deltaTime = Gfx::getCurrentFrameDelta(); - params.frameTime = Gfx::getCurrentFrameTime(); + params.deltaTime = (float)Gfx::getCurrentFrameDelta(); + params.frameTime = (float)Gfx::getCurrentFrameTime(); paramsBuffer->updateContents(0, sizeof(ComputeParams), ¶ms); paramsBuffer->pipelineBarrier(Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT, Gfx::SE_ACCESS_UNIFORM_READ_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT); diff --git a/src/Engine/Graphics/RenderPass/WaterRenderer.h b/src/Engine/Graphics/RenderPass/WaterRenderer.h index 33648fc..b995f4c 100644 --- a/src/Engine/Graphics/RenderPass/WaterRenderer.h +++ b/src/Engine/Graphics/RenderPass/WaterRenderer.h @@ -57,8 +57,8 @@ class WaterRenderer { }; StaticArray displaySpectrums; struct ComputeParams { - float frameTime; - float deltaTime; + float frameTime = 0.0f; + float deltaTime = 0.0f; float gravity = 9.81f; float repeatTime = 200.0f; float depth = 20.0f; diff --git a/src/Engine/Graphics/RenderTarget.cpp b/src/Engine/Graphics/RenderTarget.cpp index d2ec3e0..4651da7 100644 --- a/src/Engine/Graphics/RenderTarget.cpp +++ b/src/Engine/Graphics/RenderTarget.cpp @@ -9,6 +9,12 @@ RenderTargetAttachment::RenderTargetAttachment(PTexture2D texture, SeImageLayout : clear(), componentFlags(0), texture(texture), initialLayout(initialLayout), finalLayout(finalLayout), loadOp(loadOp), storeOp(storeOp), stencilLoadOp(stencilLoadOp), stencilStoreOp(stencilStoreOp) {} +RenderTargetAttachment::RenderTargetAttachment(PTextureCube texture, SeImageLayout initialLayout, SeImageLayout finalLayout, + SeAttachmentLoadOp loadOp, SeAttachmentStoreOp storeOp, SeAttachmentLoadOp stencilLoadOp, + SeAttachmentStoreOp stencilStoreOp) + : clear(), componentFlags(0), texture(texture), initialLayout(initialLayout), finalLayout(finalLayout), loadOp(loadOp), + storeOp(storeOp), stencilLoadOp(stencilLoadOp), stencilStoreOp(stencilStoreOp) {} + RenderTargetAttachment::RenderTargetAttachment(PViewport viewport, SeImageLayout initialLayout, SeImageLayout finalLayout, SeAttachmentLoadOp loadOp, SeAttachmentStoreOp storeOp, SeAttachmentLoadOp stencilLoadOp, SeAttachmentStoreOp stencilStoreOp) diff --git a/src/Engine/Graphics/RenderTarget.h b/src/Engine/Graphics/RenderTarget.h index 6aed4b4..376e87b 100644 --- a/src/Engine/Graphics/RenderTarget.h +++ b/src/Engine/Graphics/RenderTarget.h @@ -14,16 +14,21 @@ class RenderTargetAttachment { SeAttachmentStoreOp storeOp = SE_ATTACHMENT_STORE_OP_STORE, SeAttachmentLoadOp stencilLoadOp = SE_ATTACHMENT_LOAD_OP_DONT_CARE, SeAttachmentStoreOp stencilStoreOp = SE_ATTACHMENT_STORE_OP_DONT_CARE); - + RenderTargetAttachment(PTextureCube texture, SeImageLayout initialLayout, SeImageLayout finalLayout, + SeAttachmentLoadOp loadOp = SE_ATTACHMENT_LOAD_OP_LOAD, + SeAttachmentStoreOp storeOp = SE_ATTACHMENT_STORE_OP_STORE, + SeAttachmentLoadOp stencilLoadOp = SE_ATTACHMENT_LOAD_OP_DONT_CARE, + SeAttachmentStoreOp stencilStoreOp = SE_ATTACHMENT_STORE_OP_DONT_CARE); RenderTargetAttachment(PViewport viewport, SeImageLayout initialLayout, SeImageLayout finalLayout, SeAttachmentLoadOp loadOp = SE_ATTACHMENT_LOAD_OP_LOAD, SeAttachmentStoreOp storeOp = SE_ATTACHMENT_STORE_OP_STORE, SeAttachmentLoadOp stencilLoadOp = SE_ATTACHMENT_LOAD_OP_DONT_CARE, SeAttachmentStoreOp stencilStoreOp = SE_ATTACHMENT_STORE_OP_DONT_CARE); ~RenderTargetAttachment(); - PTexture2D getTexture() const { + void setTexture(PTexture _texture) { texture = _texture; } + PTexture getTexture() const { if (viewport != nullptr) { - return viewport->getOwner()->getBackBuffer(); + return PTexture(viewport->getOwner()->getBackBuffer()); } return texture; } @@ -68,7 +73,7 @@ class RenderTargetAttachment { SeColorComponentFlags componentFlags = 0; protected: - PTexture2D texture = nullptr; + PTexture texture = nullptr; PViewport viewport = nullptr; SeImageLayout initialLayout = SE_IMAGE_LAYOUT_UNDEFINED; SeImageLayout finalLayout = SE_IMAGE_LAYOUT_UNDEFINED; diff --git a/src/Engine/Graphics/StaticMeshVertexData.cpp b/src/Engine/Graphics/StaticMeshVertexData.cpp index 3457866..7b43ef5 100644 --- a/src/Engine/Graphics/StaticMeshVertexData.cpp +++ b/src/Engine/Graphics/StaticMeshVertexData.cpp @@ -7,9 +7,7 @@ using namespace Seele; -extern List vertexDataList; - -StaticMeshVertexData::StaticMeshVertexData() { vertexDataList.add(this); } +StaticMeshVertexData::StaticMeshVertexData() { VertexData::addVertexDataInstance(this); } StaticMeshVertexData::~StaticMeshVertexData() {} @@ -41,11 +39,12 @@ void StaticMeshVertexData::loadTangents(uint64 offset, const Array& std::memcpy(tanData.data() + offset, data.data(), data.size() * sizeof(TangentType)); dirty = true; } -void StaticMeshVertexData::loadBitangents(uint64 offset, const Array& data) { + +/*void StaticMeshVertexData::loadBitangents(uint64 offset, const Array& data) { assert(offset + data.size() <= head); std::memcpy(bitData.data() + offset, data.data(), data.size() * sizeof(BiTangentType)); dirty = true; -} +}*/ void StaticMeshVertexData::loadColors(uint64 offset, const Array& data) { assert(offset + data.size() <= head); @@ -71,17 +70,17 @@ void StaticMeshVertexData::serializeMesh(MeshId id, ArchiveBuffer& buffer) { Array pos(numVertices); Array nor(numVertices); Array tan(numVertices); - Array bit(numVertices); + //Array bit(numVertices); Array col(numVertices); std::memcpy(pos.data(), posData.data() + offset, numVertices * sizeof(PositionType)); std::memcpy(nor.data(), norData.data() + offset, numVertices * sizeof(NormalType)); std::memcpy(tan.data(), tanData.data() + offset, numVertices * sizeof(TangentType)); - std::memcpy(bit.data(), bitData.data() + offset, numVertices * sizeof(BiTangentType)); + //std::memcpy(bit.data(), bitData.data() + offset, numVertices * sizeof(BiTangentType)); std::memcpy(col.data(), colData.data() + offset, numVertices * sizeof(ColorType)); Serialization::save(buffer, pos); Serialization::save(buffer, nor); Serialization::save(buffer, tan); - Serialization::save(buffer, bit); + //Serialization::save(buffer, bit); Serialization::save(buffer, col); } @@ -101,22 +100,22 @@ uint64 StaticMeshVertexData::deserializeMesh(MeshId id, ArchiveBuffer& buffer) { Array pos; Array nor; Array tan; - Array bit; + //Array bit; Array col; Serialization::load(buffer, pos); Serialization::load(buffer, nor); Serialization::load(buffer, tan); - Serialization::load(buffer, bit); + //Serialization::load(buffer, bit); Serialization::load(buffer, col); loadPositions(offset, pos); loadNormals(offset, nor); loadTangents(offset, tan); - loadBitangents(offset, bit); + //loadBitangents(offset, bit); loadColors(offset, col); result += pos.size() * sizeof(PositionType); result += nor.size() * sizeof(NormalType); result += tan.size() * sizeof(TangentType); - result += bit.size() * sizeof(BiTangentType); + //result += bit.size() * sizeof(BiTangentType); result += col.size() * sizeof(ColorType); return result; } @@ -136,10 +135,10 @@ void StaticMeshVertexData::init(Gfx::PGraphics _graphics) { .name = TANGENTS_NAME, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER, }); - descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{ + /*descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{ .name = BITANGENTS_NAME, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER, - }); + });*/ descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{ .name = COLORS_NAME, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER, @@ -161,25 +160,17 @@ void StaticMeshVertexData::destroy() { positions = nullptr; normals = nullptr; tangents = nullptr; - biTangents = nullptr; + //biTangents = nullptr; colors = nullptr; descriptorSet = nullptr; descriptorLayout = nullptr; } -void StaticMeshVertexData::bindBuffers(Gfx::PRenderCommand) { - // TODO: for legacy vertex buffer binding -} - -Gfx::PDescriptorLayout StaticMeshVertexData::getVertexDataLayout() { return descriptorLayout; } - -Gfx::PDescriptorSet StaticMeshVertexData::getVertexDataSet() { return descriptorSet; } - void StaticMeshVertexData::resizeBuffers() { posData.resize(verticesAllocated); norData.resize(verticesAllocated); tanData.resize(verticesAllocated); - bitData.resize(verticesAllocated); + //bitData.resize(verticesAllocated); colData.resize(verticesAllocated); for (size_t i = 0; i < MAX_TEXCOORDS; ++i) { texData[i].resize(verticesAllocated); @@ -212,14 +203,14 @@ void StaticMeshVertexData::updateBuffers() { }, .name = "Tangents", }); - biTangents = graphics->createShaderBuffer(ShaderBufferCreateInfo{ + /*biTangents = graphics->createShaderBuffer(ShaderBufferCreateInfo{ .sourceData = { .size = verticesAllocated * sizeof(BiTangentType), .data = (uint8*)bitData.data(), }, .name = "BiTangents", - }); + });*/ colors = graphics->createShaderBuffer(ShaderBufferCreateInfo{ .sourceData = { @@ -243,9 +234,9 @@ void StaticMeshVertexData::updateBuffers() { descriptorSet->updateBuffer(POSITIONS_NAME, 0, positions); descriptorSet->updateBuffer(NORMALS_NAME, 0, normals); descriptorSet->updateBuffer(TANGENTS_NAME, 0, tangents); - descriptorSet->updateBuffer(BITANGENTS_NAME, 0, biTangents); + //descriptorSet->updateBuffer(BITANGENTS_NAME, 0, biTangents); descriptorSet->updateBuffer(COLORS_NAME, 0, colors); - for (size_t i = 0; i < MAX_TEXCOORDS; ++i) { + for (uint32 i = 0; i < MAX_TEXCOORDS; ++i) { descriptorSet->updateBuffer(TEXCOORDS_NAME, i, texCoords[i]); } descriptorSet->writeChanges(); diff --git a/src/Engine/Graphics/StaticMeshVertexData.h b/src/Engine/Graphics/StaticMeshVertexData.h index ed59ac2..52b4f42 100644 --- a/src/Engine/Graphics/StaticMeshVertexData.h +++ b/src/Engine/Graphics/StaticMeshVertexData.h @@ -5,14 +5,13 @@ #include "VertexData.h" #include "entt/entt.hpp" - namespace Seele { class StaticMeshVertexData : public VertexData { public: using PositionType = Vector; using NormalType = Vector; - using TangentType = Vector; - using BiTangentType = Vector; + using TangentType = Vector4; + //using BiTangentType = Vector; using TexCoordType = U16Vector2; using ColorType = U16Vector; @@ -23,15 +22,14 @@ class StaticMeshVertexData : public VertexData { void loadTexCoords(uint64 offset, uint64 index, const Array& data); void loadNormals(uint64 offset, const Array& data); void loadTangents(uint64 offset, const Array& data); - void loadBitangents(uint64 offset, const Array& data); + //void loadBitangents(uint64 offset, const Array& data); void loadColors(uint64 offset, const Array& data); virtual void serializeMesh(MeshId id, ArchiveBuffer& buffer) override; virtual uint64 deserializeMesh(MeshId id, ArchiveBuffer& buffer) override; virtual void init(Gfx::PGraphics graphics) override; virtual void destroy() override; - virtual void bindBuffers(Gfx::PRenderCommand command) override; - virtual Gfx::PDescriptorLayout getVertexDataLayout() override; - virtual Gfx::PDescriptorSet getVertexDataSet() override; + virtual Gfx::PDescriptorLayout getVertexDataLayout() override { return descriptorLayout; } + virtual Gfx::PDescriptorSet getVertexDataSet() override { return descriptorSet; } virtual std::string getTypeName() const override { return "StaticMeshVertexData"; } virtual Gfx::PShaderBuffer getPositionBuffer() const override { return positions; } @@ -39,7 +37,6 @@ class StaticMeshVertexData : public VertexData { virtual void resizeBuffers() override; virtual void updateBuffers() override; - Gfx::OShaderBuffer positions; constexpr static const char* POSITIONS_NAME = "positions"; Gfx::OShaderBuffer texCoords[MAX_TEXCOORDS]; @@ -48,15 +45,15 @@ class StaticMeshVertexData : public VertexData { constexpr static const char* NORMALS_NAME = "normals"; Gfx::OShaderBuffer tangents; constexpr static const char* TANGENTS_NAME = "tangents"; - Gfx::OShaderBuffer biTangents; - constexpr static const char* BITANGENTS_NAME = "biTangents"; + //Gfx::OShaderBuffer biTangents; + //constexpr static const char* BITANGENTS_NAME = "biTangents"; Gfx::OShaderBuffer colors; constexpr static const char* COLORS_NAME = "colors"; Array posData; Array texData[MAX_TEXCOORDS]; Array norData; Array tanData; - Array bitData; + //Array bitData; Array colData; Gfx::ODescriptorLayout descriptorLayout; Gfx::PDescriptorSet descriptorSet; diff --git a/src/Engine/Graphics/VertexData.cpp b/src/Engine/Graphics/VertexData.cpp index fa4e401..b690a82 100644 --- a/src/Engine/Graphics/VertexData.cpp +++ b/src/Engine/Graphics/VertexData.cpp @@ -90,7 +90,7 @@ void VertexData::createDescriptors() { Array cullingOffsets; for (auto& mat : materialData) { for (auto& instance : mat.instances) { - instance.offsets.instanceOffset = instanceData.size(); + instance.offsets.instanceOffset = (uint32)instanceData.size(); MaterialOffsets offsets = instance.materialInstance->getMaterialOffsets(); instance.offsets.textureOffset = offsets.textureOffset; instance.offsets.samplerOffset = offsets.samplerOffset; @@ -104,7 +104,7 @@ void VertexData::createDescriptors() { } } for (uint32 i = 0; i < transparentData.size(); ++i) { - transparentData[i].offsets.instanceOffset = instanceData.size(); + transparentData[i].offsets.instanceOffset = (uint32)instanceData.size(); cullingOffsets.add(transparentData[i].cullingOffset); instanceData.add(transparentData[i].instanceData); instanceMeshData.add(transparentData[i].meshData); @@ -139,17 +139,17 @@ void VertexData::createDescriptors() { void VertexData::loadMesh(MeshId id, Array loadedIndices, Array loadedMeshlets) { std::unique_lock l(vertexDataLock); for (auto&& chunk : loadedMeshlets | std::views::chunk(2048)) { - uint32 meshletOffset = meshlets.size(); + uint32 meshletOffset = (uint32)meshlets.size(); AABB meshAABB; uint32 numMeshlets = 0; for (auto&& m : chunk) { numMeshlets++; //... meshAABB = meshAABB.combine(m.boundingBox); - uint32 vertexOffset = vertexIndices.size(); + uint32 vertexOffset = (uint32)vertexIndices.size(); vertexIndices.resize(vertexOffset + m.numVertices); std::memcpy(vertexIndices.data() + vertexOffset, m.uniqueVertices, m.numVertices * sizeof(uint32)); - uint32 primitiveOffset = primitiveIndices.size(); + uint32 primitiveOffset = (uint32)primitiveIndices.size(); primitiveIndices.resize(primitiveOffset + (m.numPrimitives * 3)); std::memcpy(primitiveIndices.data() + primitiveOffset, m.primitiveLayout, m.numPrimitives * 3 * sizeof(uint8)); meshlets.add(MeshletDescription{ @@ -268,6 +268,8 @@ uint64 VertexData::deserializeMesh(MeshId id, ArchiveBuffer& buffer) { List vertexDataList; +void VertexData::addVertexDataInstance(VertexData* vertexData) { vertexDataList.add(vertexData); } + List VertexData::getList() { return vertexDataList; } VertexData* VertexData::findByTypeName(std::string name) { @@ -349,7 +351,7 @@ void VertexData::destroy() { } uint32 VertexData::addCullingMapping(MeshId id) { - uint32 result = meshletCount; + uint32 result = (uint32)meshletCount; for (const auto& md : getMeshData(id)) { meshletCount += md.numMeshlets; } diff --git a/src/Engine/Graphics/VertexData.h b/src/Engine/Graphics/VertexData.h index 139fa50..20007b9 100644 --- a/src/Engine/Graphics/VertexData.h +++ b/src/Engine/Graphics/VertexData.h @@ -8,7 +8,7 @@ #include "Meshlet.h" #include -constexpr uint64 MAX_TEXCOORDS = 8; +constexpr uint32 MAX_TEXCOORDS = 8; namespace Seele { DECLARE_REF(MaterialInstance) @@ -64,7 +64,6 @@ class VertexData { uint64 getMeshVertexCount(MeshId id) { return meshVertexCounts[id]; } virtual void serializeMesh(MeshId id, ArchiveBuffer& buffer); virtual uint64 deserializeMesh(MeshId id, ArchiveBuffer& buffer); - virtual void bindBuffers(Gfx::PRenderCommand command) = 0; virtual Gfx::PDescriptorLayout getVertexDataLayout() = 0; virtual Gfx::PDescriptorSet getVertexDataSet() = 0; virtual std::string getTypeName() const = 0; @@ -77,11 +76,10 @@ class VertexData { const Array& getTransparentData() const { return transparentData; } const Array& getRayTracingData() const { return rayTracingScene; } const Array& getMeshData(MeshId id) const { return meshData[id]; } - void registerBottomLevelAccelerationStructure(Gfx::PBottomLevelAS blas) { - dataToBuild.add(blas); - } - uint64 getIndicesOffset(uint32 meshletIndex) { return meshlets[meshletIndex].indicesOffset; } + void registerBottomLevelAccelerationStructure(Gfx::PBottomLevelAS blas) { dataToBuild.add(blas); } + uint32 getIndicesOffset(uint32 meshletIndex) { return meshlets[meshletIndex].indicesOffset; } uint64 getNumInstances() const { return instanceData.size(); } + static void addVertexDataInstance(VertexData* vertexData); static List getList(); static VertexData* findByTypeName(std::string name); virtual void init(Gfx::PGraphics graphics); @@ -110,6 +108,7 @@ class VertexData { uint32 indicesOffset = 0; }; std::mutex materialDataLock; + debug_resource vertexDataResource = {"VertexData"}; Array materialData; Array transparentData; diff --git a/src/Engine/Graphics/Vulkan/Buffer.cpp b/src/Engine/Graphics/Vulkan/Buffer.cpp index 44c3509..deaaf94 100644 --- a/src/Engine/Graphics/Vulkan/Buffer.cpp +++ b/src/Engine/Graphics/Vulkan/Buffer.cpp @@ -11,6 +11,8 @@ using namespace Seele::Vulkan; BufferAllocation::BufferAllocation(PGraphics graphics, const std::string& name, VkBufferCreateInfo bufferInfo, VmaAllocationCreateInfo allocInfo, Gfx::QueueType owner, uint64 alignment) : CommandBoundResource(graphics, name), size(bufferInfo.size), owner(owner) { + if (bufferInfo.size == 0) + return; VK_CHECK(vmaCreateBufferWithAlignment(graphics->getAllocator(), &bufferInfo, &allocInfo, alignment, &buffer, &allocation, &info)); vmaGetAllocationMemoryProperties(graphics->getAllocator(), allocation, &properties); assert(!name.empty()); @@ -102,7 +104,7 @@ void BufferAllocation::updateContents(uint64 regionOffset, uint64 regionSize, vo .flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT, .usage = VMA_MEMORY_USAGE_AUTO, }; - OBufferAllocation staging = new BufferAllocation(graphics, "UpdateStaging", stagingInfo, stagingAlloc, Gfx::QueueType::GRAPHICS); + OBufferAllocation staging = new BufferAllocation(graphics, fmt::format("{0}UpdateStaging", name), stagingInfo, stagingAlloc, Gfx::QueueType::GRAPHICS); uint8* data; VK_CHECK(vmaMapMemory(graphics->getAllocator(), staging->allocation, (void**)&data)); @@ -111,7 +113,7 @@ void BufferAllocation::updateContents(uint64 regionOffset, uint64 regionSize, vo vmaUnmapMemory(graphics->getAllocator(), staging->allocation); Gfx::QueueType prevOwner = owner; - // transferOwnership(Gfx::QueueType::TRANSFER); + transferOwnership(Gfx::QueueType::TRANSFER); PCommand cmd = graphics->getQueueCommands(Gfx::QueueType::GRAPHICS)->getCommands(); VkBufferCopy copy = { @@ -125,7 +127,7 @@ void BufferAllocation::updateContents(uint64 regionOffset, uint64 regionSize, vo pipelineBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); - // transferOwnership(prevOwner); + transferOwnership(prevOwner); graphics->getDestructionManager()->queueResourceForDestruction(std::move(staging)); } @@ -147,7 +149,7 @@ void BufferAllocation::readContents(uint64 regionOffset, uint64 regionSize, void OBufferAllocation staging = new BufferAllocation(graphics, "ReadStaging", stagingInfo, stagingAlloc, Gfx::QueueType::GRAPHICS); Gfx::QueueType prevOwner = owner; - // transferOwnership(Gfx::QueueType::TRANSFER); + transferOwnership(Gfx::QueueType::TRANSFER); PCommandPool pool = graphics->getQueueCommands(Gfx::QueueType::TRANSFER); PCommand cmd = pool->getCommands(); @@ -164,7 +166,7 @@ void BufferAllocation::readContents(uint64 regionOffset, uint64 regionSize, void pool->submitCommands(); cmd->getFence()->wait(1000000); - // transferOwnership(prevOwner); + transferOwnership(prevOwner); uint8* data; VK_CHECK(vmaMapMemory(graphics->getAllocator(), staging->allocation, (void**)&data)); @@ -276,11 +278,11 @@ void Buffer::rotateBuffer(uint64 size, bool preserveContents) { return; } buffers.add(nullptr); - createBuffer(size, buffers.size() - 1); + createBuffer(size, (uint32)buffers.size() - 1); if (preserveContents) { copyBuffer(currentBuffer, buffers.size() - 1); } - currentBuffer = buffers.size() - 1; + currentBuffer = (uint32)buffers.size() - 1; } void Buffer::createBuffer(uint64 size, uint32 destIndex) { @@ -437,6 +439,8 @@ void* ShaderBuffer::map() { return Vulkan::Buffer::map(); } void ShaderBuffer::unmap() { Vulkan::Buffer::unmap(); } void ShaderBuffer::clear() { + if (getAlloc() == nullptr) + return; PCommand command = graphics->getQueueCommands(getAlloc()->owner)->getCommands(); command->bindResource(PBufferAllocation(getAlloc())); vkCmdFillBuffer(command->getHandle(), Vulkan::Buffer::getHandle(), 0, VK_WHOLE_SIZE, 0); diff --git a/src/Engine/Graphics/Vulkan/Command.h b/src/Engine/Graphics/Vulkan/Command.h index eaffadf..cf6f8bb 100644 --- a/src/Engine/Graphics/Vulkan/Command.h +++ b/src/Engine/Graphics/Vulkan/Command.h @@ -18,7 +18,6 @@ class Command { Command(PGraphics graphics, PCommandPool pool); ~Command(); constexpr VkCommandBuffer getHandle() { return handle; } - void reset(); void begin(); void end(); void beginRenderPass(PRenderPass renderPass, PFramebuffer framebuffer); @@ -46,8 +45,6 @@ class Command { OFence fence; OSemaphore signalSemaphore; State state; - VkViewport currentViewport; - VkRect2D currentScissor; VkCommandBuffer handle; PRenderPass boundRenderPass; PFramebuffer boundFramebuffer; @@ -91,12 +88,12 @@ class RenderCommand : public Gfx::RenderCommand { virtual void traceRays(uint32 width, uint32 height, uint32 depth) override; private: - PGraphicsPipeline pipeline; - PRayTracingPipeline rtPipeline; - bool ready; + PGraphicsPipeline pipeline = nullptr; + PRayTracingPipeline rtPipeline = nullptr; + bool ready = false; Array boundResources; - VkViewport currentViewport; - VkRect2D currentScissor; + VkViewport currentViewport = VkViewport(); + VkRect2D currentScissor = VkRect2D(); PGraphics graphics; std::thread::id threadId; VkCommandBuffer handle; @@ -123,10 +120,8 @@ class ComputeCommand : public Gfx::ComputeCommand { private: PComputePipeline pipeline; - bool ready; + bool ready = false; Array boundResources; - VkViewport currentViewport; - VkRect2D currentScissor; PGraphics graphics; std::thread::id threadId; VkCommandBuffer handle; diff --git a/src/Engine/Graphics/Vulkan/Debug.cpp b/src/Engine/Graphics/Vulkan/Debug.cpp index 50dc7ec..7af5383 100644 --- a/src/Engine/Graphics/Vulkan/Debug.cpp +++ b/src/Engine/Graphics/Vulkan/Debug.cpp @@ -3,8 +3,8 @@ using namespace Seele::Vulkan; -VkBool32 Seele::Vulkan::debugCallback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, VkDebugUtilsMessageTypeFlagsEXT messageTypes, - const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData, void* pUserData) { +VkBool32 Seele::Vulkan::debugCallback(VkDebugUtilsMessageSeverityFlagBitsEXT, VkDebugUtilsMessageTypeFlagsEXT, + const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData, void*) { std::cerr << pCallbackData->pMessage << std::endl; return VK_FALSE; } diff --git a/src/Engine/Graphics/Vulkan/Descriptor.cpp b/src/Engine/Graphics/Vulkan/Descriptor.cpp index 0e2c060..0278935 100644 --- a/src/Engine/Graphics/Vulkan/Descriptor.cpp +++ b/src/Engine/Graphics/Vulkan/Descriptor.cpp @@ -51,11 +51,11 @@ void DescriptorLayout::create() { constantsSize += gfxBinding.uniformLength; constantsStages |= gfxBinding.shaderStages; } else { - mappings[gfxBinding.name] = { + mappings[gfxBinding.name] = DescriptorMapping{ .binding = (uint32)bindings.size(), .type = cast(gfxBinding.descriptorType), }; - bindings.add({ + bindings.add(VkDescriptorSetLayoutBinding{ .binding = (uint32)bindings.size(), .descriptorType = cast(gfxBinding.descriptorType), .descriptorCount = gfxBinding.descriptorCount, @@ -97,11 +97,11 @@ DescriptorPool::DescriptorPool(PGraphics graphics, PDescriptorLayout layout) perTypeSizes[binding.descriptorType] += 512; } Array poolSizes; - for (const auto [type, num] : perTypeSizes) { - VkDescriptorPoolSize size; - size.descriptorCount = num; - size.type = cast(type); - poolSizes.add(size); + for (const auto& [type, num] : perTypeSizes) { + poolSizes.add(VkDescriptorPoolSize{ + .type = cast(type), + .descriptorCount = num, + }); } VkDescriptorPoolCreateInfo createInfo = { .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, @@ -199,14 +199,14 @@ DescriptorSet::DescriptorSet(PGraphics graphics, PDescriptorPool owner) DescriptorSet::~DescriptorSet() {} -void DescriptorSet::updateConstants(const std::string& name, uint32 offset, void* data) { - std::memcpy(constantData.data() + owner->getLayout()->mappings[name].constantOffset, (char*)data + offset, - owner->getLayout()->mappings[name].constantSize); +void DescriptorSet::updateConstants(const std::string& mappingName, uint32 offset, void* data) { + std::memcpy(constantData.data() + owner->getLayout()->mappings[mappingName].constantOffset, (char*)data + offset, + owner->getLayout()->mappings[mappingName].constantSize); } -void DescriptorSet::updateBuffer(const std::string& name, uint32 index, Gfx::PShaderBuffer shaderBuffer) { +void DescriptorSet::updateBuffer(const std::string& mappingName, uint32 index, Gfx::PShaderBuffer shaderBuffer) { PShaderBuffer vulkanBuffer = shaderBuffer.cast(); - const auto& map = owner->getLayout()->mappings[name]; + const auto& map = owner->getLayout()->mappings[mappingName]; uint32 binding = map.binding; if (boundResources[binding][index] == vulkanBuffer->getAlloc() || vulkanBuffer->getAlloc() == nullptr) { return; @@ -230,9 +230,9 @@ void DescriptorSet::updateBuffer(const std::string& name, uint32 index, Gfx::PSh boundResources[binding][index] = vulkanBuffer->getAlloc(); } -void DescriptorSet::updateBuffer(const std::string& name, uint32 index, Gfx::PVertexBuffer indexBuffer) { +void DescriptorSet::updateBuffer(const std::string& mappingName, uint32 index, Gfx::PVertexBuffer indexBuffer) { PVertexBuffer vulkanBuffer = indexBuffer.cast(); - const auto& map = owner->getLayout()->mappings[name]; + const auto& map = owner->getLayout()->mappings[mappingName]; uint32 binding = map.binding; if (boundResources[binding][index] == vulkanBuffer->getAlloc() || vulkanBuffer->getAlloc() == nullptr) { return; @@ -257,9 +257,9 @@ void DescriptorSet::updateBuffer(const std::string& name, uint32 index, Gfx::PVe boundResources[binding][index] = vulkanBuffer->getAlloc(); } -void DescriptorSet::updateBuffer(const std::string& name, uint32 index, Gfx::PIndexBuffer indexBuffer) { +void DescriptorSet::updateBuffer(const std::string& mappingName, uint32 index, Gfx::PIndexBuffer indexBuffer) { PIndexBuffer vulkanBuffer = indexBuffer.cast(); - const auto& map = owner->getLayout()->mappings[name]; + const auto& map = owner->getLayout()->mappings[mappingName]; uint32 binding = map.binding; if (boundResources[binding][index] == vulkanBuffer->getAlloc() || vulkanBuffer->getAlloc() == nullptr) { return; @@ -284,9 +284,9 @@ void DescriptorSet::updateBuffer(const std::string& name, uint32 index, Gfx::PIn boundResources[binding][index] = vulkanBuffer->getAlloc(); } -void DescriptorSet::updateSampler(const std::string& name, uint32 index, Gfx::PSampler samplerState) { +void DescriptorSet::updateSampler(const std::string& mappingName, uint32 index, Gfx::PSampler samplerState) { PSampler vulkanSampler = samplerState.cast(); - const auto& map = owner->getLayout()->mappings[name]; + const auto& map = owner->getLayout()->mappings[mappingName]; uint32 binding = map.binding; if (boundResources[binding][index] == vulkanSampler->getHandle()) { return; @@ -312,9 +312,9 @@ void DescriptorSet::updateSampler(const std::string& name, uint32 index, Gfx::PS boundResources[binding][index] = vulkanSampler->getHandle(); } -void DescriptorSet::updateTexture(const std::string& name, uint32 index, Gfx::PTexture2D texture) { +void DescriptorSet::updateTexture(const std::string& mappingName, uint32 index, Gfx::PTexture texture) { TextureBase* vulkanTexture = texture.cast().getHandle(); - const auto& map = owner->getLayout()->mappings[name]; + const auto& map = owner->getLayout()->mappings[mappingName]; uint32 binding = map.binding; if (boundResources[binding][index] == vulkanTexture->getHandle()) { return; @@ -340,65 +340,9 @@ void DescriptorSet::updateTexture(const std::string& name, uint32 index, Gfx::PT boundResources[binding][index] = vulkanTexture->getHandle(); } -void DescriptorSet::updateTexture(const std::string& name, uint32 index, Gfx::PTexture3D texture) { - TextureBase* vulkanTexture = texture.cast().getHandle(); - const auto& map = owner->getLayout()->mappings[name]; - uint32 binding = map.binding; - if (boundResources[binding][index] == vulkanTexture->getHandle()) { - return; - } - - // It is assumed that the image is in the correct layout - imageInfos.add(VkDescriptorImageInfo{ - .sampler = VK_NULL_HANDLE, - .imageView = vulkanTexture->getView(), - .imageLayout = cast(vulkanTexture->getLayout()), - }); - writeDescriptors.add(VkWriteDescriptorSet{ - .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, - .pNext = nullptr, - .dstSet = setHandle, - .dstBinding = binding, - .dstArrayElement = index, - .descriptorCount = 1, - .descriptorType = map.type, - .pImageInfo = &imageInfos.back(), - }); - - boundResources[binding][index] = vulkanTexture->getHandle(); -} - -void DescriptorSet::updateTexture(const std::string& name, uint32 index, Gfx::PTextureCube texture) { - TextureBase* vulkanTexture = texture.cast().getHandle(); - const auto& map = owner->getLayout()->mappings[name]; - uint32 binding = map.binding; - if (boundResources[binding][index] == vulkanTexture->getHandle()) { - return; - } - - // It is assumed that the image is in the correct layout - imageInfos.add(VkDescriptorImageInfo{ - .sampler = VK_NULL_HANDLE, - .imageView = vulkanTexture->getView(), - .imageLayout = cast(vulkanTexture->getLayout()), - }); - writeDescriptors.add(VkWriteDescriptorSet{ - .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, - .pNext = nullptr, - .dstSet = setHandle, - .dstBinding = binding, - .dstArrayElement = index, - .descriptorCount = 1, - .descriptorType = map.type, - .pImageInfo = &imageInfos.back(), - }); - - boundResources[binding][index] = vulkanTexture->getHandle(); -} - -void DescriptorSet::updateAccelerationStructure(const std::string& name, uint32 index, Gfx::PTopLevelAS as) { +void DescriptorSet::updateAccelerationStructure(const std::string& mappingName, uint32 index, Gfx::PTopLevelAS as) { auto tlas = as.cast(); - uint32 binding = owner->getLayout()->mappings[name].binding; + uint32 binding = owner->getLayout()->mappings[mappingName].binding; accelerationInfos.add(VkWriteDescriptorSetAccelerationStructureKHR{ .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR, .pNext = nullptr, @@ -418,8 +362,7 @@ void DescriptorSet::updateAccelerationStructure(const std::string& name, uint32 void DescriptorSet::writeChanges() { if (constantData.size() > 0) { - if (constantsBuffer != nullptr) - { + if (constantsBuffer != nullptr) { graphics->getDestructionManager()->queueResourceForDestruction(std::move(constantsBuffer)); } constantsBuffer = new BufferAllocation(graphics, owner->getLayout()->getName(), @@ -452,7 +395,7 @@ void DescriptorSet::writeChanges() { .pBufferInfo = &bufferInfos.back(), }); } - + if (writeDescriptors.size() > 0) { if (isCurrentlyBound()) { std::cout << "Descriptor currently bound, allocate a new one instead" << std::endl; @@ -474,7 +417,7 @@ std::mutex layoutLock; Map cachedLayouts; void PipelineLayout::create() { - for (auto [name, desc] : descriptorSetLayouts) { + for (const auto& [_, desc] : descriptorSetLayouts) { PDescriptorLayout layout = desc.cast(); layout->create(); uint32 parameterIndex = parameterMapping[layout->getName()]; diff --git a/src/Engine/Graphics/Vulkan/Descriptor.h b/src/Engine/Graphics/Vulkan/Descriptor.h index ec23b38..23cf191 100644 --- a/src/Engine/Graphics/Vulkan/Descriptor.h +++ b/src/Engine/Graphics/Vulkan/Descriptor.h @@ -24,7 +24,7 @@ class DescriptorLayout : public Gfx::DescriptorLayout { private: PGraphics graphics; uint32 constantsSize = 0; - VkShaderStageFlags constantsStages; + VkShaderStageFlags constantsStages = 0; Array bindings; Map mappings; VkDescriptorSetLayout layoutHandle; @@ -64,9 +64,7 @@ class DescriptorSet : public Gfx::DescriptorSet, public CommandBoundResource { virtual void updateBuffer(const std::string& name, uint32 index, Gfx::PVertexBuffer indexBuffer) override; virtual void updateBuffer(const std::string& name, uint32 index, Gfx::PIndexBuffer indexBuffer) override; virtual void updateSampler(const std::string& name, uint32 index, Gfx::PSampler samplerState) override; - virtual void updateTexture(const std::string& name, uint32 index, Gfx::PTexture2D texture) override; - virtual void updateTexture(const std::string& name, uint32 index, Gfx::PTexture3D texture) override; - virtual void updateTexture(const std::string& name, uint32 index, Gfx::PTextureCube texture) override; + virtual void updateTexture(const std::string& name, uint32 index, Gfx::PTexture texture) override; virtual void updateAccelerationStructure(const std::string& name, uint32 index, Gfx::PTopLevelAS as) override; constexpr VkDescriptorSet getHandle() const { return setHandle; } @@ -74,7 +72,6 @@ class DescriptorSet : public Gfx::DescriptorSet, public CommandBoundResource { private: std::vector constantData; OBufferAllocation constantsBuffer; - VkShaderStageFlags constantsStageFlags; List imageInfos; List bufferInfos; List accelerationInfos; diff --git a/src/Engine/Graphics/Vulkan/Framebuffer.cpp b/src/Engine/Graphics/Vulkan/Framebuffer.cpp index 7c4f00b..3ef4275 100644 --- a/src/Engine/Graphics/Vulkan/Framebuffer.cpp +++ b/src/Engine/Graphics/Vulkan/Framebuffer.cpp @@ -16,40 +16,46 @@ Framebuffer::Framebuffer(PGraphics graphics, PRenderPass renderPass, Gfx::Render Array attachments; uint32 width = 0; uint32 height = 0; + uint32 layers = 0; for (auto inputAttachment : layout.inputAttachments) { - PTexture2D vkInputAttachment = inputAttachment.getTexture().cast(); + PTextureBase vkInputAttachment = inputAttachment.getTexture().cast(); attachments.add(vkInputAttachment->getView()); description.inputAttachments[description.numInputAttachments++] = vkInputAttachment->getView(); width = std::max(width, vkInputAttachment->getWidth()); height = std::max(height, vkInputAttachment->getHeight()); + layers = std::max(layers, vkInputAttachment->getNumLayers()); } for (auto colorAttachment : layout.colorAttachments) { - PTexture2D vkColorAttachment = colorAttachment.getTexture().cast(); + PTextureBase vkColorAttachment = colorAttachment.getTexture().cast(); attachments.add(vkColorAttachment->getView()); description.colorAttachments[description.numColorAttachments++] = vkColorAttachment->getView(); width = std::max(width, vkColorAttachment->getWidth()); height = std::max(height, vkColorAttachment->getHeight()); + layers = std::max(layers, vkColorAttachment->getNumLayers()); } for (auto resolveAttachment : layout.resolveAttachments) { - PTexture2D vkResolveAttachment = resolveAttachment.getTexture().cast(); + PTextureBase vkResolveAttachment = resolveAttachment.getTexture().cast(); attachments.add(vkResolveAttachment->getView()); description.resolveAttachments[description.numResolveAttachments++] = vkResolveAttachment->getView(); width = std::max(width, vkResolveAttachment->getWidth()); height = std::max(height, vkResolveAttachment->getHeight()); + layers = std::max(layers, vkResolveAttachment->getNumLayers()); } if (layout.depthAttachment.getTexture() != nullptr) { - PTexture2D vkDepthAttachment = layout.depthAttachment.getTexture().cast(); + PTextureBase vkDepthAttachment = layout.depthAttachment.getTexture().cast(); attachments.add(vkDepthAttachment->getView()); description.depthAttachment = vkDepthAttachment->getView(); width = std::max(width, vkDepthAttachment->getWidth()); height = std::max(height, vkDepthAttachment->getHeight()); + layers = std::max(layers, vkDepthAttachment->getNumLayers()); } if (layout.depthResolveAttachment.getTexture() != nullptr) { - PTexture2D vkDepthAttachment = layout.depthResolveAttachment.getTexture().cast(); + PTextureBase vkDepthAttachment = layout.depthResolveAttachment.getTexture().cast(); attachments.add(vkDepthAttachment->getView()); description.depthResolveAttachment = vkDepthAttachment->getView(); width = std::max(width, vkDepthAttachment->getWidth()); height = std::max(height, vkDepthAttachment->getHeight()); + layers = std::max(layers, vkDepthAttachment->getNumLayers()); } VkFramebufferCreateInfo createInfo = { .sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, diff --git a/src/Engine/Graphics/Vulkan/Graphics.cpp b/src/Engine/Graphics/Vulkan/Graphics.cpp index dfcefc1..a3a0006 100644 --- a/src/Engine/Graphics/Vulkan/Graphics.cpp +++ b/src/Engine/Graphics/Vulkan/Graphics.cpp @@ -172,8 +172,9 @@ Gfx::OViewport Graphics::createViewport(Gfx::PWindow owner, const ViewportCreate } Gfx::ORenderPass Graphics::createRenderPass(Gfx::RenderTargetLayout layout, Array dependencies, - Gfx::PViewport renderArea, std::string name) { - return new RenderPass(this, std::move(layout), std::move(dependencies), renderArea, name); + URect renderArea, std::string name, Array viewMasks, + Array correlationMasks) { + return new RenderPass(this, std::move(layout), std::move(dependencies), renderArea, name, std::move(viewMasks), std::move(correlationMasks)); } void Graphics::beginRenderPass(Gfx::PRenderPass renderPass) { PRenderPass rp = renderPass.cast(); @@ -321,7 +322,7 @@ Gfx::OPipelineStatisticsQuery Graphics::createPipelineStatisticsQuery(const std: return new PipelineStatisticsQuery(this, name); } -Gfx::OTimestampQuery Graphics::createTimestampQuery(uint64 numTimestamps, const std::string& name) { +Gfx::OTimestampQuery Graphics::createTimestampQuery(uint64, const std::string& name) { return new TimestampQuery(this, name); } @@ -446,7 +447,7 @@ Gfx::OTopLevelAS Graphics::createTopLevelAccelerationStructure(const Gfx::TopLev } void Graphics::buildBottomLevelAccelerationStructures(Array data) { - if (!supportRayTracing()) + if (!supportRayTracing() || data.empty()) return; Gfx::PShaderBuffer verticesBuffer = StaticMeshVertexData::getInstance()->getPositionBuffer(); Gfx::PIndexBuffer indexBuffer = StaticMeshVertexData::getInstance()->getIndexBuffer(); @@ -457,9 +458,6 @@ void Graphics::buildBottomLevelAccelerationStructures(Array // For the sake of simplicity we won't stage the vertex data to the GPU memory // Note that the buffer usage flags for buffers consumed by the bottom level acceleration structure require special flags - const VkBufferUsageFlags buffer_usage_flags = VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR | - VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT; - VkBufferCreateInfo transformBufferInfo = { .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, .pNext = nullptr, @@ -593,7 +591,7 @@ void Graphics::buildBottomLevelAccelerationStructures(Array } PCommand cmd = graphicsCommands->getCommands(); - vkCmdBuildAccelerationStructuresKHR(cmd->getHandle(), buildGeometries.size(), buildGeometries.data(), buildRangePointers.data()); + vkCmdBuildAccelerationStructuresKHR(cmd->getHandle(), (uint32)buildGeometries.size(), buildGeometries.data(), buildRangePointers.data()); cmd->bindResource(PBufferAllocation(transformBuffer)); destructionManager->queueResourceForDestruction(std::move(transformBuffer)); for (auto& scratchAlloc : scratchBuffers) { @@ -827,6 +825,7 @@ void Graphics::pickPhysicalDevice() { .pNext = &features12, .storageBuffer16BitAccess = true, .uniformAndStorageBuffer16BitAccess = true, + .multiview = true, }; features = { .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2, @@ -953,6 +952,7 @@ void Graphics::createDevice(GraphicsInitializer initializer) { initializer.deviceExtensions.add(VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME); initializer.deviceExtensions.add(VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME); } + initializer.deviceExtensions.add(VK_KHR_MULTIVIEW_EXTENSION_NAME); #ifdef __APPLE__ initializer.deviceExtensions.add("VK_KHR_portability_subset"); #endif @@ -971,11 +971,11 @@ void Graphics::createDevice(GraphicsInitializer initializer) { transferQueue = 0; queues.add(new Queue(this, graphicsQueueInfo.familyIndex, graphicsQueueInfo.queueIndex)); if (computeQueueInfo.familyIndex != -1) { - computeQueue = queues.size(); + computeQueue = (uint32)queues.size(); queues.add(new Queue(this, computeQueueInfo.familyIndex, computeQueueInfo.queueIndex)); } if (transferQueueInfo.familyIndex != -1) { - transferQueue = queues.size(); + transferQueue = (uint32)queues.size(); queues.add(new Queue(this, transferQueueInfo.familyIndex, transferQueueInfo.queueIndex)); } diff --git a/src/Engine/Graphics/Vulkan/Graphics.h b/src/Engine/Graphics/Vulkan/Graphics.h index 58cb080..74dfe70 100644 --- a/src/Engine/Graphics/Vulkan/Graphics.h +++ b/src/Engine/Graphics/Vulkan/Graphics.h @@ -35,7 +35,8 @@ class Graphics : public Gfx::Graphics { virtual Gfx::OViewport createViewport(Gfx::PWindow owner, const ViewportCreateInfo& createInfo) override; virtual Gfx::ORenderPass createRenderPass(Gfx::RenderTargetLayout layout, Array dependencies, - Gfx::PViewport renderArea, std::string name) override; + URect renderArea, std::string name, Array viewMasks, + Array correlationMasks) override; virtual void beginRenderPass(Gfx::PRenderPass renderPass) override; virtual void endRenderPass() override; virtual void waitDeviceIdle() override; diff --git a/src/Engine/Graphics/Vulkan/PipelineCache.cpp b/src/Engine/Graphics/Vulkan/PipelineCache.cpp index 15dec29..80283eb 100644 --- a/src/Engine/Graphics/Vulkan/PipelineCache.cpp +++ b/src/Engine/Graphics/Vulkan/PipelineCache.cpp @@ -11,23 +11,23 @@ using namespace Seele; using namespace Seele::Vulkan; PipelineCache::PipelineCache(PGraphics graphics, const std::string& cacheFilePath) : graphics(graphics), cacheFile(cacheFilePath) { + Array cacheData; std::ifstream stream(cacheFilePath, std::ios::binary | std::ios::ate); - VkPipelineCacheCreateInfo cacheCreateInfo = { - .sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO, - .pNext = nullptr, - .flags = 0, - .initialDataSize = 0, - }; if (stream.good()) { - Array cacheData; uint32 fileSize = static_cast(stream.tellg()); cacheData.resize(fileSize); stream.seekg(0); stream.read((char*)cacheData.data(), fileSize); - cacheCreateInfo.initialDataSize = fileSize; - cacheCreateInfo.pInitialData = cacheData.data(); std::cout << "Loaded " << fileSize << " bytes from pipeline cache" << std::endl; } + VkPipelineCacheCreateInfo cacheCreateInfo = { + .sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO, + .pNext = nullptr, + .flags = 0, + .initialDataSize = cacheData.size(), + .pInitialData = cacheData.data(), + }; + VK_CHECK(vkCreatePipelineCache(graphics->getDevice(), &cacheCreateInfo, nullptr, &cache)); } @@ -508,7 +508,7 @@ PRayTracingPipeline PipelineCache::createPipeline(Gfx::RayTracingPipelineCreateI uint32 intersectionIndex = VK_SHADER_UNUSED_KHR; if (hitgroup.anyHitShader != nullptr) { auto anyHit = hitgroup.anyHitShader.cast(); - anyHitIndex = shaderStages.size(); + anyHitIndex = (uint32)shaderStages.size(); shaderStages.add(VkPipelineShaderStageCreateInfo{ .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, .pNext = nullptr, @@ -521,7 +521,7 @@ PRayTracingPipeline PipelineCache::createPipeline(Gfx::RayTracingPipelineCreateI } if (hitgroup.intersectionShader != nullptr) { auto intersect = hitgroup.intersectionShader.cast(); - intersectionIndex = shaderGroups.size(); + intersectionIndex = (uint32)shaderGroups.size(); shaderStages.add(VkPipelineShaderStageCreateInfo{ .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, .pNext = nullptr, @@ -592,7 +592,8 @@ PRayTracingPipeline PipelineCache::createPipeline(Gfx::RayTracingPipelineCreateI }); } } - uint32 hash = CRC::Calculate(shaderStages.data(), sizeof(VkPipelineShaderStageCreateInfo) * shaderStages.size(), CRC::CRC_32()); + uint32 hash = CRC::Calculate(shaderStages.data(), sizeof(VkPipelineShaderStageCreateInfo) * shaderStages.size(), CRC::CRC_32(), + createInfo.pipelineLayout->getHash()); hash = CRC::Calculate(shaderGroups.data(), sizeof(VkRayTracingShaderGroupCreateInfoKHR) * shaderGroups.size(), CRC::CRC_32(), hash); if (rayTracingPipelines.contains(hash)) { return rayTracingPipelines[hash]; @@ -624,7 +625,7 @@ PRayTracingPipeline PipelineCache::createPipeline(Gfx::RayTracingPipelineCreateI const VkBufferUsageFlags sbtBufferUsage = VK_BUFFER_USAGE_SHADER_BINDING_TABLE_BIT_KHR | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT; const VmaMemoryUsage sbtMemoryUsage = VMA_MEMORY_USAGE_AUTO; - + uint64 rayGenStride = align(handleSize + createInfo.rayGenGroup.parameters.size(), handleAlignment); uint64 hitStride = handleSize; for (const auto& h : createInfo.hitGroups) { @@ -674,7 +675,7 @@ PRayTracingPipeline PipelineCache::createPipeline(Gfx::RayTracingPipelineCreateI Gfx::QueueType::GRAPHICS, sbtAlignment); Array sbt(sbtSize); - vkGetRayTracingShaderGroupHandlesKHR(graphics->getDevice(), pipelineHandle, 0, shaderGroups.size(), sbtSize, sbt.data()); + vkGetRayTracingShaderGroupHandlesKHR(graphics->getDevice(), pipelineHandle, 0, (uint32)shaderGroups.size(), sbtSize, sbt.data()); uint64 sbtOffset = 0; Array rayGenSbt(rayGenStride); @@ -685,7 +686,6 @@ PRayTracingPipeline PipelineCache::createPipeline(Gfx::RayTracingPipelineCreateI rayGenBuffer->pipelineBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_SHADER_READ_BIT, VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR); - Array hitSbt(hitStride * createInfo.hitGroups.size()); for (uint64 i = 0; i < createInfo.hitGroups.size(); ++i) { std::memcpy(hitSbt.data() + i * hitStride, sbt.data() + sbtOffset, handleSize); @@ -695,9 +695,8 @@ PRayTracingPipeline PipelineCache::createPipeline(Gfx::RayTracingPipelineCreateI } hitBuffer->updateContents(0, hitSbt.size(), hitSbt.data()); hitBuffer->pipelineBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_SHADER_READ_BIT, - VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR); + VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR); - Array missSbt(missStride * createInfo.missGroups.size()); for (uint64 i = 0; i < createInfo.missGroups.size(); ++i) { std::memcpy(missSbt.data() + i * missStride, sbt.data() + sbtOffset, handleSize); @@ -707,11 +706,11 @@ PRayTracingPipeline PipelineCache::createPipeline(Gfx::RayTracingPipelineCreateI } missBuffer->updateContents(0, missSbt.size(), missSbt.data()); missBuffer->pipelineBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_SHADER_READ_BIT, - VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR); + VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR); ORayTracingPipeline pipeline = - new RayTracingPipeline(graphics, pipelineHandle, std::move(rayGenBuffer), rayGenStride, std::move(hitBuffer), - hitStride, std::move(missBuffer), missStride, nullptr, 0, createInfo.pipelineLayout); + new RayTracingPipeline(graphics, pipelineHandle, std::move(rayGenBuffer), rayGenStride, std::move(hitBuffer), hitStride, + std::move(missBuffer), missStride, nullptr, 0, createInfo.pipelineLayout); PRayTracingPipeline handle = pipeline; rayTracingPipelines[hash] = std::move(pipeline); return handle; diff --git a/src/Engine/Graphics/Vulkan/Query.h b/src/Engine/Graphics/Vulkan/Query.h index 28158b1..b4122b0 100644 --- a/src/Engine/Graphics/Vulkan/Query.h +++ b/src/Engine/Graphics/Vulkan/Query.h @@ -23,8 +23,8 @@ class QueryPool { std::string name; VkQueryPipelineStatisticFlags flags; // ring buffer - uint64 head = 0; - uint64 tail = 0; + uint32 head = 0; + uint32 tail = 0; uint64 numAvailable; uint32 numQueries; uint32 resultsStride; diff --git a/src/Engine/Graphics/Vulkan/RayTracing.cpp b/src/Engine/Graphics/Vulkan/RayTracing.cpp index 1b4fb4e..dfd6b0d 100644 --- a/src/Engine/Graphics/Vulkan/RayTracing.cpp +++ b/src/Engine/Graphics/Vulkan/RayTracing.cpp @@ -106,7 +106,7 @@ TopLevelAS::TopLevelAS(PGraphics graphics, const Gfx::TopLevelASCreateInfo& crea .pGeometries = &geometry, }; - const uint32 primitiveCount = instances.size(); + const uint32 primitiveCount = (uint32)instances.size(); VkAccelerationStructureBuildSizesInfoKHR buildSizesInfo = { .sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_SIZES_INFO_KHR, diff --git a/src/Engine/Graphics/Vulkan/RenderPass.cpp b/src/Engine/Graphics/Vulkan/RenderPass.cpp index 613ddcf..738fa08 100644 --- a/src/Engine/Graphics/Vulkan/RenderPass.cpp +++ b/src/Engine/Graphics/Vulkan/RenderPass.cpp @@ -6,17 +6,16 @@ #include "Resources.h" #include "Texture.h" - using namespace Seele; using namespace Seele::Vulkan; -RenderPass::RenderPass(PGraphics graphics, Gfx::RenderTargetLayout _layout, Array _dependencies, - Gfx::PViewport viewport, std::string name) +RenderPass::RenderPass(PGraphics graphics, Gfx::RenderTargetLayout _layout, Array _dependencies, URect viewport, + std::string name, Array viewMasks, Array correlationMasks) : Gfx::RenderPass(std::move(_layout), std::move(_dependencies)), graphics(graphics) { - renderArea.extent.width = viewport->getWidth(); - renderArea.extent.height = viewport->getHeight(); - renderArea.offset.x = viewport->getOffsetX(); - renderArea.offset.y = viewport->getOffsetY(); + renderArea.extent.width = viewport.size.x; + renderArea.extent.height = viewport.size.y; + renderArea.offset.x = viewport.offset.x; + renderArea.offset.y = viewport.offset.y; subpassContents = VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS; Array attachments; Array inputRefs; @@ -167,6 +166,7 @@ RenderPass::RenderPass(PGraphics graphics, Gfx::RenderTargetLayout _layout, Arra .pNext = layout.depthResolveAttachment.getTexture() != nullptr ? &depthResolve : nullptr, .flags = 0, .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS, + .viewMask = viewMasks[0], .inputAttachmentCount = (uint32)inputRefs.size(), .pInputAttachments = inputRefs.data(), .colorAttachmentCount = (uint32)colorRefs.size(), @@ -197,8 +197,9 @@ RenderPass::RenderPass(PGraphics graphics, Gfx::RenderTargetLayout _layout, Arra .pSubpasses = &subPassDesc, .dependencyCount = (uint32)dep.size(), .pDependencies = dep.data(), + .correlatedViewMaskCount = (uint32)correlationMasks.size(), + .pCorrelatedViewMasks = correlationMasks.data(), }; - VK_CHECK(vkCreateRenderPass2(graphics->getDevice(), &info, nullptr, &renderPass)); VkDebugUtilsObjectNameInfoEXT nameInfo = { .sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT, @@ -220,23 +221,23 @@ uint32 RenderPass::getFramebufferHash() { FramebufferDescription description; std::memset(&description, 0, sizeof(FramebufferDescription)); for (auto& inputAttachment : layout.inputAttachments) { - PTexture2D tex = inputAttachment.getTexture().cast(); + PTextureBase tex = inputAttachment.getTexture().cast(); description.inputAttachments[description.numInputAttachments++] = tex->getView(); } for (auto& colorAttachment : layout.colorAttachments) { - PTexture2D tex = colorAttachment.getTexture().cast(); + PTextureBase tex = colorAttachment.getTexture().cast(); description.colorAttachments[description.numColorAttachments++] = tex->getView(); } for (auto& resolveAttachment : layout.resolveAttachments) { - PTexture2D tex = resolveAttachment.getTexture().cast(); - description.resolveAttachments[description.numResolveAttachments++] = tex->getView(); + PTextureBase tex = resolveAttachment.getTexture().cast(); + description.resolveAttachments[description.numResolveAttachments++] = tex->getView(); } if (layout.depthAttachment.getTexture() != nullptr) { - PTexture2D tex = layout.depthAttachment.getTexture().cast(); + PTextureBase tex = layout.depthAttachment.getTexture().cast(); description.depthAttachment = tex->getView(); } if (layout.depthResolveAttachment.getTexture() != nullptr) { - PTexture2D tex = layout.depthResolveAttachment.getTexture().cast(); + PTextureBase tex = layout.depthResolveAttachment.getTexture().cast(); description.depthResolveAttachment = tex->getView(); } return CRC::Calculate(&description, sizeof(FramebufferDescription), CRC::CRC_32()); @@ -244,23 +245,23 @@ uint32 RenderPass::getFramebufferHash() { void RenderPass::endRenderPass() { for (auto& inputAttachment : layout.inputAttachments) { - PTexture2D tex = inputAttachment.getTexture().cast(); + PTextureBase tex = inputAttachment.getTexture().cast(); tex->setLayout(inputAttachment.getFinalLayout()); } for (auto& colorAttachment : layout.colorAttachments) { - PTexture2D tex = colorAttachment.getTexture().cast(); + PTextureBase tex = colorAttachment.getTexture().cast(); tex->setLayout(colorAttachment.getFinalLayout()); } for (auto& resolveAttachment : layout.resolveAttachments) { - PTexture2D tex = resolveAttachment.getTexture().cast(); + PTextureBase tex = resolveAttachment.getTexture().cast(); tex->setLayout(resolveAttachment.getFinalLayout()); } if (layout.depthAttachment.getTexture() != nullptr) { - PTexture2D tex = layout.depthAttachment.getTexture().cast(); + PTextureBase tex = layout.depthAttachment.getTexture().cast(); tex->setLayout(layout.depthAttachment.getFinalLayout()); } if (layout.depthResolveAttachment.getTexture() != nullptr) { - PTexture2D tex = layout.depthResolveAttachment.getTexture().cast(); + PTextureBase tex = layout.depthResolveAttachment.getTexture().cast(); tex->setLayout(layout.depthResolveAttachment.getFinalLayout()); } } diff --git a/src/Engine/Graphics/Vulkan/RenderPass.h b/src/Engine/Graphics/Vulkan/RenderPass.h index 66fbf19..ee5c5cf 100644 --- a/src/Engine/Graphics/Vulkan/RenderPass.h +++ b/src/Engine/Graphics/Vulkan/RenderPass.h @@ -6,7 +6,8 @@ namespace Seele { namespace Vulkan { class RenderPass : public Gfx::RenderPass { public: - RenderPass(PGraphics graphics, Gfx::RenderTargetLayout layout, Array dependencies, Gfx::PViewport viewport, std::string name); + RenderPass(PGraphics graphics, Gfx::RenderTargetLayout layout, Array dependencies, URect viewport, + std::string name, Array viewMasks = {}, Array correlationMasks = {}); virtual ~RenderPass(); uint32 getFramebufferHash(); void endRenderPass(); diff --git a/src/Engine/Graphics/Vulkan/Resources.cpp b/src/Engine/Graphics/Vulkan/Resources.cpp index 7cca67d..1b5e75e 100644 --- a/src/Engine/Graphics/Vulkan/Resources.cpp +++ b/src/Engine/Graphics/Vulkan/Resources.cpp @@ -34,7 +34,7 @@ void Semaphore::rotateSemaphore() { currentHandle = i; return; } - currentHandle = handles.size(); + currentHandle = (uint32)handles.size(); handles.add(new SemaphoreHandle(graphics, "Semaphore")); } diff --git a/src/Engine/Graphics/Vulkan/Texture.cpp b/src/Engine/Graphics/Vulkan/Texture.cpp index ec16f74..d70f52a 100644 --- a/src/Engine/Graphics/Vulkan/Texture.cpp +++ b/src/Engine/Graphics/Vulkan/Texture.cpp @@ -29,10 +29,10 @@ VkImageAspectFlags getAspectFromFormat(Gfx::SeFormat format) { } TextureHandle::TextureHandle(PGraphics graphics, VkImageViewType viewType, const TextureCreateInfo& createInfo, VkImage existingImage) - : CommandBoundResource(graphics, createInfo.name), image(existingImage), owner(createInfo.sourceData.owner), width(createInfo.width), - height(createInfo.height), depth(createInfo.depth), arrayCount(createInfo.elements), layerCount(createInfo.layers), mipLevels(1), - samples(createInfo.samples), format(createInfo.format), usage(createInfo.usage), - layout(Gfx::SE_IMAGE_LAYOUT_UNDEFINED), aspect(getAspectFromFormat(createInfo.format)), ownsImage(false) { + : CommandBoundResource(graphics, createInfo.name), image(existingImage), imageView(VK_NULL_HANDLE), allocation(nullptr), + owner(createInfo.sourceData.owner), width(createInfo.width), height(createInfo.height), depth(createInfo.depth), + layerCount(createInfo.elements), mipLevels(1), samples(createInfo.samples), format(createInfo.format), + usage(createInfo.usage), layout(Gfx::SE_IMAGE_LAYOUT_UNDEFINED), aspect(getAspectFromFormat(createInfo.format)), ownsImage(false) { if (createInfo.useMip) { mipLevels = static_cast(std::floor(std::log2(std::max(width, height)))) + 1; } @@ -55,7 +55,7 @@ TextureHandle::TextureHandle(PGraphics graphics, VkImageViewType viewType, const case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY: type = VK_IMAGE_TYPE_2D; flags = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT; - layerCount = 6 * arrayCount; + layerCount = 6 * layerCount; break; default: break; @@ -76,7 +76,7 @@ TextureHandle::TextureHandle(PGraphics graphics, VkImageViewType viewType, const .depth = depth, }, .mipLevels = mipLevels, - .arrayLayers = arrayCount * layerCount, + .arrayLayers = layerCount, .samples = (VkSampleCountFlagBits)samples, .tiling = VK_IMAGE_TILING_OPTIMAL, .usage = usage, @@ -95,7 +95,8 @@ TextureHandle::TextureHandle(PGraphics graphics, VkImageViewType viewType, const .pObjectName = name.c_str(), }; vkSetDebugUtilsObjectNameEXT(graphics->getDevice(), &nameInfo); - ownsImage = true;const DataSource& sourceData = createInfo.sourceData; + ownsImage = true; + const DataSource& sourceData = createInfo.sourceData; if (sourceData.size > 0) { changeLayout(Gfx::SE_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_ACCESS_NONE, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); @@ -117,7 +118,7 @@ TextureHandle::TextureHandle(PGraphics graphics, VkImageViewType viewType, const vmaMapMemory(graphics->getAllocator(), stagingAlloc->allocation, &data); std::memcpy(data, sourceData.data, sourceData.size); vmaUnmapMemory(graphics->getAllocator(), stagingAlloc->allocation); - + PCommandPool commandPool = graphics->getQueueCommands(owner); VkBufferImageCopy region = { .bufferOffset = 0, @@ -128,7 +129,7 @@ TextureHandle::TextureHandle(PGraphics graphics, VkImageViewType viewType, const .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, .mipLevel = 0, .baseArrayLayer = 0, - .layerCount = arrayCount * layerCount, + .layerCount = layerCount, }, .imageOffset = { @@ -138,10 +139,10 @@ TextureHandle::TextureHandle(PGraphics graphics, VkImageViewType viewType, const }, .imageExtent = {.width = width, .height = height, .depth = depth}, }; - - vkCmdCopyBufferToImage(commandPool->getCommands()->getHandle(), stagingAlloc->buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - 1, ®ion); - + + vkCmdCopyBufferToImage(commandPool->getCommands()->getHandle(), stagingAlloc->buffer, image, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion); + commandPool->getCommands()->bindResource(PBufferAllocation(stagingAlloc)); generateMipmaps(); // When loading a texture from a file, we will almost always use it as a texture map for fragment shaders @@ -150,7 +151,7 @@ TextureHandle::TextureHandle(PGraphics graphics, VkImageViewType viewType, const graphics->getDestructionManager()->queueResourceForDestruction(std::move(stagingAlloc)); } } - + VkImageViewCreateInfo viewInfo = { .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, .pNext = nullptr, @@ -162,7 +163,7 @@ TextureHandle::TextureHandle(PGraphics graphics, VkImageViewType viewType, const { .aspectMask = aspect, .levelCount = mipLevels, - .layerCount = layerCount * arrayCount, + .layerCount = layerCount, }, }; @@ -194,7 +195,7 @@ void TextureHandle::pipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlag .baseMipLevel = 0, .levelCount = mipLevels, .baseArrayLayer = 0, - .layerCount = layerCount * arrayCount, + .layerCount = layerCount, }, }; PCommand command = graphics->getQueueCommands(owner)->getCommands(); @@ -222,7 +223,7 @@ void TextureHandle::transferOwnership(Gfx::QueueType newOwner) { .baseMipLevel = 0, .levelCount = mipLevels, .baseArrayLayer = 0, - .layerCount = arrayCount, + .layerCount = layerCount, }, }; PCommandPool sourcePool = graphics->getQueueCommands(owner); @@ -385,7 +386,10 @@ TextureBase::TextureBase(PGraphics graphics, VkImageViewType viewType, const Tex : handle(new TextureHandle(graphics, viewType, createInfo, existingImage)), graphics(graphics), initialOwner(createInfo.sourceData.owner) {} -TextureBase::~TextureBase() { graphics->getDestructionManager()->queueResourceForDestruction(std::move(handle)); } +TextureBase::~TextureBase() { + graphics->getDestructionManager()->queueResourceForDestruction(std::move(handle)); + handle = nullptr; +} void TextureBase::pipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, VkAccessFlags dstAccess, VkPipelineStageFlags dstStage) { diff --git a/src/Engine/Graphics/Vulkan/Texture.h b/src/Engine/Graphics/Vulkan/Texture.h index 7865c5f..acd998b 100644 --- a/src/Engine/Graphics/Vulkan/Texture.h +++ b/src/Engine/Graphics/Vulkan/Texture.h @@ -6,15 +6,13 @@ #include "Resources.h" #include - namespace Seele { namespace Vulkan { class TextureHandle : public CommandBoundResource { public: TextureHandle(PGraphics graphics, VkImageViewType viewType, const TextureCreateInfo& createInfo, VkImage existingImage); virtual ~TextureHandle(); - void pipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, VkAccessFlags dstAccess, - VkPipelineStageFlags dstStage); + void pipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, VkAccessFlags dstAccess, VkPipelineStageFlags dstStage); void transferOwnership(Gfx::QueueType newOwner); void changeLayout(Gfx::SeImageLayout newLayout, VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, VkAccessFlags dstAccess, VkPipelineStageFlags dstStage); @@ -27,7 +25,6 @@ class TextureHandle : public CommandBoundResource { uint32 width; uint32 height; uint32 depth; - uint32 arrayCount; uint32 layerCount; uint32 mipLevels; uint32 samples; @@ -37,15 +34,20 @@ class TextureHandle : public CommandBoundResource { VkImageAspectFlags aspect; uint8 ownsImage; }; -DECLARE_REF(TextureHandle) +DEFINE_REF(TextureHandle) + +DECLARE_REF(TextureBase) +DECLARE_REF(Texture2D) +DECLARE_REF(Texture3D) +DECLARE_REF(TextureCube) class TextureBase { public: - TextureBase(PGraphics graphics, VkImageViewType viewType, const TextureCreateInfo& createInfo, - VkImage existingImage = VK_NULL_HANDLE); + TextureBase(PGraphics graphics, VkImageViewType viewType, const TextureCreateInfo& createInfo, VkImage existingImage = VK_NULL_HANDLE); virtual ~TextureBase(); uint32 getWidth() const { return handle->width; } uint32 getHeight() const { return handle->height; } uint32 getDepth() const { return handle->depth; } + uint32 getNumLayers() const { return handle->layerCount; } PTextureHandle getHandle() const { return handle; } VkImage getImage() const { return handle->image; }; VkImageView getView() const { return handle->imageView; }; @@ -58,13 +60,13 @@ class TextureBase { constexpr uint32 getMipLevels() const { return handle->mipLevels; } constexpr bool isDepthStencil() const { return handle->aspect & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT); } - void pipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, VkAccessFlags dstAccess, - VkPipelineStageFlags dstStage); + void pipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, VkAccessFlags dstAccess, VkPipelineStageFlags dstStage); void transferOwnership(Gfx::QueueType newOwner); void changeLayout(Gfx::SeImageLayout newLayout, VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, VkAccessFlags dstAccess, VkPipelineStageFlags dstStage); void download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array& buffer); void generateMipmaps(); + protected: OTextureHandle handle; // Updates via reference diff --git a/src/Engine/Graphics/Vulkan/Window.cpp b/src/Engine/Graphics/Vulkan/Window.cpp index a5f0e18..300ecbd 100644 --- a/src/Engine/Graphics/Vulkan/Window.cpp +++ b/src/Engine/Graphics/Vulkan/Window.cpp @@ -276,7 +276,6 @@ void Window::createSwapChain() { .width = extent.width, .height = extent.height, .depth = 1, - .layers = 1, .elements = 1, .samples = 1, .usage = Gfx::SE_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | Gfx::SE_IMAGE_USAGE_TRANSFER_DST_BIT, diff --git a/src/Engine/Graphics/Window.cpp b/src/Engine/Graphics/Window.cpp index 70bd098..b33cc6d 100644 --- a/src/Engine/Graphics/Window.cpp +++ b/src/Engine/Graphics/Window.cpp @@ -8,9 +8,13 @@ Window::Window() {} Window::~Window() {} Viewport::Viewport(PWindow owner, const ViewportCreateInfo& viewportInfo) - : sizeX(std::min(owner->getFramebufferWidth(), viewportInfo.dimensions.size.x)), - sizeY(std::min(owner->getFramebufferHeight(), viewportInfo.dimensions.size.y)), offsetX(viewportInfo.dimensions.offset.x), - offsetY(viewportInfo.dimensions.offset.y), fieldOfView(viewportInfo.fieldOfView), owner(owner) {} + : sizeX(viewportInfo.dimensions.size.x), sizeY(viewportInfo.dimensions.size.y), offsetX(viewportInfo.dimensions.offset.x), + offsetY(viewportInfo.dimensions.offset.y), fieldOfView(viewportInfo.fieldOfView), owner(owner) { + if (owner != nullptr) { + sizeX = std::min(owner->getFramebufferWidth(), sizeX); + sizeY = std::min(owner->getFramebufferHeight(), sizeY); + } +} Viewport::~Viewport() {} diff --git a/src/Engine/Graphics/Window.h b/src/Engine/Graphics/Window.h index 11dfded..7effa72 100644 --- a/src/Engine/Graphics/Window.h +++ b/src/Engine/Graphics/Window.h @@ -53,6 +53,12 @@ class Viewport { constexpr float getContentScaleX() const { return owner->getContentScaleX(); } constexpr float getContentScaleY() const { return owner->getContentScaleY(); } Matrix4 getProjectionMatrix() const; + URect getRenderArea() const { + return URect{ + .size = {sizeX, sizeY}, + .offset = {offsetX, offsetY}, + }; + } protected: uint32 sizeX; diff --git a/src/Engine/Graphics/slang-compile.cpp b/src/Engine/Graphics/slang-compile.cpp index 55d8494..dd355e2 100644 --- a/src/Engine/Graphics/slang-compile.cpp +++ b/src/Engine/Graphics/slang-compile.cpp @@ -77,7 +77,7 @@ void Seele::beginCompilation(const ShaderCompilationInfo& info, SlangCompileTarg }; sessionDesc.compilerOptionEntries = option.data(); - sessionDesc.compilerOptionEntryCount = option.size(); + sessionDesc.compilerOptionEntryCount = (uint32)option.size(); sessionDesc.defaultMatrixLayoutMode = SLANG_MATRIX_LAYOUT_COLUMN_MAJOR; Array macros; for (const auto& [key, val] : info.defines) { @@ -139,11 +139,9 @@ void Seele::beginCompilation(const ShaderCompilationInfo& info, SlangCompileTarg slang::ProgramLayout* signature = specializedComponent->getLayout(0, diagnostics.writeRef()); CHECK_DIAGNOSTICS(); - std::cout << info.name << std::endl; - for (size_t i = 0; i < signature->getParameterCount(); ++i) { + for (uint32 i = 0; i < signature->getParameterCount(); ++i) { auto param = signature->getParameterByIndex(i); layout->addMapping(param->getName(), param->getBindingIndex()); - //std::cout << param->getName() << ": " << param->getBindingIndex() << std::endl; } // workaround diff --git a/src/Engine/Material/Material.cpp b/src/Engine/Material/Material.cpp index 7f58c47..9001d87 100644 --- a/src/Engine/Material/Material.cpp +++ b/src/Engine/Material/Material.cpp @@ -99,21 +99,21 @@ void Material::updateFloatData(uint32 offset, uint32 numFloats, float* data) { } uint32 Material::addTextures(uint32 numTextures) { - uint32 textureOffset = textures.size(); + uint32 textureOffset = (uint32)textures.size(); textures.resize(textures.size() + numTextures); assert(textures.size() < 512); return textureOffset; } uint32 Material::addSamplers(uint32 numSamplers) { - uint32 samplerOffset = samplers.size(); + uint32 samplerOffset = (uint32)samplers.size(); samplers.resize(samplers.size() + numSamplers); assert(textures.size() < 512); return samplerOffset; } uint32 Material::addFloats(uint32 numFloats) { - uint32 floatOffset = floatData.size(); + uint32 floatOffset = (uint32)floatData.size(); floatData.resize(floatData.size() + numFloats); return floatOffset; } @@ -158,8 +158,8 @@ void Material::load(ArchiveBuffer& buffer) { void Material::compile() { std::ofstream codeStream("./shaders/generated/" + materialName + ".slang"); - codeStream << "import BRDF;\n"; codeStream << "import MaterialParameter;\n"; + codeStream << "import LightEnv;\n"; codeStream << "import Material;\n"; codeStream << "struct Material{\n"; codeStream << "\ttypedef " << brdf.profile << " BRDF;\n"; diff --git a/src/Engine/Material/ShaderExpression.cpp b/src/Engine/Material/ShaderExpression.cpp index b626cb4..d2fec09 100644 --- a/src/Engine/Material/ShaderExpression.cpp +++ b/src/Engine/Material/ShaderExpression.cpp @@ -69,7 +69,7 @@ FloatParameter::FloatParameter(std::string name, float data, uint32 index) : Sha FloatParameter::~FloatParameter() {} -void FloatParameter::updateDescriptorSet(uint32 textureOffset, uint32 samplerOffset, uint32 floatOffset) { +void FloatParameter::updateDescriptorSet(uint32, uint32, uint32 floatOffset) { Material::updateFloatData(floatOffset + index, 1, &data); } @@ -98,7 +98,7 @@ VectorParameter::VectorParameter(std::string name, Vector data, uint32 index) VectorParameter::~VectorParameter() {} -void VectorParameter::updateDescriptorSet(uint32 textureOffset, uint32 samplerOffset, uint32 floatOffset) { +void VectorParameter::updateDescriptorSet(uint32, uint32, uint32 floatOffset) { Material::updateFloatData(floatOffset + index, 3, (float*) & data); } @@ -125,7 +125,7 @@ TextureParameter::TextureParameter(std::string name, PTextureAsset asset, uint32 TextureParameter::~TextureParameter() {} -void TextureParameter::updateDescriptorSet(uint32 textureOffset, uint32 samplerOffset, uint32 floatOffset) { +void TextureParameter::updateDescriptorSet(uint32 textureOffset, uint32, uint32) { Material::updateTexture(textureOffset + index, data->getTexture()); } @@ -158,7 +158,7 @@ SamplerParameter::SamplerParameter(std::string name, Gfx::OSampler sampler, uint SamplerParameter::~SamplerParameter() {} -void SamplerParameter::updateDescriptorSet(uint32 textureOffset, uint32 samplerOffset, uint32 floatOffset) { +void SamplerParameter::updateDescriptorSet(uint32, uint32 samplerOffset, uint32) { Material::updateSampler(samplerOffset + index, data); } @@ -183,9 +183,9 @@ CombinedTextureParameter::CombinedTextureParameter(std::string name, PTextureAss CombinedTextureParameter::~CombinedTextureParameter() {} -void CombinedTextureParameter::updateDescriptorSet(uint32 textureOffset, uint32 samplerOffset, uint32 floatOffset) { assert(false); } +void CombinedTextureParameter::updateDescriptorSet(uint32 , uint32 , uint32 ) { assert(false); } -std::string CombinedTextureParameter::evaluate(Map& varState) const { return ""; } +std::string CombinedTextureParameter::evaluate(Map&) const { return ""; } void CombinedTextureParameter::save(ArchiveBuffer& buffer) const { ShaderParameter::save(buffer); diff --git a/src/Engine/Material/ShaderExpression.h b/src/Engine/Material/ShaderExpression.h index 4dc81bf..f79232c 100644 --- a/src/Engine/Material/ShaderExpression.h +++ b/src/Engine/Material/ShaderExpression.h @@ -4,7 +4,6 @@ #include "Math/Math.h" #include "MinimalEngine.h" - namespace Seele { enum class ExpressionType { UNKNOWN, @@ -184,6 +183,9 @@ struct SwizzleExpression : public ShaderExpression { StaticArray comp = {-1, -1, -1, -1}; SwizzleExpression() {} SwizzleExpression(StaticArray comp) : comp(std::move(comp)) {} + SwizzleExpression(std::string key, std::string target, StaticArray comp) : ShaderExpression(key) { + inputs["target"].source = target; + } virtual ~SwizzleExpression() {} virtual uint64 getIdentifier() const override { return IDENTIFIER; } virtual std::string evaluate(Map& varState) const override; @@ -194,6 +196,11 @@ DEFINE_REF(SwizzleExpression) struct SampleExpression : public ShaderExpression { static constexpr uint64 IDENTIFIER = 0x16; SampleExpression() {} + SampleExpression(std::string key, std::string texture, std::string sampler, std::string texCoords) : ShaderExpression(key) { + inputs["texture"].source = texture; + inputs["sampler"].source = sampler; + inputs["texCoords"].source = texCoords; + } virtual ~SampleExpression() {} virtual uint64 getIdentifier() const override { return IDENTIFIER; } virtual std::string evaluate(Map& varState) const override; @@ -205,8 +212,6 @@ DEFINE_REF(SampleExpression) struct MaterialNode { std::string profile; Map variables; - MaterialNode() {} - ~MaterialNode() {} void save(ArchiveBuffer& buffer) const; void load(ArchiveBuffer& buffer); }; diff --git a/src/Engine/Math/AABB.h b/src/Engine/Math/AABB.h index 8a36fe8..12b7586 100644 --- a/src/Engine/Math/AABB.h +++ b/src/Engine/Math/AABB.h @@ -11,9 +11,9 @@ struct BoundingSphere { }; struct AABB { Vector min = Vector(std::numeric_limits::max()); - float pad0; // So that it can be used directly in shaders + float pad0 = 0; // So that it can be used directly in shaders Vector max = Vector(std::numeric_limits::lowest()); // cause of reasons - float pad1; + float pad1 = 0; BoundingSphere toSphere() const { Vector center = (min + max) / 2.f; StaticArray corners; diff --git a/src/Engine/Physics/BVH.cpp b/src/Engine/Physics/BVH.cpp index eca8b9e..ae03a5e 100644 --- a/src/Engine/Physics/BVH.cpp +++ b/src/Engine/Physics/BVH.cpp @@ -85,7 +85,7 @@ void BVH::reinsertCollider(entt::entity entity, AABB aabb) { void BVH::removeCollider(entt::entity entity) { int32 nodeIndex = -1; - for (size_t i = 0; i < dynamicNodes.size(); i++) { + for (uint32_t i = 0; i < dynamicNodes.size(); i++) { if (dynamicNodes[i].isLeaf && dynamicNodes[i].owner == entity) { nodeIndex = i; break; @@ -275,7 +275,7 @@ int32 BVH::splitNode(Array aabbs) { } struct { bool operator()(const AABBCenter& lhs, const AABBCenter& rhs) { return lhs.center[longestAxis] < rhs.center[longestAxis]; } - int32 longestAxis; + int32 longestAxis = 0; } compare = {longestAxis}; std::sort(aabbs.begin(), aabbs.end(), compare); @@ -291,7 +291,7 @@ int32 BVH::splitNode(Array aabbs) { return rootIndex; } int32 BVH::allocateNode() { - for (size_t i = 0; i < dynamicNodes.size(); i++) { + for (uint32 i = 0; i < dynamicNodes.size(); i++) { if (!dynamicNodes[i].isValid) { return i; } @@ -309,14 +309,12 @@ void BVH::validateBVH() const { if (dynamicRoot != -1) { assert(dynamicNodes[dynamicRoot].parentIndex == -1); } - for (size_t i = 0; i < dynamicNodes.size(); ++i) { + for (uint32 i = 0; i < dynamicNodes.size(); ++i) { int32 nodeIdx = i; - size_t counter = dynamicNodes.size(); if (!dynamicNodes[nodeIdx].isValid) continue; while (dynamicNodes[nodeIdx].parentIndex != -1) { nodeIdx = dynamicNodes[nodeIdx].parentIndex; - assert(counter-- > 0 && dynamicNodes[nodeIdx].isValid); } } } diff --git a/src/Engine/Physics/BVH.h b/src/Engine/Physics/BVH.h index 705d105..77fa151 100644 --- a/src/Engine/Physics/BVH.h +++ b/src/Engine/Physics/BVH.h @@ -17,17 +17,17 @@ class BVH { private: struct AABBCenter { AABB bb; - Vector center; - entt::entity id; + Vector center = Vector(); + entt::entity id = entt::entity(); }; struct Node { AABB box; int32 parentIndex = -1; int32 left = -1; int32 right = -1; - bool isLeaf; + bool isLeaf = false; bool isValid = true; - entt::entity owner; + entt::entity owner = entt::entity(); }; void traverseStaticTree(const AABB& aabb, entt::entity source, int32 nodeIndex, Array>& overlaps); void traverseDynamicTree(const AABB& aabb, entt::entity source, int32 nodeIndex, Array>& overlaps); diff --git a/src/Engine/Physics/PhysicsSystem.cpp b/src/Engine/Physics/PhysicsSystem.cpp index 538fede..137fbdf 100644 --- a/src/Engine/Physics/PhysicsSystem.cpp +++ b/src/Engine/Physics/PhysicsSystem.cpp @@ -144,7 +144,7 @@ void PhysicsSystem::writeRigidBody(const Body& body) const { } } -Array PhysicsSystem::integratePhysics(const Array& bodies, const float t0, const float tdelta) const { +Array PhysicsSystem::integratePhysics(const Array& bodies, const float, const float) const { Array result; Array buffer; result.resize(bodies.size()); diff --git a/src/Engine/Scene/LightEnvironment.cpp b/src/Engine/Scene/LightEnvironment.cpp index 52409da..fbbd1a6 100644 --- a/src/Engine/Scene/LightEnvironment.cpp +++ b/src/Engine/Scene/LightEnvironment.cpp @@ -1,9 +1,12 @@ #include "LightEnvironment.h" +#include "Asset/EnvironmentMapAsset.h" #include "Graphics/Graphics.h" +#include "Asset/AssetRegistry.h" using namespace Seele; -LightEnvironment::LightEnvironment(Gfx::PGraphics graphics) : graphics(graphics) { +LightEnvironment::LightEnvironment(Gfx::PGraphics graphics) + : graphics(graphics), environment(AssetRegistry::findEnvironmentMap("", "newport_loft")) { layout = graphics->createDescriptorLayout("pLightEnv"); layout->addDescriptorBinding(Gfx::DescriptorBinding{ .name = "directionalLights", @@ -21,6 +24,10 @@ LightEnvironment::LightEnvironment(Gfx::PGraphics graphics) : graphics(graphics) .name = "numPointLights", .uniformLength = sizeof(uint32), }); + layout->addDescriptorBinding(Gfx::DescriptorBinding{ + .name = "irradianceMap", + .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE, + }); layout->create(); directionalLights = graphics->createShaderBuffer(ShaderBufferCreateInfo{ @@ -29,6 +36,13 @@ LightEnvironment::LightEnvironment(Gfx::PGraphics graphics) : graphics(graphics) pointLights = graphics->createShaderBuffer(ShaderBufferCreateInfo{ .name = "PointLights", }); + environmentSampler = graphics->createSampler({ + .magFilter = Gfx::SE_FILTER_LINEAR, + .minFilter = Gfx::SE_FILTER_LINEAR, + .addressModeU = Gfx::SE_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, + .addressModeV = Gfx::SE_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, + .addressModeW = Gfx::SE_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, + }); } LightEnvironment::~LightEnvironment() {} @@ -57,12 +71,13 @@ void LightEnvironment::commit() { Gfx::SE_ACCESS_SHADER_READ_BIT | Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT | Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT); - uint32 numPointLights = points.size(); - uint32 numDirectionalLights = dirs.size(); + uint32 numPointLights = (uint32)points.size(); + uint32 numDirectionalLights = (uint32)dirs.size(); set->updateConstants("numPointLights", 0, &numPointLights); set->updateBuffer("pointLights", 0, pointLights); set->updateConstants("numDirectionalLights", 0, &numDirectionalLights); set->updateBuffer("directionalLights", 0, directionalLights); + set->updateTexture("irradianceMap", 0, environment->getIrradianceMap()); set->writeChanges(); } diff --git a/src/Engine/Scene/LightEnvironment.h b/src/Engine/Scene/LightEnvironment.h index ac889b8..1cf2435 100644 --- a/src/Engine/Scene/LightEnvironment.h +++ b/src/Engine/Scene/LightEnvironment.h @@ -4,8 +4,8 @@ #include "Graphics/Buffer.h" #include "Graphics/Descriptor.h" - namespace Seele { +DECLARE_REF(EnvironmentMapAsset) class LightEnvironment { public: LightEnvironment(Gfx::PGraphics graphics); @@ -16,12 +16,15 @@ class LightEnvironment { void commit(); const Gfx::PDescriptorLayout getDescriptorLayout() const; Gfx::PDescriptorSet getDescriptorSet(); + PEnvironmentMapAsset getEnvironmentMap() { return environment; } private: Gfx::OShaderBuffer directionalLights; Gfx::OShaderBuffer pointLights; Array dirs; Array points; + PEnvironmentMapAsset environment; + Gfx::OSampler environmentSampler; Gfx::ODescriptorLayout layout; Gfx::PDescriptorSet set; Gfx::PGraphics graphics; diff --git a/src/Engine/Scene/Scene.cpp b/src/Engine/Scene/Scene.cpp index c7ae0ee..7f646f3 100644 --- a/src/Engine/Scene/Scene.cpp +++ b/src/Engine/Scene/Scene.cpp @@ -1,6 +1,5 @@ #include "Scene.h" #include "Actor/PointLightActor.h" -#include "Asset/AssetRegistry.h" #include "Asset/MaterialAsset.h" #include "Asset/TextureAsset.h" #include "Component/DirectionalLight.h" @@ -13,16 +12,11 @@ using namespace Seele; -Scene::Scene(Gfx::PGraphics graphics) : graphics(graphics), lightEnv(new LightEnvironment(graphics)), physics(registry) {} +Scene::Scene(Gfx::PGraphics graphics) + : graphics(graphics), lightEnv(new LightEnvironment(graphics)), physics(registry) {} Scene::~Scene() {} -void Scene::bakeLighting() { - const auto& matData = StaticMeshVertexData::getInstance()->getMaterialData(); - for (const auto& mat : matData) - { - - } -} +void Scene::bakeLighting() {} void Scene::update(float deltaTime) { physics.update(deltaTime); } diff --git a/src/Engine/Scene/Scene.h b/src/Engine/Scene/Scene.h index 59d7238..e68b025 100644 --- a/src/Engine/Scene/Scene.h +++ b/src/Engine/Scene/Scene.h @@ -1,8 +1,8 @@ #pragma once +#include "MinimalEngine.h" #include "Component/Skybox.h" #include "Graphics/Graphics.h" #include "LightEnvironment.h" -#include "MinimalEngine.h" #include "Physics/PhysicsSystem.h" #include #include diff --git a/src/Engine/System/KeyboardInput.cpp b/src/Engine/System/KeyboardInput.cpp index 85ce322..f6e37a5 100644 --- a/src/Engine/System/KeyboardInput.cpp +++ b/src/Engine/System/KeyboardInput.cpp @@ -28,8 +28,8 @@ void KeyboardInput::update(Component::KeyboardInput& input) { void KeyboardInput::keyCallback(KeyCode code, InputAction action, KeyModifier) { keys[code] = action != InputAction::RELEASE; } void KeyboardInput::mouseCallback(double x, double y) { - mouseX = x; - mouseY = y; + mouseX = (float)x; + mouseY = (float)y; } void KeyboardInput::mouseButtonCallback(MouseButton button, InputAction action, KeyModifier) { @@ -42,6 +42,6 @@ void KeyboardInput::mouseButtonCallback(MouseButton button, InputAction action, } void KeyboardInput::scrollCallback(double xScroll, double yScroll) { - scrollX = xScroll; - scrollY = yScroll; + scrollX = (float)xScroll; + scrollY = (float)yScroll; } diff --git a/src/Engine/System/MeshUpdater.cpp b/src/Engine/System/MeshUpdater.cpp index 5940733..ea716e6 100644 --- a/src/Engine/System/MeshUpdater.cpp +++ b/src/Engine/System/MeshUpdater.cpp @@ -10,6 +10,7 @@ MeshUpdater::MeshUpdater(PScene scene) : ComponentSystemaccessComponent(id); if (comp.meshletOffsets.empty()) { for (uint32 i = 0; i < comp.asset->meshes.size(); ++i) { comp.meshletOffsets.add(comp.asset->meshes[i]->vertexData->addCullingMapping(comp.asset->meshes[i]->id)); diff --git a/src/Engine/System/SystemBase.h b/src/Engine/System/SystemBase.h index 09d86ff..0437575 100644 --- a/src/Engine/System/SystemBase.h +++ b/src/Engine/System/SystemBase.h @@ -16,7 +16,7 @@ class SystemBase { virtual void update() {} protected: - double deltaTime; + double deltaTime = 0.0; entt::registry& registry; PScene scene; }; diff --git a/src/Engine/ThreadPool.cpp b/src/Engine/ThreadPool.cpp index 205efcc..950b640 100644 --- a/src/Engine/ThreadPool.cpp +++ b/src/Engine/ThreadPool.cpp @@ -1,5 +1,6 @@ #include "ThreadPool.h" #include "MinimalEngine.h" +#include "Graphics/Texture.h" using namespace Seele; @@ -7,6 +8,8 @@ Globals globals; Globals& Seele::getGlobals() { return globals; } +void test(Gfx::PTexture base) { (void)base; } + ThreadPool::ThreadPool(uint32 numWorkers) { for (uint32 i = 0; i < numWorkers; ++i) { workers.add(std::thread(&ThreadPool::work, this)); diff --git a/src/Engine/UI/Element.h b/src/Engine/UI/Element.h index bd3922d..6a47bf2 100644 --- a/src/Engine/UI/Element.h +++ b/src/Engine/UI/Element.h @@ -31,10 +31,10 @@ class Element { // calculates the relative positions of the child elements for the applied layout style virtual void layout(UVector2 parentSize) { if (style.maxWidthType == DimensionType::Auto) { - maxDimensions.x = parentSize.x; + maxDimensions.x = (float)parentSize.x; } if (style.maxHeightType == DimensionType::Auto) { - maxDimensions.y = parentSize.y; + maxDimensions.y = (float)parentSize.y; } if (style.widthType == DimensionType::Pixel) { dimensions.x = style.width; @@ -69,7 +69,7 @@ class Element { // create a new line in case the element doesnt fit on the current one anymore, // but keep in current line in case we are still at the start, as a new line wouldnt help here if (cursor.x + child->dimensions.x > maxDimensions.x - child->style.left && cursor.x != 0) { - cursor.x = style.paddingLeft; + cursor.x = (float)style.paddingLeft; cursor.y += lineHeight; lineHeight = 0; } @@ -90,7 +90,7 @@ class Element { if (child->style.position == PositionType::Static || child->style.position == PositionType::Relative) { // create a new line in case we are not already at one if (cursor.x != 0) { - cursor.x = style.paddingLeft; + cursor.x = (float)style.paddingLeft; cursor.y += lineHeight; } child->position.x = cursor.x + child->style.marginLeft; diff --git a/src/Engine/UI/Element/Text.h b/src/Engine/UI/Element/Text.h index f08fb96..6e1d43c 100644 --- a/src/Engine/UI/Element/Text.h +++ b/src/Engine/UI/Element/Text.h @@ -13,7 +13,7 @@ template class Text : public Element { style.outerDisplay = OuterDisplayType::Inline; (classes::apply(style), ...); } - virtual void layout(UVector2 parentSize) override { + virtual void layout(UVector2) override { UVector2 cursor = UVector2(0); dimensions = style.fontFamily->shapeText(text, style.fontSize, glyphRenders); } diff --git a/src/Engine/UI/Style/Class.h b/src/Engine/UI/Style/Class.h index d727fff..23f4129 100644 --- a/src/Engine/UI/Style/Class.h +++ b/src/Engine/UI/Style/Class.h @@ -67,24 +67,24 @@ using BG_Red = BackgroundColorClass; template struct MarginClass { static void apply(UI::Style& s) { - if (ml != -1) + if constexpr (ml != -1) s.marginLeft = ml; - if (mr != -1) + if constexpr (mr != -1) s.marginRight = mr; - if (mt != -1) + if constexpr (mt != -1) s.marginTop = mt; - if (mb != -1) + if constexpr (mb != -1) s.marginBottom = mb; } }; #define DECLARE_MARGIN_CLASSES(x) \ using M_##x = MarginClass; \ - using M_X##x = MarginClass; \ - using M_Y##x = MarginClass<-1u, -1u, x, x>; \ - using M_L##x = MarginClass; \ - using M_R##x = MarginClass<-1u, x, -1u, -1u>; \ - using M_T##x = MarginClass<-1u, -1u, x, -1u>; \ - using M_B##x = MarginClass<-1u, -1u, -1u, x>; + using M_X##x = MarginClass::max(), std::numeric_limits::max()>; \ + using M_Y##x = MarginClass::max(), std::numeric_limits::max(), x, x>; \ + using M_L##x = MarginClass::max(), std::numeric_limits::max(), std::numeric_limits::max()>; \ + using M_R##x = MarginClass::max(), x, std::numeric_limits::max(), std::numeric_limits::max()>; \ + using M_T##x = MarginClass::max(), std::numeric_limits::max(), x, std::numeric_limits::max()>; \ + using M_B##x = MarginClass::max(), std::numeric_limits::max(), std::numeric_limits::max(), x>; DECLARE_MARGIN_CLASSES(0) DECLARE_MARGIN_CLASSES(1) diff --git a/src/Engine/Window/GameView.cpp b/src/Engine/Window/GameView.cpp index 2b6582b..8c28137 100644 --- a/src/Engine/Window/GameView.cpp +++ b/src/Engine/Window/GameView.cpp @@ -32,6 +32,7 @@ GameView::GameView(Gfx::PGraphics graphics, PWindow window, const ViewportCreate renderGraph.createRenderPass(); if (graphics->supportRayTracing()) { rayTracingGraph.addPass(new RayTracingPass(graphics, scene)); + rayTracingGraph.addPass(new ToneMappingPass(graphics)); rayTracingGraph.setViewport(viewport); rayTracingGraph.createRenderPass(); } diff --git a/test.py b/test.py index ae7340f..353c3da 100644 --- a/test.py +++ b/test.py @@ -16,3 +16,11 @@ print(positions) print(indices) +# Create a tensor with attached grads from a numpy array +# Note: We pass zero=True to initialize the grads to zero on allocation +x = spy.Tensor.numpy(device, np.array([1, 2, 3, 4], dtype=np.float32)).with_grads(zero=True) + +# Evaluate the polynomial and ask for a tensor back +# Expecting result = 2x^2 + 8x - 1 +result: spy.Tensor = module.polynomial(a=2, b=8, c=-1, x=x, _result='tensor') +print(result.to_numpy()) \ No newline at end of file diff --git a/tests/Engine/Containers/Array.cpp b/tests/Engine/Containers/Array.cpp index 9512bcf..2e78b80 100644 --- a/tests/Engine/Containers/Array.cpp +++ b/tests/Engine/Containers/Array.cpp @@ -88,7 +88,7 @@ TEST(ArraySuite, remove_iterator) array.add(3); array.add(4); array.add(5); - array.remove(array.find(1), false); + array.erase(array.find(1), false); ASSERT_EQ(array[0], 5); ASSERT_EQ(array[1], 2); ASSERT_EQ(array[2], 3); @@ -104,7 +104,7 @@ TEST(ArraySuite, remove_iterator_keep_order) array.add(3); array.add(4); array.add(5); - array.remove(array.find(1)); + array.erase(array.find(1)); ASSERT_EQ(array[0], 2); ASSERT_EQ(array[1], 3); ASSERT_EQ(array[2], 4); diff --git a/tests/Engine/Containers/List.cpp b/tests/Engine/Containers/List.cpp index 2d17c4d..ad6f80c 100644 --- a/tests/Engine/Containers/List.cpp +++ b/tests/Engine/Containers/List.cpp @@ -35,22 +35,4 @@ TEST(ListSuite, basic_remove) it = list.remove(it); ASSERT_EQ(*it, 4); ASSERT_EQ(list.size(), 2); -} - -TEST(ListSuite, list_join) -{ - List list1; - List list2; - list1.add(2); - list1.add(1); - list1.add(3); - list1.add(4); - list2.add(5); - list2.add(7); - list2.add(8); - list2.add(6); - list2.add(9); - list1.moveElements(std::move(list2)); - ASSERT_EQ(list1.size(), 9); - ASSERT_EQ(list2.size(), 0); -} +} \ No newline at end of file diff --git a/tests/Engine/Containers/Map.cpp b/tests/Engine/Containers/Map.cpp index 92371b4..a92b3ed 100644 --- a/tests/Engine/Containers/Map.cpp +++ b/tests/Engine/Containers/Map.cpp @@ -31,7 +31,7 @@ TEST(CachedMap, for_each) map[6] = 4; map[4] = 7; int count = 0; - for(auto [key, val] : map) + for(const auto& [key, val] : map) { count++; } diff --git a/tests/Engine/MinimalEngine.cpp b/tests/Engine/MinimalEngine.cpp new file mode 100644 index 0000000..76d1098 --- /dev/null +++ b/tests/Engine/MinimalEngine.cpp @@ -0,0 +1,11 @@ +#include "EngineTest.h" + +struct Foo {}; + +struct Derivate : public Foo {}; + +TEST(RefPtr, ImplicitUpcast) { + OwningPtr owner = new Derivate(); + RefPtr der = owner; + RefPtr foo = der; +} \ No newline at end of file