Fixing the maximum 2048 meshlet limit
This commit is contained in:
@@ -20,9 +20,8 @@ struct MeshData
|
||||
uint32_t numIndices;
|
||||
};
|
||||
|
||||
static const uint32_t MAX_VERTICES = 64;
|
||||
static const uint32_t MAX_PRIMITIVES = 128;
|
||||
static const uint32_t MAX_MESHLETS_PER_INSTANCE = 2048;
|
||||
static const uint32_t MAX_VERTICES = 256;
|
||||
static const uint32_t MAX_PRIMITIVES = 256;
|
||||
|
||||
struct InstanceData
|
||||
{
|
||||
@@ -77,7 +76,7 @@ uint decodePrimitive(uint32_t encoded)
|
||||
|
||||
struct MeshPayload
|
||||
{
|
||||
uint culledMeshlets[MAX_MESHLETS_PER_INSTANCE];
|
||||
uint culledMeshlets[2048];
|
||||
uint instanceId;
|
||||
uint meshletOffset;
|
||||
uint cullingOffset;
|
||||
|
||||
@@ -159,8 +159,8 @@ static constexpr bool useAsyncCompute = false;
|
||||
static constexpr bool useMeshShading = true;
|
||||
static constexpr uint32 numFramesBuffered = 3;
|
||||
|
||||
static constexpr uint32 numVerticesPerMeshlet = 64;
|
||||
static constexpr uint32 numPrimitivesPerMeshlet = 126;
|
||||
static constexpr uint32 numVerticesPerMeshlet = 256;
|
||||
static constexpr uint32 numPrimitivesPerMeshlet = 256;
|
||||
double getCurrentFrameDelta();
|
||||
double getCurrentFrameTime();
|
||||
uint32 getCurrentFrameIndex();
|
||||
|
||||
@@ -14,7 +14,7 @@ void Mesh::save(ArchiveBuffer& buffer) const {
|
||||
Serialization::save(buffer, vertexCount);
|
||||
Serialization::save(buffer, referencedMaterial->getFolderPath());
|
||||
Serialization::save(buffer, referencedMaterial->getName());
|
||||
vertexData->serializeMesh(id, vertexCount, buffer);
|
||||
vertexData->serializeMesh(id, buffer);
|
||||
}
|
||||
|
||||
void Mesh::load(ArchiveBuffer& buffer) {
|
||||
|
||||
@@ -135,10 +135,10 @@ void BasePass::beginFrame(const Component::Camera& cam) {
|
||||
}
|
||||
|
||||
void BasePass::render() {
|
||||
/*opaqueCulling->updateBuffer(0, 0, oLightIndexList);
|
||||
opaqueCulling->updateTexture(1, 0, oLightGrid);
|
||||
transparentCulling->updateBuffer(0, 0, tLightIndexList);
|
||||
transparentCulling->updateTexture(1, 0, tLightGrid);
|
||||
opaqueCulling->updateBuffer(LIGHTINDEX_NAME, 0, oLightIndexList);
|
||||
opaqueCulling->updateTexture(LIGHTGRID_NAME, 0, oLightGrid);
|
||||
transparentCulling->updateBuffer(LIGHTINDEX_NAME, 0, tLightIndexList);
|
||||
transparentCulling->updateTexture(LIGHTGRID_NAME, 0, tLightGrid);
|
||||
opaqueCulling->writeChanges();
|
||||
transparentCulling->writeChanges();
|
||||
|
||||
@@ -153,7 +153,7 @@ void BasePass::render() {
|
||||
// Base Rendering
|
||||
for (VertexData* vertexData : VertexData::getList()) {
|
||||
transparentData.addAll(vertexData->getTransparentData());
|
||||
vertexData->getInstanceDataSet()->updateBuffer(6, 0, cullingBuffer);
|
||||
vertexData->getInstanceDataSet()->updateBuffer(VertexData::CULLINGDATA_NAME, 0, cullingBuffer);
|
||||
vertexData->getInstanceDataSet()->writeChanges();
|
||||
permutation.setVertexData(vertexData->getTypeName());
|
||||
const auto& materials = vertexData->getMaterialData();
|
||||
@@ -231,7 +231,7 @@ void BasePass::render() {
|
||||
Gfx::SE_SHADER_STAGE_FRAGMENT_BIT,
|
||||
0, sizeof(VertexData::DrawCallOffsets), &drawCall.offsets);
|
||||
if (graphics->supportMeshShading()) {
|
||||
command->drawMesh(drawCall.instanceMeshData.size(), 1, 1);
|
||||
//command->drawMesh(drawCall.instanceMeshData.size(), 1, 1);
|
||||
} else {
|
||||
command->bindIndexBuffer(vertexData->getIndexBuffer());
|
||||
for (const auto& meshData : drawCall.instanceMeshData) {
|
||||
@@ -247,9 +247,8 @@ void BasePass::render() {
|
||||
|
||||
//commands.add(waterRenderer->render(viewParamsSet));
|
||||
//commands.add(terrainRenderer->render(viewParamsSet));
|
||||
*/
|
||||
|
||||
// Skybox
|
||||
graphics->beginRenderPass(renderPass);
|
||||
{
|
||||
Gfx::ORenderCommand skyboxCommand = graphics->createRenderCommand("SkyboxRender");
|
||||
skyboxCommand->setViewport(viewport);
|
||||
@@ -258,8 +257,6 @@ void BasePass::render() {
|
||||
skyboxCommand->draw(36, 1, 0, 0);
|
||||
graphics->executeCommands(std::move(skyboxCommand));
|
||||
}
|
||||
graphics->endRenderPass();
|
||||
/*
|
||||
// Transparent rendering
|
||||
{
|
||||
permutation.setDepthCulling(false); // ignore visibility infos for transparency
|
||||
@@ -348,7 +345,7 @@ void BasePass::render() {
|
||||
Gfx::SE_SHADER_STAGE_FRAGMENT_BIT,
|
||||
0, sizeof(VertexData::DrawCallOffsets), &t.offsets);
|
||||
if (graphics->supportMeshShading()) {
|
||||
transparentCommand->drawMesh(1, 1, 1);
|
||||
//transparentCommand->drawMesh(1, 1, 1);
|
||||
} else {
|
||||
// command->bindIndexBuffer(t.vertexData->getIndexBuffer());
|
||||
// for (const auto& meshData : drawCall.instanceMeshData) {
|
||||
@@ -376,37 +373,40 @@ void BasePass::render() {
|
||||
query->endQuery();
|
||||
timestamps->write(Gfx::SE_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, "BaseEnd");
|
||||
gDebugVertices.clear();
|
||||
*/
|
||||
}
|
||||
|
||||
void BasePass::endFrame() {}
|
||||
|
||||
void BasePass::publishOutputs() {
|
||||
TextureCreateInfo depthBufferInfo = {
|
||||
basePassDepth = graphics->createTexture2D(TextureCreateInfo{
|
||||
.format = Gfx::SE_FORMAT_D32_SFLOAT,
|
||||
.width = viewport->getOwner()->getFramebufferWidth(),
|
||||
.height = viewport->getOwner()->getFramebufferHeight(),
|
||||
.usage = Gfx::SE_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
|
||||
};
|
||||
basePassDepth = graphics->createTexture2D(depthBufferInfo);
|
||||
});
|
||||
|
||||
TextureCreateInfo msDepthInfo = {
|
||||
basePassColor = graphics->createTexture2D(TextureCreateInfo{
|
||||
.format = Gfx::SE_FORMAT_R32G32B32A32_SFLOAT,
|
||||
.width = viewport->getOwner()->getFramebufferWidth(),
|
||||
.height = viewport->getOwner()->getFramebufferHeight(),
|
||||
.usage = Gfx::SE_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
|
||||
});
|
||||
|
||||
msBasePassDepth = graphics->createTexture2D(TextureCreateInfo{
|
||||
.format = Gfx::SE_FORMAT_D32_SFLOAT,
|
||||
.width = viewport->getOwner()->getFramebufferWidth(),
|
||||
.height = viewport->getOwner()->getFramebufferHeight(),
|
||||
.samples = viewport->getSamples(),
|
||||
.usage = Gfx::SE_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | Gfx::SE_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT,
|
||||
};
|
||||
msBasePassDepth = graphics->createTexture2D(msDepthInfo);
|
||||
|
||||
TextureCreateInfo msBaseColorInfo = {
|
||||
.format = viewport->getOwner()->getSwapchainFormat(),
|
||||
});
|
||||
|
||||
msBasePassColor = graphics->createTexture2D(TextureCreateInfo{
|
||||
.format = Gfx::SE_FORMAT_R32G32B32A32_SFLOAT,
|
||||
.width = viewport->getOwner()->getFramebufferWidth(),
|
||||
.height = viewport->getOwner()->getFramebufferHeight(),
|
||||
.samples = viewport->getSamples(),
|
||||
.usage = Gfx::SE_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | Gfx::SE_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT,
|
||||
};
|
||||
msBasePassColor = graphics->createTexture2D(msBaseColorInfo);
|
||||
});
|
||||
|
||||
depthAttachment =
|
||||
Gfx::RenderTargetAttachment(basePassDepth, Gfx::SE_IMAGE_LAYOUT_UNDEFINED, Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
|
||||
@@ -418,7 +418,7 @@ void BasePass::publishOutputs() {
|
||||
msDepthAttachment.clear.depthStencil.depth = 0.0f;
|
||||
|
||||
colorAttachment = Gfx::RenderTargetAttachment(viewport, Gfx::SE_IMAGE_LAYOUT_UNDEFINED, Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||
Gfx::SE_ATTACHMENT_LOAD_OP_DONT_CARE, Gfx::SE_ATTACHMENT_STORE_OP_DONT_CARE);
|
||||
Gfx::SE_ATTACHMENT_LOAD_OP_DONT_CARE, Gfx::SE_ATTACHMENT_STORE_OP_STORE);
|
||||
|
||||
msColorAttachment =
|
||||
Gfx::RenderTargetAttachment(msBasePassColor, Gfx::SE_IMAGE_LAYOUT_UNDEFINED, Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||
|
||||
@@ -19,6 +19,7 @@ class BasePass : public RenderPass {
|
||||
virtual void createRenderPass() override;
|
||||
|
||||
private:
|
||||
// hdr
|
||||
Gfx::RenderTargetAttachment msColorAttachment;
|
||||
Gfx::RenderTargetAttachment colorAttachment;
|
||||
Gfx::RenderTargetAttachment msDepthAttachment;
|
||||
@@ -37,7 +38,9 @@ class BasePass : public RenderPass {
|
||||
// use a different texture here so we can do multisampling
|
||||
Gfx::OTexture2D msBasePassDepth;
|
||||
Gfx::OTexture2D basePassDepth;
|
||||
// hdr
|
||||
Gfx::OTexture2D msBasePassColor;
|
||||
Gfx::OTexture2D basePassColor;
|
||||
|
||||
// used for transparency sorting
|
||||
Vector cameraPos;
|
||||
|
||||
@@ -43,7 +43,7 @@ CachedDepthPass::~CachedDepthPass() {}
|
||||
void CachedDepthPass::beginFrame(const Component::Camera& cam) { RenderPass::beginFrame(cam); }
|
||||
|
||||
void CachedDepthPass::render() {
|
||||
/* query->beginQuery();
|
||||
query->beginQuery();
|
||||
timestamps->write(Gfx::SE_PIPELINE_STAGE_TOP_OF_PIPE_BIT, "CachedBegin");
|
||||
graphics->beginRenderPass(renderPass);
|
||||
Array<Gfx::ORenderCommand> commands;
|
||||
@@ -53,7 +53,7 @@ void CachedDepthPass::render() {
|
||||
permutation.setDepthCulling(true);
|
||||
for (VertexData* vertexData : VertexData::getList()) {
|
||||
permutation.setVertexData(vertexData->getTypeName());
|
||||
vertexData->getInstanceDataSet()->updateBuffer(6, 0, cullingBuffer);
|
||||
vertexData->getInstanceDataSet()->updateBuffer(VertexData::CULLINGDATA_NAME, 0, cullingBuffer);
|
||||
vertexData->getInstanceDataSet()->writeChanges();
|
||||
|
||||
// Create Pipeline(VertexData)
|
||||
@@ -134,9 +134,8 @@ void CachedDepthPass::render() {
|
||||
|
||||
graphics->executeCommands(std::move(commands));
|
||||
graphics->endRenderPass();
|
||||
graphics->waitDeviceIdle();
|
||||
timestamps->write(Gfx::SE_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, "CachedEnd");
|
||||
query->endQuery();*/
|
||||
query->endQuery();
|
||||
}
|
||||
|
||||
void CachedDepthPass::endFrame() {}
|
||||
|
||||
@@ -68,7 +68,7 @@ DepthCullingPass::~DepthCullingPass() {}
|
||||
void DepthCullingPass::beginFrame(const Component::Camera& cam) { RenderPass::beginFrame(cam); }
|
||||
|
||||
void DepthCullingPass::render() {
|
||||
/*query->beginQuery();
|
||||
query->beginQuery();
|
||||
depthAttachment.getTexture()->changeLayout(Gfx::SE_IMAGE_LAYOUT_GENERAL, Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, Gfx::SE_ACCESS_SHADER_READ_BIT,
|
||||
Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
|
||||
@@ -125,7 +125,7 @@ void DepthCullingPass::render() {
|
||||
permutation.setDepthCulling(getGlobals().useDepthCulling);
|
||||
for (VertexData* vertexData : VertexData::getList()) {
|
||||
permutation.setVertexData(vertexData->getTypeName());
|
||||
vertexData->getInstanceDataSet()->updateBuffer(6, 0, cullingBuffer);
|
||||
vertexData->getInstanceDataSet()->updateBuffer(VertexData::CULLINGDATA_NAME, 0, cullingBuffer);
|
||||
vertexData->getInstanceDataSet()->writeChanges();
|
||||
// Create Pipeline(VertexData)
|
||||
// Descriptors:
|
||||
@@ -217,7 +217,7 @@ void DepthCullingPass::render() {
|
||||
// Sync visibility write with compute read
|
||||
visibilityAttachment.getTexture()->pipelineBarrier(Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||
Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, Gfx::SE_ACCESS_SHADER_READ_BIT,
|
||||
Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT);*/
|
||||
Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
|
||||
}
|
||||
|
||||
void DepthCullingPass::endFrame() {}
|
||||
|
||||
@@ -37,19 +37,19 @@ void LightCullingPass::beginFrame(const Component::Camera& cam) {
|
||||
}
|
||||
|
||||
void LightCullingPass::render() {
|
||||
/*query->beginQuery();
|
||||
query->beginQuery();
|
||||
timestamps->write(Gfx::SE_PIPELINE_STAGE_TOP_OF_PIPE_BIT, "LightCullBegin");
|
||||
oLightGrid->pipelineBarrier(Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, Gfx::SE_ACCESS_SHADER_WRITE_BIT,
|
||||
Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
|
||||
tLightGrid->pipelineBarrier(Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, Gfx::SE_ACCESS_SHADER_WRITE_BIT,
|
||||
Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
|
||||
cullingDescriptorSet->updateTexture(0, 0, depthAttachment);
|
||||
cullingDescriptorSet->updateBuffer(1, 0, oLightIndexCounter);
|
||||
cullingDescriptorSet->updateBuffer(2, 0, tLightIndexCounter);
|
||||
cullingDescriptorSet->updateBuffer(3, 0, oLightIndexList);
|
||||
cullingDescriptorSet->updateBuffer(4, 0, tLightIndexList);
|
||||
cullingDescriptorSet->updateTexture(5, 0, oLightGrid);
|
||||
cullingDescriptorSet->updateTexture(6, 0, tLightGrid);
|
||||
cullingDescriptorSet->updateTexture(DEPTHATTACHMENT_NAME, 0, depthAttachment);
|
||||
cullingDescriptorSet->updateBuffer(OLIGHTINDEXCOUNTER_NAME, 0, oLightIndexCounter);
|
||||
cullingDescriptorSet->updateBuffer(TLIGHTINDEXCOUNTER_NAME, 0, tLightIndexCounter);
|
||||
cullingDescriptorSet->updateBuffer(OLIGHTINDEXLIST_NAME, 0, oLightIndexList);
|
||||
cullingDescriptorSet->updateBuffer(TLIGHTINDEXLIST_NAME, 0, tLightIndexList);
|
||||
cullingDescriptorSet->updateTexture(OLIGHTGRID_NAME, 0, oLightGrid);
|
||||
cullingDescriptorSet->updateTexture(TLIGHTGRID_NAME, 0, tLightGrid);
|
||||
cullingDescriptorSet->writeChanges();
|
||||
Gfx::OComputeCommand computeCommand = graphics->createComputeCommand("CullingCommand");
|
||||
if (getGlobals().useLightCulling) {
|
||||
@@ -58,7 +58,7 @@ void LightCullingPass::render() {
|
||||
computeCommand->bindPipeline(cullingPipeline);
|
||||
}
|
||||
computeCommand->bindDescriptor({viewParamsSet, dispatchParamsSet, cullingDescriptorSet, lightEnv->getDescriptorSet()});
|
||||
computeCommand->dispatch(dispatchParams.numThreadGroups.x, dispatchParams.numThreadGroups.y, dispatchParams.numThreadGroups.z);
|
||||
computeCommand->dispatch(numThreadGroups.x, numThreadGroups.y, numThreadGroups.z);
|
||||
Array<Gfx::OComputeCommand> commands;
|
||||
commands.add(std::move(computeCommand));
|
||||
// std::cout << "Execute" << std::endl;
|
||||
@@ -72,7 +72,7 @@ void LightCullingPass::render() {
|
||||
oLightGrid->pipelineBarrier(Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT, Gfx::SE_ACCESS_SHADER_READ_BIT,
|
||||
Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
||||
tLightGrid->pipelineBarrier(Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT, Gfx::SE_ACCESS_SHADER_READ_BIT,
|
||||
Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);*/
|
||||
Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
||||
}
|
||||
|
||||
void LightCullingPass::endFrame() {}
|
||||
@@ -81,8 +81,8 @@ void LightCullingPass::publishOutputs() {
|
||||
setupFrustums();
|
||||
uint32_t viewportWidth = viewport->getWidth();
|
||||
uint32_t viewportHeight = viewport->getHeight();
|
||||
UVector4 numThreadGroups = glm::ceil(glm::vec4(viewportWidth / (float)BLOCK_SIZE, viewportHeight / (float)BLOCK_SIZE, 1, 0));
|
||||
UVector4 numThreads = numThreadGroups * glm::uvec4(BLOCK_SIZE, BLOCK_SIZE, 1, 0);
|
||||
numThreadGroups = glm::ceil(glm::vec4(viewportWidth / (float)BLOCK_SIZE, viewportHeight / (float)BLOCK_SIZE, 1, 0));
|
||||
numThreads = numThreadGroups * glm::uvec4(BLOCK_SIZE, BLOCK_SIZE, 1, 0);
|
||||
dispatchParamsSet = dispatchParamsLayout->allocateDescriptorSet();
|
||||
dispatchParamsSet->updateConstants("numThreadGroups", 0, &numThreadGroups);
|
||||
dispatchParamsSet->updateConstants("numThreads", 0, &numThreads);
|
||||
@@ -225,8 +225,8 @@ void LightCullingPass::setupFrustums() {
|
||||
uint32_t viewportWidth = viewport->getWidth();
|
||||
uint32_t viewportHeight = viewport->getHeight();
|
||||
|
||||
glm::uvec4 numThreads = glm::ceil(glm::vec4(viewportWidth / (float)BLOCK_SIZE, viewportHeight / (float)BLOCK_SIZE, 1, 0));
|
||||
glm::uvec4 numThreadGroups = glm::ceil(glm::vec4(numThreads.x / (float)BLOCK_SIZE, numThreads.y / (float)BLOCK_SIZE, 1, 0));
|
||||
numThreads = glm::ceil(glm::vec4(viewportWidth / (float)BLOCK_SIZE, viewportHeight / (float)BLOCK_SIZE, 1, 0));
|
||||
numThreadGroups = glm::ceil(glm::vec4(numThreads.x / (float)BLOCK_SIZE, numThreads.y / (float)BLOCK_SIZE, 1, 0));
|
||||
|
||||
RenderPass::beginFrame(Component::Camera());
|
||||
|
||||
|
||||
@@ -59,7 +59,9 @@ class LightCullingPass : public RenderPass {
|
||||
Gfx::PComputePipeline cullingEnabledPipeline;
|
||||
Gfx::OPipelineStatisticsQuery query;
|
||||
Gfx::PTimestampQuery timestamps;
|
||||
|
||||
UVector4 numThreadGroups;
|
||||
UVector4 numThreads;
|
||||
|
||||
PScene scene;
|
||||
};
|
||||
DEFINE_REF(LightCullingPass)
|
||||
|
||||
@@ -13,11 +13,12 @@ void VisibilityPass::beginFrame(const Component::Camera& cam) {
|
||||
}
|
||||
|
||||
void VisibilityPass::render() {
|
||||
/*cullingBuffer->pipelineBarrier(Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_MESH_SHADER_BIT_EXT,
|
||||
cullingBuffer->pipelineBarrier(Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_MESH_SHADER_BIT_EXT,
|
||||
Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT);
|
||||
cullingBuffer->clear();
|
||||
|
||||
cullingBuffer->pipelineBarrier(Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT, Gfx::SE_ACCESS_SHADER_READ_BIT,
|
||||
cullingBuffer->pipelineBarrier(Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
Gfx::SE_ACCESS_SHADER_READ_BIT | Gfx::SE_ACCESS_SHADER_WRITE_BIT,
|
||||
Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
|
||||
visibilityDescriptor->reset();
|
||||
visibilitySet = visibilityDescriptor->allocateDescriptorSet();
|
||||
@@ -38,7 +39,7 @@ void VisibilityPass::render() {
|
||||
query->endQuery();
|
||||
cullingBuffer->pipelineBarrier(Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
||||
Gfx::SE_ACCESS_SHADER_READ_BIT,
|
||||
Gfx::SE_PIPELINE_STAGE_TASK_SHADER_BIT_EXT | Gfx::SE_PIPELINE_STAGE_MESH_SHADER_BIT_EXT);*/
|
||||
Gfx::SE_PIPELINE_STAGE_TASK_SHADER_BIT_EXT | Gfx::SE_PIPELINE_STAGE_MESH_SHADER_BIT_EXT);
|
||||
}
|
||||
|
||||
void VisibilityPass::endFrame() {}
|
||||
|
||||
@@ -53,12 +53,14 @@ void StaticMeshVertexData::loadColors(uint64 offset, const Array<ColorType>& dat
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
void StaticMeshVertexData::serializeMesh(MeshId id, uint64 numVertices, ArchiveBuffer& buffer) {
|
||||
VertexData::serializeMesh(id, numVertices, buffer);
|
||||
void StaticMeshVertexData::serializeMesh(MeshId id, ArchiveBuffer& buffer) {
|
||||
VertexData::serializeMesh(id, buffer);
|
||||
uint64 offset;
|
||||
uint64 numVertices;
|
||||
{
|
||||
std::unique_lock l(vertexDataLock);
|
||||
offset = meshOffsets[id];
|
||||
numVertices = meshVertexCounts[id];
|
||||
}
|
||||
Array<TexCoordType> tex[MAX_TEXCOORDS];
|
||||
for (size_t i = 0; i < MAX_TEXCOORDS; ++i) {
|
||||
|
||||
@@ -25,7 +25,7 @@ class StaticMeshVertexData : public VertexData {
|
||||
void loadTangents(uint64 offset, const Array<TangentType>& data);
|
||||
void loadBitangents(uint64 offset, const Array<BiTangentType>& data);
|
||||
void loadColors(uint64 offset, const Array<ColorType>& data);
|
||||
virtual void serializeMesh(MeshId id, uint64 numVertices, ArchiveBuffer& buffer) override;
|
||||
virtual void serializeMesh(MeshId id, ArchiveBuffer& buffer) override;
|
||||
virtual uint64 deserializeMesh(MeshId id, ArchiveBuffer& buffer) override;
|
||||
virtual void init(Gfx::PGraphics graphics) override;
|
||||
virtual void destroy() override;
|
||||
|
||||
@@ -39,8 +39,6 @@ void VertexData::updateMesh(uint32 meshletOffset, PMesh mesh, Component::Transfo
|
||||
std::unique_lock l(materialDataLock);
|
||||
PMaterialInstance referencedInstance = mesh->referencedMaterial->getHandle();
|
||||
PMaterial mat = referencedInstance->getBaseMaterial();
|
||||
const auto& data = meshData[mesh->id];
|
||||
|
||||
Matrix4 transformMatrix = transform.toMatrix() * mesh->transform;
|
||||
InstanceData inst = InstanceData{
|
||||
.transformMatrix = transformMatrix,
|
||||
@@ -48,26 +46,6 @@ void VertexData::updateMesh(uint32 meshletOffset, PMesh mesh, Component::Transfo
|
||||
};
|
||||
|
||||
referencedInstance->updateDescriptor();
|
||||
if (mat->hasTransparency()) {
|
||||
auto params = referencedInstance->getMaterialOffsets();
|
||||
transparentData.add(TransparentDraw{
|
||||
.matInst = referencedInstance,
|
||||
.vertexData = this,
|
||||
.offsets =
|
||||
{
|
||||
.instanceOffset = 0,
|
||||
.textureOffset = params.textureOffset,
|
||||
.samplerOffset = params.samplerOffset,
|
||||
.floatOffset = params.floatOffset,
|
||||
},
|
||||
.worldPosition = Vector(inst.transformMatrix[3]),
|
||||
.instanceData = inst,
|
||||
.meshData = data,
|
||||
.cullingOffset = meshletOffset,
|
||||
.rayTracingScene = mesh->blas,
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (materialData.size() <= mat->getId()) {
|
||||
materialData.resize(mat->getId() + 1);
|
||||
}
|
||||
@@ -77,50 +55,33 @@ void VertexData::updateMesh(uint32 meshletOffset, PMesh mesh, Component::Transfo
|
||||
matData.instances.resize(referencedInstance->getId() + 1);
|
||||
}
|
||||
BatchedDrawCall& matInstanceData = matData.instances[referencedInstance->getId()];
|
||||
matInstanceData.materialInstance = referencedInstance;
|
||||
matInstanceData.rayTracingData.add(mesh->blas);
|
||||
matInstanceData.instanceData.add(inst);
|
||||
matInstanceData.instanceMeshData.add(data);
|
||||
matInstanceData.cullingOffsets.add(meshletOffset);
|
||||
|
||||
/* 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});
|
||||
}*/
|
||||
for (const auto& data : meshData[mesh->id]) {
|
||||
if (mat->hasTransparency()) {
|
||||
auto params = referencedInstance->getMaterialOffsets();
|
||||
transparentData.add(TransparentDraw{
|
||||
.matInst = referencedInstance,
|
||||
.vertexData = this,
|
||||
.offsets =
|
||||
{
|
||||
.instanceOffset = 0,
|
||||
.textureOffset = params.textureOffset,
|
||||
.samplerOffset = params.samplerOffset,
|
||||
.floatOffset = params.floatOffset,
|
||||
},
|
||||
.worldPosition = Vector(inst.transformMatrix[3]),
|
||||
.instanceData = inst,
|
||||
.meshData = data,
|
||||
.cullingOffset = meshletOffset,
|
||||
.rayTracingScene = mesh->blas,
|
||||
});
|
||||
} else { // opaque
|
||||
matInstanceData.materialInstance = referencedInstance;
|
||||
matInstanceData.rayTracingData.add(mesh->blas);
|
||||
matInstanceData.instanceData.add(inst);
|
||||
matInstanceData.instanceMeshData.add(data);
|
||||
matInstanceData.cullingOffsets.add(meshletOffset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void VertexData::createDescriptors() {
|
||||
@@ -177,37 +138,42 @@ void VertexData::createDescriptors() {
|
||||
|
||||
void VertexData::loadMesh(MeshId id, Array<uint32> loadedIndices, Array<Meshlet> loadedMeshlets) {
|
||||
std::unique_lock l(vertexDataLock);
|
||||
uint32 meshletOffset = meshlets.size();
|
||||
AABB meshAABB;
|
||||
for (uint32 i = 0; i < loadedMeshlets.size(); ++i) {
|
||||
Meshlet& m = loadedMeshlets[i];
|
||||
meshAABB = meshAABB.combine(m.boundingBox);
|
||||
uint32 vertexOffset = vertexIndices.size();
|
||||
vertexIndices.resize(vertexOffset + m.numVertices);
|
||||
std::memcpy(vertexIndices.data() + vertexOffset, m.uniqueVertices, m.numVertices * sizeof(uint32));
|
||||
uint32 primitiveOffset = primitiveIndices.size();
|
||||
primitiveIndices.resize(primitiveOffset + (m.numPrimitives * 3));
|
||||
std::memcpy(primitiveIndices.data() + primitiveOffset, m.primitiveLayout, m.numPrimitives * 3 * sizeof(uint8));
|
||||
meshlets.add(MeshletDescription{
|
||||
.bounding = m.boundingBox, //.toSphere(),
|
||||
.vertexCount = m.numVertices,
|
||||
.primitiveCount = m.numPrimitives,
|
||||
.vertexOffset = vertexOffset,
|
||||
.primitiveOffset = primitiveOffset,
|
||||
.color = Vector((float)rand() / RAND_MAX, (float)rand() / RAND_MAX, (float)rand() / RAND_MAX),
|
||||
.indicesOffset = (uint32)meshOffsets[id],
|
||||
uint32 numMeshData = (loadedMeshlets.size() + 2047) / 2048; // todo: magic number
|
||||
for (uint32 n = 0; n < numMeshData; ++n) {
|
||||
uint32 meshletsToProcess = std::min<uint32>(loadedMeshlets.size() - n * 2048, 2048);
|
||||
uint32 meshletOffset = meshlets.size();
|
||||
AABB meshAABB;
|
||||
for (uint32 i = 0; i < meshletsToProcess; ++i) {
|
||||
Meshlet& m = loadedMeshlets[n * 2048 + i];
|
||||
//...
|
||||
meshAABB = meshAABB.combine(m.boundingBox);
|
||||
uint32 vertexOffset = vertexIndices.size();
|
||||
vertexIndices.resize(vertexOffset + m.numVertices);
|
||||
std::memcpy(vertexIndices.data() + vertexOffset, m.uniqueVertices, m.numVertices * sizeof(uint32));
|
||||
uint32 primitiveOffset = primitiveIndices.size();
|
||||
primitiveIndices.resize(primitiveOffset + (m.numPrimitives * 3));
|
||||
std::memcpy(primitiveIndices.data() + primitiveOffset, m.primitiveLayout, m.numPrimitives * 3 * sizeof(uint8));
|
||||
meshlets.add(MeshletDescription{
|
||||
.bounding = m.boundingBox, //.toSphere(),
|
||||
.vertexCount = m.numVertices,
|
||||
.primitiveCount = m.numPrimitives,
|
||||
.vertexOffset = vertexOffset,
|
||||
.primitiveOffset = primitiveOffset,
|
||||
.color = Vector((float)rand() / RAND_MAX, (float)rand() / RAND_MAX, (float)rand() / RAND_MAX),
|
||||
.indicesOffset = (uint32)meshOffsets[id],
|
||||
});
|
||||
}
|
||||
meshData[id].add(MeshData{
|
||||
.bounding = meshAABB, //.toSphere(),
|
||||
.numMeshlets = (uint32)meshletsToProcess,
|
||||
.meshletOffset = meshletOffset,
|
||||
});
|
||||
}
|
||||
meshData[id] = MeshData{
|
||||
.bounding = meshAABB, //.toSphere(),
|
||||
.numMeshlets = (uint32)loadedMeshlets.size(),
|
||||
.meshletOffset = meshletOffset,
|
||||
.firstIndex = (uint32)indices.size(),
|
||||
.numIndices = (uint32)loadedIndices.size(),
|
||||
};
|
||||
|
||||
// todo: in case of a index split for 16 bit, do something here
|
||||
meshData[id][0].firstIndex = (uint32)indices.size();
|
||||
meshData[id][0].numIndices = (uint32)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][0].firstIndex, loadedIndices.data(), loadedIndices.size() * sizeof(uint32));
|
||||
}
|
||||
|
||||
void VertexData::commitMeshes() {
|
||||
@@ -268,22 +234,24 @@ MeshId VertexData::allocateVertexData(uint64 numVertices) {
|
||||
return res;
|
||||
}
|
||||
|
||||
void VertexData::serializeMesh(MeshId id, uint64, ArchiveBuffer& buffer) {
|
||||
void VertexData::serializeMesh(MeshId id, ArchiveBuffer& buffer) {
|
||||
std::unique_lock l(vertexDataLock);
|
||||
Array<Meshlet> out;
|
||||
MeshData data = meshData[id];
|
||||
for (size_t i = 0; i < data.numMeshlets; ++i) {
|
||||
MeshletDescription& desc = meshlets[i + data.meshletOffset];
|
||||
Meshlet m;
|
||||
std::memcpy(m.uniqueVertices, &vertexIndices[desc.vertexOffset], desc.vertexCount * sizeof(uint32));
|
||||
std::memcpy(m.primitiveLayout, &primitiveIndices[desc.primitiveOffset], desc.primitiveCount * 3 * sizeof(uint8));
|
||||
m.numPrimitives = desc.primitiveCount;
|
||||
m.numVertices = desc.vertexCount;
|
||||
m.boundingBox = desc.bounding;
|
||||
out.add(std::move(m));
|
||||
for (uint32 n = 0; n < meshData[id].size(); ++n) {
|
||||
MeshData data = meshData[id][n];
|
||||
for (size_t i = 0; i < data.numMeshlets; ++i) {
|
||||
MeshletDescription& desc = meshlets[i + data.meshletOffset];
|
||||
Meshlet m;
|
||||
std::memcpy(m.uniqueVertices, &vertexIndices[desc.vertexOffset], desc.vertexCount * sizeof(uint32));
|
||||
std::memcpy(m.primitiveLayout, &primitiveIndices[desc.primitiveOffset], desc.primitiveCount * 3 * sizeof(uint8));
|
||||
m.numPrimitives = desc.primitiveCount;
|
||||
m.numVertices = desc.vertexCount;
|
||||
m.boundingBox = desc.bounding;
|
||||
out.add(std::move(m));
|
||||
}
|
||||
}
|
||||
Array<uint32> ind(data.numIndices);
|
||||
std::memcpy(ind.data(), &indices[data.firstIndex], data.numIndices * sizeof(uint32));
|
||||
Array<uint32> ind(meshData[id][0].numIndices);
|
||||
std::memcpy(ind.data(), &indices[meshData[id][0].firstIndex], meshData[id][0].numIndices * sizeof(uint32));
|
||||
Serialization::save(buffer, out);
|
||||
Serialization::save(buffer, ind);
|
||||
}
|
||||
@@ -383,7 +351,9 @@ void VertexData::destroy() {
|
||||
|
||||
uint32 VertexData::addCullingMapping(MeshId id) {
|
||||
uint32 result = meshletCount;
|
||||
meshletCount += getMeshData(id).numMeshlets;
|
||||
for (const auto& md : getMeshData(id)) {
|
||||
meshletCount += md.numMeshlets;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@ class VertexData {
|
||||
MeshId allocateVertexData(uint64 numVertices);
|
||||
uint64 getMeshOffset(MeshId id) const { return meshOffsets[id]; }
|
||||
uint64 getMeshVertexCount(MeshId id) { return meshVertexCounts[id]; }
|
||||
virtual void serializeMesh(MeshId id, uint64 numVertices, ArchiveBuffer& buffer);
|
||||
virtual void serializeMesh(MeshId id, ArchiveBuffer& buffer);
|
||||
virtual uint64 deserializeMesh(MeshId id, ArchiveBuffer& buffer);
|
||||
virtual void bindBuffers(Gfx::PRenderCommand command) = 0;
|
||||
virtual Gfx::PDescriptorLayout getVertexDataLayout() = 0;
|
||||
@@ -76,7 +76,7 @@ class VertexData {
|
||||
const Array<MaterialData>& getMaterialData() const { return materialData; }
|
||||
const Array<TransparentDraw>& getTransparentData() const { return transparentData; }
|
||||
const Array<Gfx::PBottomLevelAS>& getRayTracingData() const { return rayTracingScene; }
|
||||
const MeshData& getMeshData(MeshId id) const { return meshData[id]; }
|
||||
const Array<MeshData>& getMeshData(MeshId id) const { return meshData[id]; }
|
||||
void registerBottomLevelAccelerationStructure(Gfx::PBottomLevelAS blas) {
|
||||
dataToBuild.add(blas);
|
||||
}
|
||||
@@ -89,6 +89,7 @@ class VertexData {
|
||||
|
||||
uint32 addCullingMapping(MeshId id);
|
||||
static uint64 getMeshletCount() { return meshletCount; }
|
||||
constexpr static const char* CULLINGDATA_NAME = "cullingData";
|
||||
|
||||
protected:
|
||||
virtual void resizeBuffers() = 0;
|
||||
@@ -113,7 +114,8 @@ class VertexData {
|
||||
Array<TransparentDraw> transparentData;
|
||||
|
||||
std::mutex vertexDataLock;
|
||||
Array<MeshData> meshData;
|
||||
// each mesh id can have multiple meshdata, in case it needs to be split for having too many meshlets
|
||||
Array<Array<MeshData>> meshData;
|
||||
Array<uint64> meshOffsets;
|
||||
Array<uint64> meshVertexCounts;
|
||||
|
||||
@@ -135,7 +137,6 @@ class VertexData {
|
||||
constexpr static const char* PRIMITIVEINDICES_NAME = "primitiveIndices";
|
||||
Gfx::OShaderBuffer cullingOffsetBuffer;
|
||||
constexpr static const char* CULLINGOFFSETS_NAME = "cullingOffsets";
|
||||
constexpr static const char* CULLINGDATA_NAME = "cullingData";
|
||||
|
||||
// for legacy pipeline
|
||||
Gfx::OIndexBuffer indexBuffer;
|
||||
|
||||
@@ -22,7 +22,8 @@ BottomLevelAS::BottomLevelAS(PGraphics graphics, const Gfx::BottomLevelASCreateI
|
||||
1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f,
|
||||
};
|
||||
VertexData* vertexData = createInfo.mesh->vertexData;
|
||||
MeshData meshData = vertexData->getMeshData(createInfo.mesh->id);
|
||||
//todo: indices might be split as well
|
||||
MeshData meshData = vertexData->getMeshData(createInfo.mesh->id)[0];
|
||||
vertexOffset = vertexData->getMeshOffset(createInfo.mesh->id) * sizeof(Vector);
|
||||
vertexCount = vertexData->getMeshVertexCount(createInfo.mesh->id);
|
||||
indexOffset = meshData.firstIndex * sizeof(uint32);
|
||||
|
||||
@@ -55,7 +55,7 @@ void Seele::beginCompilation(const ShaderCompilationInfo& info, SlangCompileTarg
|
||||
.value =
|
||||
{
|
||||
.kind = slang::CompilerOptionValueKind::Int,
|
||||
.intValue0 = SLANG_DEBUG_INFO_LEVEL_NONE,
|
||||
.intValue0 = SLANG_DEBUG_INFO_LEVEL_STANDARD,
|
||||
},
|
||||
},
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user