Merge remote-tracking branch 'origin/master'

This commit is contained in:
Dynamitos
2025-04-10 16:59:37 +02:00
121 changed files with 1628 additions and 1137 deletions
+1 -2
View File
@@ -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/",
+3 -15
View File
@@ -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)
+63 -63
View File
@@ -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"
}
]
}
-1
View File
@@ -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 {
+1 -1
+1 -1
View File
@@ -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());
}
+125
View File
@@ -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<ViewParams> 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);
}
+15
View File
@@ -0,0 +1,15 @@
{
"name": "Placeholder",
"params": {
},
"code": [
{
"exp": "BRDF",
"profile": "BlinnPhong",
"values": {
"baseColor": "float3(0, 1, 0)",
"normal": "float3(0, 0, 1)"
}
}
]
}
+57 -57
View File
@@ -12,66 +12,66 @@ struct SkyboxData
};
ParameterBlock<SkyboxData> 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);
}
+18 -18
View File
@@ -1,23 +1,5 @@
import Common;
struct GlyphInstanceData
{
float x;
float y;
float z;
float width;
float height;
uint glyphIndex;
};
struct TextData
{
StructuredBuffer<GlyphInstanceData> glyphs;
SamplerState glyphSampler;
Texture2D<float> glyphTextures[];
};
ParameterBlock<TextData> 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<GlyphInstanceData> glyphs;
SamplerState glyphSampler;
Texture2D<float> glyphTextures[];
};
ParameterBlock<TextData> pText;
[shader("vertex")]
VertexOutput vertexMain(VertexInput input)
{
+1 -1
View File
@@ -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);
-291
View File
@@ -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;
}
};
+307 -2
View File
@@ -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<PointLight> pointLights;
uint numPointLights;
TextureCube irradianceMap;
SamplerState irradianceSampler;
};
layout(set=3)
ParameterBlock<LightEnv> 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;
}
};
-1
View File
@@ -1,5 +1,4 @@
import Common;
import BRDF;
import MaterialParameter;
import Scene;
+4 -3
View File
@@ -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<float> positions;
//StructuredBuffer<float> qTangents;
StructuredBuffer<float> normals;
StructuredBuffer<float> tangents;
StructuredBuffer<float> biTangents;
StructuredBuffer<uint16_t> color;
StructuredBuffer<uint16_t> texCoords[MAX_TEXCOORDS];
};
+1 -1
View File
@@ -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);
@@ -1,5 +1,4 @@
import MaterialParameter;
import BRDF;
struct RayTracingParams
{
+7 -7
View File
@@ -36,7 +36,7 @@ int main(int, char**) {
Array<Vector> 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<Tri> 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;
+2 -3
View File
@@ -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<std::string, uint64> results;
for (uint32 i = 0; i < 11; ++i) {
auto ts = timestamps->getResult();
+10 -1
View File
@@ -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() {
+4 -1
View File
@@ -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
+2
View File
@@ -2,6 +2,8 @@ target_sources(Editor
PRIVATE
AssetImporter.h
AssetImporter.cpp
EnvironmentLoader.h
EnvironmentLoader.cpp
FontLoader.h
FontLoader.cpp
MaterialLoader.h
+210
View File
@@ -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();
}
+34
View File
@@ -0,0 +1,34 @@
#pragma once
#include "MinimalEngine.h"
#include "Graphics/Graphics.h"
#include "Graphics/Shader.h"
#include <filesystem>
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;
};
}
+23 -18
View File
@@ -151,7 +151,7 @@ void MeshLoader::loadMaterials(const aiScene* scene, const Array<PTextureAsset>&
uint32 uvIndex = 0;
aiTextureMapMode mapMode = aiTextureMapMode_Clamp;
float blend = std::numeric_limits<float>::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<PMaterialInstanceAsset>& materials, Array<OMesh>& globalMeshes,
Component::Collider& collider) {
List<std::function<void()>> 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<PMaterialIns
}
Array<StaticMeshVertexData::NormalType> normals(mesh->mNumVertices);
Array<StaticMeshVertexData::TangentType> tangents(mesh->mNumVertices);
Array<StaticMeshVertexData::BiTangentType> biTangents(mesh->mNumVertices);
//Array<StaticMeshVertexData::BiTangentType> biTangents(mesh->mNumVertices);
Array<StaticMeshVertexData::ColorType> 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 Array<PMaterialIns
tangent = Vector(mesh->mTangents[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 Array<PMaterialIns
}
vertexData->loadNormals(offset, normals);
vertexData->loadTangents(offset, tangents);
vertexData->loadBitangents(offset, biTangents);
//vertexData->loadBitangents(offset, biTangents);
vertexData->loadColors(offset, colors);
Array<uint32> indices(mesh->mNumFaces * 3);
+8 -6
View File
@@ -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;
}
+1 -1
View File
@@ -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) {}
+3 -2
View File
@@ -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();
}
}
+1 -1
View File
@@ -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;
+20 -95
View File
@@ -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<Halfedge> generateEdges() {
Array<UVector> 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<Halfedge> 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<uint32> generateArray() { return Array<uint32>(); }
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) {
+47 -13
View File
@@ -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 <fstream>
#include <iostream>
@@ -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<Pair<PAsset, ArchiveBuffer>> peeked;
Array<Pair<PAsset, ArchiveBuffer>> peeked;
{
std::unique_lock l(get().assetLock);
peeked = peekFolder(assetRoot);
@@ -295,13 +318,16 @@ Pair<PAsset, ArchiveBuffer> 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);
+5
View File
@@ -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<std::string, OTextureAsset> textures;
Map<std::string, OFontAsset> fonts;
Map<std::string, OSVGAsset> svgs;
Map<std::string, OEnvironmentMapAsset> envs;
Map<std::string, OMeshAsset> meshes;
Map<std::string, OMaterialAsset> materials;
Map<std::string, OMaterialInstanceAsset> 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);
+2
View File
@@ -4,6 +4,8 @@ target_sources(Engine
Asset.cpp
AssetRegistry.h
AssetRegistry.cpp
EnvironmentMapAsset.h
EnvironmentMapAsset.cpp
FontAsset.h
FontAsset.cpp
LevelAsset.h
+13
View File
@@ -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) {}
+23
View File
@@ -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
+8 -8
View File
@@ -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<RenderGlyph>& 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, Array<Rend
Vector2 cursor = Vector2(0);
for (uint32 i = 0; i < num_glyphs; ++i) {
hb_codepoint_t glyphid = glyphs[i].codepoint;
float xOffset = positions[i].x_offset * fontSize / xppem;
float yOffset = positions[i].y_offset * fontSize / yppem;
float xAdvance = positions[i].x_advance * fontSize / xppem;
float yAdvance = positions[i].y_advance * fontSize / yppem;
float xOffset = (float)positions[i].x_offset * fontSize / xppem;
float yOffset = (float)positions[i].y_offset * fontSize / yppem;
float xAdvance = (float)positions[i].x_advance * fontSize / xppem;
float yAdvance = (float)positions[i].y_advance * fontSize / yppem;
Vector2 position = cursor + Vector2(xOffset, yOffset);
Vector2 dimensions = fontSizes[fontSize].glyphs[glyphid].size;
render.add(RenderGlyph{
@@ -73,7 +73,7 @@ UVector2 FontAsset::shapeText(std::string_view view, uint32 fontSize, Array<Rend
void FontAsset::loadGlyphs(uint32 fontSize) {
FT_Set_Pixel_Sizes(ft_face, 0, fontSize);
for (uint32 i = 0; i < ft_face->num_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);
+2 -2
View File
@@ -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&) { }
+1 -1
View File
@@ -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();
+1 -1
View File
@@ -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;
}
-3
View File
@@ -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,
+8 -8
View File
@@ -5,14 +5,14 @@ namespace Seele {
namespace Component {
struct KeyboardInput {
Seele::StaticArray<bool, static_cast<size_t>(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
+19 -17
View File
@@ -1,6 +1,7 @@
#pragma once
#include "EngineTypes.h"
#include "Concepts.h"
#include "EngineTypes.h"
#include "MemoryResource.h"
#include <algorithm>
#include <assert.h>
#include <initializer_list>
@@ -12,7 +13,7 @@
#endif
namespace Seele {
template <typename T, typename Allocator = std::pmr::polymorphic_allocator<T>> struct Array {
template <typename T> struct Array {
public:
template <typename X> class IteratorBase {
public:
@@ -67,7 +68,7 @@ template <typename T, typename Allocator = std::pmr::polymorphic_allocator<T>> s
};
using value_type = T;
using allocator_type = Allocator;
using allocator_type = std::pmr::polymorphic_allocator<T>;
using size_type = std::size_t;
using difference_type = std::ptrdiff_t;
using pointer = T*;
@@ -82,12 +83,8 @@ template <typename T, typename Allocator = std::pmr::polymorphic_allocator<T>> s
using reverse_iterator = std::reverse_iterator<iterator>;
using const_reverse_iterator = std::reverse_iterator<const_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 <typename T, typename Allocator = std::pmr::polymorphic_allocator<T>> 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 <typename T, typename Allocator = std::pmr::polymorphic_allocator<T>> 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 <typename T, typename Allocator = std::pmr::polymorphic_allocator<T>> s
}
return *this;
}
Array& operator=(Array&& other) noexcept(std::allocator_traits<Allocator>::propagate_on_container_move_assignment::value ||
std::allocator_traits<Allocator>::is_always_equal::value) {
Array& operator=(Array&& other) noexcept(std::allocator_traits<allocator_type>::propagate_on_container_move_assignment::value ||
std::allocator_traits<allocator_type>::is_always_equal::value) {
if (this != &other) {
if (_data != nullptr) {
clear();
@@ -294,7 +292,7 @@ template <typename T, typename Allocator = std::pmr::polymorphic_allocator<T>> s
requires std::predicate<Pred, value_type>
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 <typename T, typename Allocator = std::pmr::polymorphic_allocator<T>> 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 <typename Type> T& addInternal(Type&& t) noexcept {
if (arraySize == allocated) {
size_type newSize = arraySize + 1;
@@ -449,7 +451,7 @@ template <typename T, typename Allocator = std::pmr::polymorphic_allocator<T>> s
allocator_type allocator;
};
template <class Type, class Alloc> constexpr bool operator==(const Array<Type, Alloc>& lhs, const Array<Type, Alloc>& rhs) {
template <class Type> constexpr bool operator==(const Array<Type>& lhs, const Array<Type>& rhs) {
if (lhs.size() != rhs.size()) {
return false;
}
@@ -461,7 +463,7 @@ template <class Type, class Alloc> constexpr bool operator==(const Array<Type, A
return true;
}
template <class Type, class Alloc> constexpr auto operator<=>(const Array<Type, Alloc>& lhs, const Array<Type, Alloc>& rhs) {
template <class Type> constexpr auto operator<=>(const Array<Type>& lhs, const Array<Type>& rhs) {
return std::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
}
+3
View File
@@ -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)
+3 -4
View File
@@ -5,12 +5,11 @@
#include "Tree.h"
#include <utility>
namespace Seele {
template <typename KeyType, typename PairType> struct _KeyFun {
const KeyType& operator()(const PairType& pair) const { return pair.key; }
};
template <typename K, typename V, typename Compare = std::less<K>, typename Allocator = std::pmr::polymorphic_allocator<Pair<const K, V>>>
template <typename K, typename V, typename Compare = std::less<K>, typename Allocator = std::pmr::polymorphic_allocator<Pair<K, V>>>
struct Map : public Tree<K, Pair<K, V>, _KeyFun<K, Pair<K, V>>, Compare, Allocator> {
using Super = Tree<K, Pair<K, V>, _KeyFun<K, Pair<K, V>>, Compare, Allocator>;
using key_type = Super::key_type;
@@ -35,8 +34,8 @@ struct Map : public Tree<K, Pair<K, V>, _KeyFun<K, Pair<K, V>>, Compare, Allocat
: Super(comp, alloc) {}
constexpr explicit Map(const Allocator& alloc) noexcept(noexcept(Compare())) : Super(alloc) {}
constexpr Map(std::initializer_list<Pair<K, V>> init) : Super(init) {}
constexpr mapped_type& operator[](const key_type& key) {
auto [it, inserted] = Super::insert(Pair<K, V>(key, V()));
constexpr mapped_type& operator[](const key_type& key) {
auto [it, _] = Super::insert(Pair<K, V>(key));
return it->value;
}
constexpr const mapped_type& operator[](const key_type& key) const { return Super::find(key)->value; }
+40
View File
@@ -0,0 +1,40 @@
#include "MemoryResource.h"
#include "Map.h"
#include <iostream>
using namespace Seele;
RefPtr<uint64> 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<std::string, debug_resource> debugResources;
std::unique_lock l(resourcesMutex);
if (!debugResources.count(name)) {
debugResources.emplace(std::pair(name, debug_resource(name)));
}
return &debugResources[name];
}
+48
View File
@@ -0,0 +1,48 @@
#pragma once
#include <memory_resource>
#include <map>
#include "MinimalEngine.h"
namespace Seele {
class MemoryManager {
public:
static RefPtr<uint64> getAllocationCounter(const std::string& name);
static void printAllocations();
private:
static MemoryManager& getInstance();
std::mutex allocationMutex;
std::map<std::string, OwningPtr<uint64>> 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<uint64> counter;
};
} // namespace Seele
-8
View File
@@ -3,14 +3,6 @@
namespace Seele {
template <typename K, typename V> struct Pair {
public:
constexpr Pair() : key(K()), value(V()) {}
constexpr Pair(const K& key, const V& value) : key(key), value(value) {}
template <class U1 = K, class U2 = V> constexpr Pair(U1&& x, U2&& y) : key(std::forward<U1>(x)), value(std::forward<U2>(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);
}
+88 -65
View File
@@ -1,18 +1,31 @@
#pragma once
#include "Pair.h"
#include "Array.h"
#include <memory_resource>
#include "List.h"
#include "Pair.h"
namespace Seele {
template <typename KeyType, typename NodeData, typename KeyFun, typename Compare, typename Allocator> 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<Allocator>::template rebind_alloc<Node>;
@@ -25,49 +38,65 @@ template <typename KeyType, typename NodeData, typename KeyFun, typename Compare
using reference = IterType&;
using pointer = IterType*;
constexpr IteratorBase(Node* x = nullptr, Array<Node*>&& beginIt = Array<Node*>()) : 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>::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 <typename KeyType, typename NodeData, typename KeyFun, typename Compare
++*this;
return tmp;
}
Node* getNode() { return node; }
Node* getNode() const { return node; }
private:
Node* node;
Array<Node*> traversal;
};
using Iterator = IteratorBase<NodeData>;
using ConstIterator = IteratorBase<const NodeData>;
@@ -123,8 +151,8 @@ template <typename KeyType, typename NodeData, typename KeyFun, typename Compare
}
}
constexpr Tree(Tree&& other) noexcept
: alloc(std::move(other.alloc)), root(std::move(other.root)), iteratorsDirty(true), _size(std::move(other._size)),
comp(std::move(other.comp)) {
: alloc(std::move(other.alloc)), root(std::move(other.root)), pseudoRoot(std::move(other.pseudoRoot)), iteratorsDirty(true),
_size(std::move(other._size)), comp(std::move(other.comp)) {
other._size = 0;
}
constexpr ~Tree() noexcept { clear(); }
@@ -148,6 +176,7 @@ template <typename KeyType, typename NodeData, typename KeyFun, typename Compare
alloc = std::move(other.alloc);
}
root = std::move(other.root);
pseudoRoot = std::move(other.pseudoRoot);
_size = std::move(other._size);
comp = std::move(other.comp);
other._size = 0;
@@ -160,6 +189,7 @@ template <typename KeyType, typename NodeData, typename KeyFun, typename Compare
root = _remove(root, keyFun(root->data));
}
root = nullptr;
pseudoRoot.setLeftChild(nullptr);
markIteratorsDirty();
}
constexpr iterator begin() {
@@ -192,6 +222,7 @@ template <typename KeyType, typename NodeData, typename KeyFun, typename Compare
protected:
constexpr iterator find(const key_type& key) {
root = _splay(root, key);
pseudoRoot.setLeftChild(root);
if (root == nullptr || !equal(root->data, key)) {
return end();
}
@@ -214,15 +245,18 @@ template <typename KeyType, typename NodeData, typename KeyFun, typename Compare
constexpr Pair<iterator, bool> insert(const NodeData& data) {
auto [r, inserted] = _insert(root, data);
root = r;
pseudoRoot.setLeftChild(root);
return Pair<iterator, bool>(iterator(root), inserted);
}
constexpr Pair<iterator, bool> insert(NodeData&& data) {
auto [r, inserted] = _insert(root, std::move(data));
root = r;
pseudoRoot.setLeftChild(root);
return Pair<iterator, bool>(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 <typename KeyType, typename NodeData, typename KeyFun, typename Compare
iteratorsDirty = false;
}
constexpr Iterator calcBeginIterator() const {
Node* begin = root;
Array<Node*> beginTraversal;
while (begin != nullptr) {
beginTraversal.add(begin);
// start at pseudoroot so that if no regular nodes exist begin == end
Node* begin = const_cast<Node*>(&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<Node*> 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<Node*>(&pseudoRoot)); }
NodeAlloc alloc;
Node* root;
// where the end iterator points to
Node pseudoRoot;
Iterator beginIt;
Iterator endIt;
bool iteratorsDirty;
@@ -272,14 +295,14 @@ template <typename KeyType, typename NodeData, typename KeyFun, typename Compare
KeyFun keyFun = KeyFun();
Node* rotateLeft(Node* x) {
Node* y = x->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 <class NodeDataType> Pair<Node*, bool> _insert(Node* r, NodeDataType&& data) {
@@ -299,13 +322,13 @@ template <typename KeyType, typename NodeData, typename KeyFun, typename Compare
std::allocator_traits<NodeAlloc>::construct(alloc, newNode, nullptr, nullptr, std::forward<NodeDataType>(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<Node*, bool>(newNode, true);
@@ -328,7 +351,7 @@ template <typename KeyType, typename NodeData, typename KeyFun, typename Compare
temp = r;
r = _splay(r->leftChild, key);
r->rightChild = temp->rightChild;
r->setRightChild(temp->rightChild);
}
std::allocator_traits<NodeAlloc>::destroy(alloc, temp);
alloc.deallocate(temp, 1);
@@ -345,11 +368,11 @@ template <typename KeyType, typename NodeData, typename KeyFun, typename Compare
return r;
if (comp(key, keyFun(r->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 <typename KeyType, typename NodeData, typename KeyFun, typename Compare
return r;
if (comp(key, keyFun(r->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);
}
+3 -3
View File
@@ -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
+2 -3
View File
@@ -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<Matrix3> 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);
+1 -1
View File
@@ -1,4 +1,4 @@
add_subdirectory(CBT/)
#add_subdirectory(CBT/)
target_sources(Engine
PRIVATE
+1 -3
View File
@@ -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; }
+1 -3
View File
@@ -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);
+2 -2
View File
@@ -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<SubPassDependency> dependencies, PViewport renderArea,
std::string name = "") = 0;
virtual ORenderPass createRenderPass(RenderTargetLayout layout, Array<SubPassDependency> dependencies, URect renderArea,
std::string name = "", Array<uint32> viewMasks = {0}, Array<uint32> correlationMasks = {}) = 0;
virtual void beginRenderPass(PRenderPass renderPass) = 0;
virtual void endRenderPass() = 0;
virtual void waitDeviceIdle() = 0;
-1
View File
@@ -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;
+1 -1
View File
@@ -25,7 +25,7 @@ void buildAdjacency(const uint32 numVerts, const Array<uint32>& indices, Adjacen
triangleOffset += info.trianglesPerVertex[j];
}
uint32 numTriangles = indices.size() / 3;
uint32 numTriangles = (uint32)indices.size() / 3;
info.triangleData.resize(triangleOffset);
Array<uint32> offsets = info.indexBufferOffset;
for (uint32 k = 0; k < numTriangles; ++k) {
-1
View File
@@ -1,5 +1,4 @@
#include "RayTracing.h"
#include "RayTracing.h"
using namespace Seele::Gfx;
+1
View File
@@ -1,5 +1,6 @@
#pragma once
#include "Resources.h"
#include "Graphics/Descriptor.h"
namespace Seele {
namespace Gfx {
+12 -14
View File
@@ -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<Gfx::TextureCube>(),
.night = AssetRegistry::findTexture("", "skybox")->getTexture().cast<Gfx::TextureCube>(),
.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));
}
}
+2 -3
View File
@@ -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;
@@ -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)
@@ -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");
}
@@ -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");
}
@@ -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);
}
@@ -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<Gfx::TextureCube>();
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<Gfx::RayTracingHitGroup> callableGroups;
Array<Gfx::PBottomLevelAS> accelerationStructures;
Array<InstanceData> 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<Gfx::ORenderCommand> 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"},
@@ -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<uint32> indices;
for (uint32 i = 0; i < cpuMesh.totalNumElements * 3; ++i)
indices.add(i);
@@ -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,
+4 -4
View File
@@ -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<uint32>::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",
+1 -1
View File
@@ -42,7 +42,7 @@ class UIPass : public RenderPass {
Vector color;
float opacity = 1;
float z = 0;
uint32 textureIndex = -1ul;
uint32 textureIndex = std::numeric_limits<uint32>::max();
uint32 pad0;
uint32 pad1;
};
@@ -10,8 +10,8 @@ WaterRenderer::WaterRenderer(Gfx::PGraphics graphics, PScene scene, Gfx::PDescri
: graphics(graphics), scene(scene) {
skyBox = AssetRegistry::findTexture("", "skyboxsun5deg_tn")->getTexture().cast<Gfx::TextureCube>();
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), &params);
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);
@@ -57,8 +57,8 @@ class WaterRenderer {
};
StaticArray<DisplaySpectrumSettings, 8> 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;
+6
View File
@@ -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)
+9 -4
View File
@@ -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;
+19 -28
View File
@@ -7,9 +7,7 @@
using namespace Seele;
extern List<VertexData*> vertexDataList;
StaticMeshVertexData::StaticMeshVertexData() { vertexDataList.add(this); }
StaticMeshVertexData::StaticMeshVertexData() { VertexData::addVertexDataInstance(this); }
StaticMeshVertexData::~StaticMeshVertexData() {}
@@ -41,11 +39,12 @@ void StaticMeshVertexData::loadTangents(uint64 offset, const Array<TangentType>&
std::memcpy(tanData.data() + offset, data.data(), data.size() * sizeof(TangentType));
dirty = true;
}
void StaticMeshVertexData::loadBitangents(uint64 offset, const Array<BiTangentType>& data) {
/*void StaticMeshVertexData::loadBitangents(uint64 offset, const Array<BiTangentType>& 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<ColorType>& data) {
assert(offset + data.size() <= head);
@@ -71,17 +70,17 @@ void StaticMeshVertexData::serializeMesh(MeshId id, ArchiveBuffer& buffer) {
Array<PositionType> pos(numVertices);
Array<NormalType> nor(numVertices);
Array<TangentType> tan(numVertices);
Array<BiTangentType> bit(numVertices);
//Array<BiTangentType> bit(numVertices);
Array<ColorType> 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<PositionType> pos;
Array<NormalType> nor;
Array<TangentType> tan;
Array<BiTangentType> bit;
//Array<BiTangentType> bit;
Array<ColorType> 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();
+8 -11
View File
@@ -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<TexCoordType>& data);
void loadNormals(uint64 offset, const Array<NormalType>& data);
void loadTangents(uint64 offset, const Array<TangentType>& data);
void loadBitangents(uint64 offset, const Array<BiTangentType>& data);
//void loadBitangents(uint64 offset, const Array<BiTangentType>& data);
void loadColors(uint64 offset, const Array<ColorType>& 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<PositionType> posData;
Array<TexCoordType> texData[MAX_TEXCOORDS];
Array<NormalType> norData;
Array<TangentType> tanData;
Array<BiTangentType> bitData;
//Array<BiTangentType> bitData;
Array<ColorType> colData;
Gfx::ODescriptorLayout descriptorLayout;
Gfx::PDescriptorSet descriptorSet;
+8 -6
View File
@@ -90,7 +90,7 @@ void VertexData::createDescriptors() {
Array<uint32> 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<uint32> loadedIndices, Array<Meshlet> 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<VertexData*> vertexDataList;
void VertexData::addVertexDataInstance(VertexData* vertexData) { vertexDataList.add(vertexData); }
List<VertexData*> 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;
}
+5 -6
View File
@@ -8,7 +8,7 @@
#include "Meshlet.h"
#include <entt/entt.hpp>
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<TransparentDraw>& getTransparentData() const { return transparentData; }
const Array<Gfx::PBottomLevelAS>& getRayTracingData() const { return rayTracingScene; }
const Array<MeshData>& 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<VertexData*> 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> materialData;
Array<TransparentDraw> transparentData;
+11 -7
View File
@@ -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);
+6 -11
View File
@@ -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<PCommandBoundResource> 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<PCommandBoundResource> boundResources;
VkViewport currentViewport;
VkRect2D currentScissor;
PGraphics graphics;
std::thread::id threadId;
VkCommandBuffer handle;
+2 -2
View File
@@ -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;
}
+25 -82
View File
@@ -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<VkDescriptorPoolSize> 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<ShaderBuffer>();
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<VertexBuffer>();
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<IndexBuffer>();
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<Sampler>();
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<TextureBase>().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<TextureBase>().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<TextureBase>().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<TopLevelAS>();
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<uint32, VkPipelineLayout> cachedLayouts;
void PipelineLayout::create() {
for (auto [name, desc] : descriptorSetLayouts) {
for (const auto& [_, desc] : descriptorSetLayouts) {
PDescriptorLayout layout = desc.cast<DescriptorLayout>();
layout->create();
uint32 parameterIndex = parameterMapping[layout->getName()];
+2 -5
View File
@@ -24,7 +24,7 @@ class DescriptorLayout : public Gfx::DescriptorLayout {
private:
PGraphics graphics;
uint32 constantsSize = 0;
VkShaderStageFlags constantsStages;
VkShaderStageFlags constantsStages = 0;
Array<VkDescriptorSetLayoutBinding> bindings;
Map<std::string, DescriptorMapping> 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<uint8> constantData;
OBufferAllocation constantsBuffer;
VkShaderStageFlags constantsStageFlags;
List<VkDescriptorImageInfo> imageInfos;
List<VkDescriptorBufferInfo> bufferInfos;
List<VkWriteDescriptorSetAccelerationStructureKHR> accelerationInfos;
+11 -5
View File
@@ -16,40 +16,46 @@ Framebuffer::Framebuffer(PGraphics graphics, PRenderPass renderPass, Gfx::Render
Array<VkImageView> attachments;
uint32 width = 0;
uint32 height = 0;
uint32 layers = 0;
for (auto inputAttachment : layout.inputAttachments) {
PTexture2D vkInputAttachment = inputAttachment.getTexture().cast<Texture2D>();
PTextureBase vkInputAttachment = inputAttachment.getTexture().cast<TextureBase>();
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<Texture2D>();
PTextureBase vkColorAttachment = colorAttachment.getTexture().cast<TextureBase>();
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<Texture2D>();
PTextureBase vkResolveAttachment = resolveAttachment.getTexture().cast<TextureBase>();
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<Texture2D>();
PTextureBase vkDepthAttachment = layout.depthAttachment.getTexture().cast<TextureBase>();
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<Texture2D>();
PTextureBase vkDepthAttachment = layout.depthResolveAttachment.getTexture().cast<TextureBase>();
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,
+10 -10
View File
@@ -172,8 +172,9 @@ Gfx::OViewport Graphics::createViewport(Gfx::PWindow owner, const ViewportCreate
}
Gfx::ORenderPass Graphics::createRenderPass(Gfx::RenderTargetLayout layout, Array<Gfx::SubPassDependency> 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<uint32> viewMasks,
Array<uint32> 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<RenderPass>();
@@ -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<Gfx::PBottomLevelAS> 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<Gfx::PBottomLevelAS>
// 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<Gfx::PBottomLevelAS>
}
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));
}
+2 -1
View File
@@ -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<Gfx::SubPassDependency> dependencies,
Gfx::PViewport renderArea, std::string name) override;
URect renderArea, std::string name, Array<uint32> viewMasks,
Array<uint32> correlationMasks) override;
virtual void beginRenderPass(Gfx::PRenderPass renderPass) override;
virtual void endRenderPass() override;
virtual void waitDeviceIdle() override;
+19 -20
View File
@@ -11,23 +11,23 @@ using namespace Seele;
using namespace Seele::Vulkan;
PipelineCache::PipelineCache(PGraphics graphics, const std::string& cacheFilePath) : graphics(graphics), cacheFile(cacheFilePath) {
Array<uint8> 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<uint8> cacheData;
uint32 fileSize = static_cast<uint32>(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<AnyHitShader>();
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<IntersectionShader>();
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<uint64>(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<uint8> 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<uint8> 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<uint8> 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<uint8> 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;
+2 -2
View File
@@ -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;
+1 -1
View File
@@ -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,
+20 -19
View File
@@ -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<Gfx::SubPassDependency> _dependencies,
Gfx::PViewport viewport, std::string name)
RenderPass::RenderPass(PGraphics graphics, Gfx::RenderTargetLayout _layout, Array<Gfx::SubPassDependency> _dependencies, URect viewport,
std::string name, Array<uint32> viewMasks, Array<uint32> 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<VkAttachmentDescription2> attachments;
Array<VkAttachmentReference2> 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<Texture2D>();
PTextureBase tex = inputAttachment.getTexture().cast<TextureBase>();
description.inputAttachments[description.numInputAttachments++] = tex->getView();
}
for (auto& colorAttachment : layout.colorAttachments) {
PTexture2D tex = colorAttachment.getTexture().cast<Texture2D>();
PTextureBase tex = colorAttachment.getTexture().cast<TextureBase>();
description.colorAttachments[description.numColorAttachments++] = tex->getView();
}
for (auto& resolveAttachment : layout.resolveAttachments) {
PTexture2D tex = resolveAttachment.getTexture().cast<Texture2D>();
description.resolveAttachments[description.numResolveAttachments++] = tex->getView();
PTextureBase tex = resolveAttachment.getTexture().cast<TextureBase>();
description.resolveAttachments[description.numResolveAttachments++] = tex->getView();
}
if (layout.depthAttachment.getTexture() != nullptr) {
PTexture2D tex = layout.depthAttachment.getTexture().cast<Texture2D>();
PTextureBase tex = layout.depthAttachment.getTexture().cast<TextureBase>();
description.depthAttachment = tex->getView();
}
if (layout.depthResolveAttachment.getTexture() != nullptr) {
PTexture2D tex = layout.depthResolveAttachment.getTexture().cast<Texture2D>();
PTextureBase tex = layout.depthResolveAttachment.getTexture().cast<TextureBase>();
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<Texture2D>();
PTextureBase tex = inputAttachment.getTexture().cast<TextureBase>();
tex->setLayout(inputAttachment.getFinalLayout());
}
for (auto& colorAttachment : layout.colorAttachments) {
PTexture2D tex = colorAttachment.getTexture().cast<Texture2D>();
PTextureBase tex = colorAttachment.getTexture().cast<TextureBase>();
tex->setLayout(colorAttachment.getFinalLayout());
}
for (auto& resolveAttachment : layout.resolveAttachments) {
PTexture2D tex = resolveAttachment.getTexture().cast<Texture2D>();
PTextureBase tex = resolveAttachment.getTexture().cast<TextureBase>();
tex->setLayout(resolveAttachment.getFinalLayout());
}
if (layout.depthAttachment.getTexture() != nullptr) {
PTexture2D tex = layout.depthAttachment.getTexture().cast<Texture2D>();
PTextureBase tex = layout.depthAttachment.getTexture().cast<TextureBase>();
tex->setLayout(layout.depthAttachment.getFinalLayout());
}
if (layout.depthResolveAttachment.getTexture() != nullptr) {
PTexture2D tex = layout.depthResolveAttachment.getTexture().cast<Texture2D>();
PTextureBase tex = layout.depthResolveAttachment.getTexture().cast<TextureBase>();
tex->setLayout(layout.depthResolveAttachment.getFinalLayout());
}
}
+2 -1
View File
@@ -6,7 +6,8 @@ namespace Seele {
namespace Vulkan {
class RenderPass : public Gfx::RenderPass {
public:
RenderPass(PGraphics graphics, Gfx::RenderTargetLayout layout, Array<Gfx::SubPassDependency> dependencies, Gfx::PViewport viewport, std::string name);
RenderPass(PGraphics graphics, Gfx::RenderTargetLayout layout, Array<Gfx::SubPassDependency> dependencies, URect viewport,
std::string name, Array<uint32> viewMasks = {}, Array<uint32> correlationMasks = {});
virtual ~RenderPass();
uint32 getFramebufferHash();
void endRenderPass();
+1 -1
View File
@@ -34,7 +34,7 @@ void Semaphore::rotateSemaphore() {
currentHandle = i;
return;
}
currentHandle = handles.size();
currentHandle = (uint32)handles.size();
handles.add(new SemaphoreHandle(graphics, "Semaphore"));
}
+22 -18
View File
@@ -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<uint32_t>(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, &region);
vkCmdCopyBufferToImage(commandPool->getCommands()->getHandle(), stagingAlloc->buffer, image,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
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) {
+11 -9
View File
@@ -6,15 +6,13 @@
#include "Resources.h"
#include <vulkan/vulkan_core.h>
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<uint8>& buffer);
void generateMipmaps();
protected:
OTextureHandle handle;
// Updates via reference
-1
View File
@@ -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,
+7 -3
View File
@@ -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() {}
+6
View File
@@ -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;
+2 -4
View File
@@ -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<slang::PreprocessorMacroDesc> 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
+4 -4
View File
@@ -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";
+6 -6
View File
@@ -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<std::string, std::string>& varState) const { return ""; }
std::string CombinedTextureParameter::evaluate(Map<std::string, std::string>&) const { return ""; }
void CombinedTextureParameter::save(ArchiveBuffer& buffer) const {
ShaderParameter::save(buffer);
+8 -3
View File
@@ -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<int32, 4> comp = {-1, -1, -1, -1};
SwizzleExpression() {}
SwizzleExpression(StaticArray<int32, 4> comp) : comp(std::move(comp)) {}
SwizzleExpression(std::string key, std::string target, StaticArray<int32, 4> comp) : ShaderExpression(key) {
inputs["target"].source = target;
}
virtual ~SwizzleExpression() {}
virtual uint64 getIdentifier() const override { return IDENTIFIER; }
virtual std::string evaluate(Map<std::string, std::string>& 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<std::string, std::string>& varState) const override;
@@ -205,8 +212,6 @@ DEFINE_REF(SampleExpression)
struct MaterialNode {
std::string profile;
Map<std::string, std::string> variables;
MaterialNode() {}
~MaterialNode() {}
void save(ArchiveBuffer& buffer) const;
void load(ArchiveBuffer& buffer);
};

Some files were not shown because too many files have changed in this diff Show More