Compare commits
10
Commits
9bd1ca1b09
...
209780cd54
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
209780cd54 | ||
|
|
7d4cd26c31 | ||
|
|
e97beda2bc | ||
|
|
5be15b4929 | ||
|
|
ef9cb9c812 | ||
|
|
757b75aaf3 | ||
|
|
7ab9e8a5e5 | ||
|
|
6537459b77 | ||
|
|
aa4b78586e | ||
|
|
30d5b62447 |
+77
-55
@@ -1,58 +1,80 @@
|
|||||||
{
|
{
|
||||||
"version": 3,
|
"version": 3,
|
||||||
"cmakeMinimumRequired": {
|
"cmakeMinimumRequired": {
|
||||||
"major": 3,
|
"major": 3,
|
||||||
"minor": 19,
|
"minor": 19,
|
||||||
"patch": 0
|
"patch": 0
|
||||||
|
},
|
||||||
|
"configurePresets": [
|
||||||
|
{
|
||||||
|
"name": "release",
|
||||||
|
"displayName": "Release (no ASan)",
|
||||||
|
"description": "Release build without sanitizers",
|
||||||
|
"binaryDir": "${sourceDir}/build",
|
||||||
|
"cacheVariables": {
|
||||||
|
"CMAKE_BUILD_TYPE": "RelWithDebInfo",
|
||||||
|
"CMAKE_INSTALL_PREFIX": "C:/Program Files/Seele"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"configurePresets": [
|
{
|
||||||
{
|
"name": "release-asan",
|
||||||
"name": "release",
|
"displayName": "Release (ASan)",
|
||||||
"displayName": "Release (no ASan)",
|
"description": "Release build with Address Sanitizer",
|
||||||
"description": "Release build without sanitizers",
|
"binaryDir": "${sourceDir}/build",
|
||||||
"binaryDir": "${sourceDir}/build",
|
"cacheVariables": {
|
||||||
"cacheVariables": {
|
"CMAKE_BUILD_TYPE": "RelWithDebInfo",
|
||||||
"CMAKE_BUILD_TYPE": "RelWithDebInfo",
|
"CMAKE_CXX_FLAGS": "-fsanitize=address -fno-omit-frame-pointer",
|
||||||
"CMAKE_INSTALL_PREFIX": "C:/Program Files/Seele"
|
"CMAKE_C_FLAGS": "-fsanitize=address -fno-omit-frame-pointer",
|
||||||
}
|
"CMAKE_EXE_LINKER_FLAGS": "-fsanitize=address",
|
||||||
},
|
"CMAKE_SHARED_LINKER_FLAGS": "-fsanitize=address",
|
||||||
{
|
"CMAKE_INSTALL_PREFIX": "C:/Program Files/Seele"
|
||||||
"name": "release-asan",
|
}
|
||||||
"displayName": "Release (ASan)",
|
},
|
||||||
"description": "Release build with Address Sanitizer",
|
{
|
||||||
"binaryDir": "${sourceDir}/build",
|
"name": "debug",
|
||||||
"cacheVariables": {
|
"displayName": "Debug (no ASan)",
|
||||||
"CMAKE_BUILD_TYPE": "RelWithDebInfo",
|
"description": "Debug build without sanitizers",
|
||||||
"CMAKE_CXX_FLAGS": "-fsanitize=address -fno-omit-frame-pointer",
|
"binaryDir": "${sourceDir}/build",
|
||||||
"CMAKE_C_FLAGS": "-fsanitize=address -fno-omit-frame-pointer",
|
"cacheVariables": {
|
||||||
"CMAKE_EXE_LINKER_FLAGS": "-fsanitize=address",
|
"CMAKE_BUILD_TYPE": "Debug",
|
||||||
"CMAKE_SHARED_LINKER_FLAGS": "-fsanitize=address",
|
"CMAKE_INSTALL_PREFIX": "C:/Program Files/Seele"
|
||||||
"CMAKE_INSTALL_PREFIX": "C:/Program Files/Seele"
|
}
|
||||||
}
|
},
|
||||||
},
|
{
|
||||||
{
|
"name": "debug-asan",
|
||||||
"name": "debug",
|
"displayName": "Debug (ASan)",
|
||||||
"displayName": "Debug (no ASan)",
|
"description": "Debug build with Address Sanitizer",
|
||||||
"description": "Debug build without sanitizers",
|
"binaryDir": "${sourceDir}/build",
|
||||||
"binaryDir": "${sourceDir}/build",
|
"cacheVariables": {
|
||||||
"cacheVariables": {
|
"CMAKE_BUILD_TYPE": "Debug",
|
||||||
"CMAKE_BUILD_TYPE": "Debug",
|
"CMAKE_CXX_FLAGS": "-fsanitize=address -fno-omit-frame-pointer",
|
||||||
"CMAKE_INSTALL_PREFIX": "C:/Program Files/Seele"
|
"CMAKE_C_FLAGS": "-fsanitize=address -fno-omit-frame-pointer",
|
||||||
}
|
"CMAKE_EXE_LINKER_FLAGS": "-fsanitize=address",
|
||||||
},
|
"CMAKE_SHARED_LINKER_FLAGS": "-fsanitize=address",
|
||||||
{
|
"CMAKE_INSTALL_PREFIX": "C:/Program Files/Seele"
|
||||||
"name": "debug-asan",
|
}
|
||||||
"displayName": "Debug (ASan)",
|
}
|
||||||
"description": "Debug build with Address Sanitizer",
|
],
|
||||||
"binaryDir": "${sourceDir}/build",
|
"buildPresets": [
|
||||||
"cacheVariables": {
|
{
|
||||||
"CMAKE_BUILD_TYPE": "Debug",
|
"name": "release",
|
||||||
"CMAKE_CXX_FLAGS": "-fsanitize=address -fno-omit-frame-pointer",
|
"displayName": "Release (no ASan)",
|
||||||
"CMAKE_C_FLAGS": "-fsanitize=address -fno-omit-frame-pointer",
|
"configurePreset": "release"
|
||||||
"CMAKE_EXE_LINKER_FLAGS": "-fsanitize=address",
|
},
|
||||||
"CMAKE_SHARED_LINKER_FLAGS": "-fsanitize=address",
|
{
|
||||||
"CMAKE_INSTALL_PREFIX": "C:/Program Files/Seele"
|
"name": "release-asan",
|
||||||
}
|
"displayName": "Release (ASan)",
|
||||||
}
|
"configurePreset": "release-asan"
|
||||||
]
|
},
|
||||||
|
{
|
||||||
|
"name": "debug",
|
||||||
|
"displayName": "Debug (no ASan)",
|
||||||
|
"configurePreset": "debug"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "debug-asan",
|
||||||
|
"displayName": "Debug (ASan)",
|
||||||
|
"configurePreset": "debug-asan"
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
import sys
|
||||||
|
sys.path.insert(0, '/usr/share/gdb/python/')
|
||||||
|
import gdb.printing
|
||||||
|
|
||||||
|
class ArrayPrinter:
|
||||||
|
def __init__(self, val):
|
||||||
|
self.val = val
|
||||||
|
|
||||||
|
def to_string(self):
|
||||||
|
return f"Array(size={int(self.val['arraySize'])})"
|
||||||
|
|
||||||
|
def children(self):
|
||||||
|
data = self.val['_data']
|
||||||
|
size = int(self.val['arraySize'])
|
||||||
|
allocated = int(self.val['allocated'])
|
||||||
|
#yield f"[size]", size
|
||||||
|
#yield f"[allocated]", allocated
|
||||||
|
for i in range(size):
|
||||||
|
elem_val = (data + i).dereference()
|
||||||
|
yield f"[{i}]", elem_val
|
||||||
|
|
||||||
|
def display_hint(self):
|
||||||
|
return "array"
|
||||||
|
|
||||||
|
class VectorPrinter:
|
||||||
|
def __init__(self, val):
|
||||||
|
self.val = val
|
||||||
|
t = val.type.strip_typedefs()
|
||||||
|
self.length = int(t.template_argument(0))
|
||||||
|
self.value_type = t.template_argument(1)
|
||||||
|
|
||||||
|
def to_string(self):
|
||||||
|
comps = [float(self.val['x']), float(self.val['y'])]
|
||||||
|
if self.length >= 3:
|
||||||
|
comps.append(float(self.val['z']))
|
||||||
|
if self.length == 4:
|
||||||
|
comps.append(float(self.val['w']))
|
||||||
|
return "(" + ", ".join(map(str, comps)) + ")"
|
||||||
|
|
||||||
|
def display_hint(self):
|
||||||
|
return "string"
|
||||||
|
|
||||||
|
def _children(self):
|
||||||
|
comps = {'x': self.val['x'], 'y': self.val['y']}
|
||||||
|
if self.length >= 3:
|
||||||
|
comps['z'] = self.val['z']
|
||||||
|
if self.length == 4:
|
||||||
|
comps['w'] = self.val['w']
|
||||||
|
for key, value in comps.items():
|
||||||
|
yield key, value
|
||||||
|
|
||||||
|
|
||||||
|
def build_pretty_printer():
|
||||||
|
pp = gdb.printing.RegexpCollectionPrettyPrinter("Seele")
|
||||||
|
pp.add_printer("Array", r'^Seele::Array<.*>$', ArrayPrinter)
|
||||||
|
pp.add_printer("Vector", r"^glm::(detail::)?t?vec(\d)?<[^<>]*>$", VectorPrinter)
|
||||||
|
return pp
|
||||||
|
|
||||||
|
|
||||||
|
gdb.printing.register_pretty_printer(gdb.current_objfile(), build_pretty_printer())
|
||||||
+19
-16
@@ -5,16 +5,18 @@ import MATERIAL_FILE_NAME;
|
|||||||
|
|
||||||
const static uint64_t NUM_CASCADES = 4;
|
const static uint64_t NUM_CASCADES = 4;
|
||||||
|
|
||||||
/*struct ShadowMappingData
|
struct ShadowMappingData
|
||||||
{
|
{
|
||||||
Texture2DArray shadowMaps[NUM_CASCADES];
|
Texture2DArray shadowMaps[NUM_CASCADES];
|
||||||
|
|
||||||
ConstantBuffer<float4x4> lightSpaceMatrices[NUM_CASCADES];
|
StructuredBuffer<float4x4> lightSpaceMatrices[NUM_CASCADES];
|
||||||
|
|
||||||
ConstantBuffer<float[NUM_CASCADES]> cascadeSplits;
|
SamplerState shadowSampler;
|
||||||
|
|
||||||
|
ConstantBuffer<float4> cascadeSplits;
|
||||||
};
|
};
|
||||||
ParameterBlock<ShadowMappingData> pShadowMapping;
|
ParameterBlock<ShadowMappingData> pShadowMapping;
|
||||||
*/
|
|
||||||
struct LightCullingData
|
struct LightCullingData
|
||||||
{
|
{
|
||||||
RWStructuredBuffer<uint> lightIndexList;
|
RWStructuredBuffer<uint> lightIndexList;
|
||||||
@@ -42,16 +44,17 @@ float4 fragmentMain(in FragmentParameter params) : SV_Target
|
|||||||
float3 result = float3(0, 0, 0);
|
float3 result = float3(0, 0, 0);
|
||||||
for(int i = 0; i < pLightEnv.numDirectionalLights; ++i)
|
for(int i = 0; i < pLightEnv.numDirectionalLights; ++i)
|
||||||
{
|
{
|
||||||
/*uint cascadeIndex = 0;
|
uint cascadeIndex = 0;
|
||||||
for (uint c = 0; c < NUM_CASCADES - 1; ++c) {
|
for (uint c = 0; c < NUM_CASCADES - 1; ++c) {
|
||||||
if (params.position_VS.z < pShadowMapping.cascadeSplits[c]) {
|
if (params.position_VS.z > pShadowMapping.cascadeSplits[c]) {
|
||||||
cascadeIndex = c + 1;
|
//cascadeIndex = c + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
float4 lightSpacePos = mul(biasMat, mul(pShadowMapping.lightSpaceMatrices[i], float4(params.position_WS, 1)));
|
float4 lightSpacePos = mul(pShadowMapping.lightSpaceMatrices[cascadeIndex][i], float4(params.position_WS, 1));
|
||||||
float4 shadowCoord = lightSpacePos / lightSpacePos.w;
|
lightSpacePos = mul(biasMat, lightSpacePos);
|
||||||
int2 texDim;
|
float4 shadowCoord = clipToScreen(lightSpacePos);
|
||||||
pLightEnv.shadowMap.GetDimensions(texDim.x, texDim.y);
|
/*int3 texDim;
|
||||||
|
pShadowMapping.shadowMaps[cascadeIndex].GetDimensions(texDim.x, texDim.y, texDim.z);
|
||||||
float scale = 1.5f;
|
float scale = 1.5f;
|
||||||
float dx = scale * 1.0 / float(texDim.x);
|
float dx = scale * 1.0 / float(texDim.x);
|
||||||
float dy = scale * 1.0 / float(texDim.y);
|
float dy = scale * 1.0 / float(texDim.y);
|
||||||
@@ -64,8 +67,8 @@ float4 fragmentMain(in FragmentParameter params) : SV_Target
|
|||||||
float shadow = 1.0f;
|
float shadow = 1.0f;
|
||||||
if (shadowCoord.z > 0.0 && shadowCoord.z < 1.0)
|
if (shadowCoord.z > 0.0 && shadowCoord.z < 1.0)
|
||||||
{
|
{
|
||||||
float dist = pLightEnv.shadowMap.Sample(pLightEnv.shadowSampler, shadowCoord.xy + float2(dx * x, dy * y)).r;
|
float dist = pShadowMapping.shadowMaps[cascadeIndex].Sample(pShadowMapping.shadowSampler, float3(shadowCoord.xy + float2(dx * x, dy * y), i)).r;
|
||||||
if (shadowCoord.w > 0 && dist > shadowCoord.z)
|
if (shadowCoord.w > 0 && dist < shadowCoord.z - 0.005f)
|
||||||
{
|
{
|
||||||
shadow = 0;
|
shadow = 0;
|
||||||
}
|
}
|
||||||
@@ -75,13 +78,13 @@ float4 fragmentMain(in FragmentParameter params) : SV_Target
|
|||||||
}
|
}
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
result += /*(shadowFactor / count) **/ pLightEnv.directionalLights[i].illuminate(lightingParams, brdf);
|
result = 1 - float3(pShadowMapping.shadowMaps[cascadeIndex].Sample(pShadowMapping.shadowSampler, float3(shadowCoord.xy, i)).r, 0, 0);//(shadowFactor / count) * pLightEnv.directionalLights[i].illuminate(lightingParams, brdf);
|
||||||
}
|
}
|
||||||
for (uint i = 0; i < pLightEnv.numPointLights; ++i)
|
for (uint i = 0; i < pLightEnv.numPointLights; ++i)
|
||||||
{
|
{
|
||||||
//uint lightIndex = pLightCullingData.lightIndexList[startOffset + i];
|
//uint lightIndex = pLightCullingData.lightIndexList[startOffset + i];
|
||||||
result += pLightEnv.pointLights[i].illuminate(lightingParams, brdf);
|
//result += pLightEnv.pointLights[i].illuminate(lightingParams, brdf);
|
||||||
}
|
}
|
||||||
result += brdf.evaluateAmbient(lightingParams.viewDir_WS);
|
//result += brdf.evaluateAmbient(lightingParams.viewDir_WS);
|
||||||
return float4(result, brdf.getAlpha());
|
return float4(result, brdf.getAlpha());
|
||||||
}
|
}
|
||||||
@@ -253,7 +253,7 @@ float2 integrateBRDF(float nDotV, float roughness) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
[shader("pixel")]
|
[shader("pixel")]
|
||||||
float2 precomputeBRDF(float2 texCoords) : SV_Target
|
float2 precomputeBRDF(float2 texCoords : UV) : SV_Target
|
||||||
{
|
{
|
||||||
return integrateBRDF(texCoords.x, texCoords.y);
|
return integrateBRDF(texCoords.x, texCoords.y);
|
||||||
}
|
}
|
||||||
@@ -61,8 +61,6 @@ struct PointLight : ILightEnv
|
|||||||
struct LightEnv
|
struct LightEnv
|
||||||
{
|
{
|
||||||
StructuredBuffer<DirectionalLight> directionalLights;
|
StructuredBuffer<DirectionalLight> directionalLights;
|
||||||
Texture2D shadowMap; // todo: not an array
|
|
||||||
SamplerState shadowSampler;
|
|
||||||
uint numDirectionalLights;
|
uint numDirectionalLights;
|
||||||
StructuredBuffer<PointLight> pointLights;
|
StructuredBuffer<PointLight> pointLights;
|
||||||
uint numPointLights;
|
uint numPointLights;
|
||||||
|
|||||||
@@ -95,6 +95,7 @@ EnvironmentLoader::EnvironmentLoader(Gfx::PGraphics graphics) : graphics(graphic
|
|||||||
{"precomputeBRDF", "EnvironmentMapping"},
|
{"precomputeBRDF", "EnvironmentMapping"},
|
||||||
},
|
},
|
||||||
.rootSignature = cubePipelineLayout,
|
.rootSignature = cubePipelineLayout,
|
||||||
|
.dumpIntermediate = true,
|
||||||
});
|
});
|
||||||
cubePipelineLayout->create();
|
cubePipelineLayout->create();
|
||||||
|
|
||||||
@@ -203,7 +204,7 @@ void EnvironmentLoader::import(EnvironmentImportArgs args, PEnvironmentMapAsset
|
|||||||
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)),
|
||||||
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();
|
Gfx::ODescriptorSet set = cubeRenderLayout->allocateDescriptorSet();
|
||||||
set->updateConstants("view", 0, captureViews);
|
set->updateConstants("view", 0, captureViews);
|
||||||
set->updateConstants("projection", 0, &captureProjection);
|
set->updateConstants("projection", 0, &captureProjection);
|
||||||
set->updateTexture("equirectangularMap", 0, hdrTexture->getDefaultView());
|
set->updateTexture("equirectangularMap", 0, hdrTexture->getDefaultView());
|
||||||
@@ -262,7 +263,7 @@ void EnvironmentLoader::import(EnvironmentImportArgs args, PEnvironmentMapAsset
|
|||||||
graphics->beginRenderPass(cubeRenderPass);
|
graphics->beginRenderPass(cubeRenderPass);
|
||||||
Gfx::ORenderCommand renderCommand = graphics->createRenderCommand("CubeMapRender");
|
Gfx::ORenderCommand renderCommand = graphics->createRenderCommand("CubeMapRender");
|
||||||
renderCommand->bindPipeline(cubeRenderPipeline);
|
renderCommand->bindPipeline(cubeRenderPipeline);
|
||||||
renderCommand->bindDescriptor({set});
|
renderCommand->bindDescriptor(set);
|
||||||
renderCommand->setViewport(cubeRenderViewport);
|
renderCommand->setViewport(cubeRenderViewport);
|
||||||
renderCommand->draw(6, 1, i * 6, 0);
|
renderCommand->draw(6, 1, i * 6, 0);
|
||||||
graphics->executeCommands(std::move(renderCommand));
|
graphics->executeCommands(std::move(renderCommand));
|
||||||
@@ -329,7 +330,7 @@ void EnvironmentLoader::import(EnvironmentImportArgs args, PEnvironmentMapAsset
|
|||||||
graphics->beginRenderPass(convolutionPass);
|
graphics->beginRenderPass(convolutionPass);
|
||||||
Gfx::ORenderCommand cmd = graphics->createRenderCommand("ConvolutionPass");
|
Gfx::ORenderCommand cmd = graphics->createRenderCommand("ConvolutionPass");
|
||||||
cmd->bindPipeline(convolutionPipeline);
|
cmd->bindPipeline(convolutionPipeline);
|
||||||
cmd->bindDescriptor({set});
|
cmd->bindDescriptor(set);
|
||||||
cmd->setViewport(convolutionViewport);
|
cmd->setViewport(convolutionViewport);
|
||||||
cmd->draw(6, 1, i * 6, 0);
|
cmd->draw(6, 1, i * 6, 0);
|
||||||
graphics->executeCommands(std::move(cmd));
|
graphics->executeCommands(std::move(cmd));
|
||||||
@@ -391,7 +392,7 @@ void EnvironmentLoader::import(EnvironmentImportArgs args, PEnvironmentMapAsset
|
|||||||
graphics->beginRenderPass(prefilterPass);
|
graphics->beginRenderPass(prefilterPass);
|
||||||
Gfx::ORenderCommand cmd = graphics->createRenderCommand("PrefilterPass");
|
Gfx::ORenderCommand cmd = graphics->createRenderCommand("PrefilterPass");
|
||||||
cmd->bindPipeline(prefilterPipeline);
|
cmd->bindPipeline(prefilterPipeline);
|
||||||
cmd->bindDescriptor({set});
|
cmd->bindDescriptor(set);
|
||||||
float roughness = (float)mip / (float)(prefilteredCubeMap->getMipLevels() - 1);
|
float roughness = (float)mip / (float)(prefilteredCubeMap->getMipLevels() - 1);
|
||||||
cmd->pushConstants(Gfx::SE_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(float), &roughness);
|
cmd->pushConstants(Gfx::SE_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(float), &roughness);
|
||||||
cmd->setViewport(prefilterViewports[mip]);
|
cmd->setViewport(prefilterViewports[mip]);
|
||||||
|
|||||||
+2
-4
@@ -12,11 +12,9 @@
|
|||||||
#endif
|
#endif
|
||||||
#include "Graphics/StaticMeshVertexData.h"
|
#include "Graphics/StaticMeshVertexData.h"
|
||||||
#include "Graphics/Vulkan/Graphics.h"
|
#include "Graphics/Vulkan/Graphics.h"
|
||||||
#include "Window/InspectorView.h"
|
|
||||||
#include "Window/PlayView.h"
|
#include "Window/PlayView.h"
|
||||||
#include "Window/WindowManager.h"
|
#include "Window/WindowManager.h"
|
||||||
#include <fmt/core.h>
|
#include <fmt/core.h>
|
||||||
#include <random>
|
|
||||||
|
|
||||||
using namespace Seele;
|
using namespace Seele;
|
||||||
using namespace Seele::Editor;
|
using namespace Seele::Editor;
|
||||||
@@ -26,8 +24,8 @@ static Gfx::OGraphics graphics;
|
|||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
std::string gameName = "MeshShadingDemo";
|
std::string gameName = "MeshShadingDemo";
|
||||||
std::filesystem::path outputPath = fmt::format("../../../../{0}Game/", gameName);
|
std::filesystem::path outputPath = fmt::format("/home/dynamitos/{0}Game/", gameName);
|
||||||
std::filesystem::path sourcePath = fmt::format("../../../../{0}/", gameName);
|
std::filesystem::path sourcePath = fmt::format("/home/dynamitos/{0}/", gameName);
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
std::string libraryEnding = "dll";
|
std::string libraryEnding = "dll";
|
||||||
#elif __APPLE__
|
#elif __APPLE__
|
||||||
|
|||||||
@@ -227,7 +227,7 @@ void AssetRegistry::initialize(const std::filesystem::path& _rootFolder, Gfx::PG
|
|||||||
this->assetRoot = new AssetFolder("");
|
this->assetRoot = new AssetFolder("");
|
||||||
if (!std::filesystem::exists(rootFolder))
|
if (!std::filesystem::exists(rootFolder))
|
||||||
{
|
{
|
||||||
std::filesystem::create_directories(rootFolder);
|
//std::filesystem::create_directories(rootFolder);
|
||||||
}
|
}
|
||||||
else if (!std::filesystem::is_directory(rootFolder))
|
else if (!std::filesystem::is_directory(rootFolder))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ namespace Seele {
|
|||||||
namespace Component {
|
namespace Component {
|
||||||
struct Camera {
|
struct Camera {
|
||||||
float nearPlane = 0.1f;
|
float nearPlane = 0.1f;
|
||||||
float farPlane = 1000.0f;
|
float farPlane = 10000.0f;
|
||||||
bool mainCamera = false;
|
bool mainCamera = false;
|
||||||
};
|
};
|
||||||
} // namespace Component
|
} // namespace Component
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ void DescriptorLayout::addDescriptorBinding(DescriptorBinding binding) {
|
|||||||
descriptorBindings.add(binding);
|
descriptorBindings.add(binding);
|
||||||
}
|
}
|
||||||
|
|
||||||
PDescriptorSet DescriptorLayout::allocateDescriptorSet() { return pool->allocateDescriptorSet(); }
|
ODescriptorSet DescriptorLayout::allocateDescriptorSet() { return pool->allocateDescriptorSet(); }
|
||||||
|
|
||||||
void DescriptorLayout::reset() { pool->reset(); }
|
void DescriptorLayout::reset() { pool->reset(); }
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ struct DescriptorBinding {
|
|||||||
std::string name;
|
std::string name;
|
||||||
// In Metal uniforms are plain bytes, and for that we need to know the struct size
|
// In Metal uniforms are plain bytes, and for that we need to know the struct size
|
||||||
uint32 uniformLength = 0;
|
uint32 uniformLength = 0;
|
||||||
SeDescriptorType descriptorType = SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
|
SeDescriptorType descriptorType = SE_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK;
|
||||||
SeImageViewType textureType = SE_IMAGE_VIEW_TYPE_2D;
|
SeImageViewType textureType = SE_IMAGE_VIEW_TYPE_2D;
|
||||||
uint32 descriptorCount = 1;
|
uint32 descriptorCount = 1;
|
||||||
SeDescriptorBindingFlags bindingFlags = 0;
|
SeDescriptorBindingFlags bindingFlags = 0;
|
||||||
@@ -25,9 +25,8 @@ class DescriptorLayout {
|
|||||||
virtual ~DescriptorLayout();
|
virtual ~DescriptorLayout();
|
||||||
void addDescriptorBinding(DescriptorBinding binding);
|
void addDescriptorBinding(DescriptorBinding binding);
|
||||||
void reset();
|
void reset();
|
||||||
PDescriptorSet allocateDescriptorSet();
|
ODescriptorSet allocateDescriptorSet();
|
||||||
virtual void create() = 0;
|
virtual void create() = 0;
|
||||||
constexpr const Array<DescriptorBinding>& getBindings() const { return descriptorBindings; }
|
|
||||||
constexpr uint32 getHash() const { return hash; }
|
constexpr uint32 getHash() const { return hash; }
|
||||||
constexpr const std::string& getName() const { return name; }
|
constexpr const std::string& getName() const { return name; }
|
||||||
|
|
||||||
@@ -46,7 +45,7 @@ class DescriptorPool {
|
|||||||
public:
|
public:
|
||||||
DescriptorPool();
|
DescriptorPool();
|
||||||
virtual ~DescriptorPool();
|
virtual ~DescriptorPool();
|
||||||
virtual PDescriptorSet allocateDescriptorSet() = 0;
|
virtual ODescriptorSet allocateDescriptorSet() = 0;
|
||||||
virtual void reset() = 0;
|
virtual void reset() = 0;
|
||||||
};
|
};
|
||||||
DEFINE_REF(DescriptorPool)
|
DEFINE_REF(DescriptorPool)
|
||||||
@@ -62,8 +61,9 @@ class DescriptorSet {
|
|||||||
virtual void writeChanges() = 0;
|
virtual void writeChanges() = 0;
|
||||||
virtual void updateConstants(const std::string& name, uint32 offset, void* data) = 0;
|
virtual void updateConstants(const std::string& name, uint32 offset, void* data) = 0;
|
||||||
virtual void updateBuffer(const std::string& name, uint32 index, Gfx::PShaderBuffer shaderBuffer) = 0;
|
virtual void updateBuffer(const std::string& name, uint32 index, Gfx::PShaderBuffer shaderBuffer) = 0;
|
||||||
virtual void updateBuffer(const std::string& name, uint32 index, Gfx::PVertexBuffer indexBuffer) = 0;
|
virtual void updateBuffer(const std::string& name, uint32 index, Gfx::PVertexBuffer vertexBuffer) = 0;
|
||||||
virtual void updateBuffer(const std::string& name, uint32 index, Gfx::PIndexBuffer indexBuffer) = 0;
|
virtual void updateBuffer(const std::string& name, uint32 index, Gfx::PIndexBuffer indexBuffer) = 0;
|
||||||
|
virtual void updateBuffer(const std::string& name, uint32 index, Gfx::PUniformBuffer uniformBuffer) = 0;
|
||||||
virtual void updateSampler(const std::string& name, uint32 index, Gfx::PSampler samplerState) = 0;
|
virtual void updateSampler(const std::string& name, uint32 index, Gfx::PSampler samplerState) = 0;
|
||||||
virtual void updateTexture(const std::string& name, uint32 index, Gfx::PTextureView texture) = 0;
|
virtual void updateTexture(const std::string& name, uint32 index, Gfx::PTextureView texture) = 0;
|
||||||
virtual void updateAccelerationStructure(const std::string& name, uint32 index, Gfx::PTopLevelAS as) = 0;
|
virtual void updateAccelerationStructure(const std::string& name, uint32 index, Gfx::PTopLevelAS as) = 0;
|
||||||
@@ -93,6 +93,13 @@ class PipelineLayout {
|
|||||||
constexpr std::string getName() const { return name; };
|
constexpr std::string getName() const { return name; };
|
||||||
constexpr bool hasPushConstants() const { return !pushConstants.empty(); }
|
constexpr bool hasPushConstants() const { return !pushConstants.empty(); }
|
||||||
constexpr uint64 getPushConstantsSize() const { return pushConstants[0].size; }
|
constexpr uint64 getPushConstantsSize() const { return pushConstants[0].size; }
|
||||||
|
constexpr const std::string& getPushConstantName(uint64 offset) {
|
||||||
|
for (uint32 i = 0; i < pushConstants.size(); ++i) {
|
||||||
|
if (offset == pushConstants[i].offset)
|
||||||
|
return pushConstants[i].name;
|
||||||
|
}
|
||||||
|
throw std::logic_error("unknown push constant offset");
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
uint32 layoutHash = 0;
|
uint32 layoutHash = 0;
|
||||||
|
|||||||
@@ -67,6 +67,7 @@ class Graphics {
|
|||||||
virtual void executeCommands(Array<OComputeCommand> commands) = 0;
|
virtual void executeCommands(Array<OComputeCommand> commands) = 0;
|
||||||
|
|
||||||
virtual OTexture2D createTexture2D(const TextureCreateInfo& createInfo) = 0;
|
virtual OTexture2D createTexture2D(const TextureCreateInfo& createInfo) = 0;
|
||||||
|
virtual OTexture2DArray createTexture2DArray(const TextureCreateInfo& createInfo) = 0;
|
||||||
virtual OTexture3D createTexture3D(const TextureCreateInfo& createInfo) = 0;
|
virtual OTexture3D createTexture3D(const TextureCreateInfo& createInfo) = 0;
|
||||||
virtual OTextureCube createTextureCube(const TextureCreateInfo& createInfo) = 0;
|
virtual OTextureCube createTextureCube(const TextureCreateInfo& createInfo) = 0;
|
||||||
virtual OUniformBuffer createUniformBuffer(const UniformBufferCreateInfo& bulkData) = 0;
|
virtual OUniformBuffer createUniformBuffer(const UniformBufferCreateInfo& bulkData) = 0;
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ using namespace Seele;
|
|||||||
using namespace Seele::Metal;
|
using namespace Seele::Metal;
|
||||||
|
|
||||||
BufferAllocation::BufferAllocation(PGraphics graphics, const std::string& name, uint64 size, MTL::ResourceOptions options)
|
BufferAllocation::BufferAllocation(PGraphics graphics, const std::string& name, uint64 size, MTL::ResourceOptions options)
|
||||||
: CommandBoundResource(graphics) {
|
: CommandBoundResource(graphics, name) {
|
||||||
buffer = graphics->getDevice()->newBuffer(size, options);
|
buffer = graphics->getDevice()->newBuffer(size, options);
|
||||||
buffer->setLabel(NS::String::string(name.c_str(), NS::ASCIIStringEncoding));
|
buffer->setLabel(NS::String::string(name.c_str(), NS::ASCIIStringEncoding));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -128,16 +128,17 @@ void RenderCommand::bindPipeline(Gfx::PRayTracingPipeline pipeline) {}
|
|||||||
|
|
||||||
void RenderCommand::bindDescriptor(Gfx::PDescriptorSet descriptorSet) {
|
void RenderCommand::bindDescriptor(Gfx::PDescriptorSet descriptorSet) {
|
||||||
auto metalSet = descriptorSet.cast<DescriptorSet>();
|
auto metalSet = descriptorSet.cast<DescriptorSet>();
|
||||||
metalSet->bind();
|
auto setHandle = metalSet->setHandle;
|
||||||
boundResources.add(metalSet);
|
setHandle->bind();
|
||||||
|
boundResources.add(setHandle);
|
||||||
uint32 descriptorIndex = boundPipeline->getPipelineLayout()->findParameter(metalSet->getLayout()->getName());
|
uint32 descriptorIndex = boundPipeline->getPipelineLayout()->findParameter(metalSet->getLayout()->getName());
|
||||||
|
|
||||||
auto createEncoder = [&metalSet, descriptorIndex](MTL::Function* function, const Array<uint32>& usedSets) {
|
auto createEncoder = [metalSet, &setHandle, descriptorIndex](MTL::Function* function, const Array<uint32>& usedSets) {
|
||||||
if(metalSet->encoder == nullptr) {
|
if(setHandle->encoder == nullptr) {
|
||||||
if (metalSet->isPlainDescriptor()) {
|
if (metalSet->isPlainDescriptor()) {
|
||||||
metalSet->encoder = metalSet->createEncoder();
|
setHandle->encoder = metalSet->createEncoder();
|
||||||
} else if (function != nullptr && usedSets.contains(descriptorIndex)) {
|
} else if (function != nullptr && usedSets.contains(descriptorIndex)) {
|
||||||
metalSet->encoder = function->newArgumentEncoder(descriptorIndex);
|
setHandle->encoder = function->newArgumentEncoder(descriptorIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -145,39 +146,39 @@ void RenderCommand::bindDescriptor(Gfx::PDescriptorSet descriptorSet) {
|
|||||||
createEncoder(boundPipeline->meshFunction, boundPipeline->meshSets);
|
createEncoder(boundPipeline->meshFunction, boundPipeline->meshSets);
|
||||||
createEncoder(boundPipeline->vertexFunction, boundPipeline->vertexSets);
|
createEncoder(boundPipeline->vertexFunction, boundPipeline->vertexSets);
|
||||||
createEncoder(boundPipeline->fragmentFunction, boundPipeline->fragmentSets);
|
createEncoder(boundPipeline->fragmentFunction, boundPipeline->fragmentSets);
|
||||||
if(metalSet->argumentBuffer == nullptr) {
|
if(setHandle->argumentBuffer == nullptr) {
|
||||||
metalSet->argumentBuffer = new BufferAllocation(metalSet->graphics, "ArgumentBuffer", metalSet->encoder->encodedLength());
|
setHandle->argumentBuffer = new BufferAllocation(metalSet->graphics, "ArgumentBuffer", setHandle->encoder->encodedLength());
|
||||||
metalSet->encoder->setArgumentBuffer(metalSet->argumentBuffer->buffer, 0);
|
setHandle->encoder->setArgumentBuffer(setHandle->argumentBuffer->buffer, 0);
|
||||||
}
|
}
|
||||||
metalSet->argumentBuffer->bind();
|
setHandle->argumentBuffer->bind();
|
||||||
boundResources.add(PBufferAllocation(metalSet->argumentBuffer));
|
boundResources.add(PBufferAllocation(setHandle->argumentBuffer));
|
||||||
for (const auto& write : metalSet->uniformWrites) {
|
for (const auto& write : setHandle->uniformWrites) {
|
||||||
write.apply(metalSet->encoder);
|
write.apply(setHandle->encoder);
|
||||||
}
|
}
|
||||||
for (const auto& write : metalSet->bufferWrites) {
|
for (const auto& write : setHandle->bufferWrites) {
|
||||||
write.apply(metalSet->encoder);
|
write.apply(setHandle->encoder);
|
||||||
encoder->useResource(write.buffer->buffer, write.access);
|
encoder->useResource(write.buffer->buffer, write.access);
|
||||||
}
|
}
|
||||||
for (const auto& write : metalSet->samplerWrites) {
|
for (const auto& write : setHandle->samplerWrites) {
|
||||||
write.apply(metalSet->encoder);
|
write.apply(setHandle->encoder);
|
||||||
}
|
}
|
||||||
for (const auto& write : metalSet->textureWrites) {
|
for (const auto& write : setHandle->textureWrites) {
|
||||||
write.apply(metalSet->encoder);
|
write.apply(setHandle->encoder);
|
||||||
encoder->useResource(write.texture->texture, write.access);
|
encoder->useResource(write.texture->getHandle(), write.access);
|
||||||
}
|
}
|
||||||
for (const auto& write : metalSet->accelerationWrites) {
|
for (const auto& write : setHandle->accelerationWrites) {
|
||||||
write.apply(metalSet->encoder);
|
write.apply(setHandle->encoder);
|
||||||
encoder->useResource(write.accelerationStructure, write.access);
|
encoder->useResource(write.accelerationStructure, write.access);
|
||||||
}
|
}
|
||||||
for(auto& res : metalSet->boundResources) {
|
for(auto& res : setHandle->boundResources) {
|
||||||
res->bind();
|
res->bind();
|
||||||
boundResources.add(res);
|
boundResources.add(res);
|
||||||
}
|
}
|
||||||
encoder->useResource(metalSet->argumentBuffer->buffer, MTL::ResourceUsageRead);
|
encoder->useResource(setHandle->argumentBuffer->buffer, MTL::ResourceUsageRead);
|
||||||
encoder->setObjectBuffer(metalSet->argumentBuffer->buffer, 0, descriptorIndex);
|
encoder->setObjectBuffer(setHandle->argumentBuffer->buffer, 0, descriptorIndex);
|
||||||
encoder->setMeshBuffer(metalSet->argumentBuffer->buffer, 0, descriptorIndex);
|
encoder->setMeshBuffer(setHandle->argumentBuffer->buffer, 0, descriptorIndex);
|
||||||
encoder->setVertexBuffer(metalSet->argumentBuffer->buffer, 0, descriptorIndex);
|
encoder->setVertexBuffer(setHandle->argumentBuffer->buffer, 0, descriptorIndex);
|
||||||
encoder->setFragmentBuffer(metalSet->argumentBuffer->buffer, 0, descriptorIndex);
|
encoder->setFragmentBuffer(setHandle->argumentBuffer->buffer, 0, descriptorIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderCommand::bindDescriptor(const Array<Gfx::PDescriptorSet>& descriptorSets) {
|
void RenderCommand::bindDescriptor(const Array<Gfx::PDescriptorSet>& descriptorSets) {
|
||||||
@@ -197,18 +198,18 @@ void RenderCommand::bindIndexBuffer(Gfx::PIndexBuffer gfxIndexBuffer) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void RenderCommand::pushConstants(Gfx::SeShaderStageFlags stage, uint32 offset, uint32 size, const void* data) {
|
void RenderCommand::pushConstants(Gfx::SeShaderStageFlags stage, uint32 offset, uint32 size, const void* data) {
|
||||||
uint pushIndex = boundPipeline->getPipelineLayout()->findParameter("pOffsets");
|
uint pushIndex = boundPipeline->getPipelineLayout()->findParameter(boundPipeline->getPipelineLayout()->getPushConstantName(offset));
|
||||||
if (stage & Gfx::SE_SHADER_STAGE_VERTEX_BIT) {
|
if (stage & Gfx::SE_SHADER_STAGE_VERTEX_BIT) {
|
||||||
encoder->setVertexBytes(data, size, pushIndex); // TODO: hardcoded
|
encoder->setVertexBytes(data, size, pushIndex);
|
||||||
}
|
}
|
||||||
if (stage & Gfx::SE_SHADER_STAGE_FRAGMENT_BIT) {
|
if (stage & Gfx::SE_SHADER_STAGE_FRAGMENT_BIT) {
|
||||||
encoder->setFragmentBytes(data, size, pushIndex); // TODO: hardcoded
|
encoder->setFragmentBytes(data, size, pushIndex);
|
||||||
}
|
}
|
||||||
if (stage & Gfx::SE_SHADER_STAGE_TASK_BIT_EXT) {
|
if (stage & Gfx::SE_SHADER_STAGE_TASK_BIT_EXT) {
|
||||||
encoder->setObjectBytes(data, size, pushIndex); // TODO: hardcoded
|
encoder->setObjectBytes(data, size, pushIndex);
|
||||||
}
|
}
|
||||||
if (stage & Gfx::SE_SHADER_STAGE_MESH_BIT_EXT) {
|
if (stage & Gfx::SE_SHADER_STAGE_MESH_BIT_EXT) {
|
||||||
encoder->setMeshBytes(data, size, pushIndex); // TODO: hardcoded
|
encoder->setMeshBytes(data, size, pushIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -252,46 +253,53 @@ void ComputeCommand::bindPipeline(Gfx::PComputePipeline pipeline) {
|
|||||||
encoder->setComputePipelineState(boundPipeline->getHandle());
|
encoder->setComputePipelineState(boundPipeline->getHandle());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ComputeCommand::bindDescriptor(Gfx::PDescriptorSet set) {
|
void ComputeCommand::bindDescriptor(Gfx::PDescriptorSet descriptorSet) {
|
||||||
auto metalSet = set.cast<DescriptorSet>();
|
auto metalSet = descriptorSet.cast<DescriptorSet>();
|
||||||
metalSet->bind();
|
auto setHandle = metalSet->setHandle;
|
||||||
boundResources.add(metalSet);
|
setHandle->bind();
|
||||||
|
boundResources.add(setHandle);
|
||||||
uint32 descriptorIndex = boundPipeline->getPipelineLayout()->findParameter(metalSet->getLayout()->getName());
|
uint32 descriptorIndex = boundPipeline->getPipelineLayout()->findParameter(metalSet->getLayout()->getName());
|
||||||
if(metalSet->encoder == nullptr) {
|
|
||||||
if (metalSet->isPlainDescriptor()) {
|
auto createEncoder = [metalSet, &setHandle, descriptorIndex](MTL::Function* function) {
|
||||||
metalSet->encoder = metalSet->createEncoder();
|
if(setHandle->encoder == nullptr) {
|
||||||
} else {
|
if (metalSet->isPlainDescriptor()) {
|
||||||
metalSet->encoder = boundPipeline->computeFunction->newArgumentEncoder(descriptorIndex);
|
setHandle->encoder = metalSet->createEncoder();
|
||||||
|
} else if (function != nullptr) {
|
||||||
|
setHandle->encoder = function->newArgumentEncoder(descriptorIndex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
metalSet->argumentBuffer = new BufferAllocation(metalSet->graphics, "ArgumentBuffer", metalSet->encoder->encodedLength());
|
};
|
||||||
metalSet->encoder->setArgumentBuffer(metalSet->argumentBuffer->buffer, 0);
|
createEncoder(boundPipeline->computeFunction);
|
||||||
|
if(setHandle->argumentBuffer == nullptr) {
|
||||||
|
setHandle->argumentBuffer = new BufferAllocation(metalSet->graphics, "ArgumentBuffer", setHandle->encoder->encodedLength());
|
||||||
|
setHandle->encoder->setArgumentBuffer(setHandle->argumentBuffer->buffer, 0);
|
||||||
}
|
}
|
||||||
metalSet->argumentBuffer->bind();
|
setHandle->argumentBuffer->bind();
|
||||||
boundResources.add(PBufferAllocation(metalSet->argumentBuffer));
|
boundResources.add(PBufferAllocation(setHandle->argumentBuffer));
|
||||||
for (const auto& write : metalSet->uniformWrites) {
|
for (const auto& write : setHandle->uniformWrites) {
|
||||||
write.apply(metalSet->encoder);
|
write.apply(setHandle->encoder);
|
||||||
}
|
}
|
||||||
for (const auto& write : metalSet->bufferWrites) {
|
for (const auto& write : setHandle->bufferWrites) {
|
||||||
write.apply(metalSet->encoder);
|
write.apply(setHandle->encoder);
|
||||||
encoder->useResource(write.buffer->buffer, write.access);
|
encoder->useResource(write.buffer->buffer, write.access);
|
||||||
}
|
}
|
||||||
for (const auto& write : metalSet->samplerWrites) {
|
for (const auto& write : setHandle->samplerWrites) {
|
||||||
write.apply(metalSet->encoder);
|
write.apply(setHandle->encoder);
|
||||||
}
|
}
|
||||||
for (const auto& write : metalSet->textureWrites) {
|
for (const auto& write : setHandle->textureWrites) {
|
||||||
write.apply(metalSet->encoder);
|
write.apply(setHandle->encoder);
|
||||||
encoder->useResource(write.texture->texture, write.access);
|
encoder->useResource(write.texture->getHandle(), write.access);
|
||||||
}
|
}
|
||||||
for (const auto& write : metalSet->accelerationWrites) {
|
for (const auto& write : setHandle->accelerationWrites) {
|
||||||
write.apply(metalSet->encoder);
|
write.apply(setHandle->encoder);
|
||||||
encoder->useResource(write.accelerationStructure, write.access);
|
encoder->useResource(write.accelerationStructure, write.access);
|
||||||
}
|
}
|
||||||
for(auto& res : metalSet->boundResources) {
|
for(auto& res : setHandle->boundResources) {
|
||||||
res->bind();
|
res->bind();
|
||||||
boundResources.add(res);
|
boundResources.add(res);
|
||||||
}
|
}
|
||||||
encoder->useResource(metalSet->argumentBuffer->buffer, MTL::ResourceUsageRead);
|
encoder->useResource(setHandle->argumentBuffer->buffer, MTL::ResourceUsageRead);
|
||||||
encoder->setBuffer(metalSet->argumentBuffer->buffer, 0, descriptorIndex);
|
encoder->setBuffer(setHandle->argumentBuffer->buffer, 0, descriptorIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ComputeCommand::bindDescriptor(const Array<Gfx::PDescriptorSet>& sets) {
|
void ComputeCommand::bindDescriptor(const Array<Gfx::PDescriptorSet>& sets) {
|
||||||
@@ -358,6 +366,7 @@ void CommandQueue::submitCommands(PEvent signalSemaphore) {
|
|||||||
for (auto it = pendingCommands.begin(); it != pendingCommands.end(); it++) {
|
for (auto it = pendingCommands.begin(); it != pendingCommands.end(); it++) {
|
||||||
if ((*it)->getHandle() == cmdBuffer) {
|
if ((*it)->getHandle() == cmdBuffer) {
|
||||||
auto& cmd = *it;
|
auto& cmd = *it;
|
||||||
|
std::cout << "Command completed" << std::endl;
|
||||||
cmd->reset();
|
cmd->reset();
|
||||||
readyCommands.add(std::move(*it));
|
readyCommands.add(std::move(*it));
|
||||||
pendingCommands.erase(it);
|
pendingCommands.erase(it);
|
||||||
@@ -367,7 +376,6 @@ void CommandQueue::submitCommands(PEvent signalSemaphore) {
|
|||||||
}));
|
}));
|
||||||
PEvent prevCmdEvent = activeCommand->getCompletedEvent();
|
PEvent prevCmdEvent = activeCommand->getCompletedEvent();
|
||||||
activeCommand->end(signalSemaphore);
|
activeCommand->end(signalSemaphore);
|
||||||
activeCommand->waitDeviceIdle();
|
|
||||||
pendingCommands.add(std::move(activeCommand));
|
pendingCommands.add(std::move(activeCommand));
|
||||||
if (!readyCommands.empty()) {
|
if (!readyCommands.empty()) {
|
||||||
activeCommand = std::move(readyCommands.front());
|
activeCommand = std::move(readyCommands.front());
|
||||||
|
|||||||
@@ -40,49 +40,28 @@ class DescriptorLayout : public Gfx::DescriptorLayout {
|
|||||||
// descriptor sets containing only uniform data are not actually argument buffers, so they need to be
|
// descriptor sets containing only uniform data are not actually argument buffers, so they need to be
|
||||||
// handled separately
|
// handled separately
|
||||||
bool plainDescriptor = true;
|
bool plainDescriptor = true;
|
||||||
friend class DescriptorSet;
|
friend class DescriptorSetHandle;
|
||||||
};
|
};
|
||||||
DEFINE_REF(DescriptorLayout)
|
DEFINE_REF(DescriptorLayout)
|
||||||
|
|
||||||
DECLARE_REF(DescriptorSet)
|
DECLARE_REF(DescriptorPool)
|
||||||
class DescriptorPool : public Gfx::DescriptorPool {
|
class DescriptorSetHandle : public CommandBoundResource {
|
||||||
public:
|
public:
|
||||||
DescriptorPool(PGraphics graphics, PDescriptorLayout layout);
|
DescriptorSetHandle(PGraphics grapics, PDescriptorPool owner, const std::string& name);
|
||||||
virtual ~DescriptorPool();
|
virtual ~DescriptorSetHandle();
|
||||||
virtual Gfx::PDescriptorSet allocateDescriptorSet() override;
|
void updateConstants(const std::string& name, uint32 offset, void* data);
|
||||||
virtual void reset() override;
|
void updateBuffer(const std::string& name, uint32 index, Gfx::PShaderBuffer uniformBuffer);
|
||||||
constexpr PDescriptorLayout getLayout() const { return layout; }
|
void updateBuffer(const std::string& name, uint32 index, Gfx::PVertexBuffer uniformBuffer);
|
||||||
|
void updateBuffer(const std::string& name, uint32 index, Gfx::PIndexBuffer uniformBuffer);
|
||||||
|
void updateBuffer(const std::string& name, uint32 index, Gfx::PUniformBuffer uniformBuffer);
|
||||||
|
void updateSampler(const std::string& name, uint32 index, Gfx::PSampler samplerState);
|
||||||
|
void updateTexture(const std::string& name, uint32 index, Gfx::PTextureView texture);
|
||||||
|
void updateAccelerationStructure(const std::string& name, uint32 index, Gfx::PTopLevelAS as);
|
||||||
|
|
||||||
private:
|
|
||||||
PGraphics graphics;
|
|
||||||
PDescriptorLayout layout;
|
|
||||||
Array<ODescriptorSet> allocatedSets;
|
|
||||||
};
|
|
||||||
DEFINE_REF(DescriptorPool)
|
|
||||||
class DescriptorSet : public Gfx::DescriptorSet, public CommandBoundResource {
|
|
||||||
public:
|
|
||||||
DescriptorSet(PGraphics graphics, PDescriptorPool owner);
|
|
||||||
virtual ~DescriptorSet();
|
|
||||||
virtual void reset();
|
|
||||||
virtual void writeChanges() override;
|
|
||||||
virtual void updateConstants(const std::string& name, uint32 offset, void* data) override;
|
|
||||||
virtual void updateBuffer(const std::string& name, uint32 index, Gfx::PShaderBuffer uniformBuffer) override;
|
|
||||||
virtual void updateBuffer(const std::string& name, uint32 index, Gfx::PVertexBuffer uniformBuffer) override;
|
|
||||||
virtual void updateBuffer(const std::string& name, uint32 index, Gfx::PIndexBuffer uniformBuffer) override;
|
|
||||||
virtual void updateSampler(const std::string& name, uint32 index, Gfx::PSampler samplerState) 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 bool isPlainDescriptor() const { return owner->getLayout()->isPlainDescriptor(); }
|
|
||||||
constexpr MTL::ArgumentEncoder* createEncoder() const { return owner->getLayout()->createEncoder(); }
|
|
||||||
|
|
||||||
private:
|
|
||||||
PGraphics graphics;
|
|
||||||
PDescriptorPool owner;
|
PDescriptorPool owner;
|
||||||
OBufferAllocation argumentBuffer = nullptr;
|
OBufferAllocation argumentBuffer = nullptr;
|
||||||
MTL::ArgumentEncoder* encoder = nullptr;
|
MTL::ArgumentEncoder* encoder = nullptr;
|
||||||
Array<PCommandBoundResource> boundResources;
|
Array<PCommandBoundResource> boundResources;
|
||||||
|
|
||||||
struct UniformWriteInfo
|
struct UniformWriteInfo
|
||||||
{
|
{
|
||||||
uint32 index;
|
uint32 index;
|
||||||
@@ -102,8 +81,8 @@ class DescriptorSet : public Gfx::DescriptorSet, public CommandBoundResource {
|
|||||||
{
|
{
|
||||||
uint32 index;
|
uint32 index;
|
||||||
MTL::ResourceUsage access;
|
MTL::ResourceUsage access;
|
||||||
PTextureHandle texture;
|
PTextureView texture;
|
||||||
void apply(MTL::ArgumentEncoder* encoder) const { encoder->setTexture(texture->texture, index); }
|
void apply(MTL::ArgumentEncoder* encoder) const { encoder->setTexture(texture->getHandle(), index); }
|
||||||
};
|
};
|
||||||
Array<TextureWriteInfo> textureWrites;
|
Array<TextureWriteInfo> textureWrites;
|
||||||
struct SamplerWriteInfo
|
struct SamplerWriteInfo
|
||||||
@@ -122,6 +101,46 @@ class DescriptorSet : public Gfx::DescriptorSet, public CommandBoundResource {
|
|||||||
};
|
};
|
||||||
Array<AccelerationStructureWriteInfo> accelerationWrites;
|
Array<AccelerationStructureWriteInfo> accelerationWrites;
|
||||||
|
|
||||||
|
};
|
||||||
|
DEFINE_REF(DescriptorSetHandle)
|
||||||
|
|
||||||
|
DECLARE_REF(DescriptorSet)
|
||||||
|
class DescriptorPool : public Gfx::DescriptorPool {
|
||||||
|
public:
|
||||||
|
DescriptorPool(PGraphics graphics, PDescriptorLayout layout);
|
||||||
|
virtual ~DescriptorPool();
|
||||||
|
virtual Gfx::ODescriptorSet allocateDescriptorSet() override;
|
||||||
|
virtual void reset() override;
|
||||||
|
constexpr PDescriptorLayout getLayout() const { return layout; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
PGraphics graphics;
|
||||||
|
PDescriptorLayout layout;
|
||||||
|
Array<ODescriptorSetHandle> allocatedSets;
|
||||||
|
};
|
||||||
|
DEFINE_REF(DescriptorPool)
|
||||||
|
|
||||||
|
class DescriptorSet : public Gfx::DescriptorSet {
|
||||||
|
public:
|
||||||
|
DescriptorSet(PGraphics graphics, PDescriptorPool owner, PDescriptorSetHandle handle);
|
||||||
|
virtual ~DescriptorSet();
|
||||||
|
virtual void writeChanges() override;
|
||||||
|
virtual void updateConstants(const std::string& name, uint32 offset, void* data) override;
|
||||||
|
virtual void updateBuffer(const std::string& name, uint32 index, Gfx::PShaderBuffer uniformBuffer) override;
|
||||||
|
virtual void updateBuffer(const std::string& name, uint32 index, Gfx::PVertexBuffer uniformBuffer) override;
|
||||||
|
virtual void updateBuffer(const std::string& name, uint32 index, Gfx::PIndexBuffer uniformBuffer) override;
|
||||||
|
virtual void updateBuffer(const std::string& name, uint32 index, Gfx::PUniformBuffer uniformBuffer) override;
|
||||||
|
virtual void updateSampler(const std::string& name, uint32 index, Gfx::PSampler samplerState) override;
|
||||||
|
virtual void updateTexture(const std::string& name, uint32 index, Gfx::PTextureView texture) override;
|
||||||
|
virtual void updateAccelerationStructure(const std::string& name, uint32 index, Gfx::PTopLevelAS as) override;
|
||||||
|
|
||||||
|
constexpr bool isPlainDescriptor() const { return owner->getLayout()->isPlainDescriptor(); }
|
||||||
|
constexpr MTL::ArgumentEncoder* createEncoder() const { return owner->getLayout()->createEncoder(); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
PGraphics graphics;
|
||||||
|
PDescriptorPool owner;
|
||||||
|
PDescriptorSetHandle setHandle;
|
||||||
friend class RenderCommand;
|
friend class RenderCommand;
|
||||||
friend class ComputeCommand;
|
friend class ComputeCommand;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -58,49 +58,20 @@ void DescriptorLayout::create() {
|
|||||||
|
|
||||||
MTL::ArgumentEncoder* DescriptorLayout::createEncoder() { return graphics->getDevice()->newArgumentEncoder(arguments); }
|
MTL::ArgumentEncoder* DescriptorLayout::createEncoder() { return graphics->getDevice()->newArgumentEncoder(arguments); }
|
||||||
|
|
||||||
DescriptorPool::DescriptorPool(PGraphics graphics, PDescriptorLayout layout) : graphics(graphics), layout(layout) {}
|
DescriptorSetHandle::DescriptorSetHandle(PGraphics graphics, PDescriptorPool owner, const std::string& name)
|
||||||
|
: CommandBoundResource(graphics, name), owner(owner)
|
||||||
|
{
|
||||||
|
|
||||||
DescriptorPool::~DescriptorPool() {}
|
|
||||||
|
|
||||||
Gfx::PDescriptorSet DescriptorPool::allocateDescriptorSet() {
|
|
||||||
for (uint32 setIndex = 0; setIndex < allocatedSets.size(); ++setIndex) {
|
|
||||||
if (allocatedSets[setIndex]->isCurrentlyBound()) {
|
|
||||||
// Currently in use, skip
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// Found set, stop searching
|
|
||||||
allocatedSets[setIndex]->reset();
|
|
||||||
return PDescriptorSet(allocatedSets[setIndex]);
|
|
||||||
}
|
|
||||||
allocatedSets.add(new DescriptorSet(graphics, this));
|
|
||||||
return PDescriptorSet(allocatedSets.back());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DescriptorPool::reset() {}
|
DescriptorSetHandle::~DescriptorSetHandle() {
|
||||||
|
|
||||||
DescriptorSet::DescriptorSet(PGraphics graphics, PDescriptorPool owner)
|
|
||||||
: Gfx::DescriptorSet(owner->getLayout()), CommandBoundResource(graphics), graphics(graphics), owner(owner) {
|
|
||||||
}
|
|
||||||
|
|
||||||
DescriptorSet::~DescriptorSet() {
|
|
||||||
if(encoder != nullptr) {
|
if(encoder != nullptr) {
|
||||||
encoder->release();
|
encoder->release();
|
||||||
}
|
}
|
||||||
std::cout << "destroying descriptor set" << std::endl;
|
std::cout << "destroying descriptor set" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DescriptorSet::reset() {
|
void DescriptorSetHandle::updateConstants(const std::string& name, uint32 offset, void* data) {
|
||||||
boundResources.clear();
|
|
||||||
uniformWrites.clear();
|
|
||||||
bufferWrites.clear();
|
|
||||||
textureWrites.clear();
|
|
||||||
samplerWrites.clear();
|
|
||||||
accelerationWrites.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void DescriptorSet::writeChanges() {}
|
|
||||||
|
|
||||||
void DescriptorSet::updateConstants(const std::string& name, uint32 offset, void* data) {
|
|
||||||
uint32 flattenedIndex = owner->getLayout()->variableMapping[name].index;
|
uint32 flattenedIndex = owner->getLayout()->variableMapping[name].index;
|
||||||
Array<uint8> contents(owner->getLayout()->variableMapping[name].constantSize);
|
Array<uint8> contents(owner->getLayout()->variableMapping[name].constantSize);
|
||||||
std::memcpy(contents.data(), (uint8*)data + offset, contents.size());
|
std::memcpy(contents.data(), (uint8*)data + offset, contents.size());
|
||||||
@@ -110,7 +81,7 @@ void DescriptorSet::updateConstants(const std::string& name, uint32 offset, void
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void DescriptorSet::updateBuffer(const std::string& name, uint32 index, Gfx::PShaderBuffer uniformBuffer) {
|
void DescriptorSetHandle::updateBuffer(const std::string& name, uint32 index, Gfx::PShaderBuffer uniformBuffer) {
|
||||||
uint32 flattenedIndex = owner->getLayout()->variableMapping[name].index + index;
|
uint32 flattenedIndex = owner->getLayout()->variableMapping[name].index + index;
|
||||||
PShaderBuffer buffer = uniformBuffer.cast<ShaderBuffer>();
|
PShaderBuffer buffer = uniformBuffer.cast<ShaderBuffer>();
|
||||||
bufferWrites.add(BufferWriteInfo{
|
bufferWrites.add(BufferWriteInfo{
|
||||||
@@ -121,7 +92,7 @@ void DescriptorSet::updateBuffer(const std::string& name, uint32 index, Gfx::PSh
|
|||||||
boundResources.add(buffer->getAlloc());
|
boundResources.add(buffer->getAlloc());
|
||||||
}
|
}
|
||||||
|
|
||||||
void DescriptorSet::updateBuffer(const std::string& name, uint32 index, Gfx::PVertexBuffer uniformBuffer) {
|
void DescriptorSetHandle::updateBuffer(const std::string& name, uint32 index, Gfx::PVertexBuffer uniformBuffer) {
|
||||||
uint32 flattenedIndex = owner->getLayout()->variableMapping[name].index + index;
|
uint32 flattenedIndex = owner->getLayout()->variableMapping[name].index + index;
|
||||||
PVertexBuffer buffer = uniformBuffer.cast<VertexBuffer>();
|
PVertexBuffer buffer = uniformBuffer.cast<VertexBuffer>();
|
||||||
bufferWrites.add(BufferWriteInfo{
|
bufferWrites.add(BufferWriteInfo{
|
||||||
@@ -132,7 +103,7 @@ void DescriptorSet::updateBuffer(const std::string& name, uint32 index, Gfx::PVe
|
|||||||
boundResources.add(buffer->getAlloc());
|
boundResources.add(buffer->getAlloc());
|
||||||
}
|
}
|
||||||
|
|
||||||
void DescriptorSet::updateBuffer(const std::string& name, uint32 index, Gfx::PIndexBuffer uniformBuffer) {
|
void DescriptorSetHandle::updateBuffer(const std::string& name, uint32 index, Gfx::PIndexBuffer uniformBuffer) {
|
||||||
uint32 flattenedIndex = owner->getLayout()->variableMapping[name].index + index;
|
uint32 flattenedIndex = owner->getLayout()->variableMapping[name].index + index;
|
||||||
PIndexBuffer buffer = uniformBuffer.cast<IndexBuffer>();
|
PIndexBuffer buffer = uniformBuffer.cast<IndexBuffer>();
|
||||||
bufferWrites.add(BufferWriteInfo{
|
bufferWrites.add(BufferWriteInfo{
|
||||||
@@ -143,7 +114,18 @@ void DescriptorSet::updateBuffer(const std::string& name, uint32 index, Gfx::PIn
|
|||||||
boundResources.add(buffer->getAlloc());
|
boundResources.add(buffer->getAlloc());
|
||||||
}
|
}
|
||||||
|
|
||||||
void DescriptorSet::updateSampler(const std::string& name, uint32 index, Gfx::PSampler samplerState) {
|
void DescriptorSetHandle::updateBuffer(const std::string& name, uint32 index, Gfx::PUniformBuffer uniformBuffer) {
|
||||||
|
uint32 flattenedIndex = owner->getLayout()->variableMapping[name].index + index;
|
||||||
|
PIndexBuffer buffer = uniformBuffer.cast<IndexBuffer>();
|
||||||
|
bufferWrites.add(BufferWriteInfo{
|
||||||
|
.index = flattenedIndex,
|
||||||
|
.buffer = buffer->getAlloc(),
|
||||||
|
.access = owner->getLayout()->variableMapping[name].access,
|
||||||
|
});
|
||||||
|
boundResources.add(buffer->getAlloc());
|
||||||
|
}
|
||||||
|
|
||||||
|
void DescriptorSetHandle::updateSampler(const std::string& name, uint32 index, Gfx::PSampler samplerState) {
|
||||||
uint32 flattenedIndex = owner->getLayout()->variableMapping[name].index + index;
|
uint32 flattenedIndex = owner->getLayout()->variableMapping[name].index + index;
|
||||||
PSampler sampler = samplerState.cast<Sampler>();
|
PSampler sampler = samplerState.cast<Sampler>();
|
||||||
samplerWrites.add(SamplerWriteInfo{
|
samplerWrites.add(SamplerWriteInfo{
|
||||||
@@ -152,18 +134,72 @@ void DescriptorSet::updateSampler(const std::string& name, uint32 index, Gfx::PS
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void DescriptorSet::updateTexture(const std::string& name, uint32 index, Gfx::PTexture texture) {
|
void DescriptorSetHandle::updateTexture(const std::string& name, uint32 index, Gfx::PTextureView texture) {
|
||||||
uint32 flattenedIndex = owner->getLayout()->variableMapping[name].index + index;
|
uint32 flattenedIndex = owner->getLayout()->variableMapping[name].index + index;
|
||||||
PTextureBase tex = texture.cast<TextureBase>();
|
PTextureView tex = texture.cast<TextureView>();
|
||||||
textureWrites.add(TextureWriteInfo{
|
textureWrites.add(TextureWriteInfo{
|
||||||
.index = flattenedIndex,
|
.index = flattenedIndex,
|
||||||
.texture = tex->getHandle(),
|
.texture = tex,
|
||||||
.access = owner->getLayout()->variableMapping[name].access,
|
.access = owner->getLayout()->variableMapping[name].access,
|
||||||
});
|
});
|
||||||
boundResources.add(tex->getHandle());
|
boundResources.add(tex);
|
||||||
|
boundResources.add(tex->getSource());
|
||||||
}
|
}
|
||||||
|
|
||||||
void DescriptorSet::updateAccelerationStructure(const std::string& name, uint32 index, Gfx::PTopLevelAS as) { assert(false && "TODO"); }
|
void DescriptorSetHandle::updateAccelerationStructure(const std::string& , uint32 , Gfx::PTopLevelAS ){}
|
||||||
|
|
||||||
|
DescriptorPool::DescriptorPool(PGraphics graphics, PDescriptorLayout layout) : graphics(graphics), layout(layout) {}
|
||||||
|
|
||||||
|
DescriptorPool::~DescriptorPool() {}
|
||||||
|
|
||||||
|
Gfx::ODescriptorSet DescriptorPool::allocateDescriptorSet() {
|
||||||
|
for (uint32 setIndex = 0; setIndex < allocatedSets.size(); ++setIndex) {
|
||||||
|
if (allocatedSets[setIndex]->isCurrentlyBound()) {
|
||||||
|
// Currently in use, skip
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// Found set, stop searching
|
||||||
|
return new DescriptorSet(graphics, this, allocatedSets[setIndex]);
|
||||||
|
}
|
||||||
|
allocatedSets.add(new DescriptorSetHandle(graphics, this, layout->getName()));
|
||||||
|
return new DescriptorSet(graphics, this, allocatedSets.back());
|
||||||
|
}
|
||||||
|
|
||||||
|
void DescriptorPool::reset() {}
|
||||||
|
|
||||||
|
DescriptorSet::DescriptorSet(PGraphics graphics, PDescriptorPool owner, PDescriptorSetHandle handle)
|
||||||
|
: Gfx::DescriptorSet(owner->getLayout()), graphics(graphics), owner(owner), setHandle(handle) {
|
||||||
|
}
|
||||||
|
|
||||||
|
DescriptorSet::~DescriptorSet() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void DescriptorSet::writeChanges() {}
|
||||||
|
|
||||||
|
void DescriptorSet::updateConstants(const std::string& name, uint32 offset, void* data) {
|
||||||
|
setHandle->updateConstants(name, offset, data);
|
||||||
|
}
|
||||||
|
void DescriptorSet::updateBuffer(const std::string& name, uint32 index, Gfx::PShaderBuffer uniformBuffer){
|
||||||
|
setHandle->updateBuffer(name, index, uniformBuffer);
|
||||||
|
}
|
||||||
|
void DescriptorSet::updateBuffer(const std::string& name, uint32 index, Gfx::PVertexBuffer uniformBuffer){
|
||||||
|
setHandle->updateBuffer(name, index, uniformBuffer);
|
||||||
|
}
|
||||||
|
void DescriptorSet::updateBuffer(const std::string& name, uint32 index, Gfx::PIndexBuffer uniformBuffer){
|
||||||
|
setHandle->updateBuffer(name, index, uniformBuffer);
|
||||||
|
}
|
||||||
|
void DescriptorSet::updateBuffer(const std::string& name, uint32 index, Gfx::PUniformBuffer uniformBuffer){
|
||||||
|
setHandle->updateBuffer(name, index, uniformBuffer);
|
||||||
|
}
|
||||||
|
void DescriptorSet::updateSampler(const std::string& name, uint32 index, Gfx::PSampler samplerState){
|
||||||
|
setHandle->updateSampler(name, index, samplerState);
|
||||||
|
}
|
||||||
|
void DescriptorSet::updateTexture(const std::string& name, uint32 index, Gfx::PTextureView texture){
|
||||||
|
setHandle->updateTexture(name, index, texture);
|
||||||
|
}
|
||||||
|
void DescriptorSet::updateAccelerationStructure(const std::string& name, uint32 index, Gfx::PTopLevelAS as){
|
||||||
|
setHandle->updateAccelerationStructure(name, index, as);
|
||||||
|
}
|
||||||
|
|
||||||
PipelineLayout::PipelineLayout(PGraphics graphics, const std::string& name, Gfx::PPipelineLayout baseLayout)
|
PipelineLayout::PipelineLayout(PGraphics graphics, const std::string& name, Gfx::PPipelineLayout baseLayout)
|
||||||
: Gfx::PipelineLayout(name, baseLayout), graphics(graphics) {}
|
: Gfx::PipelineLayout(name, baseLayout), graphics(graphics) {}
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ class Graphics : public Gfx::Graphics {
|
|||||||
virtual void executeCommands(Array<Gfx::OComputeCommand> commands) override;
|
virtual void executeCommands(Array<Gfx::OComputeCommand> commands) override;
|
||||||
|
|
||||||
virtual Gfx::OTexture2D createTexture2D(const TextureCreateInfo& createInfo) override;
|
virtual Gfx::OTexture2D createTexture2D(const TextureCreateInfo& createInfo) override;
|
||||||
|
virtual Gfx::OTexture2DArray createTexture2DArray(const TextureCreateInfo& createInfo) override;
|
||||||
virtual Gfx::OTexture3D createTexture3D(const TextureCreateInfo& createInfo) override;
|
virtual Gfx::OTexture3D createTexture3D(const TextureCreateInfo& createInfo) override;
|
||||||
virtual Gfx::OTextureCube createTextureCube(const TextureCreateInfo& createInfo) override;
|
virtual Gfx::OTextureCube createTextureCube(const TextureCreateInfo& createInfo) override;
|
||||||
virtual Gfx::OUniformBuffer createUniformBuffer(const UniformBufferCreateInfo& bulkData) override;
|
virtual Gfx::OUniformBuffer createUniformBuffer(const UniformBufferCreateInfo& bulkData) override;
|
||||||
|
|||||||
@@ -38,7 +38,8 @@ Gfx::OViewport Graphics::createViewport(Gfx::PWindow owner, const ViewportCreate
|
|||||||
return new Viewport(owner, createInfo);
|
return new Viewport(owner, createInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
Gfx::ORenderPass Graphics::createRenderPass(Gfx::RenderTargetLayout layout, Array<Gfx::SubPassDependency> dependencies, URect renderArea, std::string name, Array<uint32> viewMask, Array<uint32> correlationMask) {
|
Gfx::ORenderPass Graphics::createRenderPass(Gfx::RenderTargetLayout layout, Array<Gfx::SubPassDependency> dependencies, URect renderArea,
|
||||||
|
std::string name, Array<uint32>, Array<uint32>) {
|
||||||
return new RenderPass(this, layout, dependencies, renderArea, name);
|
return new RenderPass(this, layout, dependencies, renderArea, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -46,9 +47,7 @@ void Graphics::beginRenderPass(Gfx::PRenderPass renderPass) { queue->getCommands
|
|||||||
|
|
||||||
void Graphics::endRenderPass() { queue->getCommands()->endRenderPass(); }
|
void Graphics::endRenderPass() { queue->getCommands()->endRenderPass(); }
|
||||||
|
|
||||||
void Graphics::waitDeviceIdle() {
|
void Graphics::waitDeviceIdle() { queue->submitCommands(); }
|
||||||
queue->submitCommands();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Graphics::executeCommands(Gfx::ORenderCommand commands) {
|
void Graphics::executeCommands(Gfx::ORenderCommand commands) {
|
||||||
Array<Gfx::ORenderCommand> command;
|
Array<Gfx::ORenderCommand> command;
|
||||||
@@ -68,6 +67,8 @@ void Graphics::executeCommands(Array<Gfx::OComputeCommand> commands) { queue->ex
|
|||||||
|
|
||||||
Gfx::OTexture2D Graphics::createTexture2D(const TextureCreateInfo& createInfo) { return new Texture2D(this, createInfo); }
|
Gfx::OTexture2D Graphics::createTexture2D(const TextureCreateInfo& createInfo) { return new Texture2D(this, createInfo); }
|
||||||
|
|
||||||
|
Gfx::OTexture2DArray Graphics::createTexture2DArray(const TextureCreateInfo& createInfo) { return new Texture2DArray(this, createInfo); }
|
||||||
|
|
||||||
Gfx::OTexture3D Graphics::createTexture3D(const TextureCreateInfo& createInfo) { return new Texture3D(this, createInfo); }
|
Gfx::OTexture3D Graphics::createTexture3D(const TextureCreateInfo& createInfo) { return new Texture3D(this, createInfo); }
|
||||||
|
|
||||||
Gfx::OTextureCube Graphics::createTextureCube(const TextureCreateInfo& createInfo) { return new TextureCube(this, createInfo); }
|
Gfx::OTextureCube Graphics::createTextureCube(const TextureCreateInfo& createInfo) { return new TextureCube(this, createInfo); }
|
||||||
@@ -155,23 +156,18 @@ void Graphics::beginDebugRegion(const std::string& name) {
|
|||||||
queue->getCommands()->getHandle()->pushDebugGroup(NS::String::string(name.c_str(), NS::ASCIIStringEncoding));
|
queue->getCommands()->getHandle()->pushDebugGroup(NS::String::string(name.c_str(), NS::ASCIIStringEncoding));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Graphics::endDebugRegion() {
|
void Graphics::endDebugRegion() { queue->getCommands()->getHandle()->popDebugGroup(); }
|
||||||
queue->getCommands()->getHandle()->popDebugGroup();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Graphics::resolveTexture(Gfx::PTexture, Gfx::PTexture) {}
|
void Graphics::resolveTexture(Gfx::PTexture, Gfx::PTexture) {}
|
||||||
|
|
||||||
void Graphics::copyTexture(Gfx::PTexture, Gfx::PTexture) {}
|
void Graphics::copyTexture(Gfx::PTexture, Gfx::PTexture) { assert(false); }
|
||||||
|
|
||||||
void Graphics::copyBuffer(Gfx::PShaderBuffer src, Gfx::PShaderBuffer dst)
|
void Graphics::copyBuffer(Gfx::PShaderBuffer, Gfx::PShaderBuffer) { assert(false); }
|
||||||
{
|
|
||||||
// TODO blit commands
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ray Tracing
|
// Ray Tracing
|
||||||
Gfx::OBottomLevelAS Graphics::createBottomLevelAccelerationStructure(const Gfx::BottomLevelASCreateInfo& createInfo) { return nullptr; }
|
Gfx::OBottomLevelAS Graphics::createBottomLevelAccelerationStructure(const Gfx::BottomLevelASCreateInfo&) { return nullptr; }
|
||||||
|
|
||||||
Gfx::OTopLevelAS Graphics::createTopLevelAccelerationStructure(const Gfx::TopLevelASCreateInfo& createInfo) { return nullptr; }
|
Gfx::OTopLevelAS Graphics::createTopLevelAccelerationStructure(const Gfx::TopLevelASCreateInfo&) { return nullptr; }
|
||||||
|
|
||||||
void Graphics::buildBottomLevelAccelerationStructures(Array<Gfx::PBottomLevelAS>) {}
|
void Graphics::buildBottomLevelAccelerationStructures(Array<Gfx::PBottomLevelAS>) {}
|
||||||
|
|
||||||
|
|||||||
@@ -88,11 +88,11 @@ PGraphicsPipeline PipelineCache::createPipeline(Gfx::LegacyPipelineCreateInfo cr
|
|||||||
}
|
}
|
||||||
|
|
||||||
MTL::DepthStencilDescriptor* depthDescriptor = MTL::DepthStencilDescriptor::alloc()->init();
|
MTL::DepthStencilDescriptor* depthDescriptor = MTL::DepthStencilDescriptor::alloc()->init();
|
||||||
if (createInfo.renderPass->getLayout().depthAttachment.getTexture() != nullptr) {
|
if (createInfo.renderPass->getLayout().depthAttachment.getTextureView() != nullptr) {
|
||||||
depthDescriptor->setDepthWriteEnabled(createInfo.depthStencilState.depthWriteEnable);
|
depthDescriptor->setDepthWriteEnabled(createInfo.depthStencilState.depthWriteEnable);
|
||||||
depthDescriptor->setDepthCompareFunction(cast(createInfo.depthStencilState.depthCompareOp));
|
depthDescriptor->setDepthCompareFunction(cast(createInfo.depthStencilState.depthCompareOp));
|
||||||
pipelineDescriptor->setDepthAttachmentPixelFormat(
|
pipelineDescriptor->setDepthAttachmentPixelFormat(
|
||||||
cast(createInfo.renderPass->getLayout().depthAttachment.getTexture().cast<Texture2D>()->getFormat()));
|
cast(createInfo.renderPass->getLayout().depthAttachment.getTextureView()->getFormat()));
|
||||||
}
|
}
|
||||||
pipelineDescriptor->setAlphaToCoverageEnabled(createInfo.multisampleState.alphaCoverageEnable);
|
pipelineDescriptor->setAlphaToCoverageEnabled(createInfo.multisampleState.alphaCoverageEnable);
|
||||||
pipelineDescriptor->setAlphaToOneEnabled(createInfo.multisampleState.alphaToOneEnable);
|
pipelineDescriptor->setAlphaToOneEnabled(createInfo.multisampleState.alphaToOneEnable);
|
||||||
@@ -196,11 +196,11 @@ PGraphicsPipeline PipelineCache::createPipeline(Gfx::MeshPipelineCreateInfo crea
|
|||||||
pipelineDescriptor->colorAttachments()->setObject(desc, c);
|
pipelineDescriptor->colorAttachments()->setObject(desc, c);
|
||||||
}
|
}
|
||||||
MTL::DepthStencilDescriptor* depthDescriptor = MTL::DepthStencilDescriptor::alloc()->init();
|
MTL::DepthStencilDescriptor* depthDescriptor = MTL::DepthStencilDescriptor::alloc()->init();
|
||||||
if (createInfo.renderPass->getLayout().depthAttachment.getTexture() != nullptr) {
|
if (createInfo.renderPass->getLayout().depthAttachment.getTextureView() != nullptr) {
|
||||||
depthDescriptor->setDepthWriteEnabled(createInfo.depthStencilState.depthWriteEnable);
|
depthDescriptor->setDepthWriteEnabled(createInfo.depthStencilState.depthWriteEnable);
|
||||||
depthDescriptor->setDepthCompareFunction(cast(createInfo.depthStencilState.depthCompareOp));
|
depthDescriptor->setDepthCompareFunction(cast(createInfo.depthStencilState.depthCompareOp));
|
||||||
pipelineDescriptor->setDepthAttachmentPixelFormat(
|
pipelineDescriptor->setDepthAttachmentPixelFormat(
|
||||||
cast(createInfo.renderPass->getLayout().depthAttachment.getTexture().cast<Texture2D>()->getFormat()));
|
cast(createInfo.renderPass->getLayout().depthAttachment.getTextureView()->getFormat()));
|
||||||
}
|
}
|
||||||
pipelineDescriptor->setAlphaToCoverageEnabled(createInfo.multisampleState.alphaCoverageEnable);
|
pipelineDescriptor->setAlphaToCoverageEnabled(createInfo.multisampleState.alphaCoverageEnable);
|
||||||
pipelineDescriptor->setAlphaToOneEnabled(createInfo.multisampleState.alphaToOneEnable);
|
pipelineDescriptor->setAlphaToOneEnabled(createInfo.multisampleState.alphaToOneEnable);
|
||||||
@@ -209,9 +209,9 @@ PGraphicsPipeline PipelineCache::createPipeline(Gfx::MeshPipelineCreateInfo crea
|
|||||||
|
|
||||||
MTL::DepthStencilState* depthState = graphics->getDevice()->newDepthStencilState(depthDescriptor);
|
MTL::DepthStencilState* depthState = graphics->getDevice()->newDepthStencilState(depthDescriptor);
|
||||||
depthDescriptor->release();
|
depthDescriptor->release();
|
||||||
if (createInfo.renderPass->getLayout().depthAttachment.getTexture() != nullptr) {
|
if (createInfo.renderPass->getLayout().depthAttachment.getTextureView() != nullptr) {
|
||||||
pipelineDescriptor->setDepthAttachmentPixelFormat(
|
pipelineDescriptor->setDepthAttachmentPixelFormat(
|
||||||
cast(createInfo.renderPass->getLayout().depthAttachment.getTexture().cast<Texture2D>()->getFormat()));
|
cast(createInfo.renderPass->getLayout().depthAttachment.getTextureView()->getFormat()));
|
||||||
}
|
}
|
||||||
pipelineDescriptor->setAlphaToCoverageEnabled(createInfo.multisampleState.alphaCoverageEnable);
|
pipelineDescriptor->setAlphaToCoverageEnabled(createInfo.multisampleState.alphaCoverageEnable);
|
||||||
pipelineDescriptor->setAlphaToOneEnabled(createInfo.multisampleState.alphaToOneEnable);
|
pipelineDescriptor->setAlphaToOneEnabled(createInfo.multisampleState.alphaToOneEnable);
|
||||||
|
|||||||
@@ -33,13 +33,13 @@ RenderPass::RenderPass(PGraphics graphics, Gfx::RenderTargetLayout _layout, Arra
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (layout.depthAttachment.getTexture() != nullptr) {
|
if (layout.depthAttachment.getTextureView() != nullptr) {
|
||||||
auto depth = renderPass->depthAttachment();
|
auto depth = renderPass->depthAttachment();
|
||||||
depth->setClearDepth(layout.depthAttachment.clear.depthStencil.depth);
|
depth->setClearDepth(layout.depthAttachment.clear.depthStencil.depth);
|
||||||
depth->setLoadAction(cast(layout.depthAttachment.getLoadOp()));
|
depth->setLoadAction(cast(layout.depthAttachment.getLoadOp()));
|
||||||
depth->setStoreAction(cast(layout.depthAttachment.getStoreOp()));
|
depth->setStoreAction(cast(layout.depthAttachment.getStoreOp()));
|
||||||
|
|
||||||
if (layout.depthResolveAttachment.getTexture() != nullptr) {
|
if (layout.depthResolveAttachment.getTextureView() != nullptr) {
|
||||||
// store multisampled attachment as well
|
// store multisampled attachment as well
|
||||||
if(layout.depthAttachment.getStoreOp() == Gfx::SE_ATTACHMENT_STORE_OP_STORE) {
|
if(layout.depthAttachment.getStoreOp() == Gfx::SE_ATTACHMENT_STORE_OP_STORE) {
|
||||||
depth->setStoreAction(MTL::StoreActionStoreAndMultisampleResolve);
|
depth->setStoreAction(MTL::StoreActionStoreAndMultisampleResolve);
|
||||||
@@ -56,17 +56,17 @@ void RenderPass::updateRenderPass() {
|
|||||||
for (size_t i = 0; i < layout.colorAttachments.size(); ++i) {
|
for (size_t i = 0; i < layout.colorAttachments.size(); ++i) {
|
||||||
const auto& color = layout.colorAttachments[i];
|
const auto& color = layout.colorAttachments[i];
|
||||||
auto desc = renderPass->colorAttachments()->object(i);
|
auto desc = renderPass->colorAttachments()->object(i);
|
||||||
desc->setTexture(color.getTexture().cast<TextureBase>()->getImage());
|
desc->setTexture(color.getTextureView().cast<TextureView>()->getHandle());
|
||||||
if (!layout.resolveAttachments.empty()) {
|
if (!layout.resolveAttachments.empty()) {
|
||||||
const auto& resolve = layout.resolveAttachments[i];
|
const auto& resolve = layout.resolveAttachments[i];
|
||||||
desc->setResolveTexture(resolve.getTexture().cast<TextureBase>()->getImage());
|
desc->setResolveTexture(resolve.getTextureView().cast<TextureView>()->getHandle());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (layout.depthAttachment.getTexture() != nullptr) {
|
if (layout.depthAttachment.getTextureView() != nullptr) {
|
||||||
auto depth = renderPass->depthAttachment();
|
auto depth = renderPass->depthAttachment();
|
||||||
depth->setTexture(layout.depthAttachment.getTexture().cast<TextureBase>()->getImage());
|
depth->setTexture(layout.depthAttachment.getTextureView().cast<TextureView>()->getHandle());
|
||||||
if (layout.depthResolveAttachment.getTexture() != nullptr) {
|
if (layout.depthResolveAttachment.getTextureView() != nullptr) {
|
||||||
depth->setResolveTexture(layout.depthResolveAttachment.getTexture().cast<TextureBase>()->getImage());
|
depth->setResolveTexture(layout.depthResolveAttachment.getTextureView().cast<TextureView>()->getHandle());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
#include <Foundation/Foundation.hpp>
|
#include <Foundation/Foundation.hpp>
|
||||||
#include <Metal/Metal.hpp>
|
#include <Metal/Metal.hpp>
|
||||||
#include <QuartzCore/QuartzCore.hpp>
|
#include <QuartzCore/QuartzCore.hpp>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
namespace Seele {
|
namespace Seele {
|
||||||
namespace Metal {
|
namespace Metal {
|
||||||
@@ -25,18 +26,26 @@ class DestructionManager {
|
|||||||
DEFINE_REF(DestructionManager)
|
DEFINE_REF(DestructionManager)
|
||||||
|
|
||||||
class CommandBoundResource {
|
class CommandBoundResource {
|
||||||
public:
|
public:
|
||||||
CommandBoundResource(PGraphics graphics) : graphics(graphics) {}
|
CommandBoundResource(PGraphics graphics, const std::string& name) : graphics(graphics), name(name) {}
|
||||||
virtual ~CommandBoundResource() {
|
virtual ~CommandBoundResource() {
|
||||||
if (isCurrentlyBound())
|
if (isCurrentlyBound())
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
constexpr bool isCurrentlyBound() const { return bindCount > 0; }
|
constexpr bool isCurrentlyBound() const { return bindCount > 0; }
|
||||||
constexpr void bind() { bindCount++; }
|
void bind() { bindCount++;
|
||||||
constexpr void unbind() { bindCount--; }
|
std::cout << "Bind " << bindCount << " " << name << std::endl;
|
||||||
|
}
|
||||||
|
void unbind() { bindCount--;
|
||||||
|
std::cout << "Unbind " << bindCount << " " << name << std::endl;
|
||||||
|
}
|
||||||
|
const std::string& getName() const {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
PGraphics graphics;
|
PGraphics graphics;
|
||||||
|
std::string name;
|
||||||
uint64 bindCount = 0;
|
uint64 bindCount = 0;
|
||||||
};
|
};
|
||||||
DEFINE_REF(CommandBoundResource)
|
DEFINE_REF(CommandBoundResource)
|
||||||
|
|||||||
@@ -7,7 +7,38 @@
|
|||||||
|
|
||||||
namespace Seele {
|
namespace Seele {
|
||||||
namespace Metal {
|
namespace Metal {
|
||||||
class TextureHandle : public CommandBoundResource{
|
DECLARE_REF(TextureHandle)
|
||||||
|
class TextureView : public Gfx::TextureView, public CommandBoundResource {
|
||||||
|
public:
|
||||||
|
TextureView(PGraphics graphics, PTextureHandle source, uint32 width, uint32 height, uint32 numLayers, uint32 numMipLevels, MTL::Texture* view);
|
||||||
|
virtual ~TextureView();
|
||||||
|
virtual Gfx::SeFormat getFormat() const override;
|
||||||
|
virtual uint32 getWidth() const override;
|
||||||
|
virtual uint32 getHeight() const override;
|
||||||
|
virtual uint32 getDepth() const override;
|
||||||
|
virtual uint32 getNumLayers() const override;
|
||||||
|
virtual Gfx::SeSampleCountFlags getNumSamples() const override;
|
||||||
|
virtual uint32 getMipLevels() const override;
|
||||||
|
virtual void pipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage, Gfx::SeAccessFlags dstAccess,
|
||||||
|
Gfx::SePipelineStageFlags dstStage) override;
|
||||||
|
virtual void changeLayout(Gfx::SeImageLayout newLayout, Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage,
|
||||||
|
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) override;
|
||||||
|
|
||||||
|
MTL::Texture* getHandle() const { return view; }
|
||||||
|
PTextureHandle getSource() const { return source;}
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint32 width;
|
||||||
|
uint32 height;
|
||||||
|
uint32 numLayers;
|
||||||
|
uint32 numMipLevels;
|
||||||
|
PTextureHandle source;
|
||||||
|
MTL::Texture* view;
|
||||||
|
friend class TextureBase;
|
||||||
|
};
|
||||||
|
DEFINE_REF(TextureView)
|
||||||
|
|
||||||
|
class TextureHandle : public CommandBoundResource {
|
||||||
public:
|
public:
|
||||||
TextureHandle(PGraphics graphics, MTL::TextureType type, const TextureCreateInfo& createInfo, MTL::Texture* existingImage);
|
TextureHandle(PGraphics graphics, MTL::TextureType type, const TextureCreateInfo& createInfo, MTL::Texture* existingImage);
|
||||||
virtual ~TextureHandle();
|
virtual ~TextureHandle();
|
||||||
@@ -18,8 +49,10 @@ class TextureHandle : public CommandBoundResource{
|
|||||||
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage);
|
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage);
|
||||||
void download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer);
|
void download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer);
|
||||||
void generateMipmaps();
|
void generateMipmaps();
|
||||||
|
Gfx::OTextureView createTextureView(uint32 baseMipLevel, uint32 levelCount, uint32 baseArrayLayer, uint32 layerCount);
|
||||||
|
|
||||||
MTL::Texture* texture;
|
MTL::Texture* texture;
|
||||||
|
OTextureView textureView;
|
||||||
MTL::TextureType type;
|
MTL::TextureType type;
|
||||||
uint32 width;
|
uint32 width;
|
||||||
uint32 height;
|
uint32 height;
|
||||||
@@ -87,6 +120,8 @@ class Texture2D : public Gfx::Texture2D, public TextureBase {
|
|||||||
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) override;
|
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) override;
|
||||||
virtual void download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer) override;
|
virtual void download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer) override;
|
||||||
virtual void generateMipmaps() override;
|
virtual void generateMipmaps() override;
|
||||||
|
virtual Gfx::PTextureView getDefaultView() const override;
|
||||||
|
virtual Gfx::OTextureView createTextureView(uint32 baseMipLevel, uint32 levelCount, uint32 baseArrayLayer, uint32 layerCount) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Inherited via QueueOwnedResource
|
// Inherited via QueueOwnedResource
|
||||||
@@ -95,7 +130,31 @@ class Texture2D : public Gfx::Texture2D, public TextureBase {
|
|||||||
Gfx::SePipelineStageFlags dstStage) override;
|
Gfx::SePipelineStageFlags dstStage) override;
|
||||||
};
|
};
|
||||||
DEFINE_REF(Texture2D)
|
DEFINE_REF(Texture2D)
|
||||||
|
class Texture2DArray : public Gfx::Texture2DArray, public TextureBase {
|
||||||
|
public:
|
||||||
|
Texture2DArray(PGraphics graphics, const TextureCreateInfo& createInfo, MTL::Texture* existingImage = nullptr);
|
||||||
|
virtual ~Texture2DArray();
|
||||||
|
virtual uint32 getWidth() const override { return handle->width; }
|
||||||
|
virtual uint32 getHeight() const override { return handle->height; }
|
||||||
|
virtual uint32 getDepth() const override { return handle->depth; }
|
||||||
|
virtual uint32 getNumLayers() const override { return handle->arrayCount; }
|
||||||
|
virtual Gfx::SeFormat getFormat() const override { return handle->format; }
|
||||||
|
virtual Gfx::SeSampleCountFlags getNumSamples() const override { return handle->samples; }
|
||||||
|
virtual uint32 getMipLevels() const override { return handle->mipLevels; }
|
||||||
|
virtual void changeLayout(Gfx::SeImageLayout newLayout, Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage,
|
||||||
|
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) override;
|
||||||
|
virtual void download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer) override;
|
||||||
|
virtual void generateMipmaps() override;
|
||||||
|
virtual Gfx::PTextureView getDefaultView() const override;
|
||||||
|
virtual Gfx::OTextureView createTextureView(uint32 baseMipLevel, uint32 levelCount, uint32 baseArrayLayer, uint32 layerCount) override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// Inherited via QueueOwnedResource
|
||||||
|
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner) override;
|
||||||
|
virtual void executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage, Gfx::SeAccessFlags dstAccess,
|
||||||
|
Gfx::SePipelineStageFlags dstStage) override;
|
||||||
|
};
|
||||||
|
DEFINE_REF(Texture2DArray)
|
||||||
class Texture3D : public Gfx::Texture3D, public TextureBase {
|
class Texture3D : public Gfx::Texture3D, public TextureBase {
|
||||||
public:
|
public:
|
||||||
Texture3D(PGraphics graphics, const TextureCreateInfo& createInfo);
|
Texture3D(PGraphics graphics, const TextureCreateInfo& createInfo);
|
||||||
@@ -111,6 +170,8 @@ class Texture3D : public Gfx::Texture3D, public TextureBase {
|
|||||||
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) override;
|
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) override;
|
||||||
virtual void download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer) override;
|
virtual void download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer) override;
|
||||||
virtual void generateMipmaps() override;
|
virtual void generateMipmaps() override;
|
||||||
|
virtual Gfx::PTextureView getDefaultView() const override;
|
||||||
|
virtual Gfx::OTextureView createTextureView(uint32 baseMipLevel, uint32 levelCount, uint32 baseArrayLayer, uint32 layerCount) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Inherited via QueueOwnedResource
|
// Inherited via QueueOwnedResource
|
||||||
@@ -135,6 +196,8 @@ class TextureCube : public Gfx::TextureCube, public TextureBase {
|
|||||||
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) override;
|
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) override;
|
||||||
virtual void download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer) override;
|
virtual void download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer) override;
|
||||||
virtual void generateMipmaps() override;
|
virtual void generateMipmaps() override;
|
||||||
|
virtual Gfx::PTextureView getDefaultView() const override;
|
||||||
|
virtual Gfx::OTextureView createTextureView(uint32 baseMipLevel, uint32 levelCount, uint32 baseArrayLayer, uint32 layerCount) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Inherited via QueueOwnedResource
|
// Inherited via QueueOwnedResource
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
#include "Texture.h"
|
#include "Texture.h"
|
||||||
|
#include "Command.h"
|
||||||
#include "Enums.h"
|
#include "Enums.h"
|
||||||
#include "Graphics/Enums.h"
|
#include "Graphics/Enums.h"
|
||||||
#include "Graphics/Initializer.h"
|
#include "Graphics/Initializer.h"
|
||||||
#include "Graphics/Metal/Buffer.h"
|
#include "Graphics/Metal/Buffer.h"
|
||||||
#include "Graphics/Metal/Graphics.h"
|
#include "Graphics/Metal/Graphics.h"
|
||||||
#include "Command.h"
|
|
||||||
#include "Graphics/Metal/Resources.h"
|
#include "Graphics/Metal/Resources.h"
|
||||||
#include "Metal/MTLTexture.hpp"
|
#include "Metal/MTLTexture.hpp"
|
||||||
#include "Metal/MTLTypes.hpp"
|
#include "Metal/MTLTypes.hpp"
|
||||||
@@ -12,9 +12,54 @@
|
|||||||
using namespace Seele;
|
using namespace Seele;
|
||||||
using namespace Seele::Metal;
|
using namespace Seele::Metal;
|
||||||
|
|
||||||
|
TextureView::TextureView(PGraphics graphics, PTextureHandle source, uint32 width, uint32 height, uint32 numLayers, uint32 numMipLevels, MTL::Texture* view)
|
||||||
|
: CommandBoundResource(graphics, source->getName()), width(width), height(height), numLayers(numLayers), numMipLevels(numMipLevels), source(source), view(view) {}
|
||||||
|
|
||||||
|
TextureView::~TextureView() {}
|
||||||
|
|
||||||
|
Gfx::SeFormat TextureView::getFormat() const { return source->format; }
|
||||||
|
|
||||||
|
uint32 TextureView::getWidth() const { return width; }
|
||||||
|
|
||||||
|
uint32 TextureView::getHeight() const { return height; }
|
||||||
|
|
||||||
|
uint32 TextureView::getDepth() const { return source->depth; }
|
||||||
|
|
||||||
|
uint32 TextureView::getNumLayers() const { return numLayers; }
|
||||||
|
|
||||||
|
Gfx::SeSampleCountFlags TextureView::getNumSamples() const { return source->samples; }
|
||||||
|
|
||||||
|
uint32 TextureView::getMipLevels() const { return numMipLevels; }
|
||||||
|
|
||||||
|
void TextureView::pipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage, Gfx::SeAccessFlags dstAccess,
|
||||||
|
Gfx::SePipelineStageFlags dstStage) {
|
||||||
|
return source->pipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextureView::changeLayout(Gfx::SeImageLayout newLayout, Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage,
|
||||||
|
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) {
|
||||||
|
return source->changeLayout(newLayout, srcAccess, srcStage, dstAccess, dstStage);
|
||||||
|
}
|
||||||
|
|
||||||
|
Gfx::OTextureView TextureHandle::createTextureView(uint32 baseMipLevel, uint32 viewLevelCount, uint32 baseArrayLayer,
|
||||||
|
uint32 viewLayerCount) {
|
||||||
|
MTL::Texture* viewTexture;
|
||||||
|
if(viewLevelCount > 1)
|
||||||
|
{
|
||||||
|
viewTexture = texture->newTextureView(cast(format), type, NS::Range(baseMipLevel, viewLevelCount), NS::Range(baseArrayLayer, viewLayerCount));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
viewTexture = texture->newTextureView(cast(format));
|
||||||
|
}
|
||||||
|
uint32 viewWidth = width * std::pow(0.5, baseMipLevel);
|
||||||
|
uint32 viewHeight = height * std::pow(0.5, baseMipLevel);
|
||||||
|
return new TextureView(graphics, this, viewWidth, viewHeight, viewLayerCount, viewLevelCount, viewTexture);
|
||||||
|
}
|
||||||
|
|
||||||
TextureHandle::TextureHandle(PGraphics graphics, MTL::TextureType type, const TextureCreateInfo& createInfo, MTL::Texture* existingImage)
|
TextureHandle::TextureHandle(PGraphics graphics, MTL::TextureType type, const TextureCreateInfo& createInfo, MTL::Texture* existingImage)
|
||||||
: CommandBoundResource(graphics), texture(existingImage), type(type), width(createInfo.width), height(createInfo.height), depth(createInfo.depth),
|
: CommandBoundResource(graphics, createInfo.name), texture(existingImage), type(type), width(createInfo.width), height(createInfo.height),
|
||||||
arrayCount(createInfo.elements), mipLevels(1), samples(createInfo.samples), format(createInfo.format),
|
depth(createInfo.depth), arrayCount(createInfo.elements), mipLevels(1), samples(createInfo.samples), format(createInfo.format),
|
||||||
usage(createInfo.usage), layout(Gfx::SE_IMAGE_LAYOUT_UNDEFINED), ownsImage(existingImage == nullptr) {
|
usage(createInfo.usage), layout(Gfx::SE_IMAGE_LAYOUT_UNDEFINED), ownsImage(existingImage == nullptr) {
|
||||||
if (createInfo.useMip) {
|
if (createInfo.useMip) {
|
||||||
mipLevels = static_cast<uint32_t>(std::floor(std::log2(std::max(width, height)))) + 1;
|
mipLevels = static_cast<uint32_t>(std::floor(std::log2(std::max(width, height)))) + 1;
|
||||||
@@ -41,7 +86,7 @@ TextureHandle::TextureHandle(PGraphics graphics, MTL::TextureType type, const Te
|
|||||||
descriptor->setSampleCount(samples);
|
descriptor->setSampleCount(samples);
|
||||||
descriptor->setUsage(mtlUsage);
|
descriptor->setUsage(mtlUsage);
|
||||||
descriptor->setStorageMode(MTL::StorageModePrivate);
|
descriptor->setStorageMode(MTL::StorageModePrivate);
|
||||||
if(usage & Gfx::SE_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) {
|
if (usage & Gfx::SE_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) {
|
||||||
descriptor->setStorageMode(MTL::StorageModeMemoryless);
|
descriptor->setStorageMode(MTL::StorageModeMemoryless);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,28 +95,30 @@ TextureHandle::TextureHandle(PGraphics graphics, MTL::TextureType type, const Te
|
|||||||
|
|
||||||
descriptor->release();
|
descriptor->release();
|
||||||
}
|
}
|
||||||
if(createInfo.sourceData.data != nullptr)
|
if (createInfo.sourceData.data != nullptr) {
|
||||||
{
|
OBufferAllocation stagingBuffer =
|
||||||
OBufferAllocation stagingBuffer = new BufferAllocation(graphics, "TextureStaging", createInfo.sourceData.size, MTL::ResourceStorageModeShared);
|
new BufferAllocation(graphics, "TextureStaging", createInfo.sourceData.size, MTL::ResourceStorageModeShared);
|
||||||
std::memcpy(stagingBuffer->map(), createInfo.sourceData.data, createInfo.sourceData.size);
|
std::memcpy(stagingBuffer->map(), createInfo.sourceData.data, createInfo.sourceData.size);
|
||||||
MTL::BlitCommandEncoder* blitEnc = graphics->getQueue()->getCommands()->getBlitEncoder();
|
MTL::BlitCommandEncoder* blitEnc = graphics->getQueue()->getCommands()->getBlitEncoder();
|
||||||
uint32 sliceSize = createInfo.sourceData.size / arrayCount;
|
uint32 sliceSize = createInfo.sourceData.size / arrayCount;
|
||||||
uint32 numSlices = arrayCount;
|
uint32 numSlices = arrayCount;
|
||||||
if(type == MTL::TextureTypeCube || type == MTL::TextureTypeCubeArray) {
|
if (type == MTL::TextureTypeCube || type == MTL::TextureTypeCubeArray) {
|
||||||
sliceSize /= 6;
|
sliceSize /= 6;
|
||||||
numSlices *= 6;
|
numSlices *= 6;
|
||||||
}
|
}
|
||||||
uint32 offset = 0;
|
uint32 offset = 0;
|
||||||
for(uint32 slice = 0; slice < numSlices; ++slice){
|
for (uint32 slice = 0; slice < numSlices; ++slice) {
|
||||||
blitEnc->copyFromBuffer(stagingBuffer->buffer, offset, sliceSize / createInfo.height, arrayCount == 1 ? 0 : sliceSize, MTL::Size(createInfo.width, createInfo.height, createInfo.depth), texture, slice, 0, MTL::Origin());
|
blitEnc->copyFromBuffer(stagingBuffer->buffer, offset, sliceSize / createInfo.height, arrayCount == 1 ? 0 : sliceSize,
|
||||||
|
MTL::Size(createInfo.width, createInfo.height, createInfo.depth), texture, slice, 0, MTL::Origin());
|
||||||
offset += sliceSize;
|
offset += sliceSize;
|
||||||
}
|
}
|
||||||
if(mipLevels > 1) {
|
if (mipLevels > 1) {
|
||||||
blitEnc->generateMipmaps(texture);
|
blitEnc->generateMipmaps(texture);
|
||||||
}
|
}
|
||||||
graphics->getQueue()->getCommands()->bindResource(PBufferAllocation(stagingBuffer));
|
graphics->getQueue()->getCommands()->bindResource(PBufferAllocation(stagingBuffer));
|
||||||
graphics->getDestructionManager()->queueResourceForDestruction(std::move(stagingBuffer));
|
graphics->getDestructionManager()->queueResourceForDestruction(std::move(stagingBuffer));
|
||||||
}
|
}
|
||||||
|
textureView = new TextureView(graphics, this, width, height, arrayCount, mipLevels, texture);
|
||||||
}
|
}
|
||||||
|
|
||||||
TextureHandle::~TextureHandle() {
|
TextureHandle::~TextureHandle() {
|
||||||
@@ -85,7 +132,7 @@ void TextureHandle::pipelineBarrier(Gfx::SeAccessFlags, Gfx::SePipelineStageFlag
|
|||||||
void TextureHandle::changeLayout(Gfx::SeImageLayout, Gfx::SeAccessFlags, Gfx::SePipelineStageFlags, Gfx::SeAccessFlags,
|
void TextureHandle::changeLayout(Gfx::SeImageLayout, Gfx::SeAccessFlags, Gfx::SePipelineStageFlags, Gfx::SeAccessFlags,
|
||||||
Gfx::SePipelineStageFlags) {}
|
Gfx::SePipelineStageFlags) {}
|
||||||
|
|
||||||
void TextureHandle::transferOwnership(Gfx::QueueType newOwner) {}
|
void TextureHandle::transferOwnership(Gfx::QueueType) {}
|
||||||
|
|
||||||
void TextureHandle::download(uint32, uint32, uint32, Array<uint8>&) {}
|
void TextureHandle::download(uint32, uint32, uint32, Array<uint8>&) {}
|
||||||
|
|
||||||
@@ -94,9 +141,7 @@ void TextureHandle::generateMipmaps() {}
|
|||||||
TextureBase::TextureBase(PGraphics graphics, MTL::TextureType viewType, const TextureCreateInfo& createInfo, MTL::Texture* existingImage)
|
TextureBase::TextureBase(PGraphics graphics, MTL::TextureType viewType, const TextureCreateInfo& createInfo, MTL::Texture* existingImage)
|
||||||
: handle(new TextureHandle(graphics, viewType, createInfo, existingImage)), graphics(graphics) {}
|
: handle(new TextureHandle(graphics, viewType, createInfo, existingImage)), graphics(graphics) {}
|
||||||
|
|
||||||
TextureBase::~TextureBase() {
|
TextureBase::~TextureBase() { graphics->getDestructionManager()->queueResourceForDestruction(std::move(handle)); }
|
||||||
graphics->getDestructionManager()->queueResourceForDestruction(std::move(handle));
|
|
||||||
}
|
|
||||||
|
|
||||||
void TextureBase::pipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage, Gfx::SeAccessFlags dstAccess,
|
void TextureBase::pipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage, Gfx::SeAccessFlags dstAccess,
|
||||||
Gfx::SePipelineStageFlags dstStage) {
|
Gfx::SePipelineStageFlags dstStage) {
|
||||||
@@ -132,6 +177,12 @@ void Texture2D::download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<
|
|||||||
|
|
||||||
void Texture2D::generateMipmaps() { TextureBase::generateMipmaps(); }
|
void Texture2D::generateMipmaps() { TextureBase::generateMipmaps(); }
|
||||||
|
|
||||||
|
Gfx::PTextureView Texture2D::getDefaultView() const { return PTextureView(handle->textureView); }
|
||||||
|
|
||||||
|
Gfx::OTextureView Texture2D::createTextureView(uint32 baseMipLevel, uint32 levelCount, uint32 baseArrayLayer, uint32 layerCount) {
|
||||||
|
return handle->createTextureView(baseMipLevel, levelCount, baseArrayLayer, layerCount);
|
||||||
|
}
|
||||||
|
|
||||||
void Texture2D::executeOwnershipBarrier(Gfx::QueueType newOwner) { TextureBase::transferOwnership(newOwner); }
|
void Texture2D::executeOwnershipBarrier(Gfx::QueueType newOwner) { TextureBase::transferOwnership(newOwner); }
|
||||||
|
|
||||||
void Texture2D::executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage, Gfx::SeAccessFlags dstAccess,
|
void Texture2D::executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage, Gfx::SeAccessFlags dstAccess,
|
||||||
@@ -139,6 +190,39 @@ void Texture2D::executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipe
|
|||||||
TextureBase::pipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
|
TextureBase::pipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Texture2DArray::Texture2DArray(PGraphics graphics, const TextureCreateInfo& createInfo, MTL::Texture* existingImage)
|
||||||
|
: Gfx::Texture2DArray(graphics->getFamilyMapping()),
|
||||||
|
TextureBase(graphics,
|
||||||
|
createInfo.elements > 1 ? (createInfo.samples > 1 ? MTL::TextureType2DMultisampleArray : MTL::TextureType2DArray)
|
||||||
|
: (createInfo.samples > 1 ? MTL::TextureType2DMultisample : MTL::TextureType2D),
|
||||||
|
createInfo, existingImage) {}
|
||||||
|
|
||||||
|
Texture2DArray::~Texture2DArray() {}
|
||||||
|
|
||||||
|
void Texture2DArray::changeLayout(Gfx::SeImageLayout newLayout, Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage,
|
||||||
|
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) {
|
||||||
|
TextureBase::changeLayout(newLayout, srcAccess, srcStage, dstAccess, dstStage);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Texture2DArray::download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer) {
|
||||||
|
TextureBase::download(mipLevel, arrayLayer, face, buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Texture2DArray::generateMipmaps() { TextureBase::generateMipmaps(); }
|
||||||
|
|
||||||
|
Gfx::PTextureView Texture2DArray::getDefaultView() const { return PTextureView(handle->textureView); }
|
||||||
|
|
||||||
|
Gfx::OTextureView Texture2DArray::createTextureView(uint32 baseMipLevel, uint32 levelCount, uint32 baseArrayLayer, uint32 layerCount) {
|
||||||
|
return handle->createTextureView(baseMipLevel, levelCount, baseArrayLayer, layerCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Texture2DArray::executeOwnershipBarrier(Gfx::QueueType newOwner) { TextureBase::transferOwnership(newOwner); }
|
||||||
|
|
||||||
|
void Texture2DArray::executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage, Gfx::SeAccessFlags dstAccess,
|
||||||
|
Gfx::SePipelineStageFlags dstStage) {
|
||||||
|
TextureBase::pipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
|
||||||
|
}
|
||||||
|
|
||||||
Texture3D::Texture3D(PGraphics graphics, const TextureCreateInfo& createInfo)
|
Texture3D::Texture3D(PGraphics graphics, const TextureCreateInfo& createInfo)
|
||||||
: Gfx::Texture3D(graphics->getFamilyMapping()), TextureBase(graphics, MTL::TextureType3D, createInfo) {}
|
: Gfx::Texture3D(graphics->getFamilyMapping()), TextureBase(graphics, MTL::TextureType3D, createInfo) {}
|
||||||
|
|
||||||
@@ -155,6 +239,12 @@ void Texture3D::download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<
|
|||||||
|
|
||||||
void Texture3D::generateMipmaps() { TextureBase::generateMipmaps(); }
|
void Texture3D::generateMipmaps() { TextureBase::generateMipmaps(); }
|
||||||
|
|
||||||
|
Gfx::PTextureView Texture3D::getDefaultView() const { return PTextureView(handle->textureView); }
|
||||||
|
|
||||||
|
Gfx::OTextureView Texture3D::createTextureView(uint32 baseMipLevel, uint32 levelCount, uint32 baseArrayLayer, uint32 layerCount) {
|
||||||
|
return handle->createTextureView(baseMipLevel, levelCount, baseArrayLayer, layerCount);
|
||||||
|
}
|
||||||
|
|
||||||
void Texture3D::executeOwnershipBarrier(Gfx::QueueType newOwner) { TextureBase::transferOwnership(newOwner); }
|
void Texture3D::executeOwnershipBarrier(Gfx::QueueType newOwner) { TextureBase::transferOwnership(newOwner); }
|
||||||
|
|
||||||
void Texture3D::executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage, Gfx::SeAccessFlags dstAccess,
|
void Texture3D::executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage, Gfx::SeAccessFlags dstAccess,
|
||||||
@@ -179,6 +269,12 @@ void TextureCube::download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Arra
|
|||||||
|
|
||||||
void TextureCube::generateMipmaps() { TextureBase::generateMipmaps(); }
|
void TextureCube::generateMipmaps() { TextureBase::generateMipmaps(); }
|
||||||
|
|
||||||
|
Gfx::PTextureView TextureCube::getDefaultView() const { return PTextureView(handle->textureView); }
|
||||||
|
|
||||||
|
Gfx::OTextureView TextureCube::createTextureView(uint32 baseMipLevel, uint32 levelCount, uint32 baseArrayLayer, uint32 layerCount) {
|
||||||
|
return handle->createTextureView(baseMipLevel, levelCount, baseArrayLayer, layerCount);
|
||||||
|
}
|
||||||
|
|
||||||
void TextureCube::executeOwnershipBarrier(Gfx::QueueType newOwner) { TextureBase::transferOwnership(newOwner); }
|
void TextureCube::executeOwnershipBarrier(Gfx::QueueType newOwner) { TextureBase::transferOwnership(newOwner); }
|
||||||
|
|
||||||
void TextureCube::executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage, Gfx::SeAccessFlags dstAccess,
|
void TextureCube::executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage, Gfx::SeAccessFlags dstAccess,
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
#include "BasePass.h"
|
#include "BasePass.h"
|
||||||
#include "Asset/AssetRegistry.h"
|
#include "Asset/AssetRegistry.h"
|
||||||
#include "Asset/EnvironmentMapAsset.h"
|
|
||||||
#include "Component/Camera.h"
|
#include "Component/Camera.h"
|
||||||
#include "Graphics/Command.h"
|
#include "Graphics/Command.h"
|
||||||
#include "Graphics/Descriptor.h"
|
#include "Graphics/Descriptor.h"
|
||||||
@@ -13,6 +12,10 @@
|
|||||||
#include "Math/Matrix.h"
|
#include "Math/Matrix.h"
|
||||||
#include "Math/Vector.h"
|
#include "Math/Vector.h"
|
||||||
#include "MinimalEngine.h"
|
#include "MinimalEngine.h"
|
||||||
|
#include "ShadowPass.h"
|
||||||
|
#include "Scene/Scene.h"
|
||||||
|
#include "Asset/EnvironmentMapAsset.h"
|
||||||
|
#include "Scene/LightEnvironment.h"
|
||||||
|
|
||||||
using namespace Seele;
|
using namespace Seele;
|
||||||
|
|
||||||
@@ -41,7 +44,29 @@ BasePass::BasePass(Gfx::PGraphics graphics, PScene scene) : RenderPass(graphics)
|
|||||||
});
|
});
|
||||||
lightCullingLayout->create();
|
lightCullingLayout->create();
|
||||||
|
|
||||||
|
shadowMappingLayout = graphics->createDescriptorLayout("pShadowMapping");
|
||||||
|
shadowMappingLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||||
|
.name = SHADOWMAPS_NAME,
|
||||||
|
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
||||||
|
.descriptorCount = NUM_CASCADES,
|
||||||
|
});
|
||||||
|
shadowMappingLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||||
|
.name = LIGHTSPACE_NAME,
|
||||||
|
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||||
|
.descriptorCount = NUM_CASCADES,
|
||||||
|
});
|
||||||
|
shadowMappingLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||||
|
.name = SHADOWSAMPLER_NAME,
|
||||||
|
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLER,
|
||||||
|
});
|
||||||
|
shadowMappingLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||||
|
.name = CASCADE_SPLIT_NAME,
|
||||||
|
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER
|
||||||
|
});
|
||||||
|
shadowMappingLayout->create();
|
||||||
|
|
||||||
basePassLayout->addDescriptorLayout(lightCullingLayout);
|
basePassLayout->addDescriptorLayout(lightCullingLayout);
|
||||||
|
basePassLayout->addDescriptorLayout(shadowMappingLayout);
|
||||||
basePassLayout->addPushConstants(Gfx::SePushConstantRange{
|
basePassLayout->addPushConstants(Gfx::SePushConstantRange{
|
||||||
.stageFlags = Gfx::SE_SHADER_STAGE_TASK_BIT_EXT | Gfx::SE_SHADER_STAGE_VERTEX_BIT | Gfx::SE_SHADER_STAGE_FRAGMENT_BIT,
|
.stageFlags = Gfx::SE_SHADER_STAGE_TASK_BIT_EXT | Gfx::SE_SHADER_STAGE_VERTEX_BIT | Gfx::SE_SHADER_STAGE_FRAGMENT_BIT,
|
||||||
.offset = 0,
|
.offset = 0,
|
||||||
@@ -79,6 +104,19 @@ BasePass::BasePass(Gfx::PGraphics graphics, PScene scene) : RenderPass(graphics)
|
|||||||
.fogColor = Vector(0, 0, 0),
|
.fogColor = Vector(0, 0, 0),
|
||||||
.blendFactor = 0,
|
.blendFactor = 0,
|
||||||
};
|
};
|
||||||
|
shadowSampler = graphics->createSampler(SamplerCreateInfo{
|
||||||
|
.magFilter = Gfx::SE_FILTER_LINEAR,
|
||||||
|
.minFilter = Gfx::SE_FILTER_LINEAR,
|
||||||
|
.mipmapMode = Gfx::SE_SAMPLER_MIPMAP_MODE_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,
|
||||||
|
.mipLodBias = 0.0f,
|
||||||
|
.maxAnisotropy = 1.0f,
|
||||||
|
.minLod = 0.0f,
|
||||||
|
.maxLod = 1.0f,
|
||||||
|
.borderColor = Gfx::SE_BORDER_COLOR_FLOAT_OPAQUE_WHITE,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
BasePass::~BasePass() {}
|
BasePass::~BasePass() {}
|
||||||
@@ -140,12 +178,22 @@ void BasePass::render() {
|
|||||||
opaqueCulling->writeChanges();
|
opaqueCulling->writeChanges();
|
||||||
transparentCulling->writeChanges();
|
transparentCulling->writeChanges();
|
||||||
|
|
||||||
|
shadowMappingLayout->reset();
|
||||||
|
shadowMapping = shadowMappingLayout->allocateDescriptorSet();
|
||||||
|
for (uint32 i = 0; i < NUM_CASCADES; ++i) {
|
||||||
|
shadowMapping->updateTexture(SHADOWMAPS_NAME, i, shadowMaps[i]->getDefaultView());
|
||||||
|
shadowMapping->updateBuffer(LIGHTSPACE_NAME, i, lightSpaceMatrices[i]);
|
||||||
|
}
|
||||||
|
shadowMapping->updateSampler(SHADOWSAMPLER_NAME, 0, shadowSampler);
|
||||||
|
shadowMapping->updateBuffer(CASCADE_SPLIT_NAME, 0, cascadeSplits);
|
||||||
|
shadowMapping->writeChanges();
|
||||||
|
|
||||||
query->beginQuery();
|
query->beginQuery();
|
||||||
timestamps->write(Gfx::SE_PIPELINE_STAGE_TOP_OF_PIPE_BIT, "BaseBegin");
|
timestamps->write(Gfx::SE_PIPELINE_STAGE_TOP_OF_PIPE_BIT, "BaseBegin");
|
||||||
graphics->beginRenderPass(renderPass);
|
graphics->beginRenderPass(renderPass);
|
||||||
Array<VertexData::TransparentDraw> transparentData;
|
Array<VertexData::TransparentDraw> transparentData;
|
||||||
|
// Opaque
|
||||||
{
|
{
|
||||||
graphics->beginDebugRegion("Opaque");
|
|
||||||
Array<Gfx::ORenderCommand> commands;
|
Array<Gfx::ORenderCommand> commands;
|
||||||
Gfx::ShaderPermutation permutation = graphics->getShaderCompiler()->getTemplate("BasePass");
|
Gfx::ShaderPermutation permutation = graphics->getShaderCompiler()->getTemplate("BasePass");
|
||||||
permutation.setDepthCulling(true); // always use the culling info
|
permutation.setDepthCulling(true); // always use the culling info
|
||||||
@@ -176,7 +224,7 @@ void BasePass::render() {
|
|||||||
const Gfx::ShaderCollection* collection = graphics->getShaderCompiler()->findShaders(id);
|
const Gfx::ShaderCollection* collection = graphics->getShaderCompiler()->findShaders(id);
|
||||||
assert(collection != nullptr);
|
assert(collection != nullptr);
|
||||||
|
|
||||||
//bool twoSided = materialData.material->isTwoSided();
|
// bool twoSided = materialData.material->isTwoSided();
|
||||||
|
|
||||||
if (graphics->supportMeshShading()) {
|
if (graphics->supportMeshShading()) {
|
||||||
Gfx::MeshPipelineCreateInfo pipelineInfo = {
|
Gfx::MeshPipelineCreateInfo pipelineInfo = {
|
||||||
@@ -221,7 +269,7 @@ void BasePass::render() {
|
|||||||
command->bindPipeline(graphics->createGraphicsPipeline(std::move(pipelineInfo)));
|
command->bindPipeline(graphics->createGraphicsPipeline(std::move(pipelineInfo)));
|
||||||
}
|
}
|
||||||
command->bindDescriptor({viewParamsSet, vertexData->getVertexDataSet(), vertexData->getInstanceDataSet(),
|
command->bindDescriptor({viewParamsSet, vertexData->getVertexDataSet(), vertexData->getInstanceDataSet(),
|
||||||
scene->getLightEnvironment()->getDescriptorSet(), Material::getDescriptorSet(), opaqueCulling});
|
scene->getLightEnvironment()->getDescriptorSet(), Material::getDescriptorSet(), shadowMapping, opaqueCulling});
|
||||||
for (const auto& drawCall : materialData.instances) {
|
for (const auto& drawCall : materialData.instances) {
|
||||||
command->pushConstants(Gfx::SE_SHADER_STAGE_TASK_BIT_EXT | Gfx::SE_SHADER_STAGE_VERTEX_BIT |
|
command->pushConstants(Gfx::SE_SHADER_STAGE_TASK_BIT_EXT | Gfx::SE_SHADER_STAGE_VERTEX_BIT |
|
||||||
Gfx::SE_SHADER_STAGE_FRAGMENT_BIT,
|
Gfx::SE_SHADER_STAGE_FRAGMENT_BIT,
|
||||||
@@ -241,7 +289,6 @@ void BasePass::render() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
graphics->executeCommands(std::move(commands));
|
graphics->executeCommands(std::move(commands));
|
||||||
graphics->endDebugRegion();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// commands.add(waterRenderer->render(viewParamsSet));
|
// commands.add(waterRenderer->render(viewParamsSet));
|
||||||
@@ -249,18 +296,15 @@ void BasePass::render() {
|
|||||||
|
|
||||||
// Skybox
|
// Skybox
|
||||||
{
|
{
|
||||||
graphics->beginDebugRegion("Skybox");
|
|
||||||
Gfx::ORenderCommand skyboxCommand = graphics->createRenderCommand("SkyboxRender");
|
Gfx::ORenderCommand skyboxCommand = graphics->createRenderCommand("SkyboxRender");
|
||||||
skyboxCommand->setViewport(viewport);
|
skyboxCommand->setViewport(viewport);
|
||||||
skyboxCommand->bindPipeline(skyboxPipeline);
|
skyboxCommand->bindPipeline(skyboxPipeline);
|
||||||
skyboxCommand->bindDescriptor({viewParamsSet, skyboxDataSet, textureSet});
|
skyboxCommand->bindDescriptor({viewParamsSet, skyboxDataSet, textureSet});
|
||||||
skyboxCommand->draw(36, 1, 0, 0);
|
skyboxCommand->draw(36, 1, 0, 0);
|
||||||
graphics->executeCommands(std::move(skyboxCommand));
|
graphics->executeCommands(std::move(skyboxCommand));
|
||||||
graphics->endDebugRegion();
|
|
||||||
}
|
}
|
||||||
// Transparent rendering
|
// Transparent rendering
|
||||||
{
|
{
|
||||||
graphics->beginDebugRegion("Transparent");
|
|
||||||
Gfx::ShaderPermutation permutation = graphics->getShaderCompiler()->getTemplate("BasePass");
|
Gfx::ShaderPermutation permutation = graphics->getShaderCompiler()->getTemplate("BasePass");
|
||||||
permutation.setPositionOnly(false);
|
permutation.setPositionOnly(false);
|
||||||
permutation.setDepthCulling(false); // ignore visibility infos for transparency
|
permutation.setDepthCulling(false); // ignore visibility infos for transparency
|
||||||
@@ -280,7 +324,7 @@ void BasePass::render() {
|
|||||||
const Gfx::ShaderCollection* collection = graphics->getShaderCompiler()->findShaders(id);
|
const Gfx::ShaderCollection* collection = graphics->getShaderCompiler()->findShaders(id);
|
||||||
assert(collection != nullptr);
|
assert(collection != nullptr);
|
||||||
|
|
||||||
//bool twoSided = t.matInst->getBaseMaterial()->isTwoSided();
|
// bool twoSided = t.matInst->getBaseMaterial()->isTwoSided();
|
||||||
|
|
||||||
if (graphics->supportMeshShading()) {
|
if (graphics->supportMeshShading()) {
|
||||||
Gfx::MeshPipelineCreateInfo pipelineInfo = {
|
Gfx::MeshPipelineCreateInfo pipelineInfo = {
|
||||||
@@ -324,10 +368,6 @@ void BasePass::render() {
|
|||||||
{
|
{
|
||||||
.cullMode = Gfx::SE_CULL_MODE_BACK_BIT,
|
.cullMode = Gfx::SE_CULL_MODE_BACK_BIT,
|
||||||
},
|
},
|
||||||
.depthStencilState =
|
|
||||||
{
|
|
||||||
.depthCompareOp = Gfx::SE_COMPARE_OP_GREATER_OR_EQUAL,
|
|
||||||
},
|
|
||||||
.colorBlend =
|
.colorBlend =
|
||||||
{
|
{
|
||||||
.attachmentCount = 1,
|
.attachmentCount = 1,
|
||||||
@@ -343,7 +383,7 @@ void BasePass::render() {
|
|||||||
transparentCommand->bindPipeline(pipeline);
|
transparentCommand->bindPipeline(pipeline);
|
||||||
}
|
}
|
||||||
transparentCommand->bindDescriptor({viewParamsSet, t.vertexData->getVertexDataSet(), t.vertexData->getInstanceDataSet(),
|
transparentCommand->bindDescriptor({viewParamsSet, t.vertexData->getVertexDataSet(), t.vertexData->getInstanceDataSet(),
|
||||||
scene->getLightEnvironment()->getDescriptorSet(), Material::getDescriptorSet(),
|
scene->getLightEnvironment()->getDescriptorSet(), Material::getDescriptorSet(), shadowMapping,
|
||||||
transparentCulling});
|
transparentCulling});
|
||||||
transparentCommand->pushConstants(Gfx::SE_SHADER_STAGE_TASK_BIT_EXT | Gfx::SE_SHADER_STAGE_VERTEX_BIT |
|
transparentCommand->pushConstants(Gfx::SE_SHADER_STAGE_TASK_BIT_EXT | Gfx::SE_SHADER_STAGE_VERTEX_BIT |
|
||||||
Gfx::SE_SHADER_STAGE_FRAGMENT_BIT,
|
Gfx::SE_SHADER_STAGE_FRAGMENT_BIT,
|
||||||
@@ -360,11 +400,9 @@ void BasePass::render() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
graphics->executeCommands(std::move(transparentCommand));
|
graphics->executeCommands(std::move(transparentCommand));
|
||||||
graphics->endDebugRegion();
|
|
||||||
}
|
}
|
||||||
// Debug vertices
|
// Debug vertices
|
||||||
if (gDebugVertices.size() > 0) {
|
if (gDebugVertices.size() > 0) {
|
||||||
graphics->beginDebugRegion("Debug");
|
|
||||||
Gfx::ShaderPermutation permutation = graphics->getShaderCompiler()->getTemplate("BasePass");
|
Gfx::ShaderPermutation permutation = graphics->getShaderCompiler()->getTemplate("BasePass");
|
||||||
permutation.setDepthCulling(true); // always use the culling info
|
permutation.setDepthCulling(true); // always use the culling info
|
||||||
permutation.setPositionOnly(false);
|
permutation.setPositionOnly(false);
|
||||||
@@ -375,7 +413,6 @@ void BasePass::render() {
|
|||||||
debugCommand->bindVertexBuffer({debugVertices});
|
debugCommand->bindVertexBuffer({debugVertices});
|
||||||
debugCommand->draw((uint32)gDebugVertices.size(), 1, 0, 0);
|
debugCommand->draw((uint32)gDebugVertices.size(), 1, 0, 0);
|
||||||
graphics->executeCommands(std::move(debugCommand));
|
graphics->executeCommands(std::move(debugCommand));
|
||||||
graphics->endDebugRegion();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
graphics->endRenderPass();
|
graphics->endRenderPass();
|
||||||
@@ -422,18 +459,18 @@ void BasePass::publishOutputs() {
|
|||||||
Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
|
Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
|
||||||
Gfx::SE_ATTACHMENT_LOAD_OP_DONT_CARE, Gfx::SE_ATTACHMENT_STORE_OP_STORE);
|
Gfx::SE_ATTACHMENT_LOAD_OP_DONT_CARE, Gfx::SE_ATTACHMENT_STORE_OP_STORE);
|
||||||
|
|
||||||
msDepthAttachment =
|
msDepthAttachment = Gfx::RenderTargetAttachment(msBasePassDepth->getDefaultView(), Gfx::SE_IMAGE_LAYOUT_UNDEFINED,
|
||||||
Gfx::RenderTargetAttachment(msBasePassDepth->getDefaultView(), Gfx::SE_IMAGE_LAYOUT_UNDEFINED, Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
|
Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, Gfx::SE_ATTACHMENT_LOAD_OP_CLEAR,
|
||||||
Gfx::SE_ATTACHMENT_LOAD_OP_CLEAR, Gfx::SE_ATTACHMENT_STORE_OP_DONT_CARE);
|
Gfx::SE_ATTACHMENT_STORE_OP_DONT_CARE);
|
||||||
msDepthAttachment.clear.depthStencil.depth = 0.0f;
|
msDepthAttachment.clear.depthStencil.depth = 0.0f;
|
||||||
|
|
||||||
colorAttachment =
|
colorAttachment = Gfx::RenderTargetAttachment(basePassColor->getDefaultView(), Gfx::SE_IMAGE_LAYOUT_UNDEFINED,
|
||||||
Gfx::RenderTargetAttachment(basePassColor->getDefaultView(), Gfx::SE_IMAGE_LAYOUT_UNDEFINED, Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, Gfx::SE_ATTACHMENT_LOAD_OP_DONT_CARE,
|
||||||
Gfx::SE_ATTACHMENT_LOAD_OP_DONT_CARE, Gfx::SE_ATTACHMENT_STORE_OP_STORE);
|
Gfx::SE_ATTACHMENT_STORE_OP_STORE);
|
||||||
|
|
||||||
msColorAttachment =
|
msColorAttachment = Gfx::RenderTargetAttachment(msBasePassColor->getDefaultView(), Gfx::SE_IMAGE_LAYOUT_UNDEFINED,
|
||||||
Gfx::RenderTargetAttachment(msBasePassColor->getDefaultView(), Gfx::SE_IMAGE_LAYOUT_UNDEFINED, Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, Gfx::SE_ATTACHMENT_LOAD_OP_CLEAR,
|
||||||
Gfx::SE_ATTACHMENT_LOAD_OP_CLEAR, Gfx::SE_ATTACHMENT_STORE_OP_DONT_CARE);
|
Gfx::SE_ATTACHMENT_STORE_OP_DONT_CARE);
|
||||||
msColorAttachment.clear.color.float32[0] = 0;
|
msColorAttachment.clear.color.float32[0] = 0;
|
||||||
msColorAttachment.clear.color.float32[1] = 1;
|
msColorAttachment.clear.color.float32[1] = 1;
|
||||||
msColorAttachment.clear.color.float32[2] = 0;
|
msColorAttachment.clear.color.float32[2] = 0;
|
||||||
@@ -442,7 +479,6 @@ void BasePass::publishOutputs() {
|
|||||||
resources->registerRenderPassOutput("BASEPASS_COLOR", colorAttachment);
|
resources->registerRenderPassOutput("BASEPASS_COLOR", colorAttachment);
|
||||||
resources->registerRenderPassOutput("BASEPASS_DEPTH", depthAttachment);
|
resources->registerRenderPassOutput("BASEPASS_DEPTH", depthAttachment);
|
||||||
|
|
||||||
timestamps = graphics->createTimestampQuery(2, "BaseTS");
|
|
||||||
query = graphics->createPipelineStatisticsQuery("BasePassPipelineStatistics");
|
query = graphics->createPipelineStatisticsQuery("BasePassPipelineStatistics");
|
||||||
resources->registerQueryOutput("BASEPASS_QUERY", query);
|
resources->registerQueryOutput("BASEPASS_QUERY", query);
|
||||||
}
|
}
|
||||||
@@ -452,6 +488,11 @@ void BasePass::createRenderPass() {
|
|||||||
// terrainRenderer = new TerrainRenderer(graphics, scene, viewParamsLayout, viewParamsSet);
|
// terrainRenderer = new TerrainRenderer(graphics, scene, viewParamsLayout, viewParamsSet);
|
||||||
cullingBuffer = resources->requestBuffer("CULLINGBUFFER");
|
cullingBuffer = resources->requestBuffer("CULLINGBUFFER");
|
||||||
timestamps = resources->requestTimestampQuery("TIMESTAMPS");
|
timestamps = resources->requestTimestampQuery("TIMESTAMPS");
|
||||||
|
for (uint32 i = 0; i < NUM_CASCADES; ++i) {
|
||||||
|
shadowMaps[i] = resources->requestTexture(fmt::format("SHADOWMAP_TEXTURE{0}", i));
|
||||||
|
lightSpaceMatrices[i] = resources->requestBuffer(fmt::format("SHADOWMAP_LIGHTSPACE{0}", i));
|
||||||
|
}
|
||||||
|
cascadeSplits = resources->requestUniform("SHADOWMAP_CASCADESPLITS");
|
||||||
|
|
||||||
Gfx::RenderTargetLayout layout = Gfx::RenderTargetLayout{
|
Gfx::RenderTargetLayout layout = Gfx::RenderTargetLayout{
|
||||||
.colorAttachments = {msColorAttachment},
|
.colorAttachments = {msColorAttachment},
|
||||||
@@ -586,7 +627,17 @@ void BasePass::createRenderPass() {
|
|||||||
});
|
});
|
||||||
textureLayout->create();
|
textureLayout->create();
|
||||||
|
|
||||||
skyboxSampler = graphics->createSampler({});
|
skyboxSampler = graphics->createSampler({
|
||||||
|
.magFilter = Gfx::SE_FILTER_LINEAR,
|
||||||
|
.minFilter = Gfx::SE_FILTER_LINEAR,
|
||||||
|
.mipmapMode = Gfx::SE_SAMPLER_MIPMAP_MODE_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,
|
||||||
|
.maxAnisotropy = 1.0f,
|
||||||
|
.minLod = 0,
|
||||||
|
.maxLod = std::numeric_limits<float>::max(),
|
||||||
|
});
|
||||||
|
|
||||||
skyboxData.transformMatrix = Matrix4(1);
|
skyboxData.transformMatrix = Matrix4(1);
|
||||||
skyboxData.fogColor = skybox.fogColor;
|
skyboxData.fogColor = skybox.fogColor;
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include "Graphics/Buffer.h"
|
||||||
|
#include "Graphics/Descriptor.h"
|
||||||
|
#include "Graphics/RenderPass/ShadowPass.h"
|
||||||
#include "MinimalEngine.h"
|
#include "MinimalEngine.h"
|
||||||
#include "RenderPass.h"
|
#include "RenderPass.h"
|
||||||
#include "WaterRenderer.h"
|
|
||||||
|
|
||||||
namespace Seele {
|
namespace Seele {
|
||||||
DECLARE_REF(CameraActor)
|
DECLARE_REF(CameraActor)
|
||||||
@@ -30,9 +32,14 @@ class BasePass : public RenderPass {
|
|||||||
Gfx::PTexture2D tLightGrid;
|
Gfx::PTexture2D tLightGrid;
|
||||||
constexpr static const char* LIGHTINDEX_NAME = "lightIndexList";
|
constexpr static const char* LIGHTINDEX_NAME = "lightIndexList";
|
||||||
constexpr static const char* LIGHTGRID_NAME = "lightGrid";
|
constexpr static const char* LIGHTGRID_NAME = "lightGrid";
|
||||||
|
constexpr static const char* SHADOWMAPS_NAME = "shadowMaps";
|
||||||
|
constexpr static const char* LIGHTSPACE_NAME = "lightSpaceMatrices";
|
||||||
|
constexpr static const char* SHADOWSAMPLER_NAME = "shadowSampler";
|
||||||
|
constexpr static const char* CASCADE_SPLIT_NAME = "cascadeSplit";
|
||||||
|
|
||||||
Gfx::PDescriptorSet opaqueCulling;
|
Gfx::ODescriptorSet opaqueCulling;
|
||||||
Gfx::PDescriptorSet transparentCulling;
|
Gfx::ODescriptorSet transparentCulling;
|
||||||
|
Gfx::ODescriptorSet shadowMapping;
|
||||||
|
|
||||||
// use a different texture here so we can do multisampling
|
// use a different texture here so we can do multisampling
|
||||||
Gfx::OTexture2D msBasePassDepth;
|
Gfx::OTexture2D msBasePassDepth;
|
||||||
@@ -44,11 +51,12 @@ class BasePass : public RenderPass {
|
|||||||
// used for transparency sorting
|
// used for transparency sorting
|
||||||
Vector cameraPos;
|
Vector cameraPos;
|
||||||
Vector cameraForward;
|
Vector cameraForward;
|
||||||
Gfx::PDescriptorSet viewParamsSet;
|
Gfx::ODescriptorSet viewParamsSet;
|
||||||
|
|
||||||
PCameraActor source;
|
PCameraActor source;
|
||||||
Gfx::OPipelineLayout basePassLayout;
|
Gfx::OPipelineLayout basePassLayout;
|
||||||
Gfx::ODescriptorLayout lightCullingLayout;
|
Gfx::ODescriptorLayout lightCullingLayout;
|
||||||
|
Gfx::ODescriptorLayout shadowMappingLayout;
|
||||||
|
|
||||||
Gfx::OPipelineStatisticsQuery query;
|
Gfx::OPipelineStatisticsQuery query;
|
||||||
Gfx::PTimestampQuery timestamps;
|
Gfx::PTimestampQuery timestamps;
|
||||||
@@ -58,6 +66,12 @@ class BasePass : public RenderPass {
|
|||||||
//OWaterRenderer waterRenderer;
|
//OWaterRenderer waterRenderer;
|
||||||
//OTerrainRenderer terrainRenderer;
|
//OTerrainRenderer terrainRenderer;
|
||||||
|
|
||||||
|
// Shadow mapping
|
||||||
|
Gfx::PTexture2D shadowMaps[NUM_CASCADES];
|
||||||
|
Gfx::PShaderBuffer lightSpaceMatrices[NUM_CASCADES];
|
||||||
|
Gfx::OSampler shadowSampler;
|
||||||
|
Gfx::PUniformBuffer cascadeSplits;
|
||||||
|
|
||||||
// Debug rendering
|
// Debug rendering
|
||||||
Gfx::OVertexInput debugVertexInput;
|
Gfx::OVertexInput debugVertexInput;
|
||||||
Gfx::OVertexBuffer debugVertices;
|
Gfx::OVertexBuffer debugVertices;
|
||||||
@@ -68,9 +82,9 @@ class BasePass : public RenderPass {
|
|||||||
|
|
||||||
// Skybox
|
// Skybox
|
||||||
Gfx::ODescriptorLayout skyboxDataLayout;
|
Gfx::ODescriptorLayout skyboxDataLayout;
|
||||||
Gfx::PDescriptorSet skyboxDataSet;
|
Gfx::ODescriptorSet skyboxDataSet;
|
||||||
Gfx::ODescriptorLayout textureLayout;
|
Gfx::ODescriptorLayout textureLayout;
|
||||||
Gfx::PDescriptorSet textureSet;
|
Gfx::ODescriptorSet textureSet;
|
||||||
Gfx::OVertexShader vertexShader;
|
Gfx::OVertexShader vertexShader;
|
||||||
Gfx::OFragmentShader fragmentShader;
|
Gfx::OFragmentShader fragmentShader;
|
||||||
Gfx::OPipelineLayout pipelineLayout;
|
Gfx::OPipelineLayout pipelineLayout;
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ class CachedDepthPass : public RenderPass {
|
|||||||
Gfx::OPipelineStatisticsQuery query;
|
Gfx::OPipelineStatisticsQuery query;
|
||||||
Gfx::OTimestampQuery timestamps;
|
Gfx::OTimestampQuery timestamps;
|
||||||
|
|
||||||
Gfx::PDescriptorSet viewParamsSet;
|
Gfx::ODescriptorSet viewParamsSet;
|
||||||
Gfx::PShaderBuffer cullingBuffer;
|
Gfx::PShaderBuffer cullingBuffer;
|
||||||
PScene scene;
|
PScene scene;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ void DepthCullingPass::beginFrame(const Component::Camera& cam, const Component:
|
|||||||
|
|
||||||
void DepthCullingPass::render() {
|
void DepthCullingPass::render() {
|
||||||
graphics->beginDebugRegion("DepthCullingPass");
|
graphics->beginDebugRegion("DepthCullingPass");
|
||||||
Gfx::PDescriptorSet set = depthAttachmentLayout->allocateDescriptorSet();
|
Gfx::ODescriptorSet set = depthAttachmentLayout->allocateDescriptorSet();
|
||||||
{
|
{
|
||||||
graphics->beginDebugRegion("MipGeneration");
|
graphics->beginDebugRegion("MipGeneration");
|
||||||
query->beginQuery();
|
query->beginQuery();
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ class DepthCullingPass : public RenderPass {
|
|||||||
Gfx::PComputePipeline depthSourceCopy;
|
Gfx::PComputePipeline depthSourceCopy;
|
||||||
Gfx::OComputeShader depthReduceLevelShader;
|
Gfx::OComputeShader depthReduceLevelShader;
|
||||||
Gfx::PComputePipeline depthReduceLevel;
|
Gfx::PComputePipeline depthReduceLevel;
|
||||||
Gfx::PDescriptorSet viewParamsSet;
|
Gfx::ODescriptorSet viewParamsSet;
|
||||||
|
|
||||||
Gfx::PShaderBuffer cullingBuffer;
|
Gfx::PShaderBuffer cullingBuffer;
|
||||||
PScene scene;
|
PScene scene;
|
||||||
|
|||||||
@@ -143,7 +143,7 @@ void LightCullingPass::publishOutputs() {
|
|||||||
|
|
||||||
Gfx::ComputePipelineCreateInfo pipelineInfo;
|
Gfx::ComputePipelineCreateInfo pipelineInfo;
|
||||||
pipelineInfo.computeShader = cullingShader;
|
pipelineInfo.computeShader = cullingShader;
|
||||||
pipelineInfo.pipelineLayout = std::move(cullingLayout);
|
pipelineInfo.pipelineLayout = cullingLayout;
|
||||||
cullingPipeline = graphics->createComputePipeline(std::move(pipelineInfo));
|
cullingPipeline = graphics->createComputePipeline(std::move(pipelineInfo));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -167,7 +167,7 @@ void LightCullingPass::publishOutputs() {
|
|||||||
|
|
||||||
Gfx::ComputePipelineCreateInfo pipelineInfo;
|
Gfx::ComputePipelineCreateInfo pipelineInfo;
|
||||||
pipelineInfo.computeShader = cullingShader;
|
pipelineInfo.computeShader = cullingShader;
|
||||||
pipelineInfo.pipelineLayout = std::move(cullingEnableLayout);
|
pipelineInfo.pipelineLayout = cullingEnableLayout;
|
||||||
cullingEnabledPipeline = graphics->createComputePipeline(std::move(pipelineInfo));
|
cullingEnabledPipeline = graphics->createComputePipeline(std::move(pipelineInfo));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -29,11 +29,11 @@ class LightCullingPass : public RenderPass {
|
|||||||
Gfx::OShaderBuffer frustumBuffer;
|
Gfx::OShaderBuffer frustumBuffer;
|
||||||
const char* FRUSTUMBUFFER_NAME = "frustums";
|
const char* FRUSTUMBUFFER_NAME = "frustums";
|
||||||
Gfx::ODescriptorLayout dispatchParamsLayout;
|
Gfx::ODescriptorLayout dispatchParamsLayout;
|
||||||
Gfx::PDescriptorSet dispatchParamsSet;
|
Gfx::ODescriptorSet dispatchParamsSet;
|
||||||
Gfx::OComputeShader frustumShader;
|
Gfx::OComputeShader frustumShader;
|
||||||
Gfx::PComputePipeline frustumPipeline;
|
Gfx::PComputePipeline frustumPipeline;
|
||||||
Gfx::OPipelineLayout frustumLayout;
|
Gfx::OPipelineLayout frustumLayout;
|
||||||
Gfx::PDescriptorSet viewParamsSet;
|
Gfx::ODescriptorSet viewParamsSet;
|
||||||
|
|
||||||
PLightEnvironment lightEnv;
|
PLightEnvironment lightEnv;
|
||||||
Gfx::PTextureView depthAttachment;
|
Gfx::PTextureView depthAttachment;
|
||||||
@@ -50,7 +50,7 @@ class LightCullingPass : public RenderPass {
|
|||||||
constexpr static const char* OLIGHTGRID_NAME = "oLightGrid";
|
constexpr static const char* OLIGHTGRID_NAME = "oLightGrid";
|
||||||
Gfx::OTexture2D tLightGrid;
|
Gfx::OTexture2D tLightGrid;
|
||||||
constexpr static const char* TLIGHTGRID_NAME = "tLightGrid";
|
constexpr static const char* TLIGHTGRID_NAME = "tLightGrid";
|
||||||
Gfx::PDescriptorSet cullingDescriptorSet;
|
Gfx::ODescriptorSet cullingDescriptorSet;
|
||||||
Gfx::ODescriptorLayout cullingDescriptorLayout;
|
Gfx::ODescriptorLayout cullingDescriptorLayout;
|
||||||
Gfx::OPipelineLayout cullingLayout;
|
Gfx::OPipelineLayout cullingLayout;
|
||||||
Gfx::OPipelineLayout cullingEnableLayout;
|
Gfx::OPipelineLayout cullingEnableLayout;
|
||||||
|
|||||||
@@ -66,7 +66,8 @@ static uint32 pass = 0;
|
|||||||
static Component::Transform lastCam;
|
static Component::Transform lastCam;
|
||||||
void RayTracingPass::beginFrame(const Component::Camera& cam, const Component::Transform& transform) {
|
void RayTracingPass::beginFrame(const Component::Camera& cam, const Component::Transform& transform) {
|
||||||
updateViewParameters(cam, transform);
|
updateViewParameters(cam, transform);
|
||||||
viewParamsSet = createViewParamsSet(); if (lastCam.getPosition() != transform.getPosition() || lastCam.getForward() != transform.getForward()) {
|
viewParamsSet = createViewParamsSet();
|
||||||
|
if (lastCam.getPosition() != transform.getPosition() || lastCam.getForward() != transform.getForward()) {
|
||||||
lastCam = transform;
|
lastCam = transform;
|
||||||
pass = 0;
|
pass = 0;
|
||||||
}
|
}
|
||||||
@@ -149,7 +150,7 @@ void RayTracingPass::render() {
|
|||||||
.instances = instanceData,
|
.instances = instanceData,
|
||||||
.bottomLevelStructures = accelerationStructures,
|
.bottomLevelStructures = accelerationStructures,
|
||||||
});
|
});
|
||||||
Gfx::PDescriptorSet desc = paramsLayout->allocateDescriptorSet();
|
Gfx::ODescriptorSet desc = paramsLayout->allocateDescriptorSet();
|
||||||
desc->updateAccelerationStructure(TLAS_NAME, 0, tlas);
|
desc->updateAccelerationStructure(TLAS_NAME, 0, tlas);
|
||||||
desc->updateTexture(ACCUMULATOR_NAME, 0, radianceAccumulator->getDefaultView());
|
desc->updateTexture(ACCUMULATOR_NAME, 0, radianceAccumulator->getDefaultView());
|
||||||
desc->updateTexture(TEXTURE_NAME, 0, texture->getDefaultView());
|
desc->updateTexture(TEXTURE_NAME, 0, texture->getDefaultView());
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ class RayTracingPass : public RenderPass {
|
|||||||
Gfx::OAnyHitShader anyhit;
|
Gfx::OAnyHitShader anyhit;
|
||||||
Gfx::OMissShader miss;
|
Gfx::OMissShader miss;
|
||||||
Gfx::PRayTracingPipeline pipeline;
|
Gfx::PRayTracingPipeline pipeline;
|
||||||
Gfx::PDescriptorSet viewParamsSet;
|
Gfx::ODescriptorSet viewParamsSet;
|
||||||
PScene scene;
|
PScene scene;
|
||||||
};
|
};
|
||||||
} // namespace Seele
|
} // namespace Seele
|
||||||
@@ -38,7 +38,7 @@ class RenderGraph {
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
PRenderGraphResources res;
|
ORenderGraphResources res;
|
||||||
List<ORenderPass> passes;
|
List<ORenderPass> passes;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
#include "RenderGraphResources.h"
|
#include "RenderGraphResources.h"
|
||||||
#include "Graphics/Query.h"
|
#include "Graphics/Query.h"
|
||||||
#include <iostream>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
using namespace Seele;
|
using namespace Seele;
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ void RenderPass::updateViewParameters(const Component::Camera& cam, const Compon
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
Gfx::PDescriptorSet RenderPass::createViewParamsSet()
|
Gfx::ODescriptorSet RenderPass::createViewParamsSet()
|
||||||
{
|
{
|
||||||
// screen space
|
// screen space
|
||||||
//StaticArray<Vector4, 4> corners = {
|
//StaticArray<Vector4, 4> corners = {
|
||||||
@@ -71,8 +71,7 @@ Gfx::PDescriptorSet RenderPass::createViewParamsSet()
|
|||||||
|
|
||||||
// extract_planes_from_view_projection_matrix(viewParams.viewProjectionMatrix, viewParams.viewFrustum);
|
// extract_planes_from_view_projection_matrix(viewParams.viewProjectionMatrix, viewParams.viewFrustum);
|
||||||
|
|
||||||
viewParamsLayout->reset();
|
Gfx::ODescriptorSet viewParamsSet = viewParamsLayout->allocateDescriptorSet();
|
||||||
Gfx::PDescriptorSet viewParamsSet = viewParamsLayout->allocateDescriptorSet();
|
|
||||||
viewParamsSet->updateConstants("viewMatrix", 0, &viewParams.viewMatrix);
|
viewParamsSet->updateConstants("viewMatrix", 0, &viewParams.viewMatrix);
|
||||||
viewParamsSet->updateConstants("inverseViewMatrix", 0, &viewParams.inverseViewMatrix);
|
viewParamsSet->updateConstants("inverseViewMatrix", 0, &viewParams.inverseViewMatrix);
|
||||||
viewParamsSet->updateConstants("projectionMatrix", 0, &viewParams.projectionMatrix);
|
viewParamsSet->updateConstants("projectionMatrix", 0, &viewParams.projectionMatrix);
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ class RenderPass {
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
void updateViewParameters(const Component::Camera& cam, const Component::Transform& transform);
|
void updateViewParameters(const Component::Camera& cam, const Component::Transform& transform);
|
||||||
Gfx::PDescriptorSet createViewParamsSet();
|
Gfx::ODescriptorSet createViewParamsSet();
|
||||||
struct Plane {
|
struct Plane {
|
||||||
Vector n;
|
Vector n;
|
||||||
float d;
|
float d;
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#include "Graphics/Graphics.h"
|
#include "Graphics/Graphics.h"
|
||||||
#include "Graphics/Initializer.h"
|
#include "Graphics/Initializer.h"
|
||||||
#include "Graphics/Shader.h"
|
#include "Graphics/Shader.h"
|
||||||
|
#include "Math/Matrix.h"
|
||||||
#include <glm/ext/matrix_transform.hpp>
|
#include <glm/ext/matrix_transform.hpp>
|
||||||
#include <glm/matrix.hpp>
|
#include <glm/matrix.hpp>
|
||||||
|
|
||||||
@@ -44,8 +45,8 @@ ShadowPass::ShadowPass(Gfx::PGraphics graphics, PScene scene) : RenderPass(graph
|
|||||||
ShadowPass::~ShadowPass() {}
|
ShadowPass::~ShadowPass() {}
|
||||||
|
|
||||||
void ShadowPass::beginFrame(const Component::Camera& camera, const Component::Transform& transform) {
|
void ShadowPass::beginFrame(const Component::Camera& camera, const Component::Transform& transform) {
|
||||||
uint32 cascadeDim = SHADOW_MAP_SIZE;
|
|
||||||
float cascadeSplits[NUM_CASCADES];
|
float cascadeSplits[NUM_CASCADES];
|
||||||
|
float splitDepths[NUM_CASCADES];
|
||||||
|
|
||||||
float nearClip = camera.nearPlane;
|
float nearClip = camera.nearPlane;
|
||||||
float farClip = camera.farPlane;
|
float farClip = camera.farPlane;
|
||||||
@@ -58,58 +59,48 @@ void ShadowPass::beginFrame(const Component::Camera& camera, const Component::Tr
|
|||||||
float ratio = maxZ / minZ;
|
float ratio = maxZ / minZ;
|
||||||
constexpr float cascadeSplitLambda = 0.95f;
|
constexpr float cascadeSplitLambda = 0.95f;
|
||||||
for (uint32 i = 0; i < NUM_CASCADES; ++i) {
|
for (uint32 i = 0; i < NUM_CASCADES; ++i) {
|
||||||
cascades[i].shadowMaps = graphics->createTexture2D(TextureCreateInfo{
|
|
||||||
.format = Gfx::SE_FORMAT_D32_SFLOAT,
|
|
||||||
.width = cascadeDim,
|
|
||||||
.height = cascadeDim,
|
|
||||||
.elements = (uint32)scene->getLightEnvironment()->getNumDirectionalLights(),
|
|
||||||
.usage = Gfx::SE_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | Gfx::SE_IMAGE_USAGE_SAMPLED_BIT,
|
|
||||||
.name = "ShadowMapCascade",
|
|
||||||
});
|
|
||||||
cascades[i].views.clear();
|
|
||||||
for (uint32 j = 0; j < cascades[i].shadowMaps->getNumLayers(); ++j) {
|
|
||||||
cascades[i].views.add(cascades[i].shadowMaps->createTextureView(0, 1, j, 1));
|
|
||||||
}
|
|
||||||
cascadeDim /= 2;
|
|
||||||
float p = (i + 1) / static_cast<float>(NUM_CASCADES);
|
float p = (i + 1) / static_cast<float>(NUM_CASCADES);
|
||||||
float log = minZ * std::pow(ratio, p);
|
float log = minZ * std::pow(ratio, p);
|
||||||
float uniform = minZ + range * p;
|
float uniform = minZ + range * p;
|
||||||
float d = cascadeSplitLambda * (log - uniform) + uniform;
|
float d = cascadeSplitLambda * (log - uniform) + uniform;
|
||||||
cascadeSplits[i] = (d - nearClip) / clipRange;
|
cascadeSplits[i] = (d - nearClip) / clipRange;
|
||||||
|
splitDepths[i] = (camera.nearPlane + cascadeSplits[i] * clipRange) * -1.0f;
|
||||||
|
cascades[i].viewParams.clear();
|
||||||
}
|
}
|
||||||
|
cascadeSplitsBuffer->updateContents(0, sizeof(float) * NUM_CASCADES, splitDepths);
|
||||||
|
|
||||||
// call this to update view params member, ignore descriptor set
|
// call this to update view params member, ignore descriptor set
|
||||||
updateViewParameters(camera, transform);
|
updateViewParameters(camera, transform);
|
||||||
Array<Vector> frustumCorners = {
|
Matrix4 invCam = viewParams.inverseViewProjectionMatrix;
|
||||||
Vector(-1.0f, 1.0f, 0.0f), Vector(1.0f, 1.0f, 0.0f), Vector(1.0f, -1.0f, 0.0f), Vector(-1.0f, -1.0f, 0.0f),
|
|
||||||
Vector(-1.0f, 1.0f, 1.0f), Vector(1.0f, 1.0f, 1.0f), Vector(1.0f, -1.0f, 1.0f), Vector(-1.0f, -1.0f, 1.0f),
|
|
||||||
};
|
|
||||||
|
|
||||||
for (auto& c : frustumCorners) {
|
|
||||||
Vector4 invCorner = viewParams.inverseViewProjectionMatrix * Vector4(c, 1);
|
|
||||||
c = invCorner / invCorner.w;
|
|
||||||
}
|
|
||||||
for (uint32 s = 0; s < scene->getLightEnvironment()->getNumDirectionalLights(); ++s) {
|
for (uint32 s = 0; s < scene->getLightEnvironment()->getNumDirectionalLights(); ++s) {
|
||||||
float lastSplitDist = 0.0;
|
float lastSplitDist = 0.0;
|
||||||
for (uint32 i = 0; i < NUM_CASCADES; ++i) {
|
for (uint32 i = 0; i < NUM_CASCADES; ++i) {
|
||||||
float splitDist = cascadeSplits[i];
|
float splitDist = cascadeSplits[i];
|
||||||
|
|
||||||
Array<Vector> cascadeCorners(8);
|
Array<Vector> frustumCorners = {
|
||||||
|
Vector(-1.0f, 1.0f, 1.0f), Vector(1.0f, 1.0f, 1.0f), Vector(1.0f, -1.0f, 1.0f), Vector(-1.0f, -1.0f, 1.0f),
|
||||||
|
Vector(-1.0f, 1.0f, 0.0f), Vector(1.0f, 1.0f, 0.0f), Vector(1.0f, -1.0f, 0.0f), Vector(-1.0f, -1.0f, 0.0f),
|
||||||
|
};
|
||||||
|
|
||||||
|
for (auto& c : frustumCorners) {
|
||||||
|
Vector4 invCorner = invCam * Vector4(c, 1);
|
||||||
|
c = invCorner / invCorner.w;
|
||||||
|
}
|
||||||
for (uint32 j = 0; j < 4; j++) {
|
for (uint32 j = 0; j < 4; j++) {
|
||||||
Vector dist = frustumCorners[j + 4] - frustumCorners[j];
|
Vector dist = frustumCorners[j + 4] - frustumCorners[j];
|
||||||
cascadeCorners[j + 4] = frustumCorners[j] + (dist * splitDist);
|
frustumCorners[j + 4] = frustumCorners[j] + (dist * splitDist);
|
||||||
cascadeCorners[j] = frustumCorners[j] + (dist * lastSplitDist);
|
frustumCorners[j] = frustumCorners[j] + (dist * lastSplitDist);
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector frustumCenter = Vector(0);
|
Vector frustumCenter = Vector(0);
|
||||||
for (uint32 j = 0; j < 8; j++) {
|
for (uint32 j = 0; j < 8; j++) {
|
||||||
frustumCenter += cascadeCorners[j];
|
frustumCenter += frustumCorners[j];
|
||||||
}
|
}
|
||||||
frustumCenter /= 8.0f;
|
frustumCenter /= 8.0f;
|
||||||
|
|
||||||
float radius = 0.0f;
|
float radius = 0.0f;
|
||||||
for (uint j = 0; j < 8; j++) {
|
for (uint j = 0; j < 8; j++) {
|
||||||
float distance = glm::length(cascadeCorners[j] - frustumCenter);
|
float distance = glm::length(frustumCorners[j] - frustumCenter);
|
||||||
radius = glm::max(radius, distance);
|
radius = glm::max(radius, distance);
|
||||||
}
|
}
|
||||||
radius = std::ceil(radius * 16.0f) / 16.0f;
|
radius = std::ceil(radius * 16.0f) / 16.0f;
|
||||||
@@ -117,10 +108,11 @@ void ShadowPass::beginFrame(const Component::Camera& camera, const Component::Tr
|
|||||||
Vector maxExtents = Vector(radius);
|
Vector maxExtents = Vector(radius);
|
||||||
Vector minExtents = -maxExtents;
|
Vector minExtents = -maxExtents;
|
||||||
|
|
||||||
Vector lightDir = glm::normalize(scene->getLightEnvironment()->getDirectionalLight(s).direction);
|
Vector lightDir = glm::normalize(-scene->getLightEnvironment()->getDirectionalLight(s).direction);
|
||||||
Matrix4 viewMatrix = glm::lookAt(frustumCenter - lightDir * -minExtents.z, frustumCenter, Vector(0, 1, 0));
|
Vector cameraPos = frustumCenter - lightDir * -minExtents.z;
|
||||||
|
Matrix4 viewMatrix = glm::lookAt(cameraPos, frustumCenter, Vector(0, 1, 0));
|
||||||
Matrix4 projectionMatrix =
|
Matrix4 projectionMatrix =
|
||||||
glm::ortho(minExtents.x, maxExtents.x, minExtents.y, maxExtents.y, 0.0f, maxExtents.z - minExtents.z);
|
orthographicProjection(minExtents.x, maxExtents.x, minExtents.y, maxExtents.y, 0.0f, maxExtents.z - minExtents.z);
|
||||||
Matrix4 viewProjectionMatrix = projectionMatrix * viewMatrix;
|
Matrix4 viewProjectionMatrix = projectionMatrix * viewMatrix;
|
||||||
viewParams.viewMatrix = viewMatrix;
|
viewParams.viewMatrix = viewMatrix;
|
||||||
viewParams.inverseViewMatrix = glm::inverse(viewMatrix);
|
viewParams.inverseViewMatrix = glm::inverse(viewMatrix);
|
||||||
@@ -128,9 +120,14 @@ void ShadowPass::beginFrame(const Component::Camera& camera, const Component::Tr
|
|||||||
viewParams.inverseProjection = glm::inverse(projectionMatrix);
|
viewParams.inverseProjection = glm::inverse(projectionMatrix);
|
||||||
viewParams.viewProjectionMatrix = viewProjectionMatrix;
|
viewParams.viewProjectionMatrix = viewProjectionMatrix;
|
||||||
viewParams.inverseViewProjectionMatrix = glm::inverse(viewProjectionMatrix);
|
viewParams.inverseViewProjectionMatrix = glm::inverse(viewProjectionMatrix);
|
||||||
|
viewParams.cameraPosition_WS = Vector4(cameraPos, 1);
|
||||||
|
viewParams.cameraForward_WS = Vector4(frustumCenter - cameraPos, 0);
|
||||||
viewParams.screenDimensions = Vector2(maxExtents.x - minExtents.x, maxExtents.y - minExtents.y);
|
viewParams.screenDimensions = Vector2(maxExtents.x - minExtents.x, maxExtents.y - minExtents.y);
|
||||||
viewParams.invScreenDimensions = 1.0f / viewParams.screenDimensions;
|
viewParams.invScreenDimensions = 1.0f / viewParams.screenDimensions;
|
||||||
cascades[i].viewParams.add(createViewParamsSet());
|
cascades[i].viewParams.add(createViewParamsSet());
|
||||||
|
cascades[i].lightSpaceBuffer->updateContents(0, sizeof(Matrix4), &viewProjectionMatrix);
|
||||||
|
|
||||||
|
lastSplitDist = cascadeSplits[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -146,9 +143,9 @@ void ShadowPass::render() {
|
|||||||
Array<Gfx::ORenderCommand> commands;
|
Array<Gfx::ORenderCommand> commands;
|
||||||
renderPass = graphics->createRenderPass(
|
renderPass = graphics->createRenderPass(
|
||||||
Gfx::RenderTargetLayout{
|
Gfx::RenderTargetLayout{
|
||||||
.depthAttachment = Gfx::RenderTargetAttachment(
|
.depthAttachment = Gfx::RenderTargetAttachment(cascades[c].views[shadowIndex], Gfx::SE_IMAGE_LAYOUT_UNDEFINED,
|
||||||
cascades[c].views[shadowIndex], Gfx::SE_IMAGE_LAYOUT_UNDEFINED,
|
Gfx::SE_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
||||||
Gfx::SE_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, Gfx::SE_ATTACHMENT_LOAD_OP_CLEAR, Gfx::SE_ATTACHMENT_STORE_OP_STORE),
|
Gfx::SE_ATTACHMENT_LOAD_OP_CLEAR, Gfx::SE_ATTACHMENT_STORE_OP_STORE),
|
||||||
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -219,7 +216,8 @@ void ShadowPass::render() {
|
|||||||
Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo));
|
Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo));
|
||||||
command->bindPipeline(pipeline);
|
command->bindPipeline(pipeline);
|
||||||
}
|
}
|
||||||
command->bindDescriptor({cascades[c].viewParams[shadowIndex], vertexData->getVertexDataSet(), vertexData->getInstanceDataSet()});
|
command->bindDescriptor(
|
||||||
|
{cascades[c].viewParams[shadowIndex], vertexData->getVertexDataSet(), vertexData->getInstanceDataSet()});
|
||||||
VertexData::DrawCallOffsets offsets = {
|
VertexData::DrawCallOffsets offsets = {
|
||||||
.instanceOffset = 0,
|
.instanceOffset = 0,
|
||||||
};
|
};
|
||||||
@@ -258,6 +256,12 @@ void ShadowPass::render() {
|
|||||||
void ShadowPass::endFrame() {}
|
void ShadowPass::endFrame() {}
|
||||||
|
|
||||||
void ShadowPass::publishOutputs() {
|
void ShadowPass::publishOutputs() {
|
||||||
|
cascadeSplitsBuffer = graphics->createUniformBuffer(UniformBufferCreateInfo{.sourceData =
|
||||||
|
{
|
||||||
|
.size = sizeof(float) * NUM_CASCADES,
|
||||||
|
.data = nullptr,
|
||||||
|
},
|
||||||
|
.name = "CascadeSplits"});
|
||||||
shadowViewport = graphics->createViewport(nullptr, ViewportCreateInfo{.dimensions =
|
shadowViewport = graphics->createViewport(nullptr, ViewportCreateInfo{.dimensions =
|
||||||
{
|
{
|
||||||
.size = {SHADOW_MAP_SIZE, SHADOW_MAP_SIZE},
|
.size = {SHADOW_MAP_SIZE, SHADOW_MAP_SIZE},
|
||||||
@@ -268,6 +272,37 @@ void ShadowPass::publishOutputs() {
|
|||||||
.right = 100,
|
.right = 100,
|
||||||
.top = 100,
|
.top = 100,
|
||||||
.bottom = -100});
|
.bottom = -100});
|
||||||
|
uint32 cascadeDim = SHADOW_MAP_SIZE;
|
||||||
|
for (uint32 s = 0; s < NUM_CASCADES; ++s) {
|
||||||
|
cascades[s].shadowMaps = graphics->createTexture2DArray(TextureCreateInfo{
|
||||||
|
.format = Gfx::SE_FORMAT_D32_SFLOAT,
|
||||||
|
.width = cascadeDim,
|
||||||
|
.height = cascadeDim,
|
||||||
|
.elements = 1, // TODO:
|
||||||
|
.usage = Gfx::SE_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | Gfx::SE_IMAGE_USAGE_SAMPLED_BIT,
|
||||||
|
.name = "ShadowMapCascade",
|
||||||
|
});
|
||||||
|
cascades[s].lightSpaceBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{.sourceData =
|
||||||
|
{
|
||||||
|
.size = sizeof(Matrix4),
|
||||||
|
.data = nullptr,
|
||||||
|
},
|
||||||
|
.name = "LightSpaceBuffer"});
|
||||||
|
cascades[s].views.clear();
|
||||||
|
for (uint32 j = 0; j < cascades[s].shadowMaps->getNumLayers(); ++j) {
|
||||||
|
cascades[s].views.add(cascades[s].shadowMaps->createTextureView(0, 1, j, 1));
|
||||||
|
}
|
||||||
|
cascadeDim /= 2;
|
||||||
|
resources->registerTextureOutput(fmt::format("SHADOWMAP_TEXTURE{0}", s), Gfx::PTexture2DArray(cascades[s].shadowMaps));
|
||||||
|
resources->registerBufferOutput(fmt::format("SHADOWMAP_LIGHTSPACE{0}", s), cascades[s].lightSpaceBuffer);
|
||||||
|
}
|
||||||
|
cascadeSplitsBuffer = graphics->createUniformBuffer(UniformBufferCreateInfo{.sourceData =
|
||||||
|
{
|
||||||
|
.size = sizeof(float) * NUM_CASCADES,
|
||||||
|
.data = nullptr,
|
||||||
|
},
|
||||||
|
.name = "CASCADE_SPLITS"});
|
||||||
|
resources->registerUniformOutput("SHADOWMAP_CASCADESPLITS", cascadeSplitsBuffer);
|
||||||
viewport = shadowViewport;
|
viewport = shadowViewport;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
namespace Seele {
|
namespace Seele {
|
||||||
|
|
||||||
static constexpr uint64 SHADOW_MAP_SIZE = 8192;
|
static constexpr uint64 SHADOW_MAP_SIZE = 8192;
|
||||||
|
static constexpr uint64 NUM_CASCADES = 4;
|
||||||
|
|
||||||
class ShadowPass : public RenderPass {
|
class ShadowPass : public RenderPass {
|
||||||
public:
|
public:
|
||||||
@@ -20,13 +21,15 @@ class ShadowPass : public RenderPass {
|
|||||||
virtual void createRenderPass() override;
|
virtual void createRenderPass() override;
|
||||||
private:
|
private:
|
||||||
AABB cameraFrustumBox;
|
AABB cameraFrustumBox;
|
||||||
static constexpr uint64 NUM_CASCADES = 4;
|
|
||||||
struct Cascade {
|
struct Cascade {
|
||||||
Gfx::OTexture2D shadowMaps;
|
Gfx::OTexture2DArray shadowMaps;
|
||||||
Array<Gfx::OTextureView> views;
|
Array<Gfx::OTextureView> views;
|
||||||
Array<Gfx::PDescriptorSet> viewParams;
|
Array<Matrix4> lightSpaceMatrices;
|
||||||
|
Gfx::OShaderBuffer lightSpaceBuffer;
|
||||||
|
Array<Gfx::ODescriptorSet> viewParams;
|
||||||
};
|
};
|
||||||
StaticArray<Cascade, NUM_CASCADES> cascades;
|
StaticArray<Cascade, NUM_CASCADES> cascades;
|
||||||
|
Gfx::OUniformBuffer cascadeSplitsBuffer;
|
||||||
Gfx::OPipelineLayout shadowLayout;
|
Gfx::OPipelineLayout shadowLayout;
|
||||||
Gfx::PShaderBuffer cullingBuffer;
|
Gfx::PShaderBuffer cullingBuffer;
|
||||||
Gfx::OViewport shadowViewport;
|
Gfx::OViewport shadowViewport;
|
||||||
|
|||||||
@@ -148,7 +148,7 @@ void ToneMappingPass::render() {
|
|||||||
{
|
{
|
||||||
Gfx::OComputeCommand computeCommand = graphics->createComputeCommand("HistogramCommand");
|
Gfx::OComputeCommand computeCommand = graphics->createComputeCommand("HistogramCommand");
|
||||||
computeCommand->bindPipeline(histogramPipeline);
|
computeCommand->bindPipeline(histogramPipeline);
|
||||||
computeCommand->bindDescriptor({histogramSet});
|
computeCommand->bindDescriptor(histogramSet);
|
||||||
computeCommand->dispatch(threadGroups.x, threadGroups.y, 1);
|
computeCommand->dispatch(threadGroups.x, threadGroups.y, 1);
|
||||||
graphics->executeCommands(std::move(computeCommand));
|
graphics->executeCommands(std::move(computeCommand));
|
||||||
}
|
}
|
||||||
@@ -158,7 +158,7 @@ void ToneMappingPass::render() {
|
|||||||
{
|
{
|
||||||
Gfx::OComputeCommand computeCommand = graphics->createComputeCommand("ExposureCommand");
|
Gfx::OComputeCommand computeCommand = graphics->createComputeCommand("ExposureCommand");
|
||||||
computeCommand->bindPipeline(exposurePipeline);
|
computeCommand->bindPipeline(exposurePipeline);
|
||||||
computeCommand->bindDescriptor({histogramSet});
|
computeCommand->bindDescriptor(histogramSet);
|
||||||
computeCommand->dispatch(1, 1, 1);
|
computeCommand->dispatch(1, 1, 1);
|
||||||
graphics->executeCommands(std::move(computeCommand));
|
graphics->executeCommands(std::move(computeCommand));
|
||||||
}
|
}
|
||||||
@@ -168,7 +168,7 @@ void ToneMappingPass::render() {
|
|||||||
Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT | Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT | Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
||||||
|
|
||||||
tonemappingLayout->reset();
|
tonemappingLayout->reset();
|
||||||
Gfx::PDescriptorSet tonemappingSet = tonemappingLayout->allocateDescriptorSet();
|
Gfx::ODescriptorSet tonemappingSet = tonemappingLayout->allocateDescriptorSet();
|
||||||
tonemappingSet->updateConstants("offset", 0, &offset);
|
tonemappingSet->updateConstants("offset", 0, &offset);
|
||||||
tonemappingSet->updateConstants("slope", 0, &slope);
|
tonemappingSet->updateConstants("slope", 0, &slope);
|
||||||
tonemappingSet->updateConstants("power", 0, &power);
|
tonemappingSet->updateConstants("power", 0, &power);
|
||||||
@@ -181,7 +181,7 @@ void ToneMappingPass::render() {
|
|||||||
Gfx::ORenderCommand command = graphics->createRenderCommand("ToneMapping");
|
Gfx::ORenderCommand command = graphics->createRenderCommand("ToneMapping");
|
||||||
command->setViewport(viewport);
|
command->setViewport(viewport);
|
||||||
command->bindPipeline(pipeline);
|
command->bindPipeline(pipeline);
|
||||||
command->bindDescriptor({tonemappingSet});
|
command->bindDescriptor(tonemappingSet);
|
||||||
command->draw(3, 1, 0, 0);
|
command->draw(3, 1, 0, 0);
|
||||||
graphics->executeCommands(std::move(command));
|
graphics->executeCommands(std::move(command));
|
||||||
graphics->endRenderPass();
|
graphics->endRenderPass();
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ class ToneMappingPass : public RenderPass {
|
|||||||
uint32 numPixels;
|
uint32 numPixels;
|
||||||
UVector2 threadGroups;
|
UVector2 threadGroups;
|
||||||
Gfx::ODescriptorLayout histogramLayout;
|
Gfx::ODescriptorLayout histogramLayout;
|
||||||
Gfx::PDescriptorSet histogramSet;
|
Gfx::ODescriptorSet histogramSet;
|
||||||
Gfx::OPipelineLayout histogramPipelineLayout;
|
Gfx::OPipelineLayout histogramPipelineLayout;
|
||||||
Gfx::OComputeShader histogramShader;
|
Gfx::OComputeShader histogramShader;
|
||||||
Gfx::PComputePipeline histogramPipeline;
|
Gfx::PComputePipeline histogramPipeline;
|
||||||
@@ -48,6 +48,6 @@ class ToneMappingPass : public RenderPass {
|
|||||||
Gfx::OFragmentShader frag;
|
Gfx::OFragmentShader frag;
|
||||||
Gfx::PGraphicsPipeline pipeline;
|
Gfx::PGraphicsPipeline pipeline;
|
||||||
|
|
||||||
Gfx::PDescriptorSet viewParamsSet;
|
Gfx::ODescriptorSet viewParamsSet;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -52,7 +52,7 @@ class UIPass : public RenderPass {
|
|||||||
Gfx::OTexture2D depthBuffer;
|
Gfx::OTexture2D depthBuffer;
|
||||||
|
|
||||||
Gfx::ODescriptorLayout textDescriptorLayout;
|
Gfx::ODescriptorLayout textDescriptorLayout;
|
||||||
Gfx::PDescriptorSet textDescriptorSet;
|
Gfx::ODescriptorSet textDescriptorSet;
|
||||||
|
|
||||||
Gfx::OVertexShader textVertexShader;
|
Gfx::OVertexShader textVertexShader;
|
||||||
Gfx::OFragmentShader textFragmentShader;
|
Gfx::OFragmentShader textFragmentShader;
|
||||||
@@ -60,9 +60,9 @@ class UIPass : public RenderPass {
|
|||||||
Gfx::PGraphicsPipeline textPipeline;
|
Gfx::PGraphicsPipeline textPipeline;
|
||||||
|
|
||||||
Gfx::ODescriptorLayout uiDescriptorLayout;
|
Gfx::ODescriptorLayout uiDescriptorLayout;
|
||||||
Gfx::PDescriptorSet uiDescriptorSet;
|
Gfx::ODescriptorSet uiDescriptorSet;
|
||||||
|
|
||||||
Gfx::PDescriptorSet viewParamsSet;
|
Gfx::ODescriptorSet viewParamsSet;
|
||||||
|
|
||||||
Gfx::OVertexShader uiVertexShader;
|
Gfx::OVertexShader uiVertexShader;
|
||||||
Gfx::OFragmentShader uiFragmentShader;
|
Gfx::OFragmentShader uiFragmentShader;
|
||||||
|
|||||||
@@ -19,14 +19,14 @@ class VisibilityPass : public RenderPass {
|
|||||||
private:
|
private:
|
||||||
static constexpr uint32 BLOCK_SIZE = 32;
|
static constexpr uint32 BLOCK_SIZE = 32;
|
||||||
Gfx::RenderTargetAttachment visibilityAttachment;
|
Gfx::RenderTargetAttachment visibilityAttachment;
|
||||||
Gfx::PDescriptorSet visibilitySet;
|
Gfx::ODescriptorSet visibilitySet;
|
||||||
Gfx::ODescriptorLayout visibilityDescriptor;
|
Gfx::ODescriptorLayout visibilityDescriptor;
|
||||||
Gfx::OPipelineLayout visibilityLayout;
|
Gfx::OPipelineLayout visibilityLayout;
|
||||||
Gfx::OComputeShader visibilityShader;
|
Gfx::OComputeShader visibilityShader;
|
||||||
Gfx::PComputePipeline visibilityPipeline;
|
Gfx::PComputePipeline visibilityPipeline;
|
||||||
Gfx::OPipelineStatisticsQuery query;
|
Gfx::OPipelineStatisticsQuery query;
|
||||||
Gfx::PTimestampQuery timestamps;
|
Gfx::PTimestampQuery timestamps;
|
||||||
Gfx::PDescriptorSet viewParamsSet;
|
Gfx::ODescriptorSet viewParamsSet;
|
||||||
|
|
||||||
constexpr static const char* VISIBILITY_NAME = "visibilityTexture";
|
constexpr static const char* VISIBILITY_NAME = "visibilityTexture";
|
||||||
// Holds culling information for every meshlet for each instance
|
// Holds culling information for every meshlet for each instance
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ class WaterRenderer {
|
|||||||
Gfx::PGraphics graphics;
|
Gfx::PGraphics graphics;
|
||||||
PScene scene;
|
PScene scene;
|
||||||
Gfx::ODescriptorLayout computeLayout;
|
Gfx::ODescriptorLayout computeLayout;
|
||||||
Gfx::PDescriptorSet computeSet;
|
Gfx::ODescriptorSet computeSet;
|
||||||
Gfx::OPipelineLayout pipelineLayout;
|
Gfx::OPipelineLayout pipelineLayout;
|
||||||
|
|
||||||
Gfx::OComputeShader initSpectrumCS;
|
Gfx::OComputeShader initSpectrumCS;
|
||||||
@@ -145,7 +145,7 @@ class WaterRenderer {
|
|||||||
Gfx::OMeshShader waterMesh;
|
Gfx::OMeshShader waterMesh;
|
||||||
Gfx::OFragmentShader waterFragment;
|
Gfx::OFragmentShader waterFragment;
|
||||||
Gfx::ODescriptorLayout materialLayout;
|
Gfx::ODescriptorLayout materialLayout;
|
||||||
Gfx::PDescriptorSet materialSet;
|
Gfx::ODescriptorSet materialSet;
|
||||||
Gfx::OPipelineLayout waterLayout;
|
Gfx::OPipelineLayout waterLayout;
|
||||||
Gfx::PGraphicsPipeline waterPipeline;
|
Gfx::PGraphicsPipeline waterPipeline;
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "CRC.h"
|
#include "CRC.h"
|
||||||
#include "Enums.h"
|
|
||||||
#include "Resources.h"
|
#include "Resources.h"
|
||||||
#include "VertexData.h"
|
#include "VertexData.h"
|
||||||
|
|
||||||
|
|||||||
@@ -50,6 +50,6 @@ class StaticMeshVertexData : public VertexData {
|
|||||||
Array<BiTangentType> bitData;
|
Array<BiTangentType> bitData;
|
||||||
Array<ColorType> colData;
|
Array<ColorType> colData;
|
||||||
Gfx::ODescriptorLayout descriptorLayout;
|
Gfx::ODescriptorLayout descriptorLayout;
|
||||||
Gfx::PDescriptorSet descriptorSet;
|
Gfx::ODescriptorSet descriptorSet;
|
||||||
};
|
};
|
||||||
} // namespace Seele
|
} // namespace Seele
|
||||||
|
|||||||
@@ -16,6 +16,10 @@ Texture2D::Texture2D(QueueFamilyMapping mapping) : Texture(mapping) {}
|
|||||||
|
|
||||||
Texture2D::~Texture2D() {}
|
Texture2D::~Texture2D() {}
|
||||||
|
|
||||||
|
Texture2DArray::Texture2DArray(QueueFamilyMapping mapping) : Texture(mapping) {}
|
||||||
|
|
||||||
|
Texture2DArray::~Texture2DArray() {}
|
||||||
|
|
||||||
Texture3D::Texture3D(QueueFamilyMapping mapping) : Texture(mapping) {}
|
Texture3D::Texture3D(QueueFamilyMapping mapping) : Texture(mapping) {}
|
||||||
|
|
||||||
Texture3D::~Texture3D() {}
|
Texture3D::~Texture3D() {}
|
||||||
|
|||||||
@@ -75,6 +75,32 @@ class Texture2D : public Texture {
|
|||||||
};
|
};
|
||||||
DEFINE_REF(Texture2D)
|
DEFINE_REF(Texture2D)
|
||||||
|
|
||||||
|
class Texture2DArray : public Texture {
|
||||||
|
public:
|
||||||
|
Texture2DArray(QueueFamilyMapping mapping);
|
||||||
|
virtual ~Texture2DArray();
|
||||||
|
|
||||||
|
virtual SeFormat getFormat() const = 0;
|
||||||
|
virtual uint32 getWidth() const = 0;
|
||||||
|
virtual uint32 getHeight() const = 0;
|
||||||
|
virtual uint32 getDepth() const = 0;
|
||||||
|
virtual uint32 getNumLayers() const = 0;
|
||||||
|
virtual SeSampleCountFlags getNumSamples() const = 0;
|
||||||
|
virtual uint32 getMipLevels() const = 0;
|
||||||
|
virtual void changeLayout(SeImageLayout newLayout, SeAccessFlags srcAccess, SePipelineStageFlags srcStage, SeAccessFlags dstAccess,
|
||||||
|
SePipelineStageFlags dstStage) = 0;
|
||||||
|
virtual void generateMipmaps() = 0;
|
||||||
|
virtual PTextureView getDefaultView() const = 0;
|
||||||
|
|
||||||
|
virtual OTextureView createTextureView(uint32 baseMipLevel, uint32 levelCount, uint32 baseArrayLayer, uint32 layerCount) = 0;
|
||||||
|
protected:
|
||||||
|
// Inherited via QueueOwnedResource
|
||||||
|
virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
|
||||||
|
virtual void executePipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage, SeAccessFlags dstAccess,
|
||||||
|
SePipelineStageFlags dstStage) = 0;
|
||||||
|
};
|
||||||
|
DEFINE_REF(Texture2DArray)
|
||||||
|
|
||||||
class Texture3D : public Texture {
|
class Texture3D : public Texture {
|
||||||
public:
|
public:
|
||||||
Texture3D(QueueFamilyMapping mapping);
|
Texture3D(QueueFamilyMapping mapping);
|
||||||
|
|||||||
@@ -568,7 +568,6 @@ void VertexData::updateBuffers() {
|
|||||||
.size = verticesAllocated * sizeof(Vector),
|
.size = verticesAllocated * sizeof(Vector),
|
||||||
.data = (uint8*)positions.data(),
|
.data = (uint8*)positions.data(),
|
||||||
},
|
},
|
||||||
.usage = Gfx::SE_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR,
|
|
||||||
.name = "Positions",
|
.name = "Positions",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -158,7 +158,7 @@ class VertexData {
|
|||||||
|
|
||||||
Array<Gfx::PBottomLevelAS> rayTracingScene;
|
Array<Gfx::PBottomLevelAS> rayTracingScene;
|
||||||
|
|
||||||
Gfx::PDescriptorSet descriptorSet;
|
Gfx::ODescriptorSet descriptorSet;
|
||||||
uint64 idCounter;
|
uint64 idCounter;
|
||||||
uint64 head;
|
uint64 head;
|
||||||
uint64 verticesAllocated;
|
uint64 verticesAllocated;
|
||||||
|
|||||||
@@ -483,7 +483,9 @@ IndexBuffer::IndexBuffer(PGraphics graphics, const IndexBufferCreateInfo& create
|
|||||||
: Gfx::IndexBuffer(graphics->getFamilyMapping(), createInfo),
|
: Gfx::IndexBuffer(graphics->getFamilyMapping(), createInfo),
|
||||||
Vulkan::Buffer(graphics, createInfo.sourceData.size,
|
Vulkan::Buffer(graphics, createInfo.sourceData.size,
|
||||||
VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT |
|
VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT |
|
||||||
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR,
|
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | (graphics->supportRayTracing()
|
||||||
|
? VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR
|
||||||
|
: 0),
|
||||||
createInfo.sourceData.owner, false, createInfo.name) {
|
createInfo.sourceData.owner, false, createInfo.name) {
|
||||||
getAlloc()->updateContents(createInfo.sourceData.offset, createInfo.sourceData.size, createInfo.sourceData.data);
|
getAlloc()->updateContents(createInfo.sourceData.offset, createInfo.sourceData.size, createInfo.sourceData.data);
|
||||||
// getAlloc()->pipelineBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT, Gfx::SE_ACCESS_INDEX_READ_BIT,
|
// getAlloc()->pipelineBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT, Gfx::SE_ACCESS_INDEX_READ_BIT,
|
||||||
|
|||||||
@@ -256,8 +256,8 @@ void RenderCommand::bindDescriptor(Gfx::PDescriptorSet descriptor) {
|
|||||||
assert(threadId == std::this_thread::get_id());
|
assert(threadId == std::this_thread::get_id());
|
||||||
auto descriptorSet = descriptor.cast<DescriptorSet>();
|
auto descriptorSet = descriptor.cast<DescriptorSet>();
|
||||||
assert(descriptorSet->writeDescriptors.size() == 0);
|
assert(descriptorSet->writeDescriptors.size() == 0);
|
||||||
descriptorSet->bind();
|
descriptorSet->setHandle->bind();
|
||||||
boundResources.add(descriptorSet);
|
boundResources.add(descriptorSet->setHandle);
|
||||||
for (auto& binding : descriptorSet->boundResources) {
|
for (auto& binding : descriptorSet->boundResources) {
|
||||||
for (auto& res : binding) {
|
for (auto& res : binding) {
|
||||||
// partially bound descriptors can include nulls
|
// partially bound descriptors can include nulls
|
||||||
@@ -267,9 +267,9 @@ void RenderCommand::bindDescriptor(Gfx::PDescriptorSet descriptor) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (descriptorSet->constantsBuffer != nullptr) {
|
if (descriptorSet->setHandle->constantsBuffer != nullptr) {
|
||||||
descriptorSet->bind();
|
descriptorSet->setHandle->bind();
|
||||||
boundResources.add(PBufferAllocation(descriptorSet->constantsBuffer));
|
boundResources.add(PBufferAllocation(descriptorSet->setHandle->constantsBuffer));
|
||||||
}
|
}
|
||||||
|
|
||||||
VkDescriptorSet setHandle = descriptorSet->getHandle();
|
VkDescriptorSet setHandle = descriptorSet->getHandle();
|
||||||
@@ -286,8 +286,8 @@ void RenderCommand::bindDescriptor(const Array<Gfx::PDescriptorSet>& descriptorS
|
|||||||
for (uint32 i = 0; i < descriptorSets.size(); ++i) {
|
for (uint32 i = 0; i < descriptorSets.size(); ++i) {
|
||||||
auto descriptorSet = descriptorSets[i].cast<DescriptorSet>();
|
auto descriptorSet = descriptorSets[i].cast<DescriptorSet>();
|
||||||
assert(descriptorSet->writeDescriptors.size() == 0);
|
assert(descriptorSet->writeDescriptors.size() == 0);
|
||||||
descriptorSet->bind();
|
descriptorSet->setHandle->bind();
|
||||||
boundResources.add(descriptorSet);
|
boundResources.add(descriptorSet->setHandle);
|
||||||
|
|
||||||
for (auto& binding : descriptorSet->boundResources) {
|
for (auto& binding : descriptorSet->boundResources) {
|
||||||
for (auto& res : binding) {
|
for (auto& res : binding) {
|
||||||
@@ -298,9 +298,9 @@ void RenderCommand::bindDescriptor(const Array<Gfx::PDescriptorSet>& descriptorS
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (descriptorSet->constantsBuffer != nullptr) {
|
if (descriptorSet->setHandle->constantsBuffer != nullptr) {
|
||||||
descriptorSet->bind();
|
descriptorSet->setHandle->bind();
|
||||||
boundResources.add(PBufferAllocation(descriptorSet->constantsBuffer));
|
boundResources.add(PBufferAllocation(descriptorSet->setHandle->constantsBuffer));
|
||||||
}
|
}
|
||||||
sets[layout->findParameter(descriptorSet->getName())] = descriptorSet->getHandle();
|
sets[layout->findParameter(descriptorSet->getName())] = descriptorSet->getHandle();
|
||||||
}
|
}
|
||||||
@@ -436,8 +436,8 @@ void ComputeCommand::bindDescriptor(Gfx::PDescriptorSet descriptor) {
|
|||||||
assert(threadId == std::this_thread::get_id());
|
assert(threadId == std::this_thread::get_id());
|
||||||
auto descriptorSet = descriptor.cast<DescriptorSet>();
|
auto descriptorSet = descriptor.cast<DescriptorSet>();
|
||||||
assert(descriptorSet->writeDescriptors.size() == 0);
|
assert(descriptorSet->writeDescriptors.size() == 0);
|
||||||
descriptorSet->bind();
|
descriptorSet->setHandle->bind();
|
||||||
boundResources.add(descriptorSet.getHandle());
|
boundResources.add(descriptorSet->setHandle);
|
||||||
|
|
||||||
for (auto& binding : descriptorSet->boundResources) {
|
for (auto& binding : descriptorSet->boundResources) {
|
||||||
for (auto& res : binding) {
|
for (auto& res : binding) {
|
||||||
@@ -448,9 +448,9 @@ void ComputeCommand::bindDescriptor(Gfx::PDescriptorSet descriptor) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (descriptorSet->constantsBuffer != nullptr) {
|
if (descriptorSet->setHandle->constantsBuffer != nullptr) {
|
||||||
descriptorSet->bind();
|
descriptorSet->setHandle->bind();
|
||||||
boundResources.add(PBufferAllocation(descriptorSet->constantsBuffer));
|
boundResources.add(PBufferAllocation(descriptorSet->setHandle->constantsBuffer));
|
||||||
}
|
}
|
||||||
|
|
||||||
VkDescriptorSet setHandle = descriptorSet->getHandle();
|
VkDescriptorSet setHandle = descriptorSet->getHandle();
|
||||||
@@ -464,8 +464,8 @@ void ComputeCommand::bindDescriptor(const Array<Gfx::PDescriptorSet>& descriptor
|
|||||||
for (uint32 i = 0; i < descriptorSets.size(); ++i) {
|
for (uint32 i = 0; i < descriptorSets.size(); ++i) {
|
||||||
auto descriptorSet = descriptorSets[i].cast<DescriptorSet>();
|
auto descriptorSet = descriptorSets[i].cast<DescriptorSet>();
|
||||||
assert(descriptorSet->writeDescriptors.size() == 0);
|
assert(descriptorSet->writeDescriptors.size() == 0);
|
||||||
descriptorSet->bind();
|
descriptorSet->setHandle->bind();
|
||||||
boundResources.add(descriptorSet.getHandle());
|
boundResources.add(descriptorSet->setHandle);
|
||||||
for (auto& binding : descriptorSet->boundResources) {
|
for (auto& binding : descriptorSet->boundResources) {
|
||||||
for (auto& res : binding) {
|
for (auto& res : binding) {
|
||||||
// partially bound descriptors can include nulls
|
// partially bound descriptors can include nulls
|
||||||
@@ -475,9 +475,9 @@ void ComputeCommand::bindDescriptor(const Array<Gfx::PDescriptorSet>& descriptor
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (descriptorSet->constantsBuffer != nullptr) {
|
if (descriptorSet->setHandle->constantsBuffer != nullptr) {
|
||||||
descriptorSet->bind();
|
descriptorSet->setHandle->bind();
|
||||||
boundResources.add(PBufferAllocation(descriptorSet->constantsBuffer));
|
boundResources.add(PBufferAllocation(descriptorSet->setHandle->constantsBuffer));
|
||||||
}
|
}
|
||||||
sets[pipeline->getPipelineLayout()->findParameter(descriptorSet->getName())] = descriptorSet->getHandle();
|
sets[pipeline->getPipelineLayout()->findParameter(descriptorSet->getName())] = descriptorSet->getHandle();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,17 +2,19 @@
|
|||||||
#include "Buffer.h"
|
#include "Buffer.h"
|
||||||
#include "CRC.h"
|
#include "CRC.h"
|
||||||
#include "Command.h"
|
#include "Command.h"
|
||||||
|
#include "Enums.h"
|
||||||
#include "Graphics.h"
|
#include "Graphics.h"
|
||||||
#include "Graphics/Buffer.h"
|
#include "Graphics/Buffer.h"
|
||||||
#include "Graphics/Descriptor.h"
|
#include "Graphics/Descriptor.h"
|
||||||
#include "Graphics/Enums.h"
|
#include "Graphics/Enums.h"
|
||||||
#include "Graphics/Initializer.h"
|
#include "Graphics/Initializer.h"
|
||||||
|
#include "Graphics/Vulkan/Resources.h"
|
||||||
#include "RayTracing.h"
|
#include "RayTracing.h"
|
||||||
#include "Texture.h"
|
#include "Texture.h"
|
||||||
#include "vulkan/vulkan_core.h"
|
#include "vulkan/vulkan_core.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <iostream>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <ranges>
|
|
||||||
|
|
||||||
using namespace Seele;
|
using namespace Seele;
|
||||||
using namespace Seele::Vulkan;
|
using namespace Seele::Vulkan;
|
||||||
@@ -32,10 +34,11 @@ void DescriptorLayout::create() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Array<VkDescriptorBindingFlags> bindingFlags;
|
Array<VkDescriptorBindingFlags> bindingFlags;
|
||||||
if (std::ranges::contains(descriptorBindings, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER, &Gfx::DescriptorBinding::descriptorType)) {
|
if (std::ranges::contains(descriptorBindings, Gfx::SE_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK, &Gfx::DescriptorBinding::descriptorType)) {
|
||||||
bindings.add({
|
bindings.add({
|
||||||
.binding = 0,
|
.binding = 0,
|
||||||
.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
|
.descriptorType =
|
||||||
|
VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, // although we can pretend that we support inline uniforms, slang does not generate them
|
||||||
.descriptorCount = 1,
|
.descriptorCount = 1,
|
||||||
.stageFlags = VK_SHADER_STAGE_ALL, // todo
|
.stageFlags = VK_SHADER_STAGE_ALL, // todo
|
||||||
.pImmutableSamplers = nullptr,
|
.pImmutableSamplers = nullptr,
|
||||||
@@ -43,11 +46,12 @@ void DescriptorLayout::create() {
|
|||||||
bindingFlags.add(0);
|
bindingFlags.add(0);
|
||||||
}
|
}
|
||||||
for (const auto& gfxBinding : descriptorBindings) {
|
for (const auto& gfxBinding : descriptorBindings) {
|
||||||
if (gfxBinding.descriptorType == Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER) {
|
if (gfxBinding.descriptorType == Gfx::SE_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK) {
|
||||||
mappings[gfxBinding.name] = {
|
mappings[gfxBinding.name] = {
|
||||||
.binding = 0,
|
.binding = 0,
|
||||||
.constantOffset = constantsSize,
|
.constantOffset = constantsSize,
|
||||||
.constantSize = gfxBinding.uniformLength,
|
.constantSize = gfxBinding.uniformLength,
|
||||||
|
.type = cast(gfxBinding.descriptorType),
|
||||||
};
|
};
|
||||||
constantsSize += gfxBinding.uniformLength;
|
constantsSize += gfxBinding.uniformLength;
|
||||||
constantsStages |= gfxBinding.shaderStages;
|
constantsStages |= gfxBinding.shaderStages;
|
||||||
@@ -92,15 +96,15 @@ DescriptorPool::DescriptorPool(PGraphics graphics, PDescriptorLayout layout)
|
|||||||
cachedHandles[i] = nullptr;
|
cachedHandles[i] = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<Gfx::SeDescriptorType, uint32> perTypeSizes;
|
Map<VkDescriptorType, uint32> perTypeSizes;
|
||||||
for (uint32 i = 0; i < layout->getBindings().size(); ++i) {
|
for (uint32 i = 0; i < layout->bindings.size(); ++i) {
|
||||||
auto& binding = layout->getBindings()[i];
|
auto& binding = layout->bindings[i];
|
||||||
perTypeSizes[binding.descriptorType] += 512;
|
perTypeSizes[binding.descriptorType] += 512;
|
||||||
}
|
}
|
||||||
Array<VkDescriptorPoolSize> poolSizes;
|
Array<VkDescriptorPoolSize> poolSizes;
|
||||||
for (const auto& [type, num] : perTypeSizes) {
|
for (const auto& [type, num] : perTypeSizes) {
|
||||||
poolSizes.add(VkDescriptorPoolSize{
|
poolSizes.add(VkDescriptorPoolSize{
|
||||||
.type = cast(type),
|
.type = type,
|
||||||
.descriptorCount = num,
|
.descriptorCount = num,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -127,7 +131,7 @@ DescriptorPool::~DescriptorPool() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Gfx::PDescriptorSet DescriptorPool::allocateDescriptorSet() {
|
Gfx::ODescriptorSet DescriptorPool::allocateDescriptorSet() {
|
||||||
VkDescriptorSetLayout layoutHandle = layout->getHandle();
|
VkDescriptorSetLayout layoutHandle = layout->getHandle();
|
||||||
VkDescriptorSetVariableDescriptorCountAllocateInfo setCounts = {
|
VkDescriptorSetVariableDescriptorCountAllocateInfo setCounts = {
|
||||||
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO,
|
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO,
|
||||||
@@ -153,29 +157,27 @@ Gfx::PDescriptorSet DescriptorPool::allocateDescriptorSet() {
|
|||||||
}
|
}
|
||||||
for (uint32 setIndex = 0; setIndex < cachedHandles.size(); ++setIndex) {
|
for (uint32 setIndex = 0; setIndex < cachedHandles.size(); ++setIndex) {
|
||||||
if (cachedHandles[setIndex] == nullptr) {
|
if (cachedHandles[setIndex] == nullptr) {
|
||||||
cachedHandles[setIndex] = new DescriptorSet(graphics, this);
|
cachedHandles[setIndex] = new DescriptorSetHandle(graphics, layout->getName());
|
||||||
}
|
}
|
||||||
if (cachedHandles[setIndex]->isCurrentlyBound()) {
|
if (cachedHandles[setIndex]->isCurrentlyBound() || cachedHandles[setIndex]->isUsed) {
|
||||||
// Currently in use, skip
|
// Currently in use, skip
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (cachedHandles[setIndex]->getHandle() == VK_NULL_HANDLE) {
|
if (cachedHandles[setIndex]->getHandle() == VK_NULL_HANDLE) {
|
||||||
// If it hasnt been initialized, allocate it
|
// If it hasnt been initialized, allocate it
|
||||||
VK_CHECK(vkAllocateDescriptorSets(graphics->getDevice(), &allocInfo, &cachedHandles[setIndex]->setHandle));
|
VK_CHECK(vkAllocateDescriptorSets(graphics->getDevice(), &allocInfo, &cachedHandles[setIndex]->handle));
|
||||||
VkDebugUtilsObjectNameInfoEXT nameInfo = {
|
VkDebugUtilsObjectNameInfoEXT nameInfo = {
|
||||||
.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT,
|
.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT,
|
||||||
.pNext = nullptr,
|
.pNext = nullptr,
|
||||||
.objectType = VK_OBJECT_TYPE_DESCRIPTOR_SET,
|
.objectType = VK_OBJECT_TYPE_DESCRIPTOR_SET,
|
||||||
.objectHandle = (uint64)cachedHandles[setIndex]->setHandle,
|
.objectHandle = (uint64)cachedHandles[setIndex]->getHandle(),
|
||||||
.pObjectName = name.c_str(),
|
.pObjectName = name.c_str(),
|
||||||
};
|
};
|
||||||
vkSetDebugUtilsObjectNameEXT(graphics->getDevice(), &nameInfo);
|
vkSetDebugUtilsObjectNameEXT(graphics->getDevice(), &nameInfo);
|
||||||
}
|
}
|
||||||
|
cachedHandles[setIndex]->isUsed = true;
|
||||||
PDescriptorSet vulkanSet = cachedHandles[setIndex];
|
|
||||||
|
|
||||||
// Found set, stop searching
|
// Found set, stop searching
|
||||||
return vulkanSet;
|
return new DescriptorSet(graphics, this, cachedHandles[setIndex]);
|
||||||
}
|
}
|
||||||
if (nextAlloc == nullptr) {
|
if (nextAlloc == nullptr) {
|
||||||
nextAlloc = new DescriptorPool(graphics, layout);
|
nextAlloc = new DescriptorPool(graphics, layout);
|
||||||
@@ -185,23 +187,20 @@ Gfx::PDescriptorSet DescriptorPool::allocateDescriptorSet() {
|
|||||||
// throw std::logic_error("Out of descriptor sets");
|
// throw std::logic_error("Out of descriptor sets");
|
||||||
}
|
}
|
||||||
|
|
||||||
void DescriptorPool::reset() {
|
void DescriptorPool::reset() {}
|
||||||
for (uint32 i = 0; i < cachedHandles.size(); ++i) {
|
|
||||||
if (cachedHandles[i] == nullptr) {
|
DescriptorSetHandle::DescriptorSetHandle(PGraphics graphics, const std::string& name) : CommandBoundResource(graphics, name) {}
|
||||||
return;
|
|
||||||
}
|
DescriptorSetHandle::~DescriptorSetHandle() {
|
||||||
}
|
graphics->getDestructionManager()->queueResourceForDestruction(std::move(constantsBuffer));
|
||||||
if (nextAlloc != nullptr) {
|
|
||||||
nextAlloc->reset();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DescriptorSet::DescriptorSet(PGraphics graphics, PDescriptorPool owner)
|
DescriptorSet::DescriptorSet(PGraphics graphics, PDescriptorPool owner, PDescriptorSetHandle setHandle)
|
||||||
: Gfx::DescriptorSet(owner->getLayout()), CommandBoundResource(graphics, owner->getLayout()->getName()), setHandle(VK_NULL_HANDLE),
|
: Gfx::DescriptorSet(owner->getLayout()), setHandle(setHandle),
|
||||||
graphics(graphics), owner(owner) {
|
graphics(graphics), owner(owner) {
|
||||||
boundResources.resize(owner->getLayout()->getBindings().size());
|
boundResources.resize(owner->getLayout()->bindings.size());
|
||||||
for (uint32 i = 0; i < boundResources.size(); ++i) {
|
for (uint32 i = 0; i < boundResources.size(); ++i) {
|
||||||
boundResources[i].resize(owner->getLayout()->getBindings()[i].descriptorCount);
|
boundResources[i].resize(owner->getLayout()->bindings[i].descriptorCount);
|
||||||
for (size_t x = 0; x < boundResources[i].size(); ++x) {
|
for (size_t x = 0; x < boundResources[i].size(); ++x) {
|
||||||
boundResources[i][x] = nullptr;
|
boundResources[i][x] = nullptr;
|
||||||
}
|
}
|
||||||
@@ -209,7 +208,9 @@ DescriptorSet::DescriptorSet(PGraphics graphics, PDescriptorPool owner)
|
|||||||
constantData.resize(owner->getLayout()->constantsSize);
|
constantData.resize(owner->getLayout()->constantsSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
DescriptorSet::~DescriptorSet() { graphics->getDestructionManager()->queueResourceForDestruction(std::move(constantsBuffer)); }
|
DescriptorSet::~DescriptorSet() {
|
||||||
|
setHandle->isUsed = false;
|
||||||
|
}
|
||||||
|
|
||||||
void DescriptorSet::updateConstants(const std::string& mappingName, uint32 offset, void* data) {
|
void DescriptorSet::updateConstants(const std::string& mappingName, uint32 offset, void* data) {
|
||||||
std::memcpy(constantData.data() + owner->getLayout()->mappings[mappingName].constantOffset, (char*)data + offset,
|
std::memcpy(constantData.data() + owner->getLayout()->mappings[mappingName].constantOffset, (char*)data + offset,
|
||||||
@@ -232,7 +233,7 @@ void DescriptorSet::updateBuffer(const std::string& mappingName, uint32 index, G
|
|||||||
writeDescriptors.add(VkWriteDescriptorSet{
|
writeDescriptors.add(VkWriteDescriptorSet{
|
||||||
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||||
.pNext = nullptr,
|
.pNext = nullptr,
|
||||||
.dstSet = setHandle,
|
.dstSet = setHandle->getHandle(),
|
||||||
.dstBinding = binding,
|
.dstBinding = binding,
|
||||||
.dstArrayElement = index,
|
.dstArrayElement = index,
|
||||||
.descriptorCount = 1,
|
.descriptorCount = 1,
|
||||||
@@ -243,8 +244,8 @@ void DescriptorSet::updateBuffer(const std::string& mappingName, uint32 index, G
|
|||||||
boundResources[binding][index] = vulkanBuffer->getAlloc();
|
boundResources[binding][index] = vulkanBuffer->getAlloc();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DescriptorSet::updateBuffer(const std::string& mappingName, uint32 index, Gfx::PVertexBuffer indexBuffer) {
|
void DescriptorSet::updateBuffer(const std::string& mappingName, uint32 index, Gfx::PVertexBuffer vertexBuffer) {
|
||||||
PVertexBuffer vulkanBuffer = indexBuffer.cast<VertexBuffer>();
|
PVertexBuffer vulkanBuffer = vertexBuffer.cast<VertexBuffer>();
|
||||||
const auto& map = owner->getLayout()->mappings[mappingName];
|
const auto& map = owner->getLayout()->mappings[mappingName];
|
||||||
uint32 binding = map.binding;
|
uint32 binding = map.binding;
|
||||||
// if the buffer is empty
|
// if the buffer is empty
|
||||||
@@ -259,7 +260,7 @@ void DescriptorSet::updateBuffer(const std::string& mappingName, uint32 index, G
|
|||||||
writeDescriptors.add(VkWriteDescriptorSet{
|
writeDescriptors.add(VkWriteDescriptorSet{
|
||||||
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||||
.pNext = nullptr,
|
.pNext = nullptr,
|
||||||
.dstSet = setHandle,
|
.dstSet = setHandle->getHandle(),
|
||||||
.dstBinding = binding,
|
.dstBinding = binding,
|
||||||
.dstArrayElement = index,
|
.dstArrayElement = index,
|
||||||
.descriptorCount = 1,
|
.descriptorCount = 1,
|
||||||
@@ -286,7 +287,34 @@ void DescriptorSet::updateBuffer(const std::string& mappingName, uint32 index, G
|
|||||||
writeDescriptors.add(VkWriteDescriptorSet{
|
writeDescriptors.add(VkWriteDescriptorSet{
|
||||||
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||||
.pNext = nullptr,
|
.pNext = nullptr,
|
||||||
.dstSet = setHandle,
|
.dstSet = setHandle->getHandle(),
|
||||||
|
.dstBinding = binding,
|
||||||
|
.dstArrayElement = index,
|
||||||
|
.descriptorCount = 1,
|
||||||
|
.descriptorType = map.type,
|
||||||
|
.pBufferInfo = &bufferInfos.back(),
|
||||||
|
});
|
||||||
|
|
||||||
|
boundResources[binding][index] = vulkanBuffer->getAlloc();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DescriptorSet::updateBuffer(const std::string& mappingName, uint32 index, Gfx::PUniformBuffer uniformBuffer) {
|
||||||
|
PUniformBuffer vulkanBuffer = uniformBuffer.cast<UniformBuffer>();
|
||||||
|
const auto& map = owner->getLayout()->mappings[mappingName];
|
||||||
|
uint32 binding = map.binding;
|
||||||
|
// if the buffer is empty
|
||||||
|
if (vulkanBuffer->getAlloc() == nullptr)
|
||||||
|
return;
|
||||||
|
|
||||||
|
bufferInfos.add(VkDescriptorBufferInfo{
|
||||||
|
.buffer = vulkanBuffer->getHandle(),
|
||||||
|
.offset = 0,
|
||||||
|
.range = vulkanBuffer->getSize(),
|
||||||
|
});
|
||||||
|
writeDescriptors.add(VkWriteDescriptorSet{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||||
|
.pNext = nullptr,
|
||||||
|
.dstSet = setHandle->getHandle(),
|
||||||
.dstBinding = binding,
|
.dstBinding = binding,
|
||||||
.dstArrayElement = index,
|
.dstArrayElement = index,
|
||||||
.descriptorCount = 1,
|
.descriptorCount = 1,
|
||||||
@@ -314,7 +342,7 @@ void DescriptorSet::updateSampler(const std::string& mappingName, uint32 index,
|
|||||||
writeDescriptors.add(VkWriteDescriptorSet{
|
writeDescriptors.add(VkWriteDescriptorSet{
|
||||||
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||||
.pNext = nullptr,
|
.pNext = nullptr,
|
||||||
.dstSet = setHandle,
|
.dstSet = setHandle->getHandle(),
|
||||||
.dstBinding = binding,
|
.dstBinding = binding,
|
||||||
.dstArrayElement = index,
|
.dstArrayElement = index,
|
||||||
.descriptorCount = 1,
|
.descriptorCount = 1,
|
||||||
@@ -342,7 +370,7 @@ void DescriptorSet::updateTexture(const std::string& mappingName, uint32 index,
|
|||||||
writeDescriptors.add(VkWriteDescriptorSet{
|
writeDescriptors.add(VkWriteDescriptorSet{
|
||||||
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||||
.pNext = nullptr,
|
.pNext = nullptr,
|
||||||
.dstSet = setHandle,
|
.dstSet = setHandle->getHandle(),
|
||||||
.dstBinding = binding,
|
.dstBinding = binding,
|
||||||
.dstArrayElement = index,
|
.dstArrayElement = index,
|
||||||
.descriptorCount = 1,
|
.descriptorCount = 1,
|
||||||
@@ -365,7 +393,7 @@ void DescriptorSet::updateAccelerationStructure(const std::string& mappingName,
|
|||||||
writeDescriptors.add(VkWriteDescriptorSet{
|
writeDescriptors.add(VkWriteDescriptorSet{
|
||||||
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||||
.pNext = &accelerationInfos.back(),
|
.pNext = &accelerationInfos.back(),
|
||||||
.dstSet = setHandle,
|
.dstSet = setHandle->getHandle(),
|
||||||
.dstBinding = binding,
|
.dstBinding = binding,
|
||||||
.dstArrayElement = index,
|
.dstArrayElement = index,
|
||||||
.descriptorCount = 1,
|
.descriptorCount = 1,
|
||||||
@@ -375,10 +403,10 @@ void DescriptorSet::updateAccelerationStructure(const std::string& mappingName,
|
|||||||
|
|
||||||
void DescriptorSet::writeChanges() {
|
void DescriptorSet::writeChanges() {
|
||||||
if (constantData.size() > 0) {
|
if (constantData.size() > 0) {
|
||||||
if (constantsBuffer != nullptr) {
|
if (setHandle->constantsBuffer != nullptr) {
|
||||||
graphics->getDestructionManager()->queueResourceForDestruction(std::move(constantsBuffer));
|
graphics->getDestructionManager()->queueResourceForDestruction(std::move(setHandle->constantsBuffer));
|
||||||
}
|
}
|
||||||
constantsBuffer = new BufferAllocation(graphics, owner->getLayout()->getName(),
|
setHandle->constantsBuffer = new BufferAllocation(graphics, owner->getLayout()->getName(),
|
||||||
VkBufferCreateInfo{
|
VkBufferCreateInfo{
|
||||||
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
|
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
|
||||||
.pNext = nullptr,
|
.pNext = nullptr,
|
||||||
@@ -389,18 +417,18 @@ void DescriptorSet::writeChanges() {
|
|||||||
.usage = VMA_MEMORY_USAGE_AUTO,
|
.usage = VMA_MEMORY_USAGE_AUTO,
|
||||||
},
|
},
|
||||||
Gfx::QueueType::GRAPHICS);
|
Gfx::QueueType::GRAPHICS);
|
||||||
constantsBuffer->updateContents(0, constantData.size(), constantData.data());
|
setHandle->constantsBuffer->updateContents(0, constantData.size(), constantData.data());
|
||||||
constantsBuffer->pipelineBarrier(Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT,
|
setHandle->constantsBuffer->pipelineBarrier(Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT,
|
||||||
Gfx::SE_ACCESS_UNIFORM_READ_BIT, Gfx::SE_PIPELINE_STAGE_ALL_COMMANDS_BIT);
|
Gfx::SE_ACCESS_UNIFORM_READ_BIT, Gfx::SE_PIPELINE_STAGE_ALL_COMMANDS_BIT);
|
||||||
bufferInfos.add(VkDescriptorBufferInfo{
|
bufferInfos.add(VkDescriptorBufferInfo{
|
||||||
.buffer = constantsBuffer->buffer,
|
.buffer = setHandle->constantsBuffer->buffer,
|
||||||
.offset = 0,
|
.offset = 0,
|
||||||
.range = constantsBuffer->size,
|
.range = setHandle->constantsBuffer->size,
|
||||||
});
|
});
|
||||||
writeDescriptors.add(VkWriteDescriptorSet{
|
writeDescriptors.add(VkWriteDescriptorSet{
|
||||||
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||||
.pNext = nullptr,
|
.pNext = nullptr,
|
||||||
.dstSet = setHandle,
|
.dstSet = setHandle->getHandle(),
|
||||||
.dstBinding = 0,
|
.dstBinding = 0,
|
||||||
.dstArrayElement = 0,
|
.dstArrayElement = 0,
|
||||||
.descriptorCount = 1,
|
.descriptorCount = 1,
|
||||||
@@ -410,9 +438,9 @@ void DescriptorSet::writeChanges() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (writeDescriptors.size() > 0) {
|
if (writeDescriptors.size() > 0) {
|
||||||
if (isCurrentlyBound()) {
|
if (setHandle->isCurrentlyBound()) {
|
||||||
std::cout << "Descriptor currently bound, allocate a new one instead" << std::endl;
|
std::cout << "Descriptor currently bound, allocate a new one instead" << std::endl;
|
||||||
assert(!isCurrentlyBound());
|
assert(!setHandle->isCurrentlyBound());
|
||||||
}
|
}
|
||||||
vkUpdateDescriptorSets(graphics->getDevice(), (uint32)writeDescriptors.size(), writeDescriptors.data(), 0, nullptr);
|
vkUpdateDescriptorSets(graphics->getDevice(), (uint32)writeDescriptors.size(), writeDescriptors.data(), 0, nullptr);
|
||||||
writeDescriptors.clear();
|
writeDescriptors.clear();
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "Containers/List.h"
|
#include "Containers/List.h"
|
||||||
#include "Enums.h"
|
|
||||||
#include "Graphics/Descriptor.h"
|
#include "Graphics/Descriptor.h"
|
||||||
#include "Graphics/Vulkan/Buffer.h"
|
#include "Graphics/Vulkan/Buffer.h"
|
||||||
#include "Resources.h"
|
#include "Resources.h"
|
||||||
|
#include <vulkan/vulkan_core.h>
|
||||||
|
|
||||||
namespace Seele {
|
namespace Seele {
|
||||||
namespace Vulkan {
|
namespace Vulkan {
|
||||||
@@ -33,12 +33,24 @@ class DescriptorLayout : public Gfx::DescriptorLayout {
|
|||||||
};
|
};
|
||||||
DEFINE_REF(DescriptorLayout)
|
DEFINE_REF(DescriptorLayout)
|
||||||
|
|
||||||
|
class DescriptorSetHandle : public CommandBoundResource {
|
||||||
|
public:
|
||||||
|
DescriptorSetHandle(PGraphics graphics, const std::string& name);
|
||||||
|
virtual ~DescriptorSetHandle();
|
||||||
|
constexpr VkDescriptorSet getHandle() const { return handle; }
|
||||||
|
PGraphics graphics;
|
||||||
|
VkDescriptorSet handle = VK_NULL_HANDLE;
|
||||||
|
OBufferAllocation constantsBuffer;
|
||||||
|
bool isUsed = false;
|
||||||
|
};
|
||||||
|
DEFINE_REF(DescriptorSetHandle)
|
||||||
|
|
||||||
DECLARE_REF(DescriptorSet)
|
DECLARE_REF(DescriptorSet)
|
||||||
class DescriptorPool : public Gfx::DescriptorPool, public CommandBoundResource {
|
class DescriptorPool : public Gfx::DescriptorPool, public CommandBoundResource {
|
||||||
public:
|
public:
|
||||||
DescriptorPool(PGraphics graphics, PDescriptorLayout layout);
|
DescriptorPool(PGraphics graphics, PDescriptorLayout layout);
|
||||||
virtual ~DescriptorPool();
|
virtual ~DescriptorPool();
|
||||||
virtual Gfx::PDescriptorSet allocateDescriptorSet() override;
|
virtual Gfx::ODescriptorSet allocateDescriptorSet() override;
|
||||||
virtual void reset() override;
|
virtual void reset() override;
|
||||||
|
|
||||||
constexpr VkDescriptorPool getHandle() const { return poolHandle; }
|
constexpr VkDescriptorPool getHandle() const { return poolHandle; }
|
||||||
@@ -48,30 +60,29 @@ class DescriptorPool : public Gfx::DescriptorPool, public CommandBoundResource {
|
|||||||
PGraphics graphics;
|
PGraphics graphics;
|
||||||
PDescriptorLayout layout;
|
PDescriptorLayout layout;
|
||||||
const static int maxSets = 64;
|
const static int maxSets = 64;
|
||||||
StaticArray<ODescriptorSet, maxSets> cachedHandles;
|
StaticArray<ODescriptorSetHandle, maxSets> cachedHandles;
|
||||||
VkDescriptorPool poolHandle;
|
VkDescriptorPool poolHandle;
|
||||||
DescriptorPool* nextAlloc = nullptr;
|
DescriptorPool* nextAlloc = nullptr;
|
||||||
};
|
};
|
||||||
DEFINE_REF(DescriptorPool)
|
DEFINE_REF(DescriptorPool)
|
||||||
|
class DescriptorSet : public Gfx::DescriptorSet {
|
||||||
class DescriptorSet : public Gfx::DescriptorSet, public CommandBoundResource {
|
|
||||||
public:
|
public:
|
||||||
DescriptorSet(PGraphics graphics, PDescriptorPool owner);
|
DescriptorSet(PGraphics graphics, PDescriptorPool owner, PDescriptorSetHandle setHandle);
|
||||||
virtual ~DescriptorSet();
|
virtual ~DescriptorSet();
|
||||||
virtual void writeChanges() override;
|
virtual void writeChanges() override;
|
||||||
virtual void updateConstants(const std::string& name, uint32 offset, void* data) override;
|
virtual void updateConstants(const std::string& name, uint32 offset, void* data) override;
|
||||||
virtual void updateBuffer(const std::string& name, uint32 index, Gfx::PShaderBuffer shaderBuffer) override;
|
virtual void updateBuffer(const std::string& name, uint32 index, Gfx::PShaderBuffer shaderBuffer) override;
|
||||||
virtual void updateBuffer(const std::string& name, uint32 index, Gfx::PVertexBuffer indexBuffer) override;
|
virtual void updateBuffer(const std::string& name, uint32 index, Gfx::PVertexBuffer vertexBuffer) override;
|
||||||
virtual void updateBuffer(const std::string& name, uint32 index, Gfx::PIndexBuffer indexBuffer) override;
|
virtual void updateBuffer(const std::string& name, uint32 index, Gfx::PIndexBuffer indexBuffer) override;
|
||||||
|
virtual void updateBuffer(const std::string& name, uint32 index, Gfx::PUniformBuffer uniformBuffer) override;
|
||||||
virtual void updateSampler(const std::string& name, uint32 index, Gfx::PSampler samplerState) override;
|
virtual void updateSampler(const std::string& name, uint32 index, Gfx::PSampler samplerState) override;
|
||||||
virtual void updateTexture(const std::string& name, uint32 index, Gfx::PTextureView texture) override;
|
virtual void updateTexture(const std::string& name, uint32 index, Gfx::PTextureView texture) override;
|
||||||
virtual void updateAccelerationStructure(const std::string& name, uint32 index, Gfx::PTopLevelAS as) override;
|
virtual void updateAccelerationStructure(const std::string& name, uint32 index, Gfx::PTopLevelAS as) override;
|
||||||
|
|
||||||
constexpr VkDescriptorSet getHandle() const { return setHandle; }
|
constexpr VkDescriptorSet getHandle() const { return setHandle->getHandle(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<uint8> constantData;
|
std::vector<uint8> constantData;
|
||||||
OBufferAllocation constantsBuffer;
|
|
||||||
List<VkDescriptorImageInfo> imageInfos;
|
List<VkDescriptorImageInfo> imageInfos;
|
||||||
List<VkDescriptorBufferInfo> bufferInfos;
|
List<VkDescriptorBufferInfo> bufferInfos;
|
||||||
List<VkWriteDescriptorSetAccelerationStructureKHR> accelerationInfos;
|
List<VkWriteDescriptorSetAccelerationStructureKHR> accelerationInfos;
|
||||||
@@ -81,7 +92,7 @@ class DescriptorSet : public Gfx::DescriptorSet, public CommandBoundResource {
|
|||||||
// would not work anyways, so casts should be safe
|
// would not work anyways, so casts should be safe
|
||||||
// Array<void*> cachedData;
|
// Array<void*> cachedData;
|
||||||
Array<Array<PCommandBoundResource>> boundResources;
|
Array<Array<PCommandBoundResource>> boundResources;
|
||||||
VkDescriptorSet setHandle;
|
PDescriptorSetHandle setHandle;
|
||||||
PGraphics graphics;
|
PGraphics graphics;
|
||||||
PDescriptorPool owner;
|
PDescriptorPool owner;
|
||||||
friend class DescriptorPool;
|
friend class DescriptorPool;
|
||||||
|
|||||||
@@ -186,7 +186,7 @@ void Graphics::beginRenderPass(Gfx::PRenderPass renderPass) {
|
|||||||
allocatedFramebuffers[framebufferHash] = new Framebuffer(this, rp, rp->getLayout());
|
allocatedFramebuffers[framebufferHash] = new Framebuffer(this, rp, rp->getLayout());
|
||||||
framebuffer = allocatedFramebuffers[framebufferHash];
|
framebuffer = allocatedFramebuffers[framebufferHash];
|
||||||
} else {
|
} else {
|
||||||
framebuffer = std::move(found->value);
|
framebuffer = found->value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
getGraphicsCommands()->getCommands()->beginRenderPass(rp, framebuffer);
|
getGraphicsCommands()->getCommands()->beginRenderPass(rp, framebuffer);
|
||||||
@@ -222,6 +222,8 @@ void Graphics::executeCommands(Array<Gfx::OComputeCommand> commands) {
|
|||||||
|
|
||||||
Gfx::OTexture2D Graphics::createTexture2D(const TextureCreateInfo& createInfo) { return new Texture2D(this, createInfo); }
|
Gfx::OTexture2D Graphics::createTexture2D(const TextureCreateInfo& createInfo) { return new Texture2D(this, createInfo); }
|
||||||
|
|
||||||
|
Gfx::OTexture2DArray Graphics::createTexture2DArray(const TextureCreateInfo& createInfo) { return new Texture2DArray(this, createInfo); }
|
||||||
|
|
||||||
Gfx::OTexture3D Graphics::createTexture3D(const TextureCreateInfo& createInfo) { return new Texture3D(this, createInfo); }
|
Gfx::OTexture3D Graphics::createTexture3D(const TextureCreateInfo& createInfo) { return new Texture3D(this, createInfo); }
|
||||||
|
|
||||||
Gfx::OTextureCube Graphics::createTextureCube(const TextureCreateInfo& createInfo) { return new TextureCube(this, createInfo); }
|
Gfx::OTextureCube Graphics::createTextureCube(const TextureCreateInfo& createInfo) { return new TextureCube(this, createInfo); }
|
||||||
@@ -817,7 +819,7 @@ void Graphics::pickPhysicalDevice() {
|
|||||||
shaderFloatControls = true;
|
shaderFloatControls = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rayTracingEnabled = rayTracingPipelineSupport && accelerationStructureSupport && hostOperationsSupport && deviceAddressSupport &&
|
rayTracingEnabled = false && rayTracingPipelineSupport && accelerationStructureSupport && hostOperationsSupport && deviceAddressSupport &&
|
||||||
descriptorIndexingSupport && spirv14Support && shaderFloatControls;
|
descriptorIndexingSupport && spirv14Support && shaderFloatControls;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -113,6 +113,7 @@ class Graphics : public Gfx::Graphics {
|
|||||||
virtual void executeCommands(Array<Gfx::OComputeCommand> commands) override;
|
virtual void executeCommands(Array<Gfx::OComputeCommand> commands) override;
|
||||||
|
|
||||||
virtual Gfx::OTexture2D createTexture2D(const TextureCreateInfo& createInfo) override;
|
virtual Gfx::OTexture2D createTexture2D(const TextureCreateInfo& createInfo) override;
|
||||||
|
virtual Gfx::OTexture2DArray createTexture2DArray(const TextureCreateInfo& createInfo) override;
|
||||||
virtual Gfx::OTexture3D createTexture3D(const TextureCreateInfo& createInfo) override;
|
virtual Gfx::OTexture3D createTexture3D(const TextureCreateInfo& createInfo) override;
|
||||||
virtual Gfx::OTextureCube createTextureCube(const TextureCreateInfo& createInfo) override;
|
virtual Gfx::OTextureCube createTextureCube(const TextureCreateInfo& createInfo) override;
|
||||||
virtual Gfx::OUniformBuffer createUniformBuffer(const UniformBufferCreateInfo& bulkData) override;
|
virtual Gfx::OUniformBuffer createUniformBuffer(const UniformBufferCreateInfo& bulkData) override;
|
||||||
|
|||||||
@@ -444,18 +444,21 @@ void TextureBase::pipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags
|
|||||||
handle->pipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
|
handle->pipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
|
||||||
}
|
}
|
||||||
void TextureBase::transferOwnership(Gfx::QueueType newOwner) { handle->transferOwnership(newOwner); }
|
void TextureBase::transferOwnership(Gfx::QueueType newOwner) { handle->transferOwnership(newOwner); }
|
||||||
|
|
||||||
void TextureBase::changeLayout(Gfx::SeImageLayout newLayout, VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
|
void TextureBase::changeLayout(Gfx::SeImageLayout newLayout, VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
|
||||||
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage) {
|
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage) {
|
||||||
handle->changeLayout(newLayout, srcAccess, srcStage, dstAccess, dstStage);
|
handle->changeLayout(newLayout, srcAccess, srcStage, dstAccess, dstStage);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureBase::download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer) {
|
void TextureBase::download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer) {
|
||||||
handle->download(mipLevel, arrayLayer, face, buffer);
|
handle->download(mipLevel, arrayLayer, face, buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureBase::generateMipmaps() { handle->generateMipmaps(); }
|
void TextureBase::generateMipmaps() { handle->generateMipmaps(); }
|
||||||
|
|
||||||
Texture2D::Texture2D(PGraphics graphics, const TextureCreateInfo& createInfo, VkImage existingImage)
|
Texture2D::Texture2D(PGraphics graphics, const TextureCreateInfo& createInfo, VkImage existingImage)
|
||||||
: Gfx::Texture2D(graphics->getFamilyMapping()),
|
: Gfx::Texture2D(graphics->getFamilyMapping()),
|
||||||
TextureBase(graphics, createInfo.elements > 1 ? VK_IMAGE_VIEW_TYPE_2D_ARRAY : VK_IMAGE_VIEW_TYPE_2D, createInfo, existingImage) {}
|
TextureBase(graphics, VK_IMAGE_VIEW_TYPE_2D, createInfo, existingImage) {}
|
||||||
|
|
||||||
Texture2D::~Texture2D() {}
|
Texture2D::~Texture2D() {}
|
||||||
|
|
||||||
@@ -483,6 +486,36 @@ void Texture2D::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageF
|
|||||||
TextureBase::pipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
|
TextureBase::pipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Texture2DArray::Texture2DArray(PGraphics graphics, const TextureCreateInfo& createInfo, VkImage existingImage)
|
||||||
|
: Gfx::Texture2DArray(graphics->getFamilyMapping()),
|
||||||
|
TextureBase(graphics, VK_IMAGE_VIEW_TYPE_2D_ARRAY, createInfo, existingImage) {}
|
||||||
|
|
||||||
|
Texture2DArray::~Texture2DArray() {}
|
||||||
|
|
||||||
|
void Texture2DArray::changeLayout(Gfx::SeImageLayout newLayout, Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage,
|
||||||
|
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) {
|
||||||
|
TextureBase::changeLayout(newLayout, srcAccess, srcStage, dstAccess, dstStage);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Texture2DArray::download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer) {
|
||||||
|
TextureBase::download(mipLevel, arrayLayer, face, buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Texture2DArray::generateMipmaps() { TextureBase::generateMipmaps(); }
|
||||||
|
|
||||||
|
Gfx::PTextureView Texture2DArray::getDefaultView() const { return PTextureView(handle->imageView); }
|
||||||
|
|
||||||
|
Gfx::OTextureView Texture2DArray::createTextureView(uint32 baseMipLevel, uint32 levelCount, uint32 baseArrayLayer, uint32 layerCount) {
|
||||||
|
return handle->createTextureView(baseMipLevel, levelCount, baseArrayLayer, layerCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Texture2DArray::executeOwnershipBarrier(Gfx::QueueType newOwner) { TextureBase::transferOwnership(newOwner); }
|
||||||
|
|
||||||
|
void Texture2DArray::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, VkAccessFlags dstAccess,
|
||||||
|
VkPipelineStageFlags dstStage) {
|
||||||
|
TextureBase::pipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
|
||||||
|
}
|
||||||
|
|
||||||
Texture3D::Texture3D(PGraphics graphics, const TextureCreateInfo& createInfo, VkImage existingImage)
|
Texture3D::Texture3D(PGraphics graphics, const TextureCreateInfo& createInfo, VkImage existingImage)
|
||||||
: Gfx::Texture3D(graphics->getFamilyMapping()), TextureBase(graphics, VK_IMAGE_VIEW_TYPE_3D, createInfo, existingImage) {}
|
: Gfx::Texture3D(graphics->getFamilyMapping()), TextureBase(graphics, VK_IMAGE_VIEW_TYPE_3D, createInfo, existingImage) {}
|
||||||
|
|
||||||
|
|||||||
@@ -135,6 +135,32 @@ class Texture2D : public Gfx::Texture2D, public TextureBase {
|
|||||||
};
|
};
|
||||||
DEFINE_REF(Texture2D)
|
DEFINE_REF(Texture2D)
|
||||||
|
|
||||||
|
class Texture2DArray : public Gfx::Texture2DArray, public TextureBase {
|
||||||
|
public:
|
||||||
|
Texture2DArray(PGraphics graphics, const TextureCreateInfo& createInfo, VkImage existingImage = VK_NULL_HANDLE);
|
||||||
|
virtual ~Texture2DArray();
|
||||||
|
virtual uint32 getWidth() const override { return handle->width; }
|
||||||
|
virtual uint32 getHeight() const override { return handle->height; }
|
||||||
|
virtual uint32 getDepth() const override { return handle->depth; }
|
||||||
|
virtual uint32 getNumLayers() const override { return handle->layerCount; }
|
||||||
|
virtual Gfx::SeFormat getFormat() const override { return handle->format; }
|
||||||
|
virtual Gfx::SeSampleCountFlags getNumSamples() const override { return handle->samples; }
|
||||||
|
virtual uint32 getMipLevels() const override { return handle->mipLevels; }
|
||||||
|
virtual void changeLayout(Gfx::SeImageLayout newLayout, Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage,
|
||||||
|
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) override;
|
||||||
|
virtual void download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer) override;
|
||||||
|
virtual void generateMipmaps() override;
|
||||||
|
virtual Gfx::PTextureView getDefaultView() const override;
|
||||||
|
virtual Gfx::OTextureView createTextureView(uint32 baseMipLevel, uint32 levelCount, uint32 baseArrayLayer, uint32 layerCount) override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// Inherited via QueueOwnedResource
|
||||||
|
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner) override;
|
||||||
|
virtual void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, VkAccessFlags dstAccess,
|
||||||
|
VkPipelineStageFlags dstStage) override;
|
||||||
|
};
|
||||||
|
DEFINE_REF(Texture2DArray)
|
||||||
|
|
||||||
class Texture3D : public Gfx::Texture3D, public TextureBase {
|
class Texture3D : public Gfx::Texture3D, public TextureBase {
|
||||||
public:
|
public:
|
||||||
Texture3D(PGraphics graphics, const TextureCreateInfo& createInfo, VkImage existingImage = VK_NULL_HANDLE);
|
Texture3D(PGraphics graphics, const TextureCreateInfo& createInfo, VkImage existingImage = VK_NULL_HANDLE);
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#include "Window.h"
|
#include "Window.h"
|
||||||
|
#include "Math/Matrix.h"
|
||||||
|
|
||||||
using namespace Seele;
|
using namespace Seele;
|
||||||
using namespace Seele::Gfx;
|
using namespace Seele::Gfx;
|
||||||
@@ -20,37 +21,9 @@ Viewport::Viewport(PWindow owner, const ViewportCreateInfo& viewportInfo)
|
|||||||
Viewport::~Viewport() {}
|
Viewport::~Viewport() {}
|
||||||
|
|
||||||
Matrix4 Viewport::getProjectionMatrix(float nearPlane, float farPlane) const {
|
Matrix4 Viewport::getProjectionMatrix(float nearPlane, float farPlane) const {
|
||||||
Matrix4 correctionMatrix = Matrix4(1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1 / 2.f, 0, 0, 0, 1 / 2.f, 1);
|
|
||||||
if (fieldOfView > 0.0f) {
|
if (fieldOfView > 0.0f) {
|
||||||
const float aspect = static_cast<float>(sizeX) / sizeY;
|
return perspectiveProjection(fieldOfView, static_cast<float>(sizeX) / sizeY, nearPlane, farPlane);
|
||||||
const float e = 1.0f / std::tan(fieldOfView * 0.5f);
|
|
||||||
return {
|
|
||||||
{
|
|
||||||
e / aspect,
|
|
||||||
0.0f,
|
|
||||||
0.0f,
|
|
||||||
0.0f,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
0.0f,
|
|
||||||
-e,
|
|
||||||
0.0f,
|
|
||||||
0.0f,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
0.0f,
|
|
||||||
0.0f,
|
|
||||||
0.5f * (farPlane + nearPlane) / (nearPlane - farPlane),
|
|
||||||
-1.0f,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
0.0f,
|
|
||||||
0.0f,
|
|
||||||
(farPlane * nearPlane) / (nearPlane - farPlane),
|
|
||||||
0.0f,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
} else {
|
} else {
|
||||||
return correctionMatrix * glm::ortho(orthoLeft, orthoRight, orthoBottom, orthoTop, nearPlane, farPlane);
|
return orthographicProjection(orthoLeft, orthoRight, orthoBottom, orthoTop, nearPlane, farPlane);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -152,7 +152,7 @@ void Seele::beginCompilation(const ShaderCompilationInfo& info, SlangCompileTarg
|
|||||||
layout->addMapping("pResources", 4);
|
layout->addMapping("pResources", 4);
|
||||||
layout->addMapping("pRayTracingParams", 5);
|
layout->addMapping("pRayTracingParams", 5);
|
||||||
}
|
}
|
||||||
layout->addMapping("pVertexData", 1);
|
//layout->addMapping("pVertexData", 1);
|
||||||
// layout->addMapping("pWaterMaterial", 1);
|
// layout->addMapping("pWaterMaterial", 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ Array<Gfx::PSampler> Material::samplers;
|
|||||||
Gfx::OShaderBuffer Material::floatBuffer;
|
Gfx::OShaderBuffer Material::floatBuffer;
|
||||||
Array<float> Material::floatData;
|
Array<float> Material::floatData;
|
||||||
Gfx::ODescriptorLayout Material::layout;
|
Gfx::ODescriptorLayout Material::layout;
|
||||||
Gfx::PDescriptorSet Material::set;
|
Gfx::ODescriptorSet Material::set;
|
||||||
std::atomic_uint64_t Material::materialIdCounter = 0;
|
std::atomic_uint64_t Material::materialIdCounter = 0;
|
||||||
Array<PMaterial> Material::materials;
|
Array<PMaterial> Material::materials;
|
||||||
|
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ class Material {
|
|||||||
static Gfx::OShaderBuffer floatBuffer;
|
static Gfx::OShaderBuffer floatBuffer;
|
||||||
static Array<float> floatData;
|
static Array<float> floatData;
|
||||||
static Gfx::ODescriptorLayout layout;
|
static Gfx::ODescriptorLayout layout;
|
||||||
static Gfx::PDescriptorSet set;
|
static Gfx::ODescriptorSet set;
|
||||||
static std::atomic_uint64_t materialIdCounter;
|
static std::atomic_uint64_t materialIdCounter;
|
||||||
static Array<PMaterial> materials;
|
static Array<PMaterial> materials;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <glm/mat2x2.hpp>
|
#include <glm/mat2x2.hpp>
|
||||||
#include <glm/mat3x3.hpp>
|
#include <glm/mat3x3.hpp>
|
||||||
#include <glm/mat4x4.hpp>
|
#include <glm/mat4x4.hpp>
|
||||||
@@ -7,4 +6,62 @@ namespace Seele {
|
|||||||
typedef glm::mat2 Matrix2;
|
typedef glm::mat2 Matrix2;
|
||||||
typedef glm::mat3 Matrix3;
|
typedef glm::mat3 Matrix3;
|
||||||
typedef glm::mat4 Matrix4;
|
typedef glm::mat4 Matrix4;
|
||||||
|
|
||||||
|
static Matrix4 perspectiveProjection(float fov, float aspect, float nearPlane, float farPlane) {
|
||||||
|
const float e = 1.0f / std::tan(fov * 0.5f);
|
||||||
|
return {
|
||||||
|
{
|
||||||
|
e / aspect,
|
||||||
|
0.0f,
|
||||||
|
0.0f,
|
||||||
|
0.0f,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
0.0f,
|
||||||
|
-e,
|
||||||
|
0.0f,
|
||||||
|
0.0f,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
0.0f,
|
||||||
|
0.0f,
|
||||||
|
(nearPlane + farPlane) / (nearPlane - farPlane),
|
||||||
|
-1.0f,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
0.0f,
|
||||||
|
0.0f,
|
||||||
|
(farPlane * nearPlane) / (nearPlane - farPlane),
|
||||||
|
0.0f,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
static Matrix4 orthographicProjection(float left, float right, float bottom, float top, float nearPlane, float farPlane) {
|
||||||
|
return Matrix4{
|
||||||
|
{
|
||||||
|
2.0f / (right - left),
|
||||||
|
0.0f,
|
||||||
|
0.0f,
|
||||||
|
0.0f,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
0.0f,
|
||||||
|
2.0f / (top - bottom),
|
||||||
|
0.0f,
|
||||||
|
0.0f,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
0.0f,
|
||||||
|
0.0f,
|
||||||
|
-2.0f / (nearPlane - farPlane),
|
||||||
|
0.0f,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
-(right + left) / (right - left),
|
||||||
|
-(top + bottom) / (top - bottom),
|
||||||
|
-(nearPlane + farPlane) / (nearPlane - farPlane),
|
||||||
|
1.0f,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
} // namespace Seele
|
} // namespace Seele
|
||||||
@@ -5,7 +5,6 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
|
|
||||||
#define DEFINE_REF(x) \
|
#define DEFINE_REF(x) \
|
||||||
typedef ::Seele::RefPtr<x> P##x; \
|
typedef ::Seele::RefPtr<x> P##x; \
|
||||||
typedef ::Seele::UniquePtr<x> UP##x; \
|
typedef ::Seele::UniquePtr<x> UP##x; \
|
||||||
@@ -26,10 +25,12 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
namespace Seele {
|
namespace Seele {
|
||||||
|
template <typename T> class OwningPtr;
|
||||||
template <typename T> class RefPtr {
|
template <typename T> class RefPtr {
|
||||||
public:
|
public:
|
||||||
constexpr RefPtr() noexcept : object(nullptr) {}
|
constexpr RefPtr() noexcept : object(nullptr) {}
|
||||||
constexpr RefPtr(std::nullptr_t) noexcept : object(nullptr) {}
|
constexpr RefPtr(std::nullptr_t) noexcept : object(nullptr) {}
|
||||||
|
constexpr RefPtr(OwningPtr<T>&&) = delete;
|
||||||
RefPtr(T* ptr) : object(ptr) {}
|
RefPtr(T* ptr) : object(ptr) {}
|
||||||
constexpr RefPtr(const RefPtr& other) noexcept : object(other.object) {}
|
constexpr RefPtr(const RefPtr& other) noexcept : object(other.object) {}
|
||||||
constexpr RefPtr(RefPtr&& rhs) noexcept : object(std::move(rhs.object)) { rhs.object = nullptr; }
|
constexpr RefPtr(RefPtr&& rhs) noexcept : object(std::move(rhs.object)) { rhs.object = nullptr; }
|
||||||
@@ -49,6 +50,7 @@ template <typename T> class RefPtr {
|
|||||||
}
|
}
|
||||||
return RefPtr<F>(f);
|
return RefPtr<F>(f);
|
||||||
}
|
}
|
||||||
|
constexpr RefPtr& operator=(OwningPtr<T>&&) = delete;
|
||||||
constexpr RefPtr& operator=(const RefPtr& other) {
|
constexpr RefPtr& operator=(const RefPtr& other) {
|
||||||
if (this != &other) {
|
if (this != &other) {
|
||||||
object = other.object;
|
object = other.object;
|
||||||
@@ -62,6 +64,10 @@ template <typename T> class RefPtr {
|
|||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
constexpr RefPtr& operator=(std::nullptr_t) noexcept {
|
||||||
|
object = nullptr;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
constexpr ~RefPtr() {}
|
constexpr ~RefPtr() {}
|
||||||
constexpr bool operator==(const RefPtr& rhs) const noexcept { return object == rhs.object; }
|
constexpr bool operator==(const RefPtr& rhs) const noexcept { return object == rhs.object; }
|
||||||
constexpr auto operator<=>(const RefPtr& rhs) const noexcept { return object <=> rhs.object; }
|
constexpr auto operator<=>(const RefPtr& rhs) const noexcept { return object <=> rhs.object; }
|
||||||
@@ -77,7 +83,7 @@ template <typename T> class RefPtr {
|
|||||||
private:
|
private:
|
||||||
T* object;
|
T* object;
|
||||||
};
|
};
|
||||||
template <typename T, typename Deleter = std::default_delete<T>> class OwningPtr {
|
template <typename T> class OwningPtr {
|
||||||
public:
|
public:
|
||||||
OwningPtr() : pointer(nullptr) {}
|
OwningPtr() : pointer(nullptr) {}
|
||||||
OwningPtr(T* ptr) : pointer(ptr) {}
|
OwningPtr(T* ptr) : pointer(ptr) {}
|
||||||
@@ -94,14 +100,18 @@ template <typename T, typename Deleter = std::default_delete<T>> class OwningPtr
|
|||||||
OwningPtr& operator=(OwningPtr&& other) noexcept {
|
OwningPtr& operator=(OwningPtr&& other) noexcept {
|
||||||
if (this != &other) {
|
if (this != &other) {
|
||||||
if (pointer != nullptr) {
|
if (pointer != nullptr) {
|
||||||
Deleter()(pointer);
|
std::default_delete<T> d;
|
||||||
|
d(pointer);
|
||||||
}
|
}
|
||||||
pointer = other.pointer;
|
pointer = other.pointer;
|
||||||
other.pointer = nullptr;
|
other.pointer = nullptr;
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
~OwningPtr() { Deleter()(pointer); }
|
~OwningPtr() {
|
||||||
|
std::default_delete<T> d;
|
||||||
|
d(pointer);
|
||||||
|
}
|
||||||
constexpr operator RefPtr<T>() { return RefPtr<T>(pointer); }
|
constexpr operator RefPtr<T>() { return RefPtr<T>(pointer); }
|
||||||
constexpr operator RefPtr<T>() const { return RefPtr<T>(pointer); }
|
constexpr operator RefPtr<T>() const { return RefPtr<T>(pointer); }
|
||||||
constexpr T* operator->() { return pointer; }
|
constexpr T* operator->() { return pointer; }
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ void GameInterface::reload() {
|
|||||||
destroyInstance(game);
|
destroyInstance(game);
|
||||||
dlclose(lib);
|
dlclose(lib);
|
||||||
}
|
}
|
||||||
std::filesystem::copy(soPath.parent_path().parent_path() / "res" / "shaders", "shaders/game", std::filesystem::copy_options::overwrite_existing);
|
//std::filesystem::copy(soPath.parent_path().parent_path() / "res" / "shaders", "shaders/game", std::filesystem::copy_options::overwrite_existing);
|
||||||
lib = dlopen(soPath.c_str(), RTLD_NOW);
|
lib = dlopen(soPath.c_str(), RTLD_NOW);
|
||||||
createInstance = (decltype(createInstance))dlsym(lib, "createInstance");
|
createInstance = (decltype(createInstance))dlsym(lib, "createInstance");
|
||||||
destroyInstance = (decltype(destroyInstance))dlsym(lib, "destroyInstance");
|
destroyInstance = (decltype(destroyInstance))dlsym(lib, "destroyInstance");
|
||||||
|
|||||||
@@ -14,14 +14,6 @@ LightEnvironment::LightEnvironment(Gfx::PGraphics graphics)
|
|||||||
.name = "directionalLights",
|
.name = "directionalLights",
|
||||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||||
});
|
});
|
||||||
layout->addDescriptorBinding(Gfx::DescriptorBinding{
|
|
||||||
.name = "shadowMap",
|
|
||||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
|
||||||
});
|
|
||||||
layout->addDescriptorBinding(Gfx::DescriptorBinding{
|
|
||||||
.name = "shadowSampler",
|
|
||||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLER,
|
|
||||||
});
|
|
||||||
layout->addDescriptorBinding(Gfx::DescriptorBinding{
|
layout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||||
.name = "numDirectionalLights",
|
.name = "numDirectionalLights",
|
||||||
.uniformLength = sizeof(uint32),
|
.uniformLength = sizeof(uint32),
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ class LightEnvironment {
|
|||||||
PEnvironmentMapAsset environment;
|
PEnvironmentMapAsset environment;
|
||||||
Gfx::OSampler environmentSampler;
|
Gfx::OSampler environmentSampler;
|
||||||
Gfx::ODescriptorLayout layout;
|
Gfx::ODescriptorLayout layout;
|
||||||
Gfx::PDescriptorSet set;
|
Gfx::ODescriptorSet set;
|
||||||
};
|
};
|
||||||
DEFINE_REF(LightEnvironment)
|
DEFINE_REF(LightEnvironment)
|
||||||
} // namespace Seele
|
} // namespace Seele
|
||||||
@@ -1,15 +1,11 @@
|
|||||||
#include "GameView.h"
|
#include "GameView.h"
|
||||||
#include "Actor/CameraActor.h"
|
|
||||||
#include "Asset/AssetRegistry.h"
|
#include "Asset/AssetRegistry.h"
|
||||||
#include "Component/KeyboardInput.h"
|
|
||||||
#include "Graphics/Graphics.h"
|
#include "Graphics/Graphics.h"
|
||||||
#include "Graphics/Query.h"
|
|
||||||
#include "Graphics/RenderPass/BasePass.h"
|
#include "Graphics/RenderPass/BasePass.h"
|
||||||
#include "Graphics/RenderPass/CachedDepthPass.h"
|
#include "Graphics/RenderPass/CachedDepthPass.h"
|
||||||
#include "Graphics/RenderPass/DepthCullingPass.h"
|
#include "Graphics/RenderPass/DepthCullingPass.h"
|
||||||
#include "Graphics/RenderPass/LightCullingPass.h"
|
#include "Graphics/RenderPass/LightCullingPass.h"
|
||||||
#include "Graphics/RenderPass/RayTracingPass.h"
|
#include "Graphics/RenderPass/RayTracingPass.h"
|
||||||
#include "Graphics/RenderPass/RenderGraphResources.h"
|
|
||||||
#include "Graphics/RenderPass/ToneMappingPass.h"
|
#include "Graphics/RenderPass/ToneMappingPass.h"
|
||||||
#include "Graphics/RenderPass/VisibilityPass.h"
|
#include "Graphics/RenderPass/VisibilityPass.h"
|
||||||
#include "Graphics/RenderPass/ShadowPass.h"
|
#include "Graphics/RenderPass/ShadowPass.h"
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ class GameView : public View {
|
|||||||
RenderGraph renderGraph;
|
RenderGraph renderGraph;
|
||||||
RenderGraph rayTracingGraph;
|
RenderGraph rayTracingGraph;
|
||||||
|
|
||||||
PSystemGraph systemGraph;
|
OSystemGraph systemGraph;
|
||||||
System::PKeyboardInput keyboardSystem;
|
System::PKeyboardInput keyboardSystem;
|
||||||
float updateTime = 0;
|
float updateTime = 0;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user