Staging before meshlet linearization

This commit is contained in:
Dynamitos
2024-05-09 08:41:46 +02:00
parent 46a2713729
commit 7fc7ba56d4
33 changed files with 888 additions and 709 deletions
-1
View File
@@ -12,7 +12,6 @@ target_sources(Engine
Graphics.h
Graphics.cpp
Initializer.h
Initializer.cpp
Mesh.h
Mesh.cpp
Meshlet.h
+1
View File
@@ -22,6 +22,7 @@ public:
virtual void draw(uint32 vertexCount, uint32 instanceCount, int32 firstVertex, uint32 firstInstance) = 0;
virtual void drawIndexed(uint32 indexCount, uint32 instanceCount, int32 firstIndex, uint32 vertexOffset, uint32 firstInstance) = 0;
virtual void drawMesh(uint32 groupX, uint32 groupY, uint32 groupZ) = 0;
virtual void drawMeshIndirect(Gfx::PShaderBuffer buffer, uint64 offset, uint32 drawCount, uint32 stride) = 0;
std::string name;
};
DEFINE_REF(RenderCommand)
-102
View File
@@ -1,102 +0,0 @@
#include "Initializer.h"
#include "Descriptor.h"
using namespace Seele;
using namespace Seele::Gfx;
LegacyPipelineCreateInfo::LegacyPipelineCreateInfo()
: topology(Gfx::SE_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST)
, multisampleState(MultisampleState{
.samples = 1,
})
, rasterizationState(RasterizationState{
.polygonMode = Gfx::SE_POLYGON_MODE_FILL,
.cullMode = Gfx::SE_CULL_MODE_BACK_BIT,
.frontFace = Gfx::SE_FRONT_FACE_COUNTER_CLOCKWISE,
})
, depthStencilState(DepthStencilState{
.depthTestEnable = true,
.depthWriteEnable = true,
.depthCompareOp = Gfx::SE_COMPARE_OP_LESS_OR_EQUAL,
.stencilTestEnable = false,
.minDepthBounds = 0.0f,
.maxDepthBounds = 1.0f,
})
, colorBlend(ColorBlendState{
.logicOpEnable = false,
.attachmentCount = 0,
.blendAttachments = {
ColorBlendState::BlendAttachment{
.colorWriteMask =
Gfx::SE_COLOR_COMPONENT_R_BIT |
Gfx::SE_COLOR_COMPONENT_G_BIT |
Gfx::SE_COLOR_COMPONENT_B_BIT |
Gfx::SE_COLOR_COMPONENT_A_BIT,
}
},
.blendConstants = {
1.0f,
1.0f,
1.0f,
1.0f,
},
})
{
}
LegacyPipelineCreateInfo::~LegacyPipelineCreateInfo()
{
}
MeshPipelineCreateInfo::MeshPipelineCreateInfo()
: multisampleState(MultisampleState{
.samples = 1,
})
, rasterizationState(RasterizationState{
.polygonMode = Gfx::SE_POLYGON_MODE_FILL,
.cullMode = Gfx::SE_CULL_MODE_BACK_BIT,
.frontFace = Gfx::SE_FRONT_FACE_COUNTER_CLOCKWISE,
})
, depthStencilState(DepthStencilState{
.depthTestEnable = true,
.depthWriteEnable = true,
.depthCompareOp = Gfx::SE_COMPARE_OP_LESS_OR_EQUAL,
.stencilTestEnable = false,
.minDepthBounds = 0.0f,
.maxDepthBounds = 1.0f,
})
, colorBlend(ColorBlendState{
.logicOpEnable = false,
.attachmentCount = 0,
.blendAttachments = {
ColorBlendState::BlendAttachment{
.colorWriteMask =
Gfx::SE_COLOR_COMPONENT_R_BIT |
Gfx::SE_COLOR_COMPONENT_G_BIT |
Gfx::SE_COLOR_COMPONENT_B_BIT |
Gfx::SE_COLOR_COMPONENT_A_BIT,
}
},
.blendConstants = {
1.0f,
1.0f,
1.0f,
1.0f,
},
})
{
}
MeshPipelineCreateInfo::~MeshPipelineCreateInfo()
{
}
ComputePipelineCreateInfo::ComputePipelineCreateInfo()
{
std::memset((void*)this, 0, sizeof(*this));
}
ComputePipelineCreateInfo::~ComputePipelineCreateInfo()
{
}
+236 -242
View File
@@ -5,250 +5,244 @@
namespace Seele
{
struct GraphicsInitializer
{
const char *applicationName;
const char *engineName;
const char *windowLayoutFile;
/**
* layers defines the enabled Vulkan layers used in the instance,
* if ENABLE_VALIDATION is defined, standard validation is already enabled
* not yet implemented
*/
Array<const char *> layers;
Array<const char *> instanceExtensions;
Array<const char *> deviceExtensions;
void *windowHandle;
GraphicsInitializer()
: applicationName("SeeleEngine")
, engineName("SeeleEngine")
, windowLayoutFile(nullptr)
, layers{"VK_LAYER_LUNARG_monitor"}
, instanceExtensions{}
, deviceExtensions{"VK_KHR_swapchain"}
, windowHandle(nullptr)
struct GraphicsInitializer
{
}
};
struct WindowCreateInfo
{
int32 width;
int32 height;
const char *title;
Gfx::SeFormat preferredFormat = Gfx::SE_FORMAT_B8G8R8A8_UNORM;
void *windowHandle;
};
struct ViewportCreateInfo
{
URect dimensions;
float fieldOfView = 1.222f; // 70 deg
Gfx::SeSampleCountFlags numSamples;
};
// doesnt own the data, only proxy it
struct DataSource
{
uint64 size = 0;
uint64 offset = 0;
uint8 *data = nullptr;
Gfx::QueueType owner = Gfx::QueueType::GRAPHICS;
};
struct TextureCreateInfo
{
DataSource sourceData = DataSource();
Gfx::SeFormat format = Gfx::SE_FORMAT_R32G32B32A32_SFLOAT;
uint32 width = 1;
uint32 height = 1;
uint32 depth = 1;
uint32 mipLevels = 1;
uint32 layers = 1;
uint32 elements = 1;
uint32 samples = 1;
Gfx::SeImageUsageFlags usage = Gfx::SE_IMAGE_USAGE_SAMPLED_BIT;
Gfx::SeMemoryPropertyFlags memoryProps = Gfx::SE_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
std::string name;
};
struct SamplerCreateInfo
{
Gfx::SeSamplerCreateFlags flags;
Gfx::SeFilter magFilter = Gfx::SE_FILTER_LINEAR;
Gfx::SeFilter minFilter = Gfx::SE_FILTER_LINEAR;
Gfx::SeSamplerMipmapMode mipmapMode = Gfx::SE_SAMPLER_MIPMAP_MODE_LINEAR;
Gfx::SeSamplerAddressMode addressModeU = Gfx::SE_SAMPLER_ADDRESS_MODE_REPEAT;
Gfx::SeSamplerAddressMode addressModeV = Gfx::SE_SAMPLER_ADDRESS_MODE_REPEAT;
Gfx::SeSamplerAddressMode addressModeW = Gfx::SE_SAMPLER_ADDRESS_MODE_REPEAT;
float mipLodBias = 0.0f;
uint32 anisotropyEnable = 0;
float maxAnisotropy = 0.0f;
uint32 compareEnable = 0;
Gfx::SeCompareOp compareOp = Gfx::SE_COMPARE_OP_NEVER;
float minLod = 0.0f;
float maxLod = 0.0f;
Gfx::SeBorderColor borderColor = Gfx::SE_BORDER_COLOR_FLOAT_OPAQUE_BLACK;
uint32 unnormalizedCoordinates = 0;
std::string name;
};
struct VertexBufferCreateInfo
{
DataSource sourceData = DataSource();
// bytes per vertex
uint32 vertexSize = 0;
uint32 numVertices = 0;
std::string name = "";
};
struct IndexBufferCreateInfo
{
DataSource sourceData = DataSource();
Gfx::SeIndexType indexType = Gfx::SeIndexType::SE_INDEX_TYPE_UINT16;
std::string name = "";
};
struct UniformBufferCreateInfo
{
DataSource sourceData = DataSource();
uint8 dynamic = 0;
std::string name = "";
};
struct ShaderBufferCreateInfo
{
DataSource sourceData = DataSource();
uint64 numElements = 1;
uint8 dynamic = 0;
std::string name = "";
};
DECLARE_NAME_REF(Gfx, PipelineLayout)
struct ShaderCreateInfo
{
std::string name; // Debug info
std::string mainModule;
Array<std::string> additionalModules;
std::string entryPoint;
Array<Pair<const char*, const char*>> typeParameter;
Map<const char*, const char*> defines;
Gfx::PPipelineLayout rootSignature;
};
struct VertexInputBinding
{
uint32 binding;
uint32 stride;
Gfx::SeVertexInputRate inputRate;
};
struct VertexInputAttribute
{
uint32 location;
uint32 binding;
Gfx::SeFormat format;
uint32 offset;
};
struct VertexInputStateCreateInfo
{
Array<VertexInputBinding> bindings;
Array<VertexInputAttribute> attributes;
};
namespace Gfx
{
struct SePushConstantRange
{
SeShaderStageFlags stageFlags;
uint32 offset;
uint32 size;
};
struct RasterizationState
{
uint32 depthClampEnable = 0;
uint32 rasterizerDiscardEnable = 0;
SePolygonMode polygonMode;
SeCullModeFlags cullMode;
SeFrontFace frontFace;
uint32 depthBiasEnable = 0;
float depthBiasConstantFactor = 0;
float depthBiasClamp = 0;
float depthBiasSlopeFactor = 0;
float lineWidth = 1.0;
};
struct MultisampleState
{
SeSampleCountFlags samples = 1;
uint32 sampleShadingEnable = 0;
float minSampleShading = 1;
uint8 alphaCoverageEnable = 0;
uint8 alphaToOneEnable = 0;
};
struct DepthStencilState
{
uint32 depthTestEnable = 0;
uint32 depthWriteEnable = 0;
SeCompareOp depthCompareOp = Gfx::SE_COMPARE_OP_LESS;
uint32 depthBoundsTestEnable = 0;
uint32 stencilTestEnable = 0;
SeStencilOp front = Gfx::SE_STENCIL_OP_ZERO;
SeStencilOp back = Gfx::SE_STENCIL_OP_ZERO;
float minDepthBounds;
float maxDepthBounds;
};
struct ColorBlendState
{
struct BlendAttachment
{
uint32 blendEnable = 0;
SeBlendFactor srcColorBlendFactor = Gfx::SE_BLEND_FACTOR_SRC_ALPHA;
SeBlendFactor dstColorBlendFactor = Gfx::SE_BLEND_FACTOR_SRC_ALPHA;
SeBlendOp colorBlendOp = Gfx::SE_BLEND_OP_ADD;
SeBlendFactor srcAlphaBlendFactor = Gfx::SE_BLEND_FACTOR_SRC_ALPHA;
SeBlendFactor dstAlphaBlendFactor = Gfx::SE_BLEND_FACTOR_SRC_ALPHA;
SeBlendOp alphaBlendOp = Gfx::SE_BLEND_OP_ADD;
SeColorComponentFlags colorWriteMask = Gfx::SE_COLOR_COMPONENT_R_BIT | Gfx::SE_COLOR_COMPONENT_G_BIT | Gfx::SE_COLOR_COMPONENT_B_BIT | Gfx::SE_COLOR_COMPONENT_A_BIT;
const char* applicationName;
const char* engineName;
const char* windowLayoutFile;
/**
* layers defines the enabled Vulkan layers used in the instance,
* if ENABLE_VALIDATION is defined, standard validation is already enabled
* not yet implemented
*/
Array<const char*> layers;
Array<const char*> instanceExtensions;
Array<const char*> deviceExtensions;
void* windowHandle;
GraphicsInitializer()
: applicationName("SeeleEngine")
, engineName("SeeleEngine")
, windowLayoutFile(nullptr)
, layers{ "VK_LAYER_LUNARG_monitor" }
, instanceExtensions{}
, deviceExtensions{ "VK_KHR_swapchain" }
, windowHandle(nullptr)
{
}
};
uint32 logicOpEnable;
SeLogicOp logicOp = Gfx::SE_LOGIC_OP_OR;
uint32 attachmentCount;
StaticArray<BlendAttachment, 16> blendAttachments;
StaticArray<float, 4> blendConstants;
};
struct WindowCreateInfo
{
int32 width;
int32 height;
const char* title;
Gfx::SeFormat preferredFormat = Gfx::SE_FORMAT_B8G8R8A8_UNORM;
void* windowHandle;
};
struct ViewportCreateInfo
{
URect dimensions;
float fieldOfView = 1.222f; // 70 deg
Gfx::SeSampleCountFlags numSamples;
};
// doesnt own the data, only proxy it
struct DataSource
{
uint64 size = 0;
uint64 offset = 0;
uint8* data = nullptr;
Gfx::QueueType owner = Gfx::QueueType::GRAPHICS;
};
struct TextureCreateInfo
{
DataSource sourceData = DataSource();
Gfx::SeFormat format = Gfx::SE_FORMAT_R32G32B32A32_SFLOAT;
uint32 width = 1;
uint32 height = 1;
uint32 depth = 1;
uint32 mipLevels = 1;
uint32 layers = 1;
uint32 elements = 1;
uint32 samples = 1;
Gfx::SeImageUsageFlags usage = Gfx::SE_IMAGE_USAGE_SAMPLED_BIT;
Gfx::SeMemoryPropertyFlags memoryProps = Gfx::SE_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
std::string name;
};
struct SamplerCreateInfo
{
Gfx::SeSamplerCreateFlags flags;
Gfx::SeFilter magFilter = Gfx::SE_FILTER_LINEAR;
Gfx::SeFilter minFilter = Gfx::SE_FILTER_LINEAR;
Gfx::SeSamplerMipmapMode mipmapMode = Gfx::SE_SAMPLER_MIPMAP_MODE_LINEAR;
Gfx::SeSamplerAddressMode addressModeU = Gfx::SE_SAMPLER_ADDRESS_MODE_REPEAT;
Gfx::SeSamplerAddressMode addressModeV = Gfx::SE_SAMPLER_ADDRESS_MODE_REPEAT;
Gfx::SeSamplerAddressMode addressModeW = Gfx::SE_SAMPLER_ADDRESS_MODE_REPEAT;
float mipLodBias = 0.0f;
uint32 anisotropyEnable = 0;
float maxAnisotropy = 0.0f;
uint32 compareEnable = 0;
Gfx::SeCompareOp compareOp = Gfx::SE_COMPARE_OP_NEVER;
float minLod = 0.0f;
float maxLod = 0.0f;
Gfx::SeBorderColor borderColor = Gfx::SE_BORDER_COLOR_FLOAT_OPAQUE_BLACK;
uint32 unnormalizedCoordinates = 0;
std::string name;
};
struct VertexBufferCreateInfo
{
DataSource sourceData = DataSource();
// bytes per vertex
uint32 vertexSize = 0;
uint32 numVertices = 0;
std::string name = "";
};
struct IndexBufferCreateInfo
{
DataSource sourceData = DataSource();
Gfx::SeIndexType indexType = Gfx::SeIndexType::SE_INDEX_TYPE_UINT16;
std::string name = "";
};
struct UniformBufferCreateInfo
{
DataSource sourceData = DataSource();
uint8 dynamic = 0;
std::string name = "";
};
struct ShaderBufferCreateInfo
{
DataSource sourceData = DataSource();
uint64 numElements = 1;
uint8 dynamic = 0;
std::string name = "";
};
DECLARE_NAME_REF(Gfx, PipelineLayout)
struct ShaderCreateInfo
{
std::string name; // Debug info
std::string mainModule;
Array<std::string> additionalModules;
std::string entryPoint;
Array<Pair<const char*, const char*>> typeParameter;
Map<const char*, const char*> defines;
Gfx::PPipelineLayout rootSignature;
};
struct VertexInputBinding
{
uint32 binding;
uint32 stride;
Gfx::SeVertexInputRate inputRate;
};
struct VertexInputAttribute
{
uint32 location;
uint32 binding;
Gfx::SeFormat format;
uint32 offset;
};
struct VertexInputStateCreateInfo
{
Array<VertexInputBinding> bindings;
Array<VertexInputAttribute> attributes;
};
namespace Gfx
{
struct SePushConstantRange
{
SeShaderStageFlags stageFlags;
uint32 offset;
uint32 size;
};
struct RasterizationState
{
uint32 depthClampEnable = 0;
uint32 rasterizerDiscardEnable = 0;
SePolygonMode polygonMode = Gfx::SE_POLYGON_MODE_FILL;
SeCullModeFlags cullMode = Gfx::SE_CULL_MODE_BACK_BIT;
SeFrontFace frontFace = Gfx::SE_FRONT_FACE_COUNTER_CLOCKWISE;
uint32 depthBiasEnable = 0;
float depthBiasConstantFactor = 0;
float depthBiasClamp = 0;
float depthBiasSlopeFactor = 0;
float lineWidth = 1.0;
};
struct MultisampleState
{
SeSampleCountFlags samples = 1;
uint32 sampleShadingEnable = 0;
float minSampleShading = 1;
uint8 alphaCoverageEnable = 0;
uint8 alphaToOneEnable = 0;
};
struct DepthStencilState
{
uint32 depthTestEnable = 1;
uint32 depthWriteEnable = 1;
SeCompareOp depthCompareOp = Gfx::SE_COMPARE_OP_GREATER;
uint32 depthBoundsTestEnable = 0;
uint32 stencilTestEnable = 0;
SeStencilOp front = Gfx::SE_STENCIL_OP_ZERO;
SeStencilOp back = Gfx::SE_STENCIL_OP_ZERO;
float minDepthBounds = 0.0f;
float maxDepthBounds = 1.0f;
};
struct ColorBlendState
{
struct BlendAttachment
{
uint32 blendEnable = 0;
SeBlendFactor srcColorBlendFactor = Gfx::SE_BLEND_FACTOR_SRC_ALPHA;
SeBlendFactor dstColorBlendFactor = Gfx::SE_BLEND_FACTOR_SRC_ALPHA;
SeBlendOp colorBlendOp = Gfx::SE_BLEND_OP_ADD;
SeBlendFactor srcAlphaBlendFactor = Gfx::SE_BLEND_FACTOR_SRC_ALPHA;
SeBlendFactor dstAlphaBlendFactor = Gfx::SE_BLEND_FACTOR_SRC_ALPHA;
SeBlendOp alphaBlendOp = Gfx::SE_BLEND_OP_ADD;
SeColorComponentFlags colorWriteMask = Gfx::SE_COLOR_COMPONENT_R_BIT | Gfx::SE_COLOR_COMPONENT_G_BIT | Gfx::SE_COLOR_COMPONENT_B_BIT | Gfx::SE_COLOR_COMPONENT_A_BIT;
};
uint32 logicOpEnable = 0;
SeLogicOp logicOp = Gfx::SE_LOGIC_OP_OR;
uint32 attachmentCount = 0;
StaticArray<BlendAttachment, 16> blendAttachments;
StaticArray<float, 4> blendConstants = { 1.0f, 1.0f, 1.0f, 1.0f, };
};
DECLARE_REF(VertexInput)
DECLARE_REF(VertexShader)
DECLARE_REF(TaskShader)
DECLARE_REF(MeshShader)
DECLARE_REF(FragmentShader)
DECLARE_REF(ComputeShader)
DECLARE_REF(RenderPass)
DECLARE_REF(PipelineLayout)
struct LegacyPipelineCreateInfo
{
SePrimitiveTopology topology;
PVertexInput vertexInput;
PVertexShader vertexShader;
PFragmentShader fragmentShader;
PRenderPass renderPass;
PPipelineLayout pipelineLayout;
MultisampleState multisampleState;
RasterizationState rasterizationState;
DepthStencilState depthStencilState;
ColorBlendState colorBlend;
LegacyPipelineCreateInfo();
~LegacyPipelineCreateInfo();
};
DECLARE_REF(VertexInput)
DECLARE_REF(VertexShader)
DECLARE_REF(TaskShader)
DECLARE_REF(MeshShader)
DECLARE_REF(FragmentShader)
DECLARE_REF(ComputeShader)
DECLARE_REF(RenderPass)
DECLARE_REF(PipelineLayout)
struct LegacyPipelineCreateInfo
{
SePrimitiveTopology topology = Gfx::SE_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
PVertexInput vertexInput = nullptr;
PVertexShader vertexShader = nullptr;
PFragmentShader fragmentShader = nullptr;
PRenderPass renderPass = nullptr;
PPipelineLayout pipelineLayout = nullptr;
MultisampleState multisampleState;
RasterizationState rasterizationState;
DepthStencilState depthStencilState;
ColorBlendState colorBlend;
};
struct MeshPipelineCreateInfo
{
PTaskShader taskShader;
PMeshShader meshShader;
PFragmentShader fragmentShader;
PRenderPass renderPass;
PPipelineLayout pipelineLayout;
MultisampleState multisampleState;
RasterizationState rasterizationState;
DepthStencilState depthStencilState;
ColorBlendState colorBlend;
MeshPipelineCreateInfo();
~MeshPipelineCreateInfo();
};
struct ComputePipelineCreateInfo
{
Gfx::PComputeShader computeShader;
Gfx::PPipelineLayout pipelineLayout;
ComputePipelineCreateInfo();
~ComputePipelineCreateInfo();
};
} // namespace Gfx
struct MeshPipelineCreateInfo
{
PTaskShader taskShader = nullptr;
PMeshShader meshShader = nullptr;
PFragmentShader fragmentShader = nullptr;
PRenderPass renderPass = nullptr;
PPipelineLayout pipelineLayout = nullptr;
MultisampleState multisampleState;
RasterizationState rasterizationState;
DepthStencilState depthStencilState;
ColorBlendState colorBlend;
};
struct ComputePipelineCreateInfo
{
Gfx::PComputeShader computeShader = nullptr;
Gfx::PPipelineLayout pipelineLayout = nullptr;
};
} // namespace Gfx
} // namespace Seele
+41 -129
View File
@@ -19,6 +19,28 @@ using namespace Seele;
BasePass::BasePass(Gfx::PGraphics graphics, PScene scene)
: RenderPass(graphics, scene)
{
basePassLayout = graphics->createPipelineLayout("BasePassLayout");
basePassLayout->addDescriptorLayout(viewParamsLayout);
basePassLayout->addDescriptorLayout(scene->getLightEnvironment()->getDescriptorLayout());
lightCullingLayout = graphics->createDescriptorLayout("pLightCullingData");
// oLightIndexList
lightCullingLayout->addDescriptorBinding(Gfx::DescriptorBinding{ .binding = 0, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER, });
// oLightGrid
lightCullingLayout->addDescriptorBinding(Gfx::DescriptorBinding{ .binding = 1, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_IMAGE, });
lightCullingLayout->create();
basePassLayout->addDescriptorLayout(lightCullingLayout);
if (graphics->supportMeshShading())
{
graphics->getShaderCompiler()->registerRenderPass(basePassLayout, "BasePass", "MeshletPass", true, true, "BasePass", true, true, "MeshletPass");
}
else
{
graphics->getShaderCompiler()->registerRenderPass(basePassLayout, "BasePass", "LegacyPass", true, true, "BasePass");
}
}
BasePass::~BasePass()
@@ -58,90 +80,7 @@ void BasePass::render()
graphics->beginRenderPass(renderPass);
Array<Gfx::ORenderCommand> commands;
// Static Meshes
{
Gfx::ShaderPermutation permutation;
if (graphics->supportMeshShading())
{
permutation.setTaskFile("StaticMeshletPass");
permutation.setMeshFile("StaticMeshletPass");
}
else
{
permutation.setVertexFile("StaticLegacyPass");
}
permutation.setFragmentFile("BasePass");
StaticMeshVertexData* vd = StaticMeshVertexData::getInstance();
permutation.setVertexData(vd->getTypeName());
for (const auto& [_, mappings] : vd->getStaticMeshes())
{
for (const auto& mapping : mappings)
{
permutation.setMaterial(mapping.material->getBaseMaterial()->getName());
Gfx::PermutationId id(permutation);
Gfx::ORenderCommand command = graphics->createRenderCommand("BaseRender");
command->setViewport(viewport);
const Gfx::ShaderCollection* collection = graphics->getShaderCompiler()->findShaders(id);
assert(collection != nullptr);
if (graphics->supportMeshShading())
{
Gfx::MeshPipelineCreateInfo pipelineInfo;
pipelineInfo.taskShader = collection->taskShader;
pipelineInfo.meshShader = collection->meshShader;
pipelineInfo.fragmentShader = collection->fragmentShader;
pipelineInfo.pipelineLayout = collection->pipelineLayout;
pipelineInfo.renderPass = renderPass;
pipelineInfo.depthStencilState.depthCompareOp = Gfx::SE_COMPARE_OP_GREATER_OR_EQUAL;
pipelineInfo.multisampleState.samples = viewport->getSamples();
pipelineInfo.colorBlend.attachmentCount = 1;
Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo));
command->bindPipeline(pipeline);
}
else
{
Gfx::LegacyPipelineCreateInfo pipelineInfo;
pipelineInfo.vertexShader = collection->vertexShader;
pipelineInfo.fragmentShader = collection->fragmentShader;
pipelineInfo.pipelineLayout = collection->pipelineLayout;
pipelineInfo.renderPass = renderPass;
pipelineInfo.depthStencilState.depthCompareOp = Gfx::SE_COMPARE_OP_GREATER_OR_EQUAL;
pipelineInfo.multisampleState.samples = viewport->getSamples();
pipelineInfo.colorBlend.attachmentCount = 1;
Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo));
command->bindPipeline(pipeline);
}
command->bindDescriptor(vd->getVertexDataSet());
command->bindDescriptor(viewParamsSet);
command->bindDescriptor(scene->getLightEnvironment()->getDescriptorSet());
command->bindDescriptor(opaqueCulling);
command->bindDescriptor(mapping.material->getDescriptorSet());
command->bindDescriptor(vd->getInstanceDataSet(), {0, 0});
if (graphics->supportMeshShading())
{
command->drawMesh(vd->getMeshData(mapping.mapped).size(), 1, 1);
}
else
{
command->bindIndexBuffer(vd->getIndexBuffer());
uint32 instanceOffset = 0;
for (const auto& meshData : vd->getMeshData(mapping.mapped))
{
if (meshData.numIndices > 0)
{
command->drawIndexed(meshData.numIndices, 1, meshData.firstIndex, meshData.indicesOffset, instanceOffset);
}
instanceOffset++;
}
}
commands.add(std::move(command));
}
}
}
// Others
{
Gfx::ShaderPermutation permutation;
if (graphics->supportMeshShading())
{
@@ -157,7 +96,7 @@ void BasePass::render()
{
permutation.setVertexData(vertexData->getTypeName());
const auto& materials = vertexData->getMaterialData();
for (const auto& [_, materialData] : materials)
for (const auto& materialData : materials)
{
// Create Pipeline(Material, VertexData)
// Descriptors:
@@ -206,7 +145,7 @@ void BasePass::render()
command->bindDescriptor(viewParamsSet);
command->bindDescriptor(scene->getLightEnvironment()->getDescriptorSet());
command->bindDescriptor(opaqueCulling);
for (const auto& [_, instance] : materialData.instances)
for (const auto& instance : materialData.instances)
{
command->bindDescriptor(instance.materialInstance->getDescriptorSet());
command->bindDescriptor(vertexData->getInstanceDataSet(), {instance.descriptorOffset, instance.descriptorOffset});
@@ -216,22 +155,22 @@ void BasePass::render()
}
else
{
command->bindIndexBuffer(vertexData->getIndexBuffer());
uint32 instanceOffset = 0;
for (const auto& meshData : vertexData->getMeshData(instance.meshId))
{
if (meshData.numIndices > 0)
{
command->drawIndexed(meshData.numIndices, 1, meshData.firstIndex, meshData.indicesOffset, instanceOffset);
}
instanceOffset++;
}
//command->bindIndexBuffer(vertexData->getIndexBuffer());
//uint32 instanceOffset = 0;
//for (const auto& meshData : vertexData->getMeshData(instance.meshId))
//{
// if (meshData.numIndices > 0)
// {
// command->drawIndexed(meshData.numIndices, 1, meshData.firstIndex, meshData.indicesOffset, instanceOffset);
// }
// instanceOffset++;
//}
}
}
commands.add(std::move(command));
}
}
}
graphics->executeCommands(std::move(commands));
graphics->endRenderPass();
@@ -243,44 +182,21 @@ void BasePass::endFrame()
void BasePass::publishOutputs()
{
basePassLayout = graphics->createPipelineLayout("BasePassLayout");
basePassLayout->addDescriptorLayout(viewParamsLayout);
basePassLayout->addDescriptorLayout(scene->getLightEnvironment()->getDescriptorLayout());
lightCullingLayout = graphics->createDescriptorLayout("pLightCullingData");
// oLightIndexList
lightCullingLayout->addDescriptorBinding(Gfx::DescriptorBinding{.binding = 0, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,});
// oLightGrid
lightCullingLayout->addDescriptorBinding(Gfx::DescriptorBinding{.binding = 1, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_IMAGE,});
lightCullingLayout->create();
basePassLayout->addDescriptorLayout(lightCullingLayout);
colorAttachment = Gfx::RenderTargetAttachment(viewport,
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_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
Gfx::SE_ATTACHMENT_LOAD_OP_LOAD, Gfx::SE_ATTACHMENT_STORE_OP_STORE);
resources->registerRenderPassOutput("BASEPASS_COLOR", colorAttachment);
if (graphics->supportMeshShading())
{
graphics->getShaderCompiler()->registerRenderPass(basePassLayout, "BasePass", "MeshletPass", true, true, "BasePass", true, true, "MeshBasePass");
graphics->getShaderCompiler()->registerRenderPass(basePassLayout, "StaticBasePass", "StaticMeshletPass", true, true, "BasePass", true, true, "StaticMeshletPass");
}
else
{
graphics->getShaderCompiler()->registerRenderPass(basePassLayout, "BasePass", "LegacyPass", true, true, "BasePass");
graphics->getShaderCompiler()->registerRenderPass(basePassLayout, "StaticBasePass", "StaticLegacyPass", true, true, "BasePass");
}
}
void BasePass::createRenderPass()
{
depthAttachment = resources->requestRenderTarget("DEPTHPREPASS_DEPTH");
meshletIdAttachment = resources->requestRenderTarget("BASEPASS_MESHLETID");
depthAttachment.setLoadOp(Gfx::SE_ATTACHMENT_LOAD_OP_LOAD);
depthAttachment.setInitialLayout(Gfx::SE_IMAGE_LAYOUT_GENERAL);
depthAttachment.setInitialLayout(Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
depthAttachment.setFinalLayout(Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
Gfx::RenderTargetLayout layout = Gfx::RenderTargetLayout{
.colorAttachments = { colorAttachment },
.colorAttachments = { colorAttachment, meshletIdAttachment },
.depthAttachment = depthAttachment,
};
Array<Gfx::SubPassDependency> dependency = {
@@ -297,7 +213,7 @@ void BasePass::createRenderPass()
.dstSubpass = 0,
.srcStage = 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,
},
{
@@ -323,7 +239,3 @@ void BasePass::createRenderPass()
oLightGrid = resources->requestTexture("LIGHTCULLING_OLIGHTGRID");
tLightGrid = resources->requestTexture("LIGHTCULLING_TLIGHTGRID");
}
void BasePass::modifyRenderPassMacros(Map<const char*, const char*>&)
{
}
+2 -1
View File
@@ -20,6 +20,7 @@ public:
private:
Gfx::RenderTargetAttachment colorAttachment;
Gfx::RenderTargetAttachment depthAttachment;
Gfx::RenderTargetAttachment meshletIdAttachment;
Gfx::PShaderBuffer oLightIndexList;
Gfx::PShaderBuffer tLightIndexList;
Gfx::PTexture2D oLightGrid;
@@ -27,7 +28,7 @@ private:
Gfx::PDescriptorSet opaqueCulling;
Gfx::PDescriptorSet transparentCulling;
//Array<Gfx::PDescriptorSet> descriptorSets;
PCameraActor source;
Gfx::OPipelineLayout basePassLayout;
Gfx::ODescriptorLayout lightCullingLayout;
+117 -81
View File
@@ -13,7 +13,7 @@
using namespace Seele;
DepthPrepass::DepthPrepass(Gfx::PGraphics graphics, PScene scene)
DepthPrepass::DepthPrepass(Gfx::PGraphics graphics, PScene scene)
: RenderPass(graphics, scene)
{
depthPrepassLayout = graphics->createPipelineLayout("DepthPrepassLayout");
@@ -29,102 +29,104 @@ DepthPrepass::DepthPrepass(Gfx::PGraphics graphics, PScene scene)
}
DepthPrepass::~DepthPrepass()
{
{
}
void DepthPrepass::beginFrame(const Component::Camera& cam)
void DepthPrepass::beginFrame(const Component::Camera& cam)
{
RenderPass::beginFrame(cam);
}
void DepthPrepass::render()
void DepthPrepass::render()
{
graphics->beginRenderPass(renderPass);
Array<Gfx::ORenderCommand> commands;
// Others
Gfx::ShaderPermutation permutation;
if (graphics->supportMeshShading())
{
Gfx::ShaderPermutation permutation;
if (graphics->supportMeshShading())
permutation.setTaskFile("MeshletPass");
permutation.setMeshFile("MeshletPass");
}
else
{
permutation.setVertexFile("LegacyPass");
}
for (VertexData* vertexData : VertexData::getList())
{
permutation.setVertexData(vertexData->getTypeName());
const auto& materials = vertexData->getMaterialData();
for (const auto& materialData : materials)
{
permutation.setTaskFile("MeshletPass");
permutation.setMeshFile("MeshletPass");
}
else
{
permutation.setVertexFile("LegacyPass");
}
for (VertexData* vertexData : VertexData::getList())
{
permutation.setVertexData(vertexData->getTypeName());
const auto& materials = vertexData->getMaterialData();
for (const auto& [_, materialData] : materials)
// Create Pipeline(VertexData)
// Descriptors:
// ViewData => global, static
// VertexData => per meshtype
// SceneData => per material instance
Gfx::PermutationId id(permutation);
Gfx::ORenderCommand command = graphics->createRenderCommand("BaseRender");
command->setViewport(viewport);
const Gfx::ShaderCollection* collection = graphics->getShaderCompiler()->findShaders(id);
assert(collection != nullptr);
if (graphics->supportMeshShading())
{
// Create Pipeline(VertexData)
// Descriptors:
// ViewData => global, static
// VertexData => per meshtype
// SceneData => per material instance
permutation.setMaterial(materialData.material->getName());
Gfx::PermutationId id(permutation);
Gfx::ORenderCommand command = graphics->createRenderCommand("BaseRender");
command->setViewport(viewport);
const Gfx::ShaderCollection* collection = graphics->getShaderCompiler()->findShaders(id);
assert(collection != nullptr);
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;
pipelineInfo.vertexShader = collection->vertexShader;
pipelineInfo.fragmentShader = collection->fragmentShader;
pipelineInfo.pipelineLayout = collection->pipelineLayout;
pipelineInfo.renderPass = renderPass;
pipelineInfo.depthStencilState.depthCompareOp = Gfx::SE_COMPARE_OP_GREATER;
pipelineInfo.multisampleState.samples = viewport->getSamples();
pipelineInfo.colorBlend.attachmentCount = 1;
Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo));
command->bindPipeline(pipeline);
}
command->bindDescriptor(vertexData->getVertexDataSet());
command->bindDescriptor(viewParamsSet);
for (const auto& instance : materialData.instances)
{
command->bindDescriptor(vertexData->getInstanceDataSet(), { instance.descriptorOffset, instance.descriptorOffset });
if (graphics->supportMeshShading())
{
Gfx::MeshPipelineCreateInfo pipelineInfo;
pipelineInfo.taskShader = collection->taskShader;
pipelineInfo.meshShader = collection->meshShader;
pipelineInfo.fragmentShader = collection->fragmentShader;
pipelineInfo.pipelineLayout = collection->pipelineLayout;
pipelineInfo.renderPass = renderPass;
pipelineInfo.depthStencilState.depthCompareOp = Gfx::SE_COMPARE_OP_GREATER;
pipelineInfo.multisampleState.samples = viewport->getSamples();
pipelineInfo.colorBlend.attachmentCount = 1;
Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo));
command->bindPipeline(pipeline);
command->drawMesh(vertexData->getMeshData(instance.meshId).size(), 1, 1);
}
else
{
Gfx::LegacyPipelineCreateInfo pipelineInfo;
pipelineInfo.vertexShader = collection->vertexShader;
pipelineInfo.fragmentShader = collection->fragmentShader;
pipelineInfo.pipelineLayout = collection->pipelineLayout;
pipelineInfo.renderPass = renderPass;
pipelineInfo.depthStencilState.depthCompareOp = Gfx::SE_COMPARE_OP_GREATER;
pipelineInfo.multisampleState.samples = viewport->getSamples();
pipelineInfo.colorBlend.attachmentCount = 1;
Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo));
command->bindPipeline(pipeline);
//command->bindIndexBuffer(vertexData->getIndexBuffer());
//uint32 instanceOffset = 0;
//for (const auto& meshData : vertexData->getMeshData(instance.meshId))
//{
// if (meshData.numIndices > 0)
// {
// command->drawIndexed(meshData.numIndices, 1, meshData.firstIndex, meshData.indicesOffset, instanceOffset);
// }
// instanceOffset++;
//}
}
command->bindDescriptor(vertexData->getVertexDataSet());
command->bindDescriptor(viewParamsSet);
for (const auto& [_, instance] : materialData.instances)
{
command->bindDescriptor(vertexData->getInstanceDataSet(), { instance.descriptorOffset, instance.descriptorOffset });
if (graphics->supportMeshShading())
{
command->drawMesh(vertexData->getMeshData(instance.meshId).size(), 1, 1);
}
else
{
command->bindIndexBuffer(vertexData->getIndexBuffer());
uint32 instanceOffset = 0;
for (const auto& meshData : vertexData->getMeshData(instance.meshId))
{
if (meshData.numIndices > 0)
{
command->drawIndexed(meshData.numIndices, 1, meshData.firstIndex, meshData.indicesOffset, instanceOffset);
}
instanceOffset++;
}
}
}
commands.add(std::move(command));
}
commands.add(std::move(command));
}
}
@@ -132,14 +134,48 @@ void DepthPrepass::render()
graphics->endRenderPass();
}
void DepthPrepass::endFrame()
void DepthPrepass::endFrame()
{
}
void DepthPrepass::publishOutputs()
void DepthPrepass::publishOutputs()
{
}
void DepthPrepass::createRenderPass()
void DepthPrepass::createRenderPass()
{
depthAttachment = resources->requestRenderTarget("DEPTHPREPASS_DEPTH");
depthAttachment.setLoadOp(Gfx::SE_ATTACHMENT_LOAD_OP_LOAD);
depthAttachment.setInitialLayout(Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
depthAttachment.setFinalLayout(Gfx::SE_IMAGE_LAYOUT_GENERAL);
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,
}
};
renderPass = graphics->createRenderPass(std::move(layout), std::move(dependency), viewport);
}
@@ -18,9 +18,7 @@ public:
virtual void createRenderPass() override;
private:
Gfx::RenderTargetAttachment depthAttachment;
Gfx::OTexture2D depthBuffer;
Gfx::OPipelineLayout depthPrepassLayout;
Gfx::ODescriptorLayout sceneDataLayout;
};
DEFINE_REF(DepthPrepass)
} // namespace Seele
@@ -189,9 +189,6 @@ void LightCullingPass::createRenderPass()
depthAttachment = resources->requestRenderTarget("DEPTHPREPASS_DEPTH").getTexture();
}
void LightCullingPass::modifyRenderPassMacros(Map<const char*, const char*>&)
{
}
void LightCullingPass::setupFrustums()
{
@@ -0,0 +1,227 @@
#include "StaticBasePass.h"
#include "Graphics/Shader.h"
#include "Graphics/StaticMeshVertexData.h"
using namespace Seele;
StaticBasePass::StaticBasePass(Gfx::PGraphics graphics, PScene scene)
: RenderPass(graphics, scene)
{
basePassLayout = graphics->createPipelineLayout("BasePassLayout");
basePassLayout->addDescriptorLayout(viewParamsLayout);
basePassLayout->addDescriptorLayout(scene->getLightEnvironment()->getDescriptorLayout());
lightCullingLayout = graphics->createDescriptorLayout("pLightCullingData");
// oLightIndexList
lightCullingLayout->addDescriptorBinding(Gfx::DescriptorBinding{ .binding = 0, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER, });
// oLightGrid
lightCullingLayout->addDescriptorBinding(Gfx::DescriptorBinding{ .binding = 1, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_IMAGE, });
lightCullingLayout->create();
basePassLayout->addDescriptorLayout(lightCullingLayout);
if (graphics->supportMeshShading())
{
graphics->getShaderCompiler()->registerRenderPass(basePassLayout, "BasePass", "StaticMeshletPass", true, true, "BasePass", true);
}
else
{
graphics->getShaderCompiler()->registerRenderPass(basePassLayout, "StaticBasePass", "StaticLegacyPass", true, true, "BasePass");
}
}
StaticBasePass::~StaticBasePass()
{
}
void StaticBasePass::beginFrame(const Component::Camera& cam)
{
RenderPass::beginFrame(cam);
lightCullingLayout->reset();
opaqueCulling = lightCullingLayout->allocateDescriptorSet();
transparentCulling = lightCullingLayout->allocateDescriptorSet();
}
void StaticBasePass::render()
{
oLightIndexList->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);
tLightIndexList->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);
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);
opaqueCulling->updateBuffer(0, oLightIndexList);
opaqueCulling->updateTexture(1, oLightGrid);
transparentCulling->updateBuffer(0, tLightIndexList);
transparentCulling->updateTexture(1, tLightGrid);
opaqueCulling->writeChanges();
transparentCulling->writeChanges();
graphics->beginRenderPass(renderPass);
Array<Gfx::ORenderCommand> commands;
Gfx::ShaderPermutation permutation;
if (graphics->supportMeshShading())
{
permutation.setTaskFile("StaticMeshletPass");
permutation.setMeshFile("StaticMeshletPass");
}
else
{
permutation.setVertexFile("StaticLegacyPass");
}
permutation.setFragmentFile("BasePass");
StaticMeshVertexData* vd = StaticMeshVertexData::getInstance();
permutation.setVertexData(vd->getTypeName());
for (size_t i = 0; i < vd->getStaticMeshes().size(); ++i)
{
const auto& mesh = vd->getStaticMeshes()[i];
permutation.setMaterial(mesh.material->getName());
Gfx::PermutationId id(permutation);
Gfx::ORenderCommand command = graphics->createRenderCommand("BaseRender");
command->setViewport(viewport);
const Gfx::ShaderCollection* collection = graphics->getShaderCompiler()->findShaders(id);
assert(collection != nullptr);
if (graphics->supportMeshShading())
{
Gfx::MeshPipelineCreateInfo pipelineInfo;
pipelineInfo.taskShader = collection->taskShader;
pipelineInfo.meshShader = collection->meshShader;
pipelineInfo.fragmentShader = collection->fragmentShader;
pipelineInfo.pipelineLayout = collection->pipelineLayout;
pipelineInfo.renderPass = renderPass;
pipelineInfo.depthStencilState.depthCompareOp = Gfx::SE_COMPARE_OP_GREATER_OR_EQUAL;
pipelineInfo.multisampleState.samples = viewport->getSamples();
pipelineInfo.colorBlend.attachmentCount = 1;
Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo));
command->bindPipeline(pipeline);
}
else
{
Gfx::LegacyPipelineCreateInfo pipelineInfo;
pipelineInfo.vertexShader = collection->vertexShader;
pipelineInfo.fragmentShader = collection->fragmentShader;
pipelineInfo.pipelineLayout = collection->pipelineLayout;
pipelineInfo.renderPass = renderPass;
pipelineInfo.depthStencilState.depthCompareOp = Gfx::SE_COMPARE_OP_GREATER_OR_EQUAL;
pipelineInfo.multisampleState.samples = viewport->getSamples();
pipelineInfo.colorBlend.attachmentCount = 1;
Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo));
command->bindPipeline(pipeline);
}
command->bindDescriptor(vd->getVertexDataSet());
command->bindDescriptor(viewParamsSet);
command->bindDescriptor(scene->getLightEnvironment()->getDescriptorSet());
command->bindDescriptor(opaqueCulling);
command->bindDescriptor(vd->getInstanceDataSet(), { 0, 0 });
for (const auto& instance : mesh.staticInstance)
{
command->bindDescriptor(instance.instance->getDescriptorSet());
if (graphics->supportMeshShading())
{
command->drawMesh(instance.meshletIds.size(), 1, 1);
}
else
{
//command->bindIndexBuffer(vd->getIndexBuffer());
//uint32 instanceOffset = 0;
//for (const auto& meshData : vd->getMeshData(mapping.mapped))
//{
// if (meshData.numIndices > 0)
// {
// command->drawIndexed(meshData.numIndices, 1, meshData.firstIndex, meshData.indicesOffset, instanceOffset);
// }
// instanceOffset++;
//}
}
}
commands.add(std::move(command));
}
graphics->executeCommands(std::move(commands));
graphics->endRenderPass();
}
void StaticBasePass::endFrame()
{
}
void StaticBasePass::publishOutputs()
{
colorAttachment = Gfx::RenderTargetAttachment(viewport,
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_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 StaticBasePass::createRenderPass()
{
depthAttachment = resources->requestRenderTarget("DEPTHPREPASS_DEPTH");
depthAttachment.setLoadOp(Gfx::SE_ATTACHMENT_LOAD_OP_LOAD);
depthAttachment.setInitialLayout(Gfx::SE_IMAGE_LAYOUT_GENERAL);
depthAttachment.setFinalLayout(Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
Gfx::RenderTargetLayout layout = Gfx::RenderTargetLayout{
.colorAttachments = { colorAttachment, meshletIdAttachment },
.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 = ~0U,
.dstSubpass = 0,
.srcStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
.dstStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
.srcAccess = Gfx::SE_ACCESS_NONE,
.dstAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
},
{
.srcSubpass = 0,
.dstSubpass = ~0U,
.srcStage = Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT,
.dstStage = Gfx::SE_PIPELINE_STAGE_LATE_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_WRITE_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);
oLightIndexList = resources->requestBuffer("LIGHTCULLING_OLIGHTLIST");
tLightIndexList = resources->requestBuffer("LIGHTCULLING_TLIGHTLIST");
oLightGrid = resources->requestTexture("LIGHTCULLING_OLIGHTGRID");
tLightGrid = resources->requestTexture("LIGHTCULLING_TLIGHTGRID");
}
@@ -0,0 +1,37 @@
#pragma once
#include "RenderPass.h"
namespace Seele
{
DECLARE_REF(CameraActor)
class StaticBasePass : public RenderPass
{
public:
StaticBasePass(Gfx::PGraphics graphics, PScene scene);
StaticBasePass(StaticBasePass&&) = default;
StaticBasePass& operator=(StaticBasePass&&) = default;
virtual ~StaticBasePass();
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 colorAttachment;
Gfx::RenderTargetAttachment depthAttachment;
Gfx::RenderTargetAttachment meshletIdAttachment;
Gfx::PShaderBuffer oLightIndexList;
Gfx::PShaderBuffer tLightIndexList;
Gfx::PTexture2D oLightGrid;
Gfx::PTexture2D tLightGrid;
Gfx::OTexture2D meshletIdTexture;
Gfx::PDescriptorSet opaqueCulling;
Gfx::PDescriptorSet transparentCulling;
PCameraActor source;
Gfx::OPipelineLayout basePassLayout;
Gfx::ODescriptorLayout lightCullingLayout;
};
}
@@ -7,11 +7,16 @@ using namespace Seele;
StaticDepthPrepass::StaticDepthPrepass(Gfx::PGraphics graphics, PScene scene)
: RenderPass(graphics, scene)
{
meshletCullingLayout = graphics->createDescriptorLayout("pCullingList");
meshletCullingLayout->addDescriptorBinding(Gfx::DescriptorBinding{ .binding = 0, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER, });
meshletCullingLayout->create();
depthPrepassLayout = graphics->createPipelineLayout("DepthPrepassLayout");
depthPrepassLayout->addDescriptorLayout(viewParamsLayout);
depthPrepassLayout->addDescriptorLayout(meshletCullingLayout);
if (graphics->supportMeshShading())
{
graphics->getShaderCompiler()->registerRenderPass(depthPrepassLayout, "DepthPass", "MeshletPass", false, false, "", true, true, "MeshletPass");
graphics->getShaderCompiler()->registerRenderPass(depthPrepassLayout, "DepthPass", "MeshletPass", false, false, "", true);
}
else
{
@@ -30,82 +35,95 @@ void StaticDepthPrepass::beginFrame(const Component::Camera& cam)
void StaticDepthPrepass::render()
{
// Static Meshes
Array<Gfx::ORenderCommand> commands;
graphics->beginRenderPass(renderPass);
Gfx::ShaderPermutation permutation;
if (graphics->supportMeshShading())
{
Gfx::ShaderPermutation permutation;
permutation.setTaskFile("StaticMeshletPass");
permutation.setMeshFile("StaticMeshletPass");
}
else
{
permutation.setVertexFile("LegacyPass");
}
StaticMeshVertexData* vd = StaticMeshVertexData::getInstance();
permutation.setVertexData(vd->getTypeName());
meshletCullingLayout->reset();
for (size_t i = 0; i < vd->getStaticMeshes().size(); ++i)
{
const auto& mesh = vd->getStaticMeshes()[i];
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())
{
permutation.setTaskFile("StaticMeshletPass");
permutation.setMeshFile("StaticMeshletPass");
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
{
permutation.setVertexFile("LegacyPass");
Gfx::LegacyPipelineCreateInfo pipelineInfo;
pipelineInfo.vertexShader = collection->vertexShader;
pipelineInfo.fragmentShader = collection->fragmentShader;
pipelineInfo.pipelineLayout = collection->pipelineLayout;
pipelineInfo.renderPass = renderPass;
pipelineInfo.depthStencilState.depthCompareOp = Gfx::SE_COMPARE_OP_GREATER;
pipelineInfo.multisampleState.samples = viewport->getSamples();
pipelineInfo.colorBlend.attachmentCount = 1;
Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo));
command->bindPipeline(pipeline);
}
StaticMeshVertexData* vd = StaticMeshVertexData::getInstance();
permutation.setVertexData(vd->getTypeName());
for (const auto& [_, mappings] : vd->)
command->bindDescriptor(viewParamsSet);
command->bindDescriptor(vd->getVertexDataSet());
command->bindDescriptor(vd->getInstanceDataSet(), { 0, 0 });
for (const auto& instance : mesh.staticInstance)
{
permutation.setMaterial(mapping.material->getBaseMaterial()->getName());
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;
pipelineInfo.taskShader = collection->taskShader;
pipelineInfo.meshShader = collection->meshShader;
pipelineInfo.fragmentShader = collection->fragmentShader;
pipelineInfo.pipelineLayout = collection->pipelineLayout;
pipelineInfo.renderPass = renderPass;
pipelineInfo.depthStencilState.depthCompareOp = Gfx::SE_COMPARE_OP_GREATER_OR_EQUAL;
pipelineInfo.multisampleState.samples = viewport->getSamples();
pipelineInfo.colorBlend.attachmentCount = 1;
Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo));
command->bindPipeline(pipeline);
}
else
{
Gfx::LegacyPipelineCreateInfo pipelineInfo;
pipelineInfo.vertexShader = collection->vertexShader;
pipelineInfo.fragmentShader = collection->fragmentShader;
pipelineInfo.pipelineLayout = collection->pipelineLayout;
pipelineInfo.renderPass = renderPass;
pipelineInfo.depthStencilState.depthCompareOp = Gfx::SE_COMPARE_OP_GREATER_OR_EQUAL;
pipelineInfo.multisampleState.samples = viewport->getSamples();
pipelineInfo.colorBlend.attachmentCount = 1;
Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo));
command->bindPipeline(pipeline);
}
command->bindDescriptor(viewParamsSet);
command->bindDescriptor(vd->getVertexDataSet());
command->bindDescriptor(vd->getInstanceDataSet(), { 0, 0 });
if (graphics->supportMeshShading())
{
command->drawMesh(vd->getMeshData(mapping.mapped).size(), 1, 1);
}
else
{
command->bindIndexBuffer(vd->getIndexBuffer());
uint32 instanceOffset = 0;
for (const auto& meshData : vd->getMeshData(mapping.mapped))
{
if (meshData.numIndices > 0)
{
command->drawIndexed(meshData.numIndices, 1, meshData.firstIndex, meshData.indicesOffset, instanceOffset);
}
instanceOffset++;
}
}
commands.add(std::move(command));
Gfx::PDescriptorSet cullingSet = meshletCullingLayout->allocateDescriptorSet();
cullingSet->updateBuffer(0, instance.culledMeshletBuffer);
cullingSet->writeChanges();
command->bindDescriptor(cullingSet);
if (graphics->supportMeshShading())
{
command->drawMesh(instance.meshletIds.size(), 1, 1);
}
else
{
//command->bindIndexBuffer(vd->getIndexBuffer());
//uint32 instanceOffset = 0;
//for (const auto& meshData : vd->getMeshData(mapping.mapped))
//{
// if (meshData.numIndices > 0)
// {
// command->drawIndexed(meshData.numIndices, 1, meshData.firstIndex, meshData.indicesOffset, instanceOffset);
// }
// instanceOffset++;
//}
}
}
commands.add(std::move(command));
}
graphics->endRenderPass();
}
void StaticDepthPrepass::endFrame()
@@ -125,7 +143,7 @@ void StaticDepthPrepass::publishOutputs()
depthBuffer = graphics->createTexture2D(depthBufferInfo);
depthAttachment =
Gfx::RenderTargetAttachment(depthBuffer,
Gfx::SE_IMAGE_LAYOUT_UNDEFINED, Gfx::SE_IMAGE_LAYOUT_GENERAL,
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);
}
@@ -144,14 +162,6 @@ void StaticDepthPrepass::createRenderPass()
.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,
@@ -19,6 +19,6 @@ private:
Gfx::RenderTargetAttachment depthAttachment;
Gfx::OTexture2D depthBuffer;
Gfx::OPipelineLayout depthPrepassLayout;
Gfx::ODescriptorLayout sceneDataLayout;
Gfx::ODescriptorLayout meshletCullingLayout;
};
}
+43 -14
View File
@@ -153,12 +153,12 @@ void StaticMeshVertexData::init(Gfx::PGraphics _graphics)
{
VertexData::init(_graphics);
descriptorLayout = _graphics->createDescriptorLayout("pVertexData");
descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{.binding = 0, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER});
descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{.binding = 1, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER});
descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{.binding = 2, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER});
descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{.binding = 3, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER});
descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{.binding = 4, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER});
descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{.binding = 5, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER, .descriptorCount = MAX_TEXCOORDS });
descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{ .binding = 0, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER });
descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{ .binding = 1, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER });
descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{ .binding = 2, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER });
descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{ .binding = 3, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER });
descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{ .binding = 4, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER });
descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{ .binding = 5, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER, .descriptorCount = MAX_TEXCOORDS });
descriptorLayout->create();
descriptorSet = descriptorLayout->allocateDescriptorSet();
}
@@ -193,14 +193,13 @@ Gfx::PDescriptorSet StaticMeshVertexData::getVertexDataSet()
return descriptorSet;
}
void StaticMeshVertexData::registerStaticMesh(entt::entity id, const Array<OMesh>& meshes, const Component::Transform& transform)
void StaticMeshVertexData::registerStaticMesh(const Array<OMesh>& meshes, const Component::Transform& transform)
{
std::unique_lock l(vertexDataLock);
std::unique_lock l2(mutex);
for (auto& mesh : meshes)
{
uint64 numVertices = meshVertexCounts[mesh->id];
uint64 offset = meshOffsets[mesh->id];
// Create new mesh where transform is "embedded"
MeshId mapped = VertexData::allocateVertexData(numVertices);
Array<Vector> pos(numVertices);
Matrix4 matrix = transform.toMatrix();
@@ -222,10 +221,40 @@ void StaticMeshVertexData::registerStaticMesh(entt::entity id, const Array<OMesh
loadBiTangents(mapped, aux);
std::memcpy(aux.data(), colorData.data() + offset, numVertices * sizeof(Vector));
loadColors(mapped, aux);
staticMeshes[id].add(StaticMeshMapping{
.original = mesh->id,
.mapped = mapped,
.material = mesh->referencedMaterial->getHandle(),
// Load meshlets again
VertexData::loadMesh(mapped, mesh->indices, mesh->meshlets);
Array<uint32> ids;
// Get references to loaded meshlets
const auto& meshData = VertexData::getMeshData(mapped);
for (const auto& md : meshData)
{
for (size_t i = 0; i < md.numMeshlets; ++i)
{
ids.add(md.meshletOffset + i);
}
}
// Get Static instance array
PMaterialInstance instance = mesh->referencedMaterial->getHandle();
PMaterial baseMat = instance->getBaseMaterial();
Array<StaticMatInstance> instances;
instances.add(StaticMatInstance{
.instance = mesh->referencedMaterial->getHandle(),
.meshletIds = ids,
.culledMeshletBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
.sourceData = {
.size = ids.size() * sizeof(uint32),
.data = (uint8*)ids.data(),
},
.numElements = ids.size(),
.dynamic = true,
}),
});
staticData.add(StaticMatData{
.material = baseMat,
.staticInstance = std::move(instances),
});
}
}
@@ -257,7 +286,7 @@ void StaticMeshVertexData::resizeBuffers()
texCoords[i] = graphics->createShaderBuffer(createInfo);
texCoordsData[i].resize(verticesAllocated);
}
positionData.resize(verticesAllocated);
normalData.resize(verticesAllocated);
tangentData.resize(verticesAllocated);
+12 -5
View File
@@ -10,11 +10,17 @@ namespace Seele
class StaticMeshVertexData : public VertexData
{
public:
struct StaticMeshMapping
struct StaticMatInstance
{
MeshId original;
MeshId mapped;
PMaterialInstance material;
PMaterialInstance instance;
Array<uint32> meshletIds;
Gfx::OShaderBuffer culledMeshletBuffer;
//Gfx::OShaderBuffer indirectDrawBuffer;
};
struct StaticMatData
{
PMaterial material;
Array<StaticMatInstance> staticInstance;
};
StaticMeshVertexData();
virtual ~StaticMeshVertexData();
@@ -34,10 +40,11 @@ public:
virtual Gfx::PDescriptorSet getVertexDataSet() override;
virtual std::string getTypeName() const override { return "StaticMeshVertexData"; }
void registerStaticMesh(const Array<OMesh>& meshes, const Component::Transform& transform);
constexpr const Array<StaticMatData>& getStaticMeshes() const { return staticData; }
private:
virtual void resizeBuffers() override;
virtual void updateBuffers() override;
Array<MeshletDescription> staticMeshlets;
Array<StaticMatData> staticData;
std::mutex mutex;
Gfx::OShaderBuffer positions;
+7 -3
View File
@@ -16,7 +16,7 @@ constexpr static uint64 NUM_DEFAULT_ELEMENTS = 1024 * 1024;
void VertexData::resetMeshData()
{
std::unique_lock l(materialDataLock);
for (auto& [_, mat] : materialData)
for (auto& mat : materialData)
{
mat.material->getDescriptorLayout()->reset();
}
@@ -33,7 +33,11 @@ void VertexData::updateMesh(PMesh mesh, Component::Transform& transform)
std::unique_lock l(materialDataLock);
PMaterialInstance referencedInstance = mesh->referencedMaterial->getHandle();
PMaterial mat = referencedInstance->getBaseMaterial();
MaterialData& matData = materialData[mat->getName()];
if (materialData.size() <= mat->getId())
{
materialData.resize(mat->getId());
}
MaterialData& matData = materialData[mat->getId()];
matData.material = mat;
MaterialInstanceData& matInstanceData = matData.instances[referencedInstance->getId()];
matInstanceData.descriptorOffset = instanceData.size();
@@ -166,13 +170,13 @@ void VertexData::loadMesh(MeshId id, Array<uint32> loadedIndices, Array<Meshlet>
.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 = numMeshlets,
.meshletOffset = meshletOffset,
.indicesOffset = (uint32)meshOffsets[id],
});
currentMesh += numMeshlets;
}
+4 -6
View File
@@ -40,8 +40,6 @@ public:
uint32 meshletOffset = 0;
uint32 firstIndex = 0;
uint32 numIndices = 0;
uint32 indicesOffset = 0;
uint32 pad0[3];
};
struct MaterialInstanceData
{
@@ -53,7 +51,7 @@ public:
struct MaterialData
{
PMaterial material;
Map<uint64, MaterialInstanceData> instances;
Array<MaterialInstanceData> instances;
};
void resetMeshData();
void updateMesh(PMesh mesh, Component::Transform& transform);
@@ -71,7 +69,7 @@ public:
Gfx::PIndexBuffer getIndexBuffer() { return indexBuffer; }
Gfx::PDescriptorLayout getInstanceDataLayout() { return instanceDataLayout; }
Gfx::PDescriptorSet getInstanceDataSet() { return descriptorSet; }
const Map<std::string, MaterialData>& getMaterialData() const { return materialData; }
const Array<MaterialData>& getMaterialData() const { return materialData; }
const Array<MeshData>& getMeshData(MeshId id) { return meshData[id]; }
static List<VertexData*> getList();
static VertexData* findByTypeName(std::string name);
@@ -89,10 +87,10 @@ protected:
uint32 vertexOffset;
uint32 primitiveOffset;
Vector color;
float pad;
uint32 indicesOffset = 0;
};
std::mutex materialDataLock;
Map<std::string, MaterialData> materialData;
Array<MaterialData> materialData;
std::mutex vertexDataLock;
Map<MeshId, Array<MeshData>> meshData;
Map<MeshId, uint64> meshOffsets;
+15 -12
View File
@@ -207,16 +207,19 @@ void Buffer::createBuffer()
.usage = VMA_MEMORY_USAGE_AUTO,
};
buffers.add();
vmaCreateBuffer(graphics->getAllocator(), &info, &allocInfo, &buffers.back().buffer, &buffers.back().allocation,
&buffers.back().info);
vmaGetAllocationMemoryProperties(graphics->getAllocator(), buffers.back().allocation, &buffers.back().properties);
if (!name.empty()) {
VkDebugUtilsObjectNameInfoEXT nameInfo = { .sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT,
.pNext = nullptr,
.objectType = VK_OBJECT_TYPE_BUFFER,
.objectHandle = (uint64)buffers.back().buffer,
.pObjectName = this->name.c_str() };
graphics->vkSetDebugUtilsObjectNameEXT(&nameInfo);
if (size > 0)
{
VK_CHECK(vmaCreateBuffer(graphics->getAllocator(), &info, &allocInfo, &buffers.back().buffer, &buffers.back().allocation,
&buffers.back().info));
vmaGetAllocationMemoryProperties(graphics->getAllocator(), buffers.back().allocation, &buffers.back().properties);
if (!name.empty()) {
VkDebugUtilsObjectNameInfoEXT nameInfo = { .sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT,
.pNext = nullptr,
.objectType = VK_OBJECT_TYPE_BUFFER,
.objectHandle = (uint64)buffers.back().buffer,
.pObjectName = this->name.c_str() };
graphics->vkSetDebugUtilsObjectNameEXT(&nameInfo);
}
}
}
@@ -224,7 +227,7 @@ UniformBuffer::UniformBuffer(PGraphics graphics, const UniformBufferCreateInfo&
: Gfx::UniformBuffer(graphics->getFamilyMapping(), createInfo.sourceData),
Vulkan::Buffer(graphics, createInfo.sourceData.size, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, currentOwner,
createInfo.dynamic, createInfo.name) {
if (createInfo.sourceData.data != nullptr) {
if (size > 0 && createInfo.sourceData.data != nullptr) {
void* data = map();
std::memcpy(data, createInfo.sourceData.data, createInfo.sourceData.size);
unmap();
@@ -265,7 +268,7 @@ ShaderBuffer::ShaderBuffer(PGraphics graphics, const ShaderBufferCreateInfo& sou
: Gfx::ShaderBuffer(graphics->getFamilyMapping(), sourceData.numElements, sourceData.sourceData),
Vulkan::Buffer(graphics, sourceData.sourceData.size, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, currentOwner,
sourceData.dynamic, sourceData.name) {
if (sourceData.sourceData.data != nullptr) {
if (size > 0 && sourceData.sourceData.data != nullptr) {
void* data = map();
std::memcpy(data, sourceData.sourceData.data, sourceData.sourceData.size);
unmap();
+6
View File
@@ -340,6 +340,12 @@ void RenderCommand::drawMesh(uint32 groupX, uint32 groupY, uint32 groupZ)
graphics->vkCmdDrawMeshTasksEXT(handle, groupX, groupY, groupZ);
}
void RenderCommand::drawMeshIndirect(Gfx::PShaderBuffer buffer, uint64 offset, uint32 drawCount, uint32 stride)
{
assert(threadId == std::this_thread::get_id());
graphics->vkCmdDrawMeshTasksIndirectEXT(handle, buffer.cast<ShaderBuffer>()->getHandle(), offset, drawCount, stride);
}
ComputeCommand::ComputeCommand(PGraphics graphics, VkCommandPool cmdPool)
: graphics(graphics)
, owner(cmdPool)
+1
View File
@@ -82,6 +82,7 @@ public:
virtual void drawIndexed(uint32 indexCount, uint32 instanceCount, int32 firstIndex, uint32 vertexOffset,
uint32 firstInstance) override;
virtual void drawMesh(uint32 groupX, uint32 groupY, uint32 groupZ) override;
virtual void drawMeshIndirect(Gfx::PShaderBuffer buffer, uint64 offset, uint32 drawCount, uint32 stride) override;
private:
PGraphicsPipeline pipeline;
+1 -1
View File
@@ -14,7 +14,7 @@
std::this_thread::sleep_for(std::chrono::seconds(3)); \
} \
std::cout << "Fatal : VkResult is " << res << " in " << __FILE__ << " at line " << __LINE__ << std::endl; \
assert(res == VK_SUCCESS); \
abort(); \
} \
}
+5 -22
View File
@@ -298,6 +298,11 @@ void Graphics::vkCmdDrawMeshTasksEXT(VkCommandBuffer handle, uint32 groupX, uint
cmdDrawMeshTasks(handle, groupX, groupY, groupZ);
}
void Graphics::vkCmdDrawMeshTasksIndirectEXT(VkCommandBuffer handle, VkBuffer buffer, uint64 offset, uint32 drawCount, uint32 stride)
{
cmdDrawMeshTasksIndirect(handle, buffer, offset, drawCount, stride);
}
void Graphics::vkSetDebugUtilsObjectNameEXT(VkDebugUtilsObjectNameInfoEXT* info)
{
VK_CHECK(setDebugUtilsObjectName(handle, info));
@@ -617,28 +622,6 @@ void Graphics::createDevice(GraphicsInitializer initializer)
queues.add(new Queue(this, transferQueueInfo.familyIndex, transferQueueInfo.queueIndex));
}
// if (Gfx::useAsyncCompute && asyncComputeInfo.familyIndex != -1)
// {
// if (asyncComputeInfo.familyIndex == graphicsQueueInfo.familyIndex)
// {
// // Same family as graphics, but different queue
// computeQueue = new Queue(this, asyncComputeInfo.familyIndex, 1);
// }
// else
// {
// // Different family
// computeQueue = new Queue(this, asyncComputeInfo.familyIndex, 0);
// }
// }
// else
// {
// computeQueue = new Queue(this, computeQueueInfo.familyIndex, 0);
// }
// transferQueue = new Queue(this, transferQueueInfo.familyIndex, 0);
// if (dedicatedTransferQueueInfo.familyIndex != -1)
// {
// dedicatedTransferQueue = new Queue(this, dedicatedTransferQueueInfo.familyIndex, 0);
// }
queueMapping.graphicsFamily = queues[graphicsQueue]->getFamilyIndex();
queueMapping.computeFamily = queues[computeQueue]->getFamilyIndex();
queueMapping.transferFamily = queues[transferQueue]->getFamilyIndex();
+2
View File
@@ -71,10 +71,12 @@ public:
virtual void resolveTexture(Gfx::PTexture source, Gfx::PTexture destination) override;
void vkCmdDrawMeshTasksEXT(VkCommandBuffer handle, uint32 groupX, uint32 groupY, uint32 groupZ);
void vkCmdDrawMeshTasksIndirectEXT(VkCommandBuffer handle, VkBuffer buffer, uint64 offset, uint32 drawCount, uint32 stride);
void vkSetDebugUtilsObjectNameEXT(VkDebugUtilsObjectNameInfoEXT* info);
protected:
PFN_vkCmdDrawMeshTasksEXT cmdDrawMeshTasks;
PFN_vkCmdDrawMeshTasksIndirectEXT cmdDrawMeshTasksIndirect;
PFN_vkSetDebugUtilsObjectNameEXT setDebugUtilsObjectName;
Array<const char *> getRequiredExtensions();
void initInstance(GraphicsInitializer initInfo);