Adding cached depth renderpass
This commit is contained in:
Vendored
+13
-1
@@ -6,12 +6,24 @@
|
|||||||
"configurations": [
|
"configurations": [
|
||||||
{
|
{
|
||||||
"name": "Editor",
|
"name": "Editor",
|
||||||
"type": "lldb",
|
"type": "cppvsdbg",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "${workspaceRoot}/build/Editor.exe",
|
"program": "${workspaceRoot}/build/Editor.exe",
|
||||||
"args": [],
|
"args": [],
|
||||||
"cwd": "${workspaceRoot}/build",
|
"cwd": "${workspaceRoot}/build",
|
||||||
"console": "internalConsole",
|
"console": "internalConsole",
|
||||||
|
"setupCommands": [
|
||||||
|
{
|
||||||
|
"description": "Enable pretty-printing for gdb",
|
||||||
|
"text": "-enable-pretty-printing",
|
||||||
|
"ignoreFailures": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Set Disassembly Flavor to Intel",
|
||||||
|
"text": "-gdb-set disassembly-flavor intel",
|
||||||
|
"ignoreFailures": true
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Editor (Mac)",
|
"name": "Editor (Mac)",
|
||||||
|
|||||||
@@ -22,6 +22,11 @@
|
|||||||
"short": "RelWithDebInfo",
|
"short": "RelWithDebInfo",
|
||||||
"long": "Release with debug symbols",
|
"long": "Release with debug symbols",
|
||||||
"buildType": "RelWithDebInfo"
|
"buildType": "RelWithDebInfo"
|
||||||
|
},
|
||||||
|
"minsizerel": {
|
||||||
|
"short": "MinSizeRel",
|
||||||
|
"long": "Minimal size Release",
|
||||||
|
"buildType": "MinSizeRel"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -3,47 +3,29 @@ import Scene;
|
|||||||
|
|
||||||
groupshared MeshPayload p;
|
groupshared MeshPayload p;
|
||||||
groupshared uint head;
|
groupshared uint head;
|
||||||
groupshared Frustum viewFrustum;
|
|
||||||
|
|
||||||
[numthreads(TASK_GROUP_SIZE, 1, 1)]
|
[numthreads(TASK_GROUP_SIZE, 1, 1)]
|
||||||
[outputtopology("triangle")]
|
|
||||||
[shader("amplification")]
|
[shader("amplification")]
|
||||||
void taskMain(
|
void taskMain(
|
||||||
uint threadID: SV_GroupIndex,
|
uint threadID: SV_GroupIndex,
|
||||||
uint groupID: SV_GroupID
|
uint groupID: SV_GroupID,
|
||||||
){
|
){
|
||||||
InstanceData instance = pScene.instances[pOffsets.instanceOffset + groupID];
|
InstanceData instance = pScene.instances[pOffsets.instanceOffset + groupID];
|
||||||
MeshData mesh = pScene.meshData[pOffsets.instanceOffset + groupID];
|
MeshData mesh = pScene.meshData[pOffsets.instanceOffset + groupID];
|
||||||
if(threadID == 0)
|
//head = 0;
|
||||||
{
|
//GroupMemoryBarrierWithGroupSync();
|
||||||
head = 0;
|
//for(uint i = threadID; i < mesh.numMeshlets; i += TASK_GROUP_SIZE)
|
||||||
float3 origin = viewToModel(instance.inverseTransformMatrix, float4(0, 0, 0, 1)).xyz;
|
//{
|
||||||
const float offset = 0.0f;
|
// uint m = mesh.meshletOffset + i;
|
||||||
float3 corners[4] = {
|
// MeshletDescription meshlet = pScene.meshletInfos[m];
|
||||||
screenToModel(instance.inverseTransformMatrix, float4(offset, offset, -1.0f, 1.0f)).xyz,
|
// MeshletCullingInfo culling = pScene.culledMeshlets[instance.meshletCullingOffset];
|
||||||
screenToModel(instance.inverseTransformMatrix, float4(pViewParams.screenDimensions.x - offset, offset, -1.0f, 1.0f)).xyz,
|
// if(culling.anyVisible())
|
||||||
screenToModel(instance.inverseTransformMatrix, float4(offset, pViewParams.screenDimensions.y - offset, -1.0f, 1.0f)).xyz,
|
// {
|
||||||
screenToModel(instance.inverseTransformMatrix, float4(pViewParams.screenDimensions - float2(offset, offset), -1.0f, 1.0f)).xyz
|
// uint index;
|
||||||
};
|
// InterlockedAdd(head, 1, index);
|
||||||
viewFrustum.sides[0] = computePlane(origin, corners[2], corners[0]);
|
// p.culledMeshlets[index] = m;
|
||||||
viewFrustum.sides[1] = computePlane(origin, corners[1], corners[3]);
|
// }
|
||||||
viewFrustum.sides[2] = computePlane(origin, corners[0], corners[1]);
|
//}
|
||||||
viewFrustum.sides[3] = computePlane(origin, corners[3], corners[2]);
|
//GroupMemoryBarrierWithGroupSync();
|
||||||
p.instanceId = pOffsets.instanceOffset + groupID;
|
//DispatchMesh(head, 1, 1, p);
|
||||||
p.cullingOffset = pScene.cullingOffsets[pOffsets.cullingCounterOffset + groupID];
|
|
||||||
}
|
|
||||||
GroupMemoryBarrierWithGroupSync();
|
|
||||||
for(uint i = threadID; i < mesh.numMeshlets; i += TASK_GROUP_SIZE)
|
|
||||||
{
|
|
||||||
uint m = mesh.meshletOffset + i;
|
|
||||||
MeshletDescription meshlet = pScene.meshletInfos[m];
|
|
||||||
if(meshlet.bounding.insideFrustum(viewFrustum))
|
|
||||||
{
|
|
||||||
uint index;
|
|
||||||
InterlockedAdd(head, 1, index);
|
|
||||||
pScene.culledMeshlets[p.cullingOffset + index] = m;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
GroupMemoryBarrierWithGroupSync();
|
|
||||||
DispatchMesh(head, 1, 1, p);
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
import Common;
|
||||||
|
import Scene;
|
||||||
|
|
||||||
|
groupshared MeshPayload p;
|
||||||
|
groupshared uint head;
|
||||||
|
|
||||||
|
[numthreads(TASK_GROUP_SIZE, 1, 1)]
|
||||||
|
[shader("amplification")]
|
||||||
|
void taskMain(
|
||||||
|
uint threadID: SV_GroupIndex,
|
||||||
|
uint groupID: SV_GroupID, )
|
||||||
|
{
|
||||||
|
if (threadID == 0)
|
||||||
|
{
|
||||||
|
head = 0;
|
||||||
|
p.instanceId = pOffsets.instanceOffset + groupID;
|
||||||
|
}
|
||||||
|
GroupMemoryBarrierWithGroupSync();
|
||||||
|
MeshData mesh = pScene.meshData[p.instanceId];
|
||||||
|
for (uint i = threadID; i < mesh.numMeshlets; i += TASK_GROUP_SIZE)
|
||||||
|
{
|
||||||
|
uint m = mesh.meshletOffset + i;
|
||||||
|
//MeshletDescription meshlet = pScene.meshletInfos[m];
|
||||||
|
//MeshletCullingInfo culling = pScene.culledMeshlets[pScene.cullingOffsets[p.instanceId] + i];
|
||||||
|
//if(culling.anyVisible())
|
||||||
|
{
|
||||||
|
uint index;
|
||||||
|
InterlockedAdd(head, 1, index);
|
||||||
|
p.culledMeshlets[i] = m;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
GroupMemoryBarrierWithGroupSync();
|
||||||
|
DispatchMesh(mesh.numMeshlets, 1, 1, p);
|
||||||
|
}
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
import Common;
|
|
||||||
import BRDF;
|
|
||||||
import Scene;
|
|
||||||
import VertexData;
|
|
||||||
import MaterialParameter;
|
|
||||||
|
|
||||||
struct PrimitiveAttributes
|
|
||||||
{
|
|
||||||
uint cull: SV_CullPrimitive;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct CulledMeshletList
|
|
||||||
{
|
|
||||||
StructuredBuffer<uint> meshletIndices;
|
|
||||||
};
|
|
||||||
ParameterBlock<CulledMeshletList> pCullingList;
|
|
||||||
|
|
||||||
[numthreads(MESH_GROUP_SIZE, 1, 1)]
|
|
||||||
[outputtopology("triangle")]
|
|
||||||
[shader("mesh")]
|
|
||||||
void meshMain(
|
|
||||||
in uint threadID: SV_GroupIndex,
|
|
||||||
in uint groupID: SV_GroupID,
|
|
||||||
out vertices FragmentParameter vertices[MAX_VERTICES],
|
|
||||||
out indices uint3 indices[MAX_PRIMITIVES]
|
|
||||||
){
|
|
||||||
uint meshletIndex = pCullingList.meshletIndices[groupID];
|
|
||||||
MeshletDescription m = pScene.meshletInfos[meshletIndex];
|
|
||||||
SetMeshOutputCounts(m.vertexCount, m.primitiveCount);
|
|
||||||
|
|
||||||
for(uint i = threadID; i < MAX_PRIMITIVES; i += MESH_GROUP_SIZE)
|
|
||||||
{
|
|
||||||
uint p = min(i, m.primitiveCount - 1);
|
|
||||||
{
|
|
||||||
uint local_idx0 = pScene.primitiveIndices[m.primitiveOffset + (p * 3) + 0];
|
|
||||||
uint local_idx1 = pScene.primitiveIndices[m.primitiveOffset + (p * 3) + 1];
|
|
||||||
uint local_idx2 = pScene.primitiveIndices[m.primitiveOffset + (p * 3) + 2];
|
|
||||||
indices[p] = uint3(local_idx0, local_idx1, local_idx2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for(uint i = threadID; i < MAX_VERTICES; i+=MESH_GROUP_SIZE)
|
|
||||||
{
|
|
||||||
uint v = min(i, m.vertexCount - 1);
|
|
||||||
{
|
|
||||||
uint vertexIndex = pScene.vertexIndices[m.vertexOffset + v];
|
|
||||||
VertexAttributes attr = pVertexData.getAttributes(m.indicesOffset + vertexIndex);
|
|
||||||
attr.meshletId = meshletIndex;
|
|
||||||
vertices[v] = attr.getParameter(float4x4(1.0));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -29,7 +29,6 @@ void taskMain(
|
|||||||
viewFrustum.sides[2] = computePlane(origin, corners[0], corners[1]);
|
viewFrustum.sides[2] = computePlane(origin, corners[0], corners[1]);
|
||||||
viewFrustum.sides[3] = computePlane(origin, corners[3], corners[2]);
|
viewFrustum.sides[3] = computePlane(origin, corners[3], corners[2]);
|
||||||
p.instanceId = pOffsets.instanceOffset + groupID;
|
p.instanceId = pOffsets.instanceOffset + groupID;
|
||||||
//p.cullingOffset = pScene.cullingOffsets[pOffsets.cullingCounterOffset + groupID];
|
|
||||||
}
|
}
|
||||||
GroupMemoryBarrierWithGroupSync();
|
GroupMemoryBarrierWithGroupSync();
|
||||||
for(uint i = threadID; i < mesh.numMeshlets; i += TASK_GROUP_SIZE)
|
for(uint i = threadID; i < mesh.numMeshlets; i += TASK_GROUP_SIZE)
|
||||||
@@ -43,7 +42,6 @@ void taskMain(
|
|||||||
uint index;
|
uint index;
|
||||||
InterlockedAdd(head, 1, index);
|
InterlockedAdd(head, 1, index);
|
||||||
p.culledMeshlets[index] = m;
|
p.culledMeshlets[index] = m;
|
||||||
//pScene.culledMeshlets[p.cullingOffset + index] = m;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
GroupMemoryBarrierWithGroupSync();
|
GroupMemoryBarrierWithGroupSync();
|
||||||
|
|||||||
@@ -31,9 +31,25 @@ struct InstanceData
|
|||||||
float4x4 inverseTransformMatrix;
|
float4x4 inverseTransformMatrix;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct MeshletCullingInfo
|
||||||
|
{
|
||||||
|
uint64_t cull[MAX_PRIMITIVES / 64];
|
||||||
|
// lookup if a specific triangle is visible
|
||||||
|
bool triangleVisible(uint32_t primIndex)
|
||||||
|
{
|
||||||
|
uint32_t arrIdx = primIndex / 64;
|
||||||
|
uint32_t cullIdx = primIndex % 64;
|
||||||
|
return (cull[arrIdx] & (1 << cullIdx)) != 0;
|
||||||
|
}
|
||||||
|
bool anyVisible()
|
||||||
|
{
|
||||||
|
return (cull[0] | cull[1] | cull[2] | cull[3]) != 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
struct DrawCallOffsets
|
struct DrawCallOffsets
|
||||||
{
|
{
|
||||||
uint32_t instanceOffset;
|
uint32_t instanceOffset;
|
||||||
};
|
};
|
||||||
layout(push_constant)
|
layout(push_constant)
|
||||||
ConstantBuffer<DrawCallOffsets> pOffsets;
|
ConstantBuffer<DrawCallOffsets> pOffsets;
|
||||||
@@ -45,8 +61,8 @@ struct Scene
|
|||||||
StructuredBuffer<MeshletDescription> meshletInfos;
|
StructuredBuffer<MeshletDescription> meshletInfos;
|
||||||
StructuredBuffer<uint8_t> primitiveIndices;
|
StructuredBuffer<uint8_t> primitiveIndices;
|
||||||
StructuredBuffer<uint32_t> vertexIndices;
|
StructuredBuffer<uint32_t> vertexIndices;
|
||||||
// StructuredBuffer<uint32_t> cullingOffsets;
|
StructuredBuffer<MeshletCullingInfo> culledMeshlets;
|
||||||
// RWStructuredBuffer<uint32_t> culledMeshlets;
|
StructuredBuffer<uint32_t> cullingOffsets;
|
||||||
};
|
};
|
||||||
layout(set=2)
|
layout(set=2)
|
||||||
ParameterBlock<Scene> pScene;
|
ParameterBlock<Scene> pScene;
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ BasePass::BasePass(Gfx::PGraphics graphics, PScene scene)
|
|||||||
|
|
||||||
if (graphics->supportMeshShading())
|
if (graphics->supportMeshShading())
|
||||||
{
|
{
|
||||||
graphics->getShaderCompiler()->registerRenderPass(basePassLayout, "BasePass", "MeshletPass", true, true, "BasePass", true, true, "ViewCullingTask");
|
graphics->getShaderCompiler()->registerRenderPass(basePassLayout, "BasePass", "MeshletPass", true, true, "BasePass", true, true, "DrawListTask");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -91,7 +91,7 @@ void BasePass::render()
|
|||||||
Gfx::ShaderPermutation permutation;
|
Gfx::ShaderPermutation permutation;
|
||||||
if (graphics->supportMeshShading())
|
if (graphics->supportMeshShading())
|
||||||
{
|
{
|
||||||
permutation.setTaskFile("ViewCullingTask");
|
permutation.setTaskFile("DrawListTask");
|
||||||
permutation.setMeshFile("MeshletPass");
|
permutation.setMeshFile("MeshletPass");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -140,7 +140,7 @@ void BasePass::render()
|
|||||||
.depthCompareOp = Gfx::SE_COMPARE_OP_GREATER_OR_EQUAL,
|
.depthCompareOp = Gfx::SE_COMPARE_OP_GREATER_OR_EQUAL,
|
||||||
},
|
},
|
||||||
.colorBlend = {
|
.colorBlend = {
|
||||||
.attachmentCount = 2,
|
.attachmentCount = 1,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo));
|
Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo));
|
||||||
@@ -160,7 +160,7 @@ void BasePass::render()
|
|||||||
.depthCompareOp = Gfx::SE_COMPARE_OP_GREATER_OR_EQUAL,
|
.depthCompareOp = Gfx::SE_COMPARE_OP_GREATER_OR_EQUAL,
|
||||||
},
|
},
|
||||||
.colorBlend = {
|
.colorBlend = {
|
||||||
.attachmentCount = 2,
|
.attachmentCount = 1,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo));
|
Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo));
|
||||||
@@ -182,11 +182,10 @@ void BasePass::render()
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
command->bindIndexBuffer(vertexData->getIndexBuffer());
|
command->bindIndexBuffer(vertexData->getIndexBuffer());
|
||||||
uint32 inst = drawCall.offsets.instanceOffset;
|
|
||||||
for (const auto& meshData : drawCall.instanceMeshData)
|
for (const auto& meshData : drawCall.instanceMeshData)
|
||||||
{
|
{
|
||||||
// all meshlets of a mesh share the same indices offset
|
// all meshlets of a mesh share the same indices offset
|
||||||
command->drawIndexed(meshData.numIndices, 1, meshData.firstIndex, vertexData->getIndicesOffset(meshData.meshletOffset), inst++);
|
command->drawIndexed(meshData.numIndices, 1, meshData.firstIndex, vertexData->getIndicesOffset(meshData.meshletOffset), 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -208,17 +207,6 @@ void BasePass::publishOutputs()
|
|||||||
Gfx::SE_IMAGE_LAYOUT_UNDEFINED, Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
Gfx::SE_IMAGE_LAYOUT_UNDEFINED, Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_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);
|
||||||
resources->registerRenderPassOutput("BASEPASS_COLOR", colorAttachment);
|
resources->registerRenderPassOutput("BASEPASS_COLOR", colorAttachment);
|
||||||
|
|
||||||
meshletIdTexture = graphics->createTexture2D(TextureCreateInfo{
|
|
||||||
.format = Gfx::SE_FORMAT_R32_UINT,
|
|
||||||
.width = viewport->getWidth(),
|
|
||||||
.height = viewport->getHeight(),
|
|
||||||
.usage = Gfx::SE_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | Gfx::SE_IMAGE_USAGE_STORAGE_BIT,
|
|
||||||
});
|
|
||||||
meshletIdAttachment = Gfx::RenderTargetAttachment(meshletIdTexture,
|
|
||||||
Gfx::SE_IMAGE_LAYOUT_UNDEFINED, Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
|
||||||
Gfx::SE_ATTACHMENT_LOAD_OP_CLEAR, Gfx::SE_ATTACHMENT_STORE_OP_STORE);
|
|
||||||
resources->registerRenderPassOutput("BASEPASS_MESHLETID", meshletIdAttachment);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BasePass::createRenderPass()
|
void BasePass::createRenderPass()
|
||||||
@@ -228,7 +216,7 @@ void BasePass::createRenderPass()
|
|||||||
depthAttachment.setInitialLayout(Gfx::SE_IMAGE_LAYOUT_GENERAL);
|
depthAttachment.setInitialLayout(Gfx::SE_IMAGE_LAYOUT_GENERAL);
|
||||||
depthAttachment.setFinalLayout(Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
|
depthAttachment.setFinalLayout(Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
|
||||||
Gfx::RenderTargetLayout layout = Gfx::RenderTargetLayout{
|
Gfx::RenderTargetLayout layout = Gfx::RenderTargetLayout{
|
||||||
.colorAttachments = { colorAttachment, meshletIdAttachment },
|
.colorAttachments = { colorAttachment },
|
||||||
.depthAttachment = depthAttachment,
|
.depthAttachment = depthAttachment,
|
||||||
};
|
};
|
||||||
Array<Gfx::SubPassDependency> dependency = {
|
Array<Gfx::SubPassDependency> dependency = {
|
||||||
@@ -245,7 +233,7 @@ void BasePass::createRenderPass()
|
|||||||
.dstSubpass = 0,
|
.dstSubpass = 0,
|
||||||
.srcStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
.srcStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||||
.dstStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
.dstStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||||
.srcAccess = Gfx::SE_ACCESS_NONE,
|
.srcAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||||
.dstAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
.dstAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -262,7 +250,7 @@ void BasePass::createRenderPass()
|
|||||||
.srcStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
.srcStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||||
.dstStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
.dstStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||||
.srcAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
.srcAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||||
.dstAccess = Gfx::SE_ACCESS_NONE,
|
.dstAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
renderPass = graphics->createRenderPass(std::move(layout), std::move(dependency), viewport);
|
renderPass = graphics->createRenderPass(std::move(layout), std::move(dependency), viewport);
|
||||||
|
|||||||
@@ -20,12 +20,11 @@ public:
|
|||||||
private:
|
private:
|
||||||
Gfx::RenderTargetAttachment colorAttachment;
|
Gfx::RenderTargetAttachment colorAttachment;
|
||||||
Gfx::RenderTargetAttachment depthAttachment;
|
Gfx::RenderTargetAttachment depthAttachment;
|
||||||
Gfx::RenderTargetAttachment meshletIdAttachment;
|
Gfx::RenderTargetAttachment visibilityAttachment;
|
||||||
Gfx::PShaderBuffer oLightIndexList;
|
Gfx::PShaderBuffer oLightIndexList;
|
||||||
Gfx::PShaderBuffer tLightIndexList;
|
Gfx::PShaderBuffer tLightIndexList;
|
||||||
Gfx::PTexture2D oLightGrid;
|
Gfx::PTexture2D oLightGrid;
|
||||||
Gfx::PTexture2D tLightGrid;
|
Gfx::PTexture2D tLightGrid;
|
||||||
Gfx::OTexture2D meshletIdTexture;
|
|
||||||
|
|
||||||
Gfx::PDescriptorSet opaqueCulling;
|
Gfx::PDescriptorSet opaqueCulling;
|
||||||
Gfx::PDescriptorSet transparentCulling;
|
Gfx::PDescriptorSet transparentCulling;
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ target_sources(Engine
|
|||||||
PRIVATE
|
PRIVATE
|
||||||
BasePass.h
|
BasePass.h
|
||||||
BasePass.cpp
|
BasePass.cpp
|
||||||
|
CachedDepthPass.h
|
||||||
|
CachedDepthPass.cpp
|
||||||
DebugPass.h
|
DebugPass.h
|
||||||
DebugPass.cpp
|
DebugPass.cpp
|
||||||
DepthPrepass.h
|
DepthPrepass.h
|
||||||
@@ -15,10 +17,6 @@ target_sources(Engine
|
|||||||
RenderPass.cpp
|
RenderPass.cpp
|
||||||
SkyboxRenderPass.h
|
SkyboxRenderPass.h
|
||||||
SkyboxRenderPass.cpp
|
SkyboxRenderPass.cpp
|
||||||
#StaticDepthPrepass.h
|
|
||||||
#StaticDepthPrepass.cpp
|
|
||||||
#StaticBasePass.h
|
|
||||||
#StaticBasePass.cpp
|
|
||||||
TextPass.h
|
TextPass.h
|
||||||
TextPass.cpp
|
TextPass.cpp
|
||||||
UIPass.h
|
UIPass.h
|
||||||
@@ -28,6 +26,7 @@ target_sources(Engine
|
|||||||
PUBLIC FILE_SET HEADERS
|
PUBLIC FILE_SET HEADERS
|
||||||
FILES
|
FILES
|
||||||
BasePass.h
|
BasePass.h
|
||||||
|
CachedDepthPass.h
|
||||||
DebugPass.h
|
DebugPass.h
|
||||||
DepthPrepass.h
|
DepthPrepass.h
|
||||||
LightCullingPass.h
|
LightCullingPass.h
|
||||||
@@ -35,7 +34,5 @@ target_sources(Engine
|
|||||||
RenderGraphResources.h
|
RenderGraphResources.h
|
||||||
RenderPass.h
|
RenderPass.h
|
||||||
SkyboxRenderPass.h
|
SkyboxRenderPass.h
|
||||||
#StaticDepthPrepass.h
|
|
||||||
#StaticBasePass.h
|
|
||||||
TextPass.h
|
TextPass.h
|
||||||
UIPass.h)
|
UIPass.h)
|
||||||
@@ -0,0 +1,222 @@
|
|||||||
|
#include "CachedDepthPass.h"
|
||||||
|
#include "Graphics/Shader.h"
|
||||||
|
|
||||||
|
using namespace Seele;
|
||||||
|
|
||||||
|
extern bool usePositionOnly;
|
||||||
|
extern bool useViewCulling;
|
||||||
|
|
||||||
|
CachedDepthPass::CachedDepthPass(Gfx::PGraphics graphics, PScene scene)
|
||||||
|
: RenderPass(graphics, scene)
|
||||||
|
{
|
||||||
|
depthPrepassLayout = graphics->createPipelineLayout("CachedDepthLayout");
|
||||||
|
depthPrepassLayout->addDescriptorLayout(viewParamsLayout);
|
||||||
|
depthPrepassLayout->addPushConstants(Gfx::SePushConstantRange{
|
||||||
|
.stageFlags = Gfx::SE_SHADER_STAGE_TASK_BIT_EXT | Gfx::SE_SHADER_STAGE_VERTEX_BIT,
|
||||||
|
.offset = 0,
|
||||||
|
.size = sizeof(VertexData::DrawCallOffsets),
|
||||||
|
});
|
||||||
|
if (graphics->supportMeshShading())
|
||||||
|
{
|
||||||
|
graphics->getShaderCompiler()->registerRenderPass(depthPrepassLayout, "CachedDepthPass", "MeshletPass", false, false, "", true, true, "DrawListTask");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
graphics->getShaderCompiler()->registerRenderPass(depthPrepassLayout, "CachedDepthPass", "LegacyPass");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CachedDepthPass::~CachedDepthPass()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void CachedDepthPass::beginFrame(const Component::Camera &cam)
|
||||||
|
{
|
||||||
|
RenderPass::beginFrame(cam);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CachedDepthPass::render()
|
||||||
|
{
|
||||||
|
graphics->beginRenderPass(renderPass);
|
||||||
|
Array<Gfx::ORenderCommand> commands;
|
||||||
|
|
||||||
|
Gfx::ShaderPermutation permutation;
|
||||||
|
permutation.setPositionOnly(usePositionOnly);
|
||||||
|
permutation.setViewCulling(useViewCulling);
|
||||||
|
if (graphics->supportMeshShading())
|
||||||
|
{
|
||||||
|
permutation.setTaskFile("DrawListTask");
|
||||||
|
permutation.setMeshFile("MeshletPass");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
permutation.setVertexFile("LegacyPass");
|
||||||
|
}
|
||||||
|
for (VertexData *vertexData : VertexData::getList())
|
||||||
|
{
|
||||||
|
permutation.setVertexData(vertexData->getTypeName());
|
||||||
|
|
||||||
|
// Create Pipeline(VertexData)
|
||||||
|
// Descriptors:
|
||||||
|
// ViewData => global, static
|
||||||
|
// VertexData => per meshtype
|
||||||
|
// SceneData => per meshtype
|
||||||
|
Gfx::PermutationId id(permutation);
|
||||||
|
|
||||||
|
Gfx::ORenderCommand command = graphics->createRenderCommand("DepthRender");
|
||||||
|
command->setViewport(viewport);
|
||||||
|
|
||||||
|
const Gfx::ShaderCollection *collection = graphics->getShaderCompiler()->findShaders(id);
|
||||||
|
assert(collection != nullptr);
|
||||||
|
if (graphics->supportMeshShading())
|
||||||
|
{
|
||||||
|
Gfx::MeshPipelineCreateInfo pipelineInfo = {
|
||||||
|
.taskShader = collection->taskShader,
|
||||||
|
.meshShader = collection->meshShader,
|
||||||
|
.fragmentShader = collection->fragmentShader,
|
||||||
|
.renderPass = renderPass,
|
||||||
|
.pipelineLayout = collection->pipelineLayout,
|
||||||
|
.multisampleState = {
|
||||||
|
.samples = viewport->getSamples(),
|
||||||
|
},
|
||||||
|
.depthStencilState = {
|
||||||
|
.depthCompareOp = Gfx::SE_COMPARE_OP_GREATER,
|
||||||
|
},
|
||||||
|
.colorBlend = {
|
||||||
|
.attachmentCount = 1,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo));
|
||||||
|
command->bindPipeline(pipeline);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Gfx::LegacyPipelineCreateInfo pipelineInfo = {
|
||||||
|
.vertexShader = collection->vertexShader,
|
||||||
|
.fragmentShader = collection->fragmentShader,
|
||||||
|
.renderPass = renderPass,
|
||||||
|
.pipelineLayout = collection->pipelineLayout,
|
||||||
|
.multisampleState = {
|
||||||
|
.samples = viewport->getSamples(),
|
||||||
|
},
|
||||||
|
.depthStencilState = {
|
||||||
|
.depthCompareOp = Gfx::SE_COMPARE_OP_GREATER,
|
||||||
|
},
|
||||||
|
.colorBlend = {
|
||||||
|
.attachmentCount = 1,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo));
|
||||||
|
command->bindPipeline(pipeline);
|
||||||
|
}
|
||||||
|
command->bindDescriptor(vertexData->getVertexDataSet());
|
||||||
|
command->bindDescriptor(viewParamsSet);
|
||||||
|
command->bindDescriptor(vertexData->getInstanceDataSet());
|
||||||
|
uint32 offset = 0;
|
||||||
|
command->pushConstants(Gfx::SE_SHADER_STAGE_TASK_BIT_EXT | Gfx::SE_SHADER_STAGE_VERTEX_BIT, 0, sizeof(VertexData::DrawCallOffsets), &offset);
|
||||||
|
if (graphics->supportMeshShading())
|
||||||
|
{
|
||||||
|
command->drawMesh(vertexData->getNumInstances(), 1, 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const auto &materials = vertexData->getMaterialData();
|
||||||
|
for (const auto &materialData : materials)
|
||||||
|
{
|
||||||
|
// material not used for any active meshes, skip
|
||||||
|
if (materialData.instances.size() == 0)
|
||||||
|
continue;
|
||||||
|
for (const auto &drawCall : materialData.instances)
|
||||||
|
{
|
||||||
|
command->bindIndexBuffer(vertexData->getIndexBuffer());
|
||||||
|
uint32 inst = drawCall.offsets.instanceOffset;
|
||||||
|
for (const auto &meshData : drawCall.instanceMeshData)
|
||||||
|
{
|
||||||
|
// all meshlets of a mesh share the same indices offset
|
||||||
|
command->drawIndexed(meshData.numIndices, 1, meshData.firstIndex, vertexData->getIndicesOffset(meshData.meshletOffset), inst++);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
commands.add(std::move(command));
|
||||||
|
}
|
||||||
|
|
||||||
|
graphics->executeCommands(std::move(commands));
|
||||||
|
graphics->endRenderPass();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CachedDepthPass::endFrame()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void CachedDepthPass::publishOutputs()
|
||||||
|
{
|
||||||
|
// If we render to a part of an image, the depth buffer itself must
|
||||||
|
// still match the size of the whole image or their coordinate systems go out of sync
|
||||||
|
TextureCreateInfo depthBufferInfo = {
|
||||||
|
.format = Gfx::SE_FORMAT_D32_SFLOAT,
|
||||||
|
.width = viewport->getOwner()->getFramebufferWidth(),
|
||||||
|
.height = viewport->getOwner()->getFramebufferHeight(),
|
||||||
|
.usage = Gfx::SE_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
|
||||||
|
};
|
||||||
|
depthBuffer = graphics->createTexture2D(depthBufferInfo);
|
||||||
|
depthAttachment =
|
||||||
|
Gfx::RenderTargetAttachment(depthBuffer,
|
||||||
|
Gfx::SE_IMAGE_LAYOUT_UNDEFINED, Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
|
||||||
|
Gfx::SE_ATTACHMENT_LOAD_OP_CLEAR, Gfx::SE_ATTACHMENT_STORE_OP_STORE);
|
||||||
|
resources->registerRenderPassOutput("DEPTHPREPASS_DEPTH", depthAttachment);
|
||||||
|
|
||||||
|
TextureCreateInfo visibilityInfo = {
|
||||||
|
.format = Gfx::SE_FORMAT_R32G32_UINT,
|
||||||
|
.width = viewport->getOwner()->getFramebufferWidth(),
|
||||||
|
.height = viewport->getOwner()->getFramebufferHeight(),
|
||||||
|
.usage = Gfx::SE_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
|
||||||
|
};
|
||||||
|
visibilityBuffer = graphics->createTexture2D(visibilityInfo);
|
||||||
|
visibilityAttachment =
|
||||||
|
Gfx::RenderTargetAttachment(visibilityBuffer,
|
||||||
|
Gfx::SE_IMAGE_LAYOUT_UNDEFINED, Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||||
|
Gfx::SE_ATTACHMENT_LOAD_OP_CLEAR, Gfx::SE_ATTACHMENT_STORE_OP_STORE);
|
||||||
|
resources->registerRenderPassOutput("VISIBILITY", visibilityAttachment);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CachedDepthPass::createRenderPass()
|
||||||
|
{
|
||||||
|
Gfx::RenderTargetLayout layout = Gfx::RenderTargetLayout{
|
||||||
|
.depthAttachment = depthAttachment,
|
||||||
|
};
|
||||||
|
Array<Gfx::SubPassDependency> dependency = {
|
||||||
|
{
|
||||||
|
.srcSubpass = ~0U,
|
||||||
|
.dstSubpass = 0,
|
||||||
|
.srcStage = Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
|
||||||
|
.dstStage = Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT,
|
||||||
|
.srcAccess = Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||||
|
.dstAccess = Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.srcSubpass = 0,
|
||||||
|
.dstSubpass = ~0U,
|
||||||
|
.srcStage = Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
|
||||||
|
.dstStage = Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
||||||
|
.srcAccess = Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||||
|
.dstAccess = Gfx::SE_ACCESS_SHADER_READ_BIT,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.srcSubpass = 0,
|
||||||
|
.dstSubpass = ~0U,
|
||||||
|
.srcStage = Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
|
||||||
|
.dstStage = Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT,
|
||||||
|
.srcAccess = Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||||
|
.dstAccess = Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.srcSubpass = 0,
|
||||||
|
.dstSubpass = ~0U,
|
||||||
|
.srcStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||||
|
.dstStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||||
|
.srcAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||||
|
.dstAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||||
|
}};
|
||||||
|
renderPass = graphics->createRenderPass(std::move(layout), std::move(dependency), viewport);
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "RenderPass.h"
|
||||||
|
|
||||||
|
namespace Seele
|
||||||
|
{
|
||||||
|
class CachedDepthPass : public RenderPass
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CachedDepthPass(Gfx::PGraphics graphics, PScene scene);
|
||||||
|
CachedDepthPass(CachedDepthPass&&) = default;
|
||||||
|
CachedDepthPass& operator=(CachedDepthPass&&) = default;
|
||||||
|
virtual ~CachedDepthPass();
|
||||||
|
virtual void beginFrame(const Component::Camera& cam) override;
|
||||||
|
virtual void render() override;
|
||||||
|
virtual void endFrame() override;
|
||||||
|
virtual void publishOutputs() override;
|
||||||
|
virtual void createRenderPass() override;
|
||||||
|
private:
|
||||||
|
Gfx::RenderTargetAttachment depthAttachment;
|
||||||
|
Gfx::RenderTargetAttachment visibilityAttachment;
|
||||||
|
Gfx::OTexture2D depthBuffer;
|
||||||
|
Gfx::OTexture2D visibilityBuffer;
|
||||||
|
Gfx::OPipelineLayout depthPrepassLayout;
|
||||||
|
};
|
||||||
|
DEFINE_REF(CachedDepthPass)
|
||||||
|
}
|
||||||
@@ -1,15 +1,5 @@
|
|||||||
#include "DepthPrepass.h"
|
#include "DepthPrepass.h"
|
||||||
#include "Graphics/Enums.h"
|
|
||||||
#include "Graphics/Graphics.h"
|
|
||||||
#include "Graphics/Shader.h"
|
#include "Graphics/Shader.h"
|
||||||
#include "Window/Window.h"
|
|
||||||
#include "Component/Camera.h"
|
|
||||||
#include "Component/Mesh.h"
|
|
||||||
#include "Actor/CameraActor.h"
|
|
||||||
#include "Math/Vector.h"
|
|
||||||
#include "RenderGraph.h"
|
|
||||||
#include "Graphics/Command.h"
|
|
||||||
#include "Graphics/StaticMeshVertexData.h"
|
|
||||||
|
|
||||||
using namespace Seele;
|
using namespace Seele;
|
||||||
|
|
||||||
@@ -19,137 +9,139 @@ extern bool useViewCulling;
|
|||||||
DepthPrepass::DepthPrepass(Gfx::PGraphics graphics, PScene scene)
|
DepthPrepass::DepthPrepass(Gfx::PGraphics graphics, PScene scene)
|
||||||
: RenderPass(graphics, scene)
|
: RenderPass(graphics, scene)
|
||||||
{
|
{
|
||||||
depthPrepassLayout = graphics->createPipelineLayout("DepthPrepassLayout");
|
depthPrepassLayout = graphics->createPipelineLayout("DepthPrepassLayout");
|
||||||
depthPrepassLayout->addDescriptorLayout(viewParamsLayout);
|
depthPrepassLayout->addDescriptorLayout(viewParamsLayout);
|
||||||
depthPrepassLayout->addPushConstants(Gfx::SePushConstantRange{
|
depthPrepassLayout->addPushConstants(Gfx::SePushConstantRange{
|
||||||
.stageFlags = Gfx::SE_SHADER_STAGE_TASK_BIT_EXT | Gfx::SE_SHADER_STAGE_VERTEX_BIT,
|
.stageFlags = Gfx::SE_SHADER_STAGE_TASK_BIT_EXT | Gfx::SE_SHADER_STAGE_VERTEX_BIT,
|
||||||
.offset = 0,
|
.offset = 0,
|
||||||
.size = sizeof(VertexData::DrawCallOffsets),
|
.size = sizeof(VertexData::DrawCallOffsets),
|
||||||
});
|
});
|
||||||
if (graphics->supportMeshShading())
|
if (graphics->supportMeshShading())
|
||||||
{
|
{
|
||||||
graphics->getShaderCompiler()->registerRenderPass(depthPrepassLayout, "DepthPass", "MeshletPass", false, false, "", true, true, "ViewCullingTask");
|
graphics->getShaderCompiler()->registerRenderPass(depthPrepassLayout, "DepthPass", "MeshletPass", false, false, "", true, true, "ViewCullingTask");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
graphics->getShaderCompiler()->registerRenderPass(depthPrepassLayout, "DepthPass", "LegacyPass");
|
graphics->getShaderCompiler()->registerRenderPass(depthPrepassLayout, "DepthPass", "LegacyPass");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DepthPrepass::~DepthPrepass()
|
DepthPrepass::~DepthPrepass()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void DepthPrepass::beginFrame(const Component::Camera& cam)
|
void DepthPrepass::beginFrame(const Component::Camera &cam)
|
||||||
{
|
{
|
||||||
RenderPass::beginFrame(cam);
|
RenderPass::beginFrame(cam);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DepthPrepass::render()
|
void DepthPrepass::render()
|
||||||
{
|
{
|
||||||
graphics->beginRenderPass(renderPass);
|
graphics->beginRenderPass(renderPass);
|
||||||
Array<Gfx::ORenderCommand> commands;
|
Array<Gfx::ORenderCommand> commands;
|
||||||
|
|
||||||
Gfx::ShaderPermutation permutation;
|
Gfx::ShaderPermutation permutation;
|
||||||
permutation.setPositionOnly(usePositionOnly);
|
permutation.setPositionOnly(usePositionOnly);
|
||||||
permutation.setViewCulling(useViewCulling);
|
permutation.setViewCulling(useViewCulling);
|
||||||
|
if (graphics->supportMeshShading())
|
||||||
|
{
|
||||||
|
permutation.setTaskFile("ViewCullingTask");
|
||||||
|
permutation.setMeshFile("MeshletPass");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
permutation.setVertexFile("LegacyPass");
|
||||||
|
}
|
||||||
|
for (VertexData *vertexData : VertexData::getList())
|
||||||
|
{
|
||||||
|
permutation.setVertexData(vertexData->getTypeName());
|
||||||
|
// Create Pipeline(VertexData)
|
||||||
|
// Descriptors:
|
||||||
|
// ViewData => global, static
|
||||||
|
// VertexData => per meshtype
|
||||||
|
// SceneData => per meshtype
|
||||||
|
Gfx::PermutationId id(permutation);
|
||||||
|
|
||||||
|
Gfx::ORenderCommand command = graphics->createRenderCommand("DepthRender");
|
||||||
|
command->setViewport(viewport);
|
||||||
|
|
||||||
|
const Gfx::ShaderCollection *collection = graphics->getShaderCompiler()->findShaders(id);
|
||||||
|
assert(collection != nullptr);
|
||||||
if (graphics->supportMeshShading())
|
if (graphics->supportMeshShading())
|
||||||
{
|
{
|
||||||
permutation.setTaskFile("ViewCullingTask");
|
Gfx::MeshPipelineCreateInfo pipelineInfo = {
|
||||||
permutation.setMeshFile("MeshletPass");
|
.taskShader = collection->taskShader,
|
||||||
|
.meshShader = collection->meshShader,
|
||||||
|
.fragmentShader = collection->fragmentShader,
|
||||||
|
.renderPass = renderPass,
|
||||||
|
.pipelineLayout = collection->pipelineLayout,
|
||||||
|
.multisampleState = {
|
||||||
|
.samples = viewport->getSamples(),
|
||||||
|
},
|
||||||
|
.depthStencilState = {
|
||||||
|
.depthCompareOp = Gfx::SE_COMPARE_OP_GREATER,
|
||||||
|
},
|
||||||
|
.colorBlend = {
|
||||||
|
.attachmentCount = 1,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo));
|
||||||
|
command->bindPipeline(pipeline);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
permutation.setVertexFile("LegacyPass");
|
Gfx::LegacyPipelineCreateInfo pipelineInfo = {
|
||||||
|
.vertexShader = collection->vertexShader,
|
||||||
|
.fragmentShader = collection->fragmentShader,
|
||||||
|
.renderPass = renderPass,
|
||||||
|
.pipelineLayout = collection->pipelineLayout,
|
||||||
|
.multisampleState = {
|
||||||
|
.samples = viewport->getSamples(),
|
||||||
|
},
|
||||||
|
.depthStencilState = {
|
||||||
|
.depthCompareOp = Gfx::SE_COMPARE_OP_GREATER,
|
||||||
|
},
|
||||||
|
.colorBlend = {
|
||||||
|
.attachmentCount = 1,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo));
|
||||||
|
command->bindPipeline(pipeline);
|
||||||
}
|
}
|
||||||
for (VertexData* vertexData : VertexData::getList())
|
command->bindDescriptor(vertexData->getVertexDataSet());
|
||||||
|
command->bindDescriptor(viewParamsSet);
|
||||||
|
command->bindDescriptor(vertexData->getInstanceDataSet());
|
||||||
|
uint32 offset = 0;
|
||||||
|
command->pushConstants(Gfx::SE_SHADER_STAGE_TASK_BIT_EXT | Gfx::SE_SHADER_STAGE_VERTEX_BIT, 0, sizeof(VertexData::DrawCallOffsets), &offset);
|
||||||
|
if (graphics->supportMeshShading())
|
||||||
{
|
{
|
||||||
permutation.setVertexData(vertexData->getTypeName());
|
command->drawMesh(vertexData->getNumInstances(), 1, 1);
|
||||||
const auto& materials = vertexData->getMaterialData();
|
|
||||||
for (const auto& materialData : materials)
|
|
||||||
{
|
|
||||||
// material not used for any active meshes, skip
|
|
||||||
if (materialData.instances.size() == 0)
|
|
||||||
continue;
|
|
||||||
// Create Pipeline(VertexData)
|
|
||||||
// Descriptors:
|
|
||||||
// ViewData => global, static
|
|
||||||
// VertexData => per meshtype
|
|
||||||
// SceneData => per meshtype
|
|
||||||
Gfx::PermutationId id(permutation);
|
|
||||||
|
|
||||||
Gfx::ORenderCommand command = graphics->createRenderCommand("DepthRender");
|
|
||||||
command->setViewport(viewport);
|
|
||||||
|
|
||||||
const Gfx::ShaderCollection* collection = graphics->getShaderCompiler()->findShaders(id);
|
|
||||||
assert(collection != nullptr);
|
|
||||||
if (graphics->supportMeshShading())
|
|
||||||
{
|
|
||||||
Gfx::MeshPipelineCreateInfo pipelineInfo = {
|
|
||||||
.taskShader = collection->taskShader,
|
|
||||||
.meshShader = collection->meshShader,
|
|
||||||
.fragmentShader = collection->fragmentShader,
|
|
||||||
.renderPass = renderPass,
|
|
||||||
.pipelineLayout = collection->pipelineLayout,
|
|
||||||
.multisampleState = {
|
|
||||||
.samples = viewport->getSamples(),},
|
|
||||||
.depthStencilState = {
|
|
||||||
.depthCompareOp = Gfx::SE_COMPARE_OP_GREATER,
|
|
||||||
},
|
|
||||||
.colorBlend = {
|
|
||||||
.attachmentCount = 1,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo));
|
|
||||||
command->bindPipeline(pipeline);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Gfx::LegacyPipelineCreateInfo pipelineInfo = {
|
|
||||||
.vertexShader = collection->vertexShader,
|
|
||||||
.fragmentShader = collection->fragmentShader,
|
|
||||||
.renderPass = renderPass,
|
|
||||||
.pipelineLayout = collection->pipelineLayout,
|
|
||||||
.multisampleState = {
|
|
||||||
.samples = viewport->getSamples(),
|
|
||||||
},
|
|
||||||
.depthStencilState = {
|
|
||||||
.depthCompareOp = Gfx::SE_COMPARE_OP_GREATER,
|
|
||||||
},
|
|
||||||
.colorBlend = {
|
|
||||||
.attachmentCount = 1,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo));
|
|
||||||
command->bindPipeline(pipeline);
|
|
||||||
}
|
|
||||||
command->bindDescriptor(vertexData->getVertexDataSet());
|
|
||||||
command->bindDescriptor(viewParamsSet);
|
|
||||||
command->bindDescriptor(vertexData->getInstanceDataSet());
|
|
||||||
for (const auto& drawCall : materialData.instances)
|
|
||||||
{
|
|
||||||
command->pushConstants(Gfx::SE_SHADER_STAGE_TASK_BIT_EXT | Gfx::SE_SHADER_STAGE_VERTEX_BIT, 0, sizeof(VertexData::DrawCallOffsets), &drawCall.offsets);
|
|
||||||
if (graphics->supportMeshShading())
|
|
||||||
{
|
|
||||||
command->drawMesh(drawCall.instanceMeshData.size(), 1, 1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
command->bindIndexBuffer(vertexData->getIndexBuffer());
|
|
||||||
uint32 inst = drawCall.offsets.instanceOffset;
|
|
||||||
for (const auto& meshData : drawCall.instanceMeshData)
|
|
||||||
{
|
|
||||||
// all meshlets of a mesh share the same indices offset
|
|
||||||
command->drawIndexed(meshData.numIndices, 1, meshData.firstIndex, vertexData->getIndicesOffset(meshData.meshletOffset), inst++);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
commands.add(std::move(command));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const auto &materials = vertexData->getMaterialData();
|
||||||
|
for (const auto &materialData : materials)
|
||||||
|
{
|
||||||
|
for (const auto &drawCall : materialData.instances)
|
||||||
|
{
|
||||||
|
// material not used for any active meshes, skip
|
||||||
|
if (materialData.instances.size() == 0)
|
||||||
|
continue;
|
||||||
|
command->bindIndexBuffer(vertexData->getIndexBuffer());
|
||||||
|
uint32 inst = drawCall.offsets.instanceOffset;
|
||||||
|
for (const auto &meshData : drawCall.instanceMeshData)
|
||||||
|
{
|
||||||
|
// all meshlets of a mesh share the same indices offset
|
||||||
|
command->drawIndexed(meshData.numIndices, 1, meshData.firstIndex, vertexData->getIndicesOffset(meshData.meshletOffset), inst++);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
commands.add(std::move(command));
|
||||||
|
}
|
||||||
|
|
||||||
graphics->executeCommands(std::move(commands));
|
graphics->executeCommands(std::move(commands));
|
||||||
graphics->endRenderPass();
|
graphics->endRenderPass();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DepthPrepass::endFrame()
|
void DepthPrepass::endFrame()
|
||||||
@@ -158,52 +150,63 @@ void DepthPrepass::endFrame()
|
|||||||
|
|
||||||
void DepthPrepass::publishOutputs()
|
void DepthPrepass::publishOutputs()
|
||||||
{
|
{
|
||||||
// If we render to a part of an image, the depth buffer itself must
|
|
||||||
// still match the size of the whole image or their coordinate systems go out of sync
|
|
||||||
TextureCreateInfo depthBufferInfo = {
|
|
||||||
.format = Gfx::SE_FORMAT_D32_SFLOAT,
|
|
||||||
.width = viewport->getOwner()->getFramebufferWidth(),
|
|
||||||
.height = viewport->getOwner()->getFramebufferHeight(),
|
|
||||||
.usage = Gfx::SE_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
|
|
||||||
};
|
|
||||||
depthBuffer = graphics->createTexture2D(depthBufferInfo);
|
|
||||||
depthAttachment =
|
|
||||||
Gfx::RenderTargetAttachment(depthBuffer,
|
|
||||||
Gfx::SE_IMAGE_LAYOUT_UNDEFINED, Gfx::SE_IMAGE_LAYOUT_GENERAL,
|
|
||||||
Gfx::SE_ATTACHMENT_LOAD_OP_CLEAR, Gfx::SE_ATTACHMENT_STORE_OP_STORE);
|
|
||||||
resources->registerRenderPassOutput("DEPTHPREPASS_DEPTH", depthAttachment);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DepthPrepass::createRenderPass()
|
void DepthPrepass::createRenderPass()
|
||||||
{
|
{
|
||||||
Gfx::RenderTargetLayout layout = Gfx::RenderTargetLayout{
|
auto depthAttachment = resources->requestRenderTarget("DEPTHPREPASS_DEPTH");
|
||||||
.depthAttachment = depthAttachment,
|
depthAttachment.setInitialLayout(Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
|
||||||
};
|
depthAttachment.setFinalLayout(Gfx::SE_IMAGE_LAYOUT_GENERAL);
|
||||||
Array<Gfx::SubPassDependency> dependency = {
|
depthAttachment.setLoadOp(Gfx::SE_ATTACHMENT_LOAD_OP_LOAD);
|
||||||
{
|
auto visibilityAttachment = resources->requestRenderTarget("VISIBILITY");
|
||||||
.srcSubpass = ~0U,
|
visibilityAttachment.setInitialLayout(Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||||
.dstSubpass = 0,
|
visibilityAttachment.setFinalLayout(Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||||
.srcStage = Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
|
visibilityAttachment.setLoadOp(Gfx::SE_ATTACHMENT_LOAD_OP_LOAD);
|
||||||
.dstStage = Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT,
|
|
||||||
.srcAccess = Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
Gfx::RenderTargetLayout layout = Gfx::RenderTargetLayout{
|
||||||
.dstAccess = Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
.colorAttachments = {visibilityAttachment},
|
||||||
},
|
.depthAttachment = depthAttachment,
|
||||||
{
|
};
|
||||||
.srcSubpass = 0,
|
Array<Gfx::SubPassDependency> dependency = {
|
||||||
.dstSubpass = ~0U,
|
{
|
||||||
.srcStage = Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
|
.srcSubpass = ~0U,
|
||||||
.dstStage = Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
.dstSubpass = 0,
|
||||||
.srcAccess = Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
.srcStage = Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
|
||||||
.dstAccess = Gfx::SE_ACCESS_SHADER_READ_BIT,
|
.dstStage = Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT,
|
||||||
},
|
.srcAccess = Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||||
{
|
.dstAccess = Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||||
.srcSubpass = 0,
|
},
|
||||||
.dstSubpass = ~0U,
|
{
|
||||||
.srcStage = Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
|
.srcSubpass = ~0U,
|
||||||
.dstStage = Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT,
|
.dstSubpass = 0,
|
||||||
.srcAccess = Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
.srcStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||||
.dstAccess = Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT,
|
.dstStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||||
}
|
.srcAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||||
};
|
.dstAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||||
renderPass = graphics->createRenderPass(std::move(layout), std::move(dependency), viewport);
|
},
|
||||||
|
{
|
||||||
|
.srcSubpass = 0,
|
||||||
|
.dstSubpass = ~0U,
|
||||||
|
.srcStage = Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
|
||||||
|
.dstStage = Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
||||||
|
.srcAccess = Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||||
|
.dstAccess = Gfx::SE_ACCESS_SHADER_READ_BIT,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.srcSubpass = 0,
|
||||||
|
.dstSubpass = ~0U,
|
||||||
|
.srcStage = Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
|
||||||
|
.dstStage = Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT,
|
||||||
|
.srcAccess = Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||||
|
.dstAccess = Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.srcSubpass = 0,
|
||||||
|
.dstSubpass = ~0U,
|
||||||
|
.srcStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||||
|
.dstStage = Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
||||||
|
.srcAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||||
|
.dstAccess = Gfx::SE_ACCESS_SHADER_READ_BIT,
|
||||||
|
}};
|
||||||
|
renderPass = graphics->createRenderPass(std::move(layout), std::move(dependency), viewport);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,9 +18,6 @@ public:
|
|||||||
virtual void createRenderPass() override;
|
virtual void createRenderPass() override;
|
||||||
private:
|
private:
|
||||||
Gfx::RenderTargetAttachment depthAttachment;
|
Gfx::RenderTargetAttachment depthAttachment;
|
||||||
|
|
||||||
Gfx::OTexture2D depthBuffer;
|
|
||||||
|
|
||||||
Gfx::OPipelineLayout depthPrepassLayout;
|
Gfx::OPipelineLayout depthPrepassLayout;
|
||||||
};
|
};
|
||||||
DEFINE_REF(DepthPrepass)
|
DEFINE_REF(DepthPrepass)
|
||||||
|
|||||||
+306
-309
@@ -15,372 +15,369 @@ constexpr static uint64 NUM_DEFAULT_ELEMENTS = 1024 * 1024;
|
|||||||
|
|
||||||
void VertexData::resetMeshData()
|
void VertexData::resetMeshData()
|
||||||
{
|
{
|
||||||
std::unique_lock l(materialDataLock);
|
std::unique_lock l(materialDataLock);
|
||||||
for (auto& mat : materialData)
|
for (auto &mat : materialData)
|
||||||
|
{
|
||||||
|
for (auto &inst : mat.instances)
|
||||||
{
|
{
|
||||||
for (auto& inst : mat.instances)
|
inst.instanceData.clear();
|
||||||
{
|
inst.instanceMeshData.clear();
|
||||||
inst.instanceData.clear();
|
|
||||||
inst.instanceMeshData.clear();
|
|
||||||
}
|
|
||||||
if (mat.material != nullptr)
|
|
||||||
{
|
|
||||||
mat.material->getDescriptorLayout()->reset();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (dirty)
|
if (mat.material != nullptr)
|
||||||
{
|
{
|
||||||
updateBuffers();
|
mat.material->getDescriptorLayout()->reset();
|
||||||
dirty = false;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (dirty)
|
||||||
|
{
|
||||||
|
updateBuffers();
|
||||||
|
dirty = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void VertexData::updateMesh(PMesh mesh, Component::Transform& transform)
|
void VertexData::updateMesh(PMesh mesh, Component::Transform &transform)
|
||||||
{
|
{
|
||||||
std::unique_lock l(materialDataLock);
|
std::unique_lock l(materialDataLock);
|
||||||
PMaterialInstance referencedInstance = mesh->referencedMaterial->getHandle();
|
PMaterialInstance referencedInstance = mesh->referencedMaterial->getHandle();
|
||||||
PMaterial mat = referencedInstance->getBaseMaterial();
|
PMaterial mat = referencedInstance->getBaseMaterial();
|
||||||
if (materialData.size() <= mat->getId())
|
if (materialData.size() <= mat->getId())
|
||||||
{
|
{
|
||||||
materialData.resize(mat->getId() + 1);
|
materialData.resize(mat->getId() + 1);
|
||||||
}
|
}
|
||||||
MaterialData& matData = materialData[mat->getId()];
|
MaterialData &matData = materialData[mat->getId()];
|
||||||
matData.material = mat;
|
matData.material = mat;
|
||||||
if (matData.instances.size() <= referencedInstance->getId())
|
if (matData.instances.size() <= referencedInstance->getId())
|
||||||
{
|
{
|
||||||
matData.instances.resize(referencedInstance->getId() + 1);
|
matData.instances.resize(referencedInstance->getId() + 1);
|
||||||
}
|
}
|
||||||
BatchedDrawCall& matInstanceData = matData.instances[referencedInstance->getId()];
|
BatchedDrawCall &matInstanceData = matData.instances[referencedInstance->getId()];
|
||||||
matInstanceData.materialInstance = referencedInstance;
|
matInstanceData.materialInstance = referencedInstance;
|
||||||
|
|
||||||
Matrix4 transformMatrix = transform.toMatrix() * mesh->transform;
|
|
||||||
matInstanceData.instanceData.add(InstanceData{
|
|
||||||
.transformMatrix = transformMatrix,
|
|
||||||
.inverseTransformMatrix = glm::inverse(transformMatrix),
|
|
||||||
});
|
|
||||||
const auto& data = meshData[mesh->id];
|
|
||||||
matInstanceData.instanceMeshData.add(data);
|
|
||||||
referencedInstance->updateDescriptor();
|
|
||||||
for (size_t i = 0; i < 0; ++i)
|
|
||||||
{
|
|
||||||
auto bounding = meshlets[data.meshletOffset + i].bounding;
|
|
||||||
StaticArray<Vector, 8> corners;
|
|
||||||
Vector min = bounding.min;//bounding.center - bounding.radius * Vector(1, 1, 1);
|
|
||||||
Vector max = bounding.max;//bounding.center + bounding.radius * Vector(1, 1, 1);
|
|
||||||
corners[0] = transformMatrix * Vector4(min.x, min.y, min.z, 1);
|
|
||||||
corners[1] = transformMatrix * Vector4(min.x, min.y, max.z, 1);
|
|
||||||
corners[2] = transformMatrix * Vector4(min.x, max.y, min.z, 1);
|
|
||||||
corners[3] = transformMatrix * Vector4(min.x, max.y, max.z, 1);
|
|
||||||
corners[4] = transformMatrix * Vector4(max.x, min.y, min.z, 1);
|
|
||||||
corners[5] = transformMatrix * Vector4(max.x, min.y, max.z, 1);
|
|
||||||
corners[6] = transformMatrix * Vector4(max.x, max.y, min.z, 1);
|
|
||||||
corners[7] = transformMatrix * Vector4(max.x, max.y, max.z, 1);
|
|
||||||
addDebugVertex(DebugVertex{ .position = corners[0], .color = meshlets[data.meshletOffset + i].color });
|
|
||||||
addDebugVertex(DebugVertex{ .position = corners[1], .color = meshlets[data.meshletOffset + i].color });
|
|
||||||
addDebugVertex(DebugVertex{ .position = corners[0], .color = meshlets[data.meshletOffset + i].color });
|
|
||||||
addDebugVertex(DebugVertex{ .position = corners[2], .color = meshlets[data.meshletOffset + i].color });
|
|
||||||
addDebugVertex(DebugVertex{ .position = corners[1], .color = meshlets[data.meshletOffset + i].color });
|
|
||||||
addDebugVertex(DebugVertex{ .position = corners[3], .color = meshlets[data.meshletOffset + i].color });
|
|
||||||
addDebugVertex(DebugVertex{ .position = corners[2], .color = meshlets[data.meshletOffset + i].color });
|
|
||||||
addDebugVertex(DebugVertex{ .position = corners[3], .color = meshlets[data.meshletOffset + i].color });
|
|
||||||
addDebugVertex(DebugVertex{ .position = corners[0], .color = meshlets[data.meshletOffset + i].color });
|
|
||||||
addDebugVertex(DebugVertex{ .position = corners[4], .color = meshlets[data.meshletOffset + i].color });
|
|
||||||
addDebugVertex(DebugVertex{ .position = corners[1], .color = meshlets[data.meshletOffset + i].color });
|
|
||||||
addDebugVertex(DebugVertex{ .position = corners[5], .color = meshlets[data.meshletOffset + i].color });
|
|
||||||
addDebugVertex(DebugVertex{ .position = corners[2], .color = meshlets[data.meshletOffset + i].color });
|
|
||||||
addDebugVertex(DebugVertex{ .position = corners[6], .color = meshlets[data.meshletOffset + i].color });
|
|
||||||
addDebugVertex(DebugVertex{ .position = corners[3], .color = meshlets[data.meshletOffset + i].color });
|
|
||||||
addDebugVertex(DebugVertex{ .position = corners[7], .color = meshlets[data.meshletOffset + i].color });
|
|
||||||
addDebugVertex(DebugVertex{ .position = corners[4], .color = meshlets[data.meshletOffset + i].color });
|
|
||||||
addDebugVertex(DebugVertex{ .position = corners[5], .color = meshlets[data.meshletOffset + i].color });
|
|
||||||
addDebugVertex(DebugVertex{ .position = corners[4], .color = meshlets[data.meshletOffset + i].color });
|
|
||||||
addDebugVertex(DebugVertex{ .position = corners[6], .color = meshlets[data.meshletOffset + i].color });
|
|
||||||
addDebugVertex(DebugVertex{ .position = corners[6], .color = meshlets[data.meshletOffset + i].color });
|
|
||||||
addDebugVertex(DebugVertex{ .position = corners[7], .color = meshlets[data.meshletOffset + i].color });
|
|
||||||
addDebugVertex(DebugVertex{ .position = corners[5], .color = meshlets[data.meshletOffset + i].color });
|
|
||||||
addDebugVertex(DebugVertex{ .position = corners[7], .color = meshlets[data.meshletOffset + i].color });
|
|
||||||
}
|
|
||||||
|
|
||||||
|
Matrix4 transformMatrix = transform.toMatrix() * mesh->transform;
|
||||||
|
matInstanceData.instanceData.add(InstanceData{
|
||||||
|
.transformMatrix = transformMatrix,
|
||||||
|
.inverseTransformMatrix = glm::inverse(transformMatrix),
|
||||||
|
});
|
||||||
|
const auto &data = meshData[mesh->id];
|
||||||
|
matInstanceData.instanceMeshData.add(data);
|
||||||
|
referencedInstance->updateDescriptor();
|
||||||
|
for (size_t i = 0; i < 0; ++i)
|
||||||
|
{
|
||||||
|
auto bounding = meshlets[data.meshletOffset + i].bounding;
|
||||||
|
StaticArray<Vector, 8> corners;
|
||||||
|
Vector min = bounding.min; // bounding.center - bounding.radius * Vector(1, 1, 1);
|
||||||
|
Vector max = bounding.max; // bounding.center + bounding.radius * Vector(1, 1, 1);
|
||||||
|
corners[0] = transformMatrix * Vector4(min.x, min.y, min.z, 1);
|
||||||
|
corners[1] = transformMatrix * Vector4(min.x, min.y, max.z, 1);
|
||||||
|
corners[2] = transformMatrix * Vector4(min.x, max.y, min.z, 1);
|
||||||
|
corners[3] = transformMatrix * Vector4(min.x, max.y, max.z, 1);
|
||||||
|
corners[4] = transformMatrix * Vector4(max.x, min.y, min.z, 1);
|
||||||
|
corners[5] = transformMatrix * Vector4(max.x, min.y, max.z, 1);
|
||||||
|
corners[6] = transformMatrix * Vector4(max.x, max.y, min.z, 1);
|
||||||
|
corners[7] = transformMatrix * Vector4(max.x, max.y, max.z, 1);
|
||||||
|
addDebugVertex(DebugVertex{.position = corners[0], .color = meshlets[data.meshletOffset + i].color});
|
||||||
|
addDebugVertex(DebugVertex{.position = corners[1], .color = meshlets[data.meshletOffset + i].color});
|
||||||
|
addDebugVertex(DebugVertex{.position = corners[0], .color = meshlets[data.meshletOffset + i].color});
|
||||||
|
addDebugVertex(DebugVertex{.position = corners[2], .color = meshlets[data.meshletOffset + i].color});
|
||||||
|
addDebugVertex(DebugVertex{.position = corners[1], .color = meshlets[data.meshletOffset + i].color});
|
||||||
|
addDebugVertex(DebugVertex{.position = corners[3], .color = meshlets[data.meshletOffset + i].color});
|
||||||
|
addDebugVertex(DebugVertex{.position = corners[2], .color = meshlets[data.meshletOffset + i].color});
|
||||||
|
addDebugVertex(DebugVertex{.position = corners[3], .color = meshlets[data.meshletOffset + i].color});
|
||||||
|
addDebugVertex(DebugVertex{.position = corners[0], .color = meshlets[data.meshletOffset + i].color});
|
||||||
|
addDebugVertex(DebugVertex{.position = corners[4], .color = meshlets[data.meshletOffset + i].color});
|
||||||
|
addDebugVertex(DebugVertex{.position = corners[1], .color = meshlets[data.meshletOffset + i].color});
|
||||||
|
addDebugVertex(DebugVertex{.position = corners[5], .color = meshlets[data.meshletOffset + i].color});
|
||||||
|
addDebugVertex(DebugVertex{.position = corners[2], .color = meshlets[data.meshletOffset + i].color});
|
||||||
|
addDebugVertex(DebugVertex{.position = corners[6], .color = meshlets[data.meshletOffset + i].color});
|
||||||
|
addDebugVertex(DebugVertex{.position = corners[3], .color = meshlets[data.meshletOffset + i].color});
|
||||||
|
addDebugVertex(DebugVertex{.position = corners[7], .color = meshlets[data.meshletOffset + i].color});
|
||||||
|
addDebugVertex(DebugVertex{.position = corners[4], .color = meshlets[data.meshletOffset + i].color});
|
||||||
|
addDebugVertex(DebugVertex{.position = corners[5], .color = meshlets[data.meshletOffset + i].color});
|
||||||
|
addDebugVertex(DebugVertex{.position = corners[4], .color = meshlets[data.meshletOffset + i].color});
|
||||||
|
addDebugVertex(DebugVertex{.position = corners[6], .color = meshlets[data.meshletOffset + i].color});
|
||||||
|
addDebugVertex(DebugVertex{.position = corners[6], .color = meshlets[data.meshletOffset + i].color});
|
||||||
|
addDebugVertex(DebugVertex{.position = corners[7], .color = meshlets[data.meshletOffset + i].color});
|
||||||
|
addDebugVertex(DebugVertex{.position = corners[5], .color = meshlets[data.meshletOffset + i].color});
|
||||||
|
addDebugVertex(DebugVertex{.position = corners[7], .color = meshlets[data.meshletOffset + i].color});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void VertexData::createDescriptors()
|
void VertexData::createDescriptors()
|
||||||
{
|
{
|
||||||
std::unique_lock l(materialDataLock);
|
std::unique_lock l(materialDataLock);
|
||||||
|
|
||||||
instanceData.clear();
|
instanceData.clear();
|
||||||
instanceMeshData.clear();
|
instanceMeshData.clear();
|
||||||
|
|
||||||
//uint32 numMeshlets = 0;
|
uint32 numMeshlets = 0;
|
||||||
//Array<uint32> cullingOffsets;
|
Array<uint32> cullingOffsets;
|
||||||
for (auto& mat : materialData)
|
for (auto &mat : materialData)
|
||||||
|
{
|
||||||
|
for (auto &instance : mat.instances)
|
||||||
{
|
{
|
||||||
for (auto& instance : mat.instances)
|
instance.offsets.instanceOffset = instanceData.size();
|
||||||
{
|
// instance.offsets.cullingCounterOffset = cullingOffsets.size();
|
||||||
instance.offsets.instanceOffset = instanceData.size();
|
// instance.numMeshlets = 0;
|
||||||
//instance.offsets.cullingCounterOffset = cullingOffsets.size();
|
for (size_t i = 0; i < instance.instanceData.size(); ++i)
|
||||||
//instance.numMeshlets = 0;
|
{
|
||||||
for (size_t i = 0; i < instance.instanceData.size(); ++i)
|
cullingOffsets.add(numMeshlets);
|
||||||
{
|
instanceData.add(instance.instanceData[i]);
|
||||||
instanceData.add(instance.instanceData[i]);
|
instanceMeshData.add(instance.instanceMeshData[i]);
|
||||||
instanceMeshData.add(instance.instanceMeshData[i]);
|
// instance.numMeshlets += instance.instanceMeshData[i].numMeshlets;
|
||||||
//instance.numMeshlets += instance.instanceMeshData[i].numMeshlets;
|
// cullingOffsets.add(numMeshlets);
|
||||||
//cullingOffsets.add(numMeshlets);
|
numMeshlets += instance.instanceMeshData[i].numMeshlets;
|
||||||
//numMeshlets += instance.numMeshlets;
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
//cullingOffsetBuffer->rotateBuffer(cullingOffsets.size() * sizeof(uint32));
|
}
|
||||||
//cullingOffsetBuffer->updateContents(ShaderBufferCreateInfo{
|
Array<MeshletCullingInfo> cullingData(numMeshlets);
|
||||||
// .sourceData = {
|
std::memset(cullingData.data(), 0xff, cullingData.size());
|
||||||
// .size = cullingOffsets.size() * sizeof(uint32),
|
cullingOffsetBuffer->rotateBuffer(cullingOffsets.size() * sizeof(uint32));
|
||||||
// .data = (uint8*)cullingOffsets.data(),
|
cullingOffsetBuffer->updateContents(ShaderBufferCreateInfo{
|
||||||
// },
|
.sourceData = {
|
||||||
// .numElements = cullingOffsets.size()
|
.size = cullingOffsets.size() * sizeof(uint32),
|
||||||
// });
|
.data = (uint8 *)cullingOffsets.data(),
|
||||||
//cullingOffsetBuffer->pipelineBarrier(
|
},
|
||||||
// Gfx::SE_ACCESS_TRANSFER_WRITE_BIT,
|
.numElements = cullingOffsets.size()});
|
||||||
// Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT,
|
cullingOffsetBuffer->pipelineBarrier(
|
||||||
// Gfx::SE_ACCESS_MEMORY_READ_BIT,
|
Gfx::SE_ACCESS_TRANSFER_WRITE_BIT,
|
||||||
// Gfx::SE_PIPELINE_STAGE_TOP_OF_PIPE_BIT
|
Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT,
|
||||||
//);
|
Gfx::SE_ACCESS_MEMORY_READ_BIT,
|
||||||
//cullingBuffer->rotateBuffer(numMeshlets * sizeof(uint32));
|
Gfx::SE_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
|
||||||
//cullingBuffer->updateContents(ShaderBufferCreateInfo{
|
|
||||||
// .sourceData = {
|
|
||||||
// .size = numMeshlets * sizeof(uint32),
|
|
||||||
// },
|
|
||||||
// .numElements = numMeshlets
|
|
||||||
// });
|
|
||||||
//cullingBuffer->pipelineBarrier(
|
|
||||||
// Gfx::SE_ACCESS_TRANSFER_WRITE_BIT,
|
|
||||||
// Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT,
|
|
||||||
// Gfx::SE_ACCESS_MEMORY_WRITE_BIT,
|
|
||||||
// Gfx::SE_PIPELINE_STAGE_TOP_OF_PIPE_BIT
|
|
||||||
//);
|
|
||||||
instanceBuffer->rotateBuffer(instanceData.size() * sizeof(InstanceData));
|
|
||||||
instanceBuffer->updateContents(ShaderBufferCreateInfo{
|
|
||||||
.sourceData = {
|
|
||||||
.size = instanceData.size() * sizeof(InstanceData),
|
|
||||||
.data = (uint8*)instanceData.data(),
|
|
||||||
},
|
|
||||||
.numElements = instanceData.size()
|
|
||||||
});
|
|
||||||
instanceBuffer->pipelineBarrier(
|
|
||||||
Gfx::SE_ACCESS_TRANSFER_WRITE_BIT,
|
|
||||||
Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT,
|
|
||||||
Gfx::SE_ACCESS_MEMORY_READ_BIT,
|
|
||||||
Gfx::SE_PIPELINE_STAGE_TOP_OF_PIPE_BIT
|
|
||||||
);
|
|
||||||
|
|
||||||
instanceMeshDataBuffer->rotateBuffer(sizeof(MeshData) * instanceMeshData.size());
|
cullingBuffer->rotateBuffer(numMeshlets * sizeof(MeshletCullingInfo));
|
||||||
instanceMeshDataBuffer->updateContents(ShaderBufferCreateInfo{
|
cullingBuffer->updateContents(ShaderBufferCreateInfo{
|
||||||
.sourceData = {
|
.sourceData = {
|
||||||
.size = sizeof(MeshData) * instanceMeshData.size(),
|
.size = numMeshlets * sizeof(MeshletCullingInfo),
|
||||||
.data = (uint8*)instanceMeshData.data(),
|
.data = (uint8 *)cullingData.data(),
|
||||||
},
|
},
|
||||||
.numElements = instanceMeshData.size()
|
.numElements = numMeshlets});
|
||||||
});
|
cullingBuffer->pipelineBarrier(
|
||||||
instanceMeshDataBuffer->pipelineBarrier(
|
Gfx::SE_ACCESS_TRANSFER_WRITE_BIT,
|
||||||
Gfx::SE_ACCESS_TRANSFER_WRITE_BIT,
|
Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT,
|
||||||
Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT,
|
Gfx::SE_ACCESS_MEMORY_WRITE_BIT,
|
||||||
Gfx::SE_ACCESS_MEMORY_READ_BIT,
|
Gfx::SE_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
|
||||||
Gfx::SE_PIPELINE_STAGE_TOP_OF_PIPE_BIT
|
instanceBuffer->rotateBuffer(instanceData.size() * sizeof(InstanceData));
|
||||||
);
|
instanceBuffer->updateContents(ShaderBufferCreateInfo{
|
||||||
instanceDataLayout->reset();
|
.sourceData = {
|
||||||
descriptorSet = instanceDataLayout->allocateDescriptorSet();
|
.size = instanceData.size() * sizeof(InstanceData),
|
||||||
descriptorSet->updateBuffer(0, instanceBuffer);
|
.data = (uint8 *)instanceData.data(),
|
||||||
descriptorSet->updateBuffer(1, instanceMeshDataBuffer);
|
},
|
||||||
descriptorSet->updateBuffer(2, meshletBuffer);
|
.numElements = instanceData.size()});
|
||||||
descriptorSet->updateBuffer(3, primitiveIndicesBuffer);
|
instanceBuffer->pipelineBarrier(
|
||||||
descriptorSet->updateBuffer(4, vertexIndicesBuffer);
|
Gfx::SE_ACCESS_TRANSFER_WRITE_BIT,
|
||||||
//descriptorSet->updateBuffer(5, cullingOffsetBuffer);
|
Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT,
|
||||||
//descriptorSet->updateBuffer(6, cullingBuffer);
|
Gfx::SE_ACCESS_MEMORY_READ_BIT,
|
||||||
|
Gfx::SE_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
|
||||||
|
|
||||||
descriptorSet->writeChanges();
|
instanceMeshDataBuffer->rotateBuffer(sizeof(MeshData) * instanceMeshData.size());
|
||||||
|
instanceMeshDataBuffer->updateContents(ShaderBufferCreateInfo{
|
||||||
|
.sourceData = {
|
||||||
|
.size = sizeof(MeshData) * instanceMeshData.size(),
|
||||||
|
.data = (uint8 *)instanceMeshData.data(),
|
||||||
|
},
|
||||||
|
.numElements = instanceMeshData.size()});
|
||||||
|
instanceMeshDataBuffer->pipelineBarrier(
|
||||||
|
Gfx::SE_ACCESS_TRANSFER_WRITE_BIT,
|
||||||
|
Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT,
|
||||||
|
Gfx::SE_ACCESS_MEMORY_READ_BIT,
|
||||||
|
Gfx::SE_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
|
||||||
|
instanceDataLayout->reset();
|
||||||
|
descriptorSet = instanceDataLayout->allocateDescriptorSet();
|
||||||
|
descriptorSet->updateBuffer(0, instanceBuffer);
|
||||||
|
descriptorSet->updateBuffer(1, instanceMeshDataBuffer);
|
||||||
|
descriptorSet->updateBuffer(2, meshletBuffer);
|
||||||
|
descriptorSet->updateBuffer(3, primitiveIndicesBuffer);
|
||||||
|
descriptorSet->updateBuffer(4, vertexIndicesBuffer);
|
||||||
|
descriptorSet->updateBuffer(5, cullingBuffer);
|
||||||
|
descriptorSet->updateBuffer(6, cullingOffsetBuffer);
|
||||||
|
|
||||||
|
descriptorSet->writeChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
void VertexData::loadMesh(MeshId id, Array<uint32> loadedIndices, Array<Meshlet> loadedMeshlets)
|
void VertexData::loadMesh(MeshId id, Array<uint32> loadedIndices, Array<Meshlet> loadedMeshlets)
|
||||||
{
|
{
|
||||||
assert(loadedMeshlets.size() < 2048);
|
assert(loadedMeshlets.size() < 2048);
|
||||||
std::unique_lock l(vertexDataLock);
|
std::unique_lock l(vertexDataLock);
|
||||||
meshlets.reserve(meshlets.size() + loadedMeshlets.size());
|
meshlets.reserve(meshlets.size() + loadedMeshlets.size());
|
||||||
vertexIndices.reserve(vertexIndices.size() + loadedMeshlets.size() * Gfx::numVerticesPerMeshlet);
|
vertexIndices.reserve(vertexIndices.size() + loadedMeshlets.size() * Gfx::numVerticesPerMeshlet);
|
||||||
primitiveIndices.reserve(primitiveIndices.size() + loadedMeshlets.size() * Gfx::numPrimitivesPerMeshlet * 3);
|
primitiveIndices.reserve(primitiveIndices.size() + loadedMeshlets.size() * Gfx::numPrimitivesPerMeshlet * 3);
|
||||||
uint32 meshletOffset = meshlets.size();
|
uint32 meshletOffset = meshlets.size();
|
||||||
AABB meshAABB;
|
AABB meshAABB;
|
||||||
for (uint32 i = 0; i < loadedMeshlets.size(); ++i)
|
for (uint32 i = 0; i < loadedMeshlets.size(); ++i)
|
||||||
{
|
{
|
||||||
Meshlet& m = loadedMeshlets[i];
|
Meshlet &m = loadedMeshlets[i];
|
||||||
meshAABB = meshAABB.combine(m.boundingBox);
|
meshAABB = meshAABB.combine(m.boundingBox);
|
||||||
uint32 vertexOffset = vertexIndices.size();
|
uint32 vertexOffset = vertexIndices.size();
|
||||||
vertexIndices.resize(vertexOffset + m.numVertices);
|
vertexIndices.resize(vertexOffset + m.numVertices);
|
||||||
std::memcpy(vertexIndices.data() + vertexOffset, m.uniqueVertices, m.numVertices * sizeof(uint32));
|
std::memcpy(vertexIndices.data() + vertexOffset, m.uniqueVertices, m.numVertices * sizeof(uint32));
|
||||||
uint32 primitiveOffset = primitiveIndices.size();
|
uint32 primitiveOffset = primitiveIndices.size();
|
||||||
primitiveIndices.resize(primitiveOffset + (m.numPrimitives * 3));
|
primitiveIndices.resize(primitiveOffset + (m.numPrimitives * 3));
|
||||||
std::memcpy(primitiveIndices.data() + primitiveOffset, m.primitiveLayout, m.numPrimitives * 3 * sizeof(uint8));
|
std::memcpy(primitiveIndices.data() + primitiveOffset, m.primitiveLayout, m.numPrimitives * 3 * sizeof(uint8));
|
||||||
meshlets.add(MeshletDescription{
|
meshlets.add(MeshletDescription{
|
||||||
.bounding = m.boundingBox,//.toSphere(),
|
.bounding = m.boundingBox, //.toSphere(),
|
||||||
.vertexCount = m.numVertices,
|
.vertexCount = m.numVertices,
|
||||||
.primitiveCount = m.numPrimitives,
|
.primitiveCount = m.numPrimitives,
|
||||||
.vertexOffset = vertexOffset,
|
.vertexOffset = vertexOffset,
|
||||||
.primitiveOffset = primitiveOffset,
|
.primitiveOffset = primitiveOffset,
|
||||||
.color = Vector((float)rand() / RAND_MAX,(float)rand() / RAND_MAX,(float)rand() / RAND_MAX),
|
.color = Vector((float)rand() / RAND_MAX, (float)rand() / RAND_MAX, (float)rand() / RAND_MAX),
|
||||||
.indicesOffset = (uint32)meshOffsets[id],
|
.indicesOffset = (uint32)meshOffsets[id],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
meshData[id] = MeshData{
|
meshData[id] = MeshData{
|
||||||
.bounding = meshAABB,//.toSphere(),
|
.bounding = meshAABB, //.toSphere(),
|
||||||
.numMeshlets = (uint32)loadedMeshlets.size(),
|
.numMeshlets = (uint32)loadedMeshlets.size(),
|
||||||
.meshletOffset = meshletOffset,
|
.meshletOffset = meshletOffset,
|
||||||
.firstIndex = (uint32)indices.size(),
|
.firstIndex = (uint32)indices.size(),
|
||||||
.numIndices = (uint32)loadedIndices.size(),
|
.numIndices = (uint32)loadedIndices.size(),
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!graphics->supportMeshShading())
|
if (!graphics->supportMeshShading())
|
||||||
{
|
{
|
||||||
indices.resize(indices.size() + loadedIndices.size());
|
indices.resize(indices.size() + loadedIndices.size());
|
||||||
std::memcpy(indices.data() + meshData[id].firstIndex, loadedIndices.data(), loadedIndices.size() * sizeof(uint32));
|
std::memcpy(indices.data() + meshData[id].firstIndex, loadedIndices.data(), loadedIndices.size() * sizeof(uint32));
|
||||||
indexBuffer = graphics->createIndexBuffer(IndexBufferCreateInfo{
|
indexBuffer = graphics->createIndexBuffer(IndexBufferCreateInfo{
|
||||||
.sourceData = {
|
.sourceData = {
|
||||||
.size = sizeof(uint32) * indices.size(),
|
.size = sizeof(uint32) * indices.size(),
|
||||||
.data = (uint8*)indices.data(),
|
.data = (uint8 *)indices.data(),
|
||||||
},
|
},
|
||||||
.indexType = Gfx::SE_INDEX_TYPE_UINT32,
|
.indexType = Gfx::SE_INDEX_TYPE_UINT32,
|
||||||
.name = "IndexBuffer",
|
.name = "IndexBuffer",
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
meshletBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||||
|
.sourceData = {
|
||||||
|
.size = sizeof(MeshletDescription) * meshlets.size(),
|
||||||
|
.data = (uint8 *)meshlets.data()},
|
||||||
|
.numElements = meshlets.size(),
|
||||||
|
.dynamic = false,
|
||||||
|
.name = "MeshletBuffer"});
|
||||||
|
|
||||||
}
|
vertexIndicesBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||||
meshletBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
.sourceData = {
|
||||||
.sourceData = {
|
.size = sizeof(uint32) * vertexIndices.size(),
|
||||||
.size = sizeof(MeshletDescription) * meshlets.size(),
|
.data = (uint8 *)vertexIndices.data(),
|
||||||
.data = (uint8*)meshlets.data()
|
},
|
||||||
},
|
.numElements = vertexIndices.size(),
|
||||||
.numElements = meshlets.size(),
|
.dynamic = false,
|
||||||
.dynamic = false,
|
.name = "VertexIndicesBuffer"});
|
||||||
.name = "MeshletBuffer"
|
|
||||||
});
|
primitiveIndicesBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||||
vertexIndicesBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
.sourceData = {
|
||||||
.sourceData = {
|
.size = sizeof(uint8) * primitiveIndices.size(),
|
||||||
.size = sizeof(uint32) * vertexIndices.size(),
|
.data = (uint8 *)primitiveIndices.data(),
|
||||||
.data = (uint8*)vertexIndices.data(),
|
},
|
||||||
},
|
.numElements = primitiveIndices.size(),
|
||||||
.numElements = vertexIndices.size(),
|
.dynamic = false,
|
||||||
.dynamic = false,
|
.name = "PrimitiveIndicesBuffer",
|
||||||
.name = "VertexIndicesBuffer"
|
});
|
||||||
});
|
|
||||||
primitiveIndicesBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
|
||||||
.sourceData = {
|
|
||||||
.size = sizeof(uint8) * primitiveIndices.size(),
|
|
||||||
.data = (uint8*)primitiveIndices.data(),
|
|
||||||
},
|
|
||||||
.numElements = primitiveIndices.size(),
|
|
||||||
.dynamic = false,
|
|
||||||
.name = "PrimitiveIndicesBuffer",
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MeshId VertexData::allocateVertexData(uint64 numVertices)
|
MeshId VertexData::allocateVertexData(uint64 numVertices)
|
||||||
{
|
{
|
||||||
std::unique_lock l(vertexDataLock);
|
std::unique_lock l(vertexDataLock);
|
||||||
MeshId res{ idCounter++ };
|
MeshId res{idCounter++};
|
||||||
meshOffsets[res] = head;
|
meshOffsets[res] = head;
|
||||||
meshVertexCounts[res] = numVertices;
|
meshVertexCounts[res] = numVertices;
|
||||||
head += numVertices;
|
head += numVertices;
|
||||||
if (head > verticesAllocated)
|
if (head > verticesAllocated)
|
||||||
{
|
{
|
||||||
verticesAllocated = std::max(head, verticesAllocated + NUM_DEFAULT_ELEMENTS);
|
verticesAllocated = std::max(head, verticesAllocated + NUM_DEFAULT_ELEMENTS);
|
||||||
resizeBuffers();
|
resizeBuffers();
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64 VertexData::getMeshOffset(MeshId id)
|
uint64 VertexData::getMeshOffset(MeshId id)
|
||||||
{
|
{
|
||||||
return meshOffsets[id];
|
return meshOffsets[id];
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64 VertexData::getMeshVertexCount(MeshId id)
|
uint64 VertexData::getMeshVertexCount(MeshId id)
|
||||||
{
|
{
|
||||||
return meshVertexCounts[id];
|
return meshVertexCounts[id];
|
||||||
}
|
}
|
||||||
|
|
||||||
List<VertexData*> vertexDataList;
|
List<VertexData *> vertexDataList;
|
||||||
|
|
||||||
List<VertexData*> VertexData::getList()
|
List<VertexData *> VertexData::getList()
|
||||||
{
|
{
|
||||||
return vertexDataList;
|
return vertexDataList;
|
||||||
}
|
}
|
||||||
|
|
||||||
VertexData* VertexData::findByTypeName(std::string name)
|
VertexData *VertexData::findByTypeName(std::string name)
|
||||||
{
|
{
|
||||||
for (auto vd : vertexDataList)
|
for (auto vd : vertexDataList)
|
||||||
|
{
|
||||||
|
if (vd->getTypeName() == name)
|
||||||
{
|
{
|
||||||
if (vd->getTypeName() == name)
|
return vd;
|
||||||
{
|
|
||||||
return vd;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return nullptr;
|
}
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VertexData::init(Gfx::PGraphics _graphics)
|
void VertexData::init(Gfx::PGraphics _graphics)
|
||||||
{
|
{
|
||||||
graphics = _graphics;
|
graphics = _graphics;
|
||||||
verticesAllocated = NUM_DEFAULT_ELEMENTS;
|
verticesAllocated = NUM_DEFAULT_ELEMENTS;
|
||||||
instanceDataLayout = graphics->createDescriptorLayout("pScene");
|
instanceDataLayout = graphics->createDescriptorLayout("pScene");
|
||||||
|
|
||||||
// instanceData
|
// instanceData
|
||||||
instanceDataLayout->addDescriptorBinding(Gfx::DescriptorBinding{ .binding = 0, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER, });
|
instanceDataLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||||
// meshData
|
.binding = 0,
|
||||||
instanceDataLayout->addDescriptorBinding(Gfx::DescriptorBinding{ .binding = 1, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER, });
|
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||||
// meshletData
|
});
|
||||||
instanceDataLayout->addDescriptorBinding(Gfx::DescriptorBinding{ .binding = 2, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER });
|
// meshData
|
||||||
// primitiveIndices
|
instanceDataLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||||
instanceDataLayout->addDescriptorBinding(Gfx::DescriptorBinding{ .binding = 3, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER });
|
.binding = 1,
|
||||||
// vertexIndices
|
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||||
instanceDataLayout->addDescriptorBinding(Gfx::DescriptorBinding{ .binding = 4, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER });
|
});
|
||||||
// cullingList
|
// meshletData
|
||||||
//instanceDataLayout->addDescriptorBinding(Gfx::DescriptorBinding{ .binding = 5, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER });
|
instanceDataLayout->addDescriptorBinding(Gfx::DescriptorBinding{.binding = 2, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER});
|
||||||
// cullingOffset
|
// primitiveIndices
|
||||||
//instanceDataLayout->addDescriptorBinding(Gfx::DescriptorBinding{ .binding = 6, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER });
|
instanceDataLayout->addDescriptorBinding(Gfx::DescriptorBinding{.binding = 3, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER});
|
||||||
|
// vertexIndices
|
||||||
|
instanceDataLayout->addDescriptorBinding(Gfx::DescriptorBinding{.binding = 4, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER});
|
||||||
|
// cullingList
|
||||||
|
instanceDataLayout->addDescriptorBinding(Gfx::DescriptorBinding{.binding = 5, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER});
|
||||||
|
// cullingOffset
|
||||||
|
instanceDataLayout->addDescriptorBinding(Gfx::DescriptorBinding{.binding = 6, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER});
|
||||||
|
|
||||||
//cullingOffsetBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
cullingOffsetBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||||
// .dynamic = true,
|
.dynamic = true,
|
||||||
// .name = "MeshletOffset",
|
.name = "MeshletOffset",
|
||||||
// });
|
});
|
||||||
//cullingBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
cullingBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||||
// .dynamic = true,
|
.dynamic = true,
|
||||||
// .name = "MeshletCulling",
|
.name = "MeshletCulling",
|
||||||
// });
|
});
|
||||||
instanceBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
instanceBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||||
.dynamic = true,
|
.dynamic = true,
|
||||||
.name = "InstanceBuffer",
|
.name = "InstanceBuffer",
|
||||||
});
|
});
|
||||||
instanceMeshDataBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
instanceMeshDataBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||||
.dynamic = true,
|
.dynamic = true,
|
||||||
.name = "MeshDataBuffer",
|
.name = "MeshDataBuffer",
|
||||||
});
|
});
|
||||||
instanceDataLayout->create();
|
instanceDataLayout->create();
|
||||||
resizeBuffers();
|
resizeBuffers();
|
||||||
graphics->getShaderCompiler()->registerVertexData(this);
|
graphics->getShaderCompiler()->registerVertexData(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VertexData::destroy()
|
void VertexData::destroy()
|
||||||
{
|
{
|
||||||
instanceBuffer = nullptr;
|
instanceBuffer = nullptr;
|
||||||
instanceMeshDataBuffer = nullptr;
|
instanceMeshDataBuffer = nullptr;
|
||||||
instanceDataLayout = nullptr;
|
instanceDataLayout = nullptr;
|
||||||
meshletBuffer = nullptr;
|
meshletBuffer = nullptr;
|
||||||
vertexIndicesBuffer = nullptr;
|
vertexIndicesBuffer = nullptr;
|
||||||
primitiveIndicesBuffer = nullptr;
|
primitiveIndicesBuffer = nullptr;
|
||||||
indexBuffer = nullptr;
|
indexBuffer = nullptr;
|
||||||
meshData.clear();
|
meshData.clear();
|
||||||
materialData.clear();
|
materialData.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
VertexData::VertexData()
|
VertexData::VertexData()
|
||||||
: idCounter(0)
|
: idCounter(0), head(0), verticesAllocated(0), dirty(false)
|
||||||
, head(0)
|
|
||||||
, verticesAllocated(0)
|
|
||||||
, dirty(false)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,60 +12,65 @@ constexpr uint64 MAX_TEXCOORDS = 8;
|
|||||||
|
|
||||||
namespace Seele
|
namespace Seele
|
||||||
{
|
{
|
||||||
DECLARE_REF(Mesh)
|
DECLARE_REF(Mesh)
|
||||||
struct MeshId
|
struct MeshId
|
||||||
{
|
{
|
||||||
uint64 id;
|
uint64 id;
|
||||||
std::strong_ordering operator<=>(const MeshId& other) const
|
std::strong_ordering operator<=>(const MeshId &other) const
|
||||||
{
|
{
|
||||||
return id <=> other.id;
|
return id <=> other.id;
|
||||||
}
|
}
|
||||||
bool operator==(const MeshId& other) const
|
bool operator==(const MeshId &other) const
|
||||||
{
|
{
|
||||||
return id == other.id;
|
return id == other.id;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
class VertexData
|
class VertexData
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
struct InstanceData
|
struct InstanceData
|
||||||
{
|
{
|
||||||
Matrix4 transformMatrix;
|
Matrix4 transformMatrix;
|
||||||
Matrix4 inverseTransformMatrix;
|
Matrix4 inverseTransformMatrix;
|
||||||
};
|
};
|
||||||
struct MeshData
|
struct MeshData
|
||||||
{
|
{
|
||||||
AABB bounding;
|
AABB bounding;
|
||||||
uint32 numMeshlets = 0;
|
uint32 numMeshlets = 0;
|
||||||
uint32 meshletOffset = 0;
|
uint32 meshletOffset = 0;
|
||||||
uint32 firstIndex = 0;
|
uint32 firstIndex = 0;
|
||||||
uint32 numIndices = 0;
|
uint32 numIndices = 0;
|
||||||
};
|
};
|
||||||
struct DrawCallOffsets
|
struct DrawCallOffsets
|
||||||
{
|
{
|
||||||
uint32 instanceOffset = 0;
|
uint32 instanceOffset = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct MeshletCullingInfo
|
||||||
|
{
|
||||||
|
uint64_t cull[256 / 64];
|
||||||
};
|
};
|
||||||
struct BatchedDrawCall
|
struct BatchedDrawCall
|
||||||
{
|
{
|
||||||
PMaterialInstance materialInstance;
|
PMaterialInstance materialInstance;
|
||||||
DrawCallOffsets offsets;
|
DrawCallOffsets offsets;
|
||||||
Array<InstanceData> instanceData;
|
Array<InstanceData> instanceData;
|
||||||
Array<MeshData> instanceMeshData;
|
Array<MeshData> instanceMeshData;
|
||||||
};
|
};
|
||||||
struct MaterialData
|
struct MaterialData
|
||||||
{
|
{
|
||||||
PMaterial material;
|
PMaterial material;
|
||||||
Array<BatchedDrawCall> instances;
|
Array<BatchedDrawCall> instances;
|
||||||
};
|
};
|
||||||
void resetMeshData();
|
void resetMeshData();
|
||||||
void updateMesh(PMesh mesh, Component::Transform& transform);
|
void updateMesh(PMesh mesh, Component::Transform &transform);
|
||||||
void createDescriptors();
|
void createDescriptors();
|
||||||
void loadMesh(MeshId id, Array<uint32> indices, Array<Meshlet> meshlets);
|
void loadMesh(MeshId id, Array<uint32> indices, Array<Meshlet> meshlets);
|
||||||
MeshId allocateVertexData(uint64 numVertices);
|
MeshId allocateVertexData(uint64 numVertices);
|
||||||
uint64 getMeshOffset(MeshId id);
|
uint64 getMeshOffset(MeshId id);
|
||||||
uint64 getMeshVertexCount(MeshId id);
|
uint64 getMeshVertexCount(MeshId id);
|
||||||
virtual void serializeMesh(MeshId id, uint64 numVertices, ArchiveBuffer& buffer) = 0;
|
virtual void serializeMesh(MeshId id, uint64 numVertices, ArchiveBuffer &buffer) = 0;
|
||||||
virtual void deserializeMesh(MeshId id, ArchiveBuffer& buffer) = 0;
|
virtual void deserializeMesh(MeshId id, ArchiveBuffer &buffer) = 0;
|
||||||
virtual void bindBuffers(Gfx::PRenderCommand command) = 0;
|
virtual void bindBuffers(Gfx::PRenderCommand command) = 0;
|
||||||
virtual Gfx::PDescriptorLayout getVertexDataLayout() = 0;
|
virtual Gfx::PDescriptorLayout getVertexDataLayout() = 0;
|
||||||
virtual Gfx::PDescriptorSet getVertexDataSet() = 0;
|
virtual Gfx::PDescriptorSet getVertexDataSet() = 0;
|
||||||
@@ -73,26 +78,28 @@ public:
|
|||||||
Gfx::PIndexBuffer getIndexBuffer() { return indexBuffer; }
|
Gfx::PIndexBuffer getIndexBuffer() { return indexBuffer; }
|
||||||
Gfx::PDescriptorLayout getInstanceDataLayout() { return instanceDataLayout; }
|
Gfx::PDescriptorLayout getInstanceDataLayout() { return instanceDataLayout; }
|
||||||
Gfx::PDescriptorSet getInstanceDataSet() { return descriptorSet; }
|
Gfx::PDescriptorSet getInstanceDataSet() { return descriptorSet; }
|
||||||
const Array<MaterialData>& getMaterialData() const { return materialData; }
|
const Array<MaterialData> &getMaterialData() const { return materialData; }
|
||||||
const MeshData& getMeshData(MeshId id) { return meshData[id]; }
|
const MeshData &getMeshData(MeshId id) { return meshData[id]; }
|
||||||
uint64 getIndicesOffset(uint32 meshletIndex) { return meshlets[meshletIndex].indicesOffset; }
|
uint64 getIndicesOffset(uint32 meshletIndex) { return meshlets[meshletIndex].indicesOffset; }
|
||||||
static List<VertexData*> getList();
|
uint64 getNumInstances() const { return instanceData.size(); }
|
||||||
static VertexData* findByTypeName(std::string name);
|
static List<VertexData *> getList();
|
||||||
|
static VertexData *findByTypeName(std::string name);
|
||||||
virtual void init(Gfx::PGraphics graphics);
|
virtual void init(Gfx::PGraphics graphics);
|
||||||
virtual void destroy();
|
virtual void destroy();
|
||||||
protected:
|
|
||||||
|
protected:
|
||||||
virtual void resizeBuffers() = 0;
|
virtual void resizeBuffers() = 0;
|
||||||
virtual void updateBuffers() = 0;
|
virtual void updateBuffers() = 0;
|
||||||
VertexData();
|
VertexData();
|
||||||
struct MeshletDescription
|
struct MeshletDescription
|
||||||
{
|
{
|
||||||
AABB bounding;
|
AABB bounding;
|
||||||
uint32 vertexCount;
|
uint32 vertexCount;
|
||||||
uint32 primitiveCount;
|
uint32 primitiveCount;
|
||||||
uint32 vertexOffset;
|
uint32 vertexOffset;
|
||||||
uint32 primitiveOffset;
|
uint32 primitiveOffset;
|
||||||
Vector color;
|
Vector color;
|
||||||
uint32 indicesOffset = 0;
|
uint32 indicesOffset = 0;
|
||||||
};
|
};
|
||||||
std::mutex materialDataLock;
|
std::mutex materialDataLock;
|
||||||
Array<MaterialData> materialData;
|
Array<MaterialData> materialData;
|
||||||
@@ -110,9 +117,9 @@ protected:
|
|||||||
Gfx::OShaderBuffer meshletBuffer;
|
Gfx::OShaderBuffer meshletBuffer;
|
||||||
Gfx::OShaderBuffer vertexIndicesBuffer;
|
Gfx::OShaderBuffer vertexIndicesBuffer;
|
||||||
Gfx::OShaderBuffer primitiveIndicesBuffer;
|
Gfx::OShaderBuffer primitiveIndicesBuffer;
|
||||||
// temporary meshlet culling buffer, passed from task to mesh shader
|
// Holds culling information for every meshlet for each instance
|
||||||
//Gfx::OShaderBuffer cullingBuffer;
|
Gfx::OShaderBuffer cullingBuffer;
|
||||||
//Gfx::OShaderBuffer cullingOffsetBuffer;
|
Gfx::OShaderBuffer cullingOffsetBuffer;
|
||||||
// for legacy pipeline
|
// for legacy pipeline
|
||||||
Gfx::OIndexBuffer indexBuffer;
|
Gfx::OIndexBuffer indexBuffer;
|
||||||
// Material data
|
// Material data
|
||||||
@@ -122,8 +129,8 @@ protected:
|
|||||||
Gfx::OShaderBuffer instanceMeshDataBuffer;
|
Gfx::OShaderBuffer instanceMeshDataBuffer;
|
||||||
Gfx::PDescriptorSet descriptorSet;
|
Gfx::PDescriptorSet descriptorSet;
|
||||||
uint64 idCounter;
|
uint64 idCounter;
|
||||||
uint64 head;
|
uint64 head;
|
||||||
uint64 verticesAllocated;
|
uint64 verticesAllocated;
|
||||||
bool dirty;
|
bool dirty;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ void Fence::reset()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Fence::wait(uint32 timeout)
|
void Fence::wait(uint64 timeout)
|
||||||
{
|
{
|
||||||
VkFence fences[] = {fence};
|
VkFence fences[] = {fence};
|
||||||
VkResult r = vkWaitForFences(graphics->getDevice(), 1, fences, true, timeout);
|
VkResult r = vkWaitForFences(graphics->getDevice(), 1, fences, true, timeout);
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ public:
|
|||||||
{
|
{
|
||||||
return fence;
|
return fence;
|
||||||
}
|
}
|
||||||
void wait(uint32 timeout);
|
void wait(uint64 timeout);
|
||||||
bool operator<(const Fence &other) const
|
bool operator<(const Fence &other) const
|
||||||
{
|
{
|
||||||
return fence < other.fence;
|
return fence < other.fence;
|
||||||
|
|||||||
@@ -7,8 +7,12 @@
|
|||||||
#include "System/LightGather.h"
|
#include "System/LightGather.h"
|
||||||
#include "System/MeshUpdater.h"
|
#include "System/MeshUpdater.h"
|
||||||
#include "System/CameraUpdater.h"
|
#include "System/CameraUpdater.h"
|
||||||
#include "Graphics/Vulkan/Graphics.h"
|
#include "Graphics/RenderPass/CachedDepthPass.h"
|
||||||
#include "Graphics/Vulkan/Allocator.h"
|
#include "Graphics/RenderPass/DepthPrepass.h"
|
||||||
|
#include "Graphics/RenderPass/LightCullingPass.h"
|
||||||
|
#include "Graphics/RenderPass/BasePass.h"
|
||||||
|
#include "Graphics/RenderPass/SkyboxRenderPass.h"
|
||||||
|
#include "Graphics/RenderPass/DebugPass.h"
|
||||||
|
|
||||||
using namespace Seele;
|
using namespace Seele;
|
||||||
|
|
||||||
@@ -22,10 +26,9 @@ GameView::GameView(Gfx::PGraphics graphics, PWindow window, const ViewportCreate
|
|||||||
, gameInterface(dllPath)
|
, gameInterface(dllPath)
|
||||||
{
|
{
|
||||||
reloadGame();
|
reloadGame();
|
||||||
//renderGraph.addPass(new StaticDepthPrepass(graphics, scene));
|
renderGraph.addPass(new CachedDepthPass(graphics, scene));
|
||||||
renderGraph.addPass(new DepthPrepass(graphics, scene));
|
renderGraph.addPass(new DepthPrepass(graphics, scene));
|
||||||
renderGraph.addPass(new LightCullingPass(graphics, scene));
|
renderGraph.addPass(new LightCullingPass(graphics, scene));
|
||||||
//renderGraph.addPass(new StaticBasePass(graphics, scene));
|
|
||||||
renderGraph.addPass(new BasePass(graphics, scene));
|
renderGraph.addPass(new BasePass(graphics, scene));
|
||||||
renderGraph.addPass(new DebugPass(graphics, scene));
|
renderGraph.addPass(new DebugPass(graphics, scene));
|
||||||
//renderGraph.addPass(new SkyboxRenderPass(graphics, scene));
|
//renderGraph.addPass(new SkyboxRenderPass(graphics, scene));
|
||||||
|
|||||||
@@ -1,11 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "Window/View.h"
|
#include "Window/View.h"
|
||||||
#include "Scene/Scene.h"
|
#include "Scene/Scene.h"
|
||||||
#include "Graphics/RenderPass/DepthPrepass.h"
|
|
||||||
#include "Graphics/RenderPass/LightCullingPass.h"
|
|
||||||
#include "Graphics/RenderPass/BasePass.h"
|
|
||||||
#include "Graphics/RenderPass/SkyboxRenderPass.h"
|
|
||||||
#include "Graphics/RenderPass/DebugPass.h"
|
|
||||||
#include "System/KeyboardInput.h"
|
#include "System/KeyboardInput.h"
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
#include "Platform/Windows/GameInterface.h" // TODO
|
#include "Platform/Windows/GameInterface.h" // TODO
|
||||||
@@ -15,34 +10,35 @@
|
|||||||
|
|
||||||
namespace Seele
|
namespace Seele
|
||||||
{
|
{
|
||||||
class GameView : public View
|
class GameView : public View
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
GameView(Gfx::PGraphics graphics, PWindow window, const ViewportCreateInfo &createInfo, std::string dllPath);
|
GameView(Gfx::PGraphics graphics, PWindow window, const ViewportCreateInfo &createInfo, std::string dllPath);
|
||||||
virtual ~GameView();
|
virtual ~GameView();
|
||||||
virtual void beginUpdate() override;
|
virtual void beginUpdate() override;
|
||||||
virtual void update() override;
|
virtual void update() override;
|
||||||
virtual void commitUpdate() override;
|
virtual void commitUpdate() override;
|
||||||
|
|
||||||
virtual void prepareRender() override;
|
virtual void prepareRender() override;
|
||||||
virtual void render() override;
|
virtual void render() override;
|
||||||
|
|
||||||
void reloadGame();
|
void reloadGame();
|
||||||
protected:
|
|
||||||
virtual void applyArea(URect rect) override;
|
protected:
|
||||||
OScene scene;
|
virtual void applyArea(URect rect) override;
|
||||||
GameInterface gameInterface;
|
OScene scene;
|
||||||
|
GameInterface gameInterface;
|
||||||
RenderGraph renderGraph;
|
RenderGraph renderGraph;
|
||||||
|
|
||||||
PSystemGraph systemGraph;
|
PSystemGraph systemGraph;
|
||||||
System::PKeyboardInput keyboardSystem;
|
System::PKeyboardInput keyboardSystem;
|
||||||
float updateTime = 0;
|
float updateTime = 0;
|
||||||
|
|
||||||
virtual void keyCallback(Seele::KeyCode code, Seele::InputAction action, Seele::KeyModifier modifier) override;
|
virtual void keyCallback(Seele::KeyCode code, Seele::InputAction action, Seele::KeyModifier modifier) override;
|
||||||
virtual void mouseMoveCallback(double xPos, double yPos) override;
|
virtual void mouseMoveCallback(double xPos, double yPos) override;
|
||||||
virtual void mouseButtonCallback(Seele::MouseButton button, Seele::InputAction action, Seele::KeyModifier modifier) override;
|
virtual void mouseButtonCallback(Seele::MouseButton button, Seele::InputAction action, Seele::KeyModifier modifier) override;
|
||||||
virtual void scrollCallback(double xOffset, double yOffset) override;
|
virtual void scrollCallback(double xOffset, double yOffset) override;
|
||||||
virtual void fileCallback(int count, const char** paths) override;
|
virtual void fileCallback(int count, const char **paths) override;
|
||||||
};
|
};
|
||||||
DEFINE_REF(GameView)
|
DEFINE_REF(GameView)
|
||||||
} // namespace Seele
|
} // namespace Seele
|
||||||
|
|||||||
Reference in New Issue
Block a user