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
+11 -2
View File
@@ -12,8 +12,14 @@ struct LightCullingData
layout(set=5) layout(set=5)
ParameterBlock<LightCullingData> pLightCullingData; ParameterBlock<LightCullingData> pLightCullingData;
struct FragmentOutput
{
float4 color : SV_Target0;
uint meshletId : SV_Target1;
};
[shader("pixel")] [shader("pixel")]
float4 fragmentMain(in FragmentParameter params) : SV_Target FragmentOutput fragmentMain(in FragmentParameter params)
{ {
LightingParameter lightingParams = params.getLightingParameter(); LightingParameter lightingParams = params.getLightingParameter();
MaterialParameter materialParams = params.getMaterialParameter(); MaterialParameter materialParams = params.getMaterialParameter();
@@ -35,5 +41,8 @@ float4 fragmentMain(in FragmentParameter params) : SV_Target
// gamma correction // gamma correction
result = result / (result + float3(1.0)); result = result / (result + float3(1.0));
result = pow(result, float3(1.0/2.2)); result = pow(result, float3(1.0/2.2));
return float4(result, 1.0f); FragmentOutput output;
output.color = float4(result, 1.0f);
output.meshletId = params.meshletId;
return output;
} }
+2 -1
View File
@@ -94,7 +94,8 @@ void meshMain(
uint v = min(i, m.vertexCount - 1); uint v = min(i, m.vertexCount - 1);
{ {
uint vertexIndex = pScene.vertexIndices[m.vertexOffset + v]; uint vertexIndex = pScene.vertexIndices[m.vertexOffset + v];
VertexAttributes attr = pVertexData.getAttributes(md.indicesOffset + vertexIndex); VertexAttributes attr = pVertexData.getAttributes(m.indicesOffset + vertexIndex);
attr.meshletId = -1;
vertices[v] = attr.getParameter(inst.transformMatrix); vertices[v] = attr.getParameter(inst.transformMatrix);
//vertices[v].vertexColor = m.color; //vertices[v].vertexColor = m.color;
} }
+10 -2
View File
@@ -9,6 +9,12 @@ struct PrimitiveAttributes
uint cull: SV_CullPrimitive; uint cull: SV_CullPrimitive;
}; };
struct CulledMeshletList
{
StructuredBuffer<uint> meshletIndices;
};
ParameterBlock<CulledMeshletList> pCullingList;
[numthreads(MESH_GROUP_SIZE, 1, 1)] [numthreads(MESH_GROUP_SIZE, 1, 1)]
[outputtopology("triangle")] [outputtopology("triangle")]
[shader("mesh")] [shader("mesh")]
@@ -18,7 +24,8 @@ void meshMain(
out vertices FragmentParameter vertices[MAX_VERTICES], out vertices FragmentParameter vertices[MAX_VERTICES],
out indices uint3 indices[MAX_PRIMITIVES] out indices uint3 indices[MAX_PRIMITIVES]
){ ){
MeshletDescription m = pScene.meshletInfos[groupID]; uint meshletIndex = pCullingList.meshletIndices[groupID];
MeshletDescription m = pScene.meshletInfos[meshletIndex];
SetMeshOutputCounts(m.vertexCount, m.primitiveCount); SetMeshOutputCounts(m.vertexCount, m.primitiveCount);
for(uint i = threadID; i < MAX_PRIMITIVES; i += MESH_GROUP_SIZE) for(uint i = threadID; i < MAX_PRIMITIVES; i += MESH_GROUP_SIZE)
@@ -36,7 +43,8 @@ void meshMain(
uint v = min(i, m.vertexCount - 1); uint v = min(i, m.vertexCount - 1);
{ {
uint vertexIndex = pScene.vertexIndices[m.vertexOffset + v]; uint vertexIndex = pScene.vertexIndices[m.vertexOffset + v];
VertexAttributes attr = pVertexData.getAttributes(md.indicesOffset + vertexIndex); VertexAttributes attr = pVertexData.getAttributes(m.indicesOffset + vertexIndex);
attr.meshletId = meshletIndex;
vertices[v] = attr.getParameter(float4x4(1.0)); vertices[v] = attr.getParameter(float4x4(1.0));
} }
} }
+3
View File
@@ -25,6 +25,7 @@ struct FragmentParameter
float3 biTangent_WS : TANGENT1; float3 biTangent_WS : TANGENT1;
float3 position_WS : POSITION2; float3 position_WS : POSITION2;
float3 vertexColor : COLOR0; float3 vertexColor : COLOR0;
uint meshletId : POSITION3;
float2 texCoords[MAX_TEXCOORDS] : TEXCOORD0; float2 texCoords[MAX_TEXCOORDS] : TEXCOORD0;
MaterialParameter getMaterialParameter() MaterialParameter getMaterialParameter()
{ {
@@ -55,6 +56,7 @@ struct VertexAttributes
float3 tangent_MS; float3 tangent_MS;
float3 biTangent_MS; float3 biTangent_MS;
float3 vertexColor; float3 vertexColor;
uint meshletId;
float2 texCoords[MAX_TEXCOORDS]; float2 texCoords[MAX_TEXCOORDS];
FragmentParameter getParameter(float4x4 transformMatrix) FragmentParameter getParameter(float4x4 transformMatrix)
{ {
@@ -73,6 +75,7 @@ struct VertexAttributes
result.position_WS = worldPos.xyz; result.position_WS = worldPos.xyz;
result.position_CS = clipPos; result.position_CS = clipPos;
result.vertexColor = vertexColor; result.vertexColor = vertexColor;
result.meshletId = meshletId;
for(uint i = 0; i < MAX_TEXCOORDS; ++i) for(uint i = 0; i < MAX_TEXCOORDS; ++i)
{ {
result.texCoords[i] = texCoords[i]; result.texCoords[i] = texCoords[i];
+1 -3
View File
@@ -8,7 +8,7 @@ struct MeshletDescription
uint32_t vertexOffset; uint32_t vertexOffset;
uint32_t primitiveOffset; uint32_t primitiveOffset;
float3 color; float3 color;
float pad; uint32_t indicesOffset;
}; };
struct MeshData struct MeshData
@@ -18,8 +18,6 @@ struct MeshData
uint32_t meshletOffset; uint32_t meshletOffset;
uint32_t firstIndex; uint32_t firstIndex;
uint32_t numIndices; uint32_t numIndices;
uint32_t indicesOffset;
uint32_t pad0[3];
}; };
static const uint MAX_VERTICES = 256; static const uint MAX_VERTICES = 256;
-1
View File
@@ -12,7 +12,6 @@ target_sources(Engine
Graphics.h Graphics.h
Graphics.cpp Graphics.cpp
Initializer.h Initializer.h
Initializer.cpp
Mesh.h Mesh.h
Mesh.cpp Mesh.cpp
Meshlet.h Meshlet.h
+1
View File
@@ -22,6 +22,7 @@ public:
virtual void draw(uint32 vertexCount, uint32 instanceCount, int32 firstVertex, uint32 firstInstance) = 0; 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 drawIndexed(uint32 indexCount, uint32 instanceCount, int32 firstIndex, uint32 vertexOffset, uint32 firstInstance) = 0;
virtual void drawMesh(uint32 groupX, uint32 groupY, uint32 groupZ) = 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; std::string name;
}; };
DEFINE_REF(RenderCommand) 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 namespace Seele
{ {
struct GraphicsInitializer struct GraphicsInitializer
{ {
const char *applicationName; const char* applicationName;
const char *engineName; const char* engineName;
const char *windowLayoutFile; const char* windowLayoutFile;
/** /**
* layers defines the enabled Vulkan layers used in the instance, * layers defines the enabled Vulkan layers used in the instance,
* if ENABLE_VALIDATION is defined, standard validation is already enabled * if ENABLE_VALIDATION is defined, standard validation is already enabled
* not yet implemented * not yet implemented
*/ */
Array<const char *> layers; Array<const char*> layers;
Array<const char *> instanceExtensions; Array<const char*> instanceExtensions;
Array<const char *> deviceExtensions; Array<const char*> deviceExtensions;
void *windowHandle; void* windowHandle;
GraphicsInitializer() GraphicsInitializer()
: applicationName("SeeleEngine") : applicationName("SeeleEngine")
, engineName("SeeleEngine") , engineName("SeeleEngine")
, windowLayoutFile(nullptr) , windowLayoutFile(nullptr)
, layers{"VK_LAYER_LUNARG_monitor"} , layers{ "VK_LAYER_LUNARG_monitor" }
, instanceExtensions{} , instanceExtensions{}
, deviceExtensions{"VK_KHR_swapchain"} , deviceExtensions{ "VK_KHR_swapchain" }
, windowHandle(nullptr) , windowHandle(nullptr)
{ {
} }
};
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;
}; };
uint32 logicOpEnable; struct WindowCreateInfo
SeLogicOp logicOp = Gfx::SE_LOGIC_OP_OR; {
uint32 attachmentCount; int32 width;
StaticArray<BlendAttachment, 16> blendAttachments; int32 height;
StaticArray<float, 4> blendConstants; 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(VertexInput)
DECLARE_REF(VertexShader) DECLARE_REF(VertexShader)
DECLARE_REF(TaskShader) DECLARE_REF(TaskShader)
DECLARE_REF(MeshShader) DECLARE_REF(MeshShader)
DECLARE_REF(FragmentShader) DECLARE_REF(FragmentShader)
DECLARE_REF(ComputeShader) DECLARE_REF(ComputeShader)
DECLARE_REF(RenderPass) DECLARE_REF(RenderPass)
DECLARE_REF(PipelineLayout) DECLARE_REF(PipelineLayout)
struct LegacyPipelineCreateInfo struct LegacyPipelineCreateInfo
{ {
SePrimitiveTopology topology; SePrimitiveTopology topology = Gfx::SE_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
PVertexInput vertexInput; PVertexInput vertexInput = nullptr;
PVertexShader vertexShader; PVertexShader vertexShader = nullptr;
PFragmentShader fragmentShader; PFragmentShader fragmentShader = nullptr;
PRenderPass renderPass; PRenderPass renderPass = nullptr;
PPipelineLayout pipelineLayout; PPipelineLayout pipelineLayout = nullptr;
MultisampleState multisampleState; MultisampleState multisampleState;
RasterizationState rasterizationState; RasterizationState rasterizationState;
DepthStencilState depthStencilState; DepthStencilState depthStencilState;
ColorBlendState colorBlend; ColorBlendState colorBlend;
LegacyPipelineCreateInfo(); };
~LegacyPipelineCreateInfo();
};
struct MeshPipelineCreateInfo struct MeshPipelineCreateInfo
{ {
PTaskShader taskShader; PTaskShader taskShader = nullptr;
PMeshShader meshShader; PMeshShader meshShader = nullptr;
PFragmentShader fragmentShader; PFragmentShader fragmentShader = nullptr;
PRenderPass renderPass; PRenderPass renderPass = nullptr;
PPipelineLayout pipelineLayout; PPipelineLayout pipelineLayout = nullptr;
MultisampleState multisampleState; MultisampleState multisampleState;
RasterizationState rasterizationState; RasterizationState rasterizationState;
DepthStencilState depthStencilState; DepthStencilState depthStencilState;
ColorBlendState colorBlend; ColorBlendState colorBlend;
MeshPipelineCreateInfo(); };
~MeshPipelineCreateInfo(); struct ComputePipelineCreateInfo
}; {
struct ComputePipelineCreateInfo Gfx::PComputeShader computeShader = nullptr;
{ Gfx::PPipelineLayout pipelineLayout = nullptr;
Gfx::PComputeShader computeShader; };
Gfx::PPipelineLayout pipelineLayout; } // namespace Gfx
ComputePipelineCreateInfo();
~ComputePipelineCreateInfo();
};
} // namespace Gfx
} // namespace Seele } // namespace Seele
+41 -129
View File
@@ -19,6 +19,28 @@ using namespace Seele;
BasePass::BasePass(Gfx::PGraphics graphics, PScene scene) BasePass::BasePass(Gfx::PGraphics graphics, PScene scene)
: RenderPass(graphics, 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() BasePass::~BasePass()
@@ -58,90 +80,7 @@ void BasePass::render()
graphics->beginRenderPass(renderPass); graphics->beginRenderPass(renderPass);
Array<Gfx::ORenderCommand> commands; 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; Gfx::ShaderPermutation permutation;
if (graphics->supportMeshShading()) if (graphics->supportMeshShading())
{ {
@@ -157,7 +96,7 @@ void BasePass::render()
{ {
permutation.setVertexData(vertexData->getTypeName()); permutation.setVertexData(vertexData->getTypeName());
const auto& materials = vertexData->getMaterialData(); const auto& materials = vertexData->getMaterialData();
for (const auto& [_, materialData] : materials) for (const auto& materialData : materials)
{ {
// Create Pipeline(Material, VertexData) // Create Pipeline(Material, VertexData)
// Descriptors: // Descriptors:
@@ -206,7 +145,7 @@ void BasePass::render()
command->bindDescriptor(viewParamsSet); command->bindDescriptor(viewParamsSet);
command->bindDescriptor(scene->getLightEnvironment()->getDescriptorSet()); command->bindDescriptor(scene->getLightEnvironment()->getDescriptorSet());
command->bindDescriptor(opaqueCulling); command->bindDescriptor(opaqueCulling);
for (const auto& [_, instance] : materialData.instances) for (const auto& instance : materialData.instances)
{ {
command->bindDescriptor(instance.materialInstance->getDescriptorSet()); command->bindDescriptor(instance.materialInstance->getDescriptorSet());
command->bindDescriptor(vertexData->getInstanceDataSet(), {instance.descriptorOffset, instance.descriptorOffset}); command->bindDescriptor(vertexData->getInstanceDataSet(), {instance.descriptorOffset, instance.descriptorOffset});
@@ -216,22 +155,22 @@ void BasePass::render()
} }
else else
{ {
command->bindIndexBuffer(vertexData->getIndexBuffer()); //command->bindIndexBuffer(vertexData->getIndexBuffer());
uint32 instanceOffset = 0; //uint32 instanceOffset = 0;
for (const auto& meshData : vertexData->getMeshData(instance.meshId)) //for (const auto& meshData : vertexData->getMeshData(instance.meshId))
{ //{
if (meshData.numIndices > 0) // if (meshData.numIndices > 0)
{ // {
command->drawIndexed(meshData.numIndices, 1, meshData.firstIndex, meshData.indicesOffset, instanceOffset); // command->drawIndexed(meshData.numIndices, 1, meshData.firstIndex, meshData.indicesOffset, instanceOffset);
} // }
instanceOffset++; // instanceOffset++;
} //}
} }
} }
commands.add(std::move(command)); commands.add(std::move(command));
} }
} }
}
graphics->executeCommands(std::move(commands)); graphics->executeCommands(std::move(commands));
graphics->endRenderPass(); graphics->endRenderPass();
@@ -243,44 +182,21 @@ void BasePass::endFrame()
void BasePass::publishOutputs() 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, colorAttachment = Gfx::RenderTargetAttachment(viewport,
Gfx::SE_IMAGE_LAYOUT_UNDEFINED, Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
Gfx::SE_ATTACHMENT_LOAD_OP_CLEAR, Gfx::SE_ATTACHMENT_STORE_OP_STORE); Gfx::SE_ATTACHMENT_LOAD_OP_LOAD, Gfx::SE_ATTACHMENT_STORE_OP_STORE);
resources->registerRenderPassOutput("BASEPASS_COLOR", colorAttachment); 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() void BasePass::createRenderPass()
{ {
depthAttachment = resources->requestRenderTarget("DEPTHPREPASS_DEPTH"); depthAttachment = resources->requestRenderTarget("DEPTHPREPASS_DEPTH");
meshletIdAttachment = resources->requestRenderTarget("BASEPASS_MESHLETID");
depthAttachment.setLoadOp(Gfx::SE_ATTACHMENT_LOAD_OP_LOAD); 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); depthAttachment.setFinalLayout(Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
Gfx::RenderTargetLayout layout = Gfx::RenderTargetLayout{ Gfx::RenderTargetLayout layout = Gfx::RenderTargetLayout{
.colorAttachments = { colorAttachment }, .colorAttachments = { colorAttachment, meshletIdAttachment },
.depthAttachment = depthAttachment, .depthAttachment = depthAttachment,
}; };
Array<Gfx::SubPassDependency> dependency = { Array<Gfx::SubPassDependency> dependency = {
@@ -297,7 +213,7 @@ void BasePass::createRenderPass()
.dstSubpass = 0, .dstSubpass = 0,
.srcStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, .srcStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
.dstStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, .dstStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
.srcAccess = Gfx::SE_ACCESS_NONE, .srcAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
.dstAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, .dstAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
}, },
{ {
@@ -323,7 +239,3 @@ void BasePass::createRenderPass()
oLightGrid = resources->requestTexture("LIGHTCULLING_OLIGHTGRID"); oLightGrid = resources->requestTexture("LIGHTCULLING_OLIGHTGRID");
tLightGrid = resources->requestTexture("LIGHTCULLING_TLIGHTGRID"); tLightGrid = resources->requestTexture("LIGHTCULLING_TLIGHTGRID");
} }
void BasePass::modifyRenderPassMacros(Map<const char*, const char*>&)
{
}
+2 -1
View File
@@ -20,6 +20,7 @@ public:
private: private:
Gfx::RenderTargetAttachment colorAttachment; Gfx::RenderTargetAttachment colorAttachment;
Gfx::RenderTargetAttachment depthAttachment; Gfx::RenderTargetAttachment depthAttachment;
Gfx::RenderTargetAttachment meshletIdAttachment;
Gfx::PShaderBuffer oLightIndexList; Gfx::PShaderBuffer oLightIndexList;
Gfx::PShaderBuffer tLightIndexList; Gfx::PShaderBuffer tLightIndexList;
Gfx::PTexture2D oLightGrid; Gfx::PTexture2D oLightGrid;
@@ -27,7 +28,7 @@ private:
Gfx::PDescriptorSet opaqueCulling; Gfx::PDescriptorSet opaqueCulling;
Gfx::PDescriptorSet transparentCulling; Gfx::PDescriptorSet transparentCulling;
//Array<Gfx::PDescriptorSet> descriptorSets;
PCameraActor source; PCameraActor source;
Gfx::OPipelineLayout basePassLayout; Gfx::OPipelineLayout basePassLayout;
Gfx::ODescriptorLayout lightCullingLayout; Gfx::ODescriptorLayout lightCullingLayout;
+109 -73
View File
@@ -42,89 +42,91 @@ void DepthPrepass::render()
graphics->beginRenderPass(renderPass); graphics->beginRenderPass(renderPass);
Array<Gfx::ORenderCommand> commands; Array<Gfx::ORenderCommand> commands;
// Others Gfx::ShaderPermutation permutation;
if (graphics->supportMeshShading())
{ {
Gfx::ShaderPermutation permutation; permutation.setTaskFile("MeshletPass");
if (graphics->supportMeshShading()) 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"); // Create Pipeline(VertexData)
permutation.setMeshFile("MeshletPass"); // Descriptors:
} // ViewData => global, static
else // VertexData => per meshtype
{ // SceneData => per material instance
permutation.setVertexFile("LegacyPass"); Gfx::PermutationId id(permutation);
}
for (VertexData* vertexData : VertexData::getList()) Gfx::ORenderCommand command = graphics->createRenderCommand("BaseRender");
{ command->setViewport(viewport);
permutation.setVertexData(vertexData->getTypeName());
const auto& materials = vertexData->getMaterialData(); const Gfx::ShaderCollection* collection = graphics->getShaderCompiler()->findShaders(id);
for (const auto& [_, materialData] : materials) assert(collection != nullptr);
if (graphics->supportMeshShading())
{ {
// Create Pipeline(VertexData) Gfx::MeshPipelineCreateInfo pipelineInfo = {
// Descriptors: .taskShader = collection->taskShader,
// ViewData => global, static .meshShader = collection->meshShader,
// VertexData => per meshtype .fragmentShader = collection->fragmentShader,
// SceneData => per material instance .renderPass = renderPass,
permutation.setMaterial(materialData.material->getName()); .pipelineLayout = collection->pipelineLayout,
Gfx::PermutationId id(permutation); .multisampleState = {
.samples = viewport->getSamples(),},
Gfx::ORenderCommand command = graphics->createRenderCommand("BaseRender"); .depthStencilState = {
command->setViewport(viewport); .depthCompareOp = Gfx::SE_COMPARE_OP_GREATER,
},
const Gfx::ShaderCollection* collection = graphics->getShaderCompiler()->findShaders(id); .colorBlend = {
assert(collection != nullptr); .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()) if (graphics->supportMeshShading())
{ {
Gfx::MeshPipelineCreateInfo pipelineInfo; command->drawMesh(vertexData->getMeshData(instance.meshId).size(), 1, 1);
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);
} }
else else
{ {
Gfx::LegacyPipelineCreateInfo pipelineInfo; //command->bindIndexBuffer(vertexData->getIndexBuffer());
pipelineInfo.vertexShader = collection->vertexShader; //uint32 instanceOffset = 0;
pipelineInfo.fragmentShader = collection->fragmentShader; //for (const auto& meshData : vertexData->getMeshData(instance.meshId))
pipelineInfo.pipelineLayout = collection->pipelineLayout; //{
pipelineInfo.renderPass = renderPass; // if (meshData.numIndices > 0)
pipelineInfo.depthStencilState.depthCompareOp = Gfx::SE_COMPARE_OP_GREATER; // {
pipelineInfo.multisampleState.samples = viewport->getSamples(); // command->drawIndexed(meshData.numIndices, 1, meshData.firstIndex, meshData.indicesOffset, instanceOffset);
pipelineInfo.colorBlend.attachmentCount = 1; // }
Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo)); // instanceOffset++;
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())
{
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));
} }
} }
@@ -142,4 +144,38 @@ 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; virtual void createRenderPass() override;
private: private:
Gfx::RenderTargetAttachment depthAttachment; Gfx::RenderTargetAttachment depthAttachment;
Gfx::OTexture2D depthBuffer;
Gfx::OPipelineLayout depthPrepassLayout; Gfx::OPipelineLayout depthPrepassLayout;
Gfx::ODescriptorLayout sceneDataLayout;
}; };
DEFINE_REF(DepthPrepass) DEFINE_REF(DepthPrepass)
} // namespace Seele } // namespace Seele
@@ -189,9 +189,6 @@ void LightCullingPass::createRenderPass()
depthAttachment = resources->requestRenderTarget("DEPTHPREPASS_DEPTH").getTexture(); depthAttachment = resources->requestRenderTarget("DEPTHPREPASS_DEPTH").getTexture();
} }
void LightCullingPass::modifyRenderPassMacros(Map<const char*, const char*>&)
{
}
void LightCullingPass::setupFrustums() 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) StaticDepthPrepass::StaticDepthPrepass(Gfx::PGraphics graphics, PScene scene)
: RenderPass(graphics, 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 = graphics->createPipelineLayout("DepthPrepassLayout");
depthPrepassLayout->addDescriptorLayout(viewParamsLayout); depthPrepassLayout->addDescriptorLayout(viewParamsLayout);
depthPrepassLayout->addDescriptorLayout(meshletCullingLayout);
if (graphics->supportMeshShading()) if (graphics->supportMeshShading())
{ {
graphics->getShaderCompiler()->registerRenderPass(depthPrepassLayout, "DepthPass", "MeshletPass", false, false, "", true, true, "MeshletPass"); graphics->getShaderCompiler()->registerRenderPass(depthPrepassLayout, "DepthPass", "MeshletPass", false, false, "", true);
} }
else else
{ {
@@ -30,82 +35,95 @@ void StaticDepthPrepass::beginFrame(const Component::Camera& cam)
void StaticDepthPrepass::render() 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()) if (graphics->supportMeshShading())
{ {
permutation.setTaskFile("StaticMeshletPass"); Gfx::MeshPipelineCreateInfo pipelineInfo = {
permutation.setMeshFile("StaticMeshletPass"); .taskShader = collection->taskShader,
.meshShader = collection->meshShader,
.fragmentShader = collection->fragmentShader,
.renderPass = renderPass,
.pipelineLayout = collection->pipelineLayout,
.multisampleState = {
.samples = viewport->getSamples(),},
.depthStencilState = {
.depthCompareOp = Gfx::SE_COMPARE_OP_GREATER,
},
.colorBlend = {
.attachmentCount = 1,
},
};
Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo));
command->bindPipeline(pipeline);
} }
else else
{ {
permutation.setVertexFile("LegacyPass"); Gfx::LegacyPipelineCreateInfo pipelineInfo;
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(); command->bindDescriptor(viewParamsSet);
permutation.setVertexData(vd->getTypeName()); command->bindDescriptor(vd->getVertexDataSet());
for (const auto& [_, mappings] : vd->) command->bindDescriptor(vd->getInstanceDataSet(), { 0, 0 });
for (const auto& instance : mesh.staticInstance)
{ {
permutation.setMaterial(mapping.material->getBaseMaterial()->getName()); Gfx::PDescriptorSet cullingSet = meshletCullingLayout->allocateDescriptorSet();
Gfx::PermutationId id(permutation); cullingSet->updateBuffer(0, instance.culledMeshletBuffer);
cullingSet->writeChanges();
Gfx::ORenderCommand command = graphics->createRenderCommand("DepthRender"); command->bindDescriptor(cullingSet);
command->setViewport(viewport); if (graphics->supportMeshShading())
{
const Gfx::ShaderCollection* collection = graphics->getShaderCompiler()->findShaders(id); command->drawMesh(instance.meshletIds.size(), 1, 1);
assert(collection != nullptr); }
if (graphics->supportMeshShading()) else
{ {
Gfx::MeshPipelineCreateInfo pipelineInfo; //command->bindIndexBuffer(vd->getIndexBuffer());
pipelineInfo.taskShader = collection->taskShader; //uint32 instanceOffset = 0;
pipelineInfo.meshShader = collection->meshShader; //for (const auto& meshData : vd->getMeshData(mapping.mapped))
pipelineInfo.fragmentShader = collection->fragmentShader; //{
pipelineInfo.pipelineLayout = collection->pipelineLayout; // if (meshData.numIndices > 0)
pipelineInfo.renderPass = renderPass; // {
pipelineInfo.depthStencilState.depthCompareOp = Gfx::SE_COMPARE_OP_GREATER_OR_EQUAL; // command->drawIndexed(meshData.numIndices, 1, meshData.firstIndex, meshData.indicesOffset, instanceOffset);
pipelineInfo.multisampleState.samples = viewport->getSamples(); // }
pipelineInfo.colorBlend.attachmentCount = 1; // instanceOffset++;
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));
} }
} }
commands.add(std::move(command));
} }
graphics->endRenderPass();
} }
void StaticDepthPrepass::endFrame() void StaticDepthPrepass::endFrame()
@@ -125,7 +143,7 @@ void StaticDepthPrepass::publishOutputs()
depthBuffer = graphics->createTexture2D(depthBufferInfo); depthBuffer = graphics->createTexture2D(depthBufferInfo);
depthAttachment = depthAttachment =
Gfx::RenderTargetAttachment(depthBuffer, 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); Gfx::SE_ATTACHMENT_LOAD_OP_CLEAR, Gfx::SE_ATTACHMENT_STORE_OP_STORE);
resources->registerRenderPassOutput("DEPTHPREPASS_DEPTH", depthAttachment); resources->registerRenderPassOutput("DEPTHPREPASS_DEPTH", depthAttachment);
} }
@@ -144,14 +162,6 @@ void StaticDepthPrepass::createRenderPass()
.srcAccess = Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_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, .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, .srcSubpass = 0,
.dstSubpass = ~0U, .dstSubpass = ~0U,
@@ -19,6 +19,6 @@ private:
Gfx::RenderTargetAttachment depthAttachment; Gfx::RenderTargetAttachment depthAttachment;
Gfx::OTexture2D depthBuffer; Gfx::OTexture2D depthBuffer;
Gfx::OPipelineLayout depthPrepassLayout; Gfx::OPipelineLayout depthPrepassLayout;
Gfx::ODescriptorLayout sceneDataLayout; Gfx::ODescriptorLayout meshletCullingLayout;
}; };
} }
+42 -13
View File
@@ -153,12 +153,12 @@ void StaticMeshVertexData::init(Gfx::PGraphics _graphics)
{ {
VertexData::init(_graphics); VertexData::init(_graphics);
descriptorLayout = _graphics->createDescriptorLayout("pVertexData"); descriptorLayout = _graphics->createDescriptorLayout("pVertexData");
descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{.binding = 0, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER}); 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 = 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 = 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 = 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 = 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 = 5, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER, .descriptorCount = MAX_TEXCOORDS });
descriptorLayout->create(); descriptorLayout->create();
descriptorSet = descriptorLayout->allocateDescriptorSet(); descriptorSet = descriptorLayout->allocateDescriptorSet();
} }
@@ -193,14 +193,13 @@ Gfx::PDescriptorSet StaticMeshVertexData::getVertexDataSet()
return descriptorSet; 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) for (auto& mesh : meshes)
{ {
uint64 numVertices = meshVertexCounts[mesh->id]; uint64 numVertices = meshVertexCounts[mesh->id];
uint64 offset = meshOffsets[mesh->id]; uint64 offset = meshOffsets[mesh->id];
// Create new mesh where transform is "embedded"
MeshId mapped = VertexData::allocateVertexData(numVertices); MeshId mapped = VertexData::allocateVertexData(numVertices);
Array<Vector> pos(numVertices); Array<Vector> pos(numVertices);
Matrix4 matrix = transform.toMatrix(); Matrix4 matrix = transform.toMatrix();
@@ -222,10 +221,40 @@ void StaticMeshVertexData::registerStaticMesh(entt::entity id, const Array<OMesh
loadBiTangents(mapped, aux); loadBiTangents(mapped, aux);
std::memcpy(aux.data(), colorData.data() + offset, numVertices * sizeof(Vector)); std::memcpy(aux.data(), colorData.data() + offset, numVertices * sizeof(Vector));
loadColors(mapped, aux); loadColors(mapped, aux);
staticMeshes[id].add(StaticMeshMapping{
.original = mesh->id, // Load meshlets again
.mapped = mapped, VertexData::loadMesh(mapped, mesh->indices, mesh->meshlets);
.material = mesh->referencedMaterial->getHandle(),
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),
}); });
} }
} }
+12 -5
View File
@@ -10,11 +10,17 @@ namespace Seele
class StaticMeshVertexData : public VertexData class StaticMeshVertexData : public VertexData
{ {
public: public:
struct StaticMeshMapping struct StaticMatInstance
{ {
MeshId original; PMaterialInstance instance;
MeshId mapped; Array<uint32> meshletIds;
PMaterialInstance material; Gfx::OShaderBuffer culledMeshletBuffer;
//Gfx::OShaderBuffer indirectDrawBuffer;
};
struct StaticMatData
{
PMaterial material;
Array<StaticMatInstance> staticInstance;
}; };
StaticMeshVertexData(); StaticMeshVertexData();
virtual ~StaticMeshVertexData(); virtual ~StaticMeshVertexData();
@@ -34,10 +40,11 @@ public:
virtual Gfx::PDescriptorSet getVertexDataSet() override; virtual Gfx::PDescriptorSet getVertexDataSet() override;
virtual std::string getTypeName() const override { return "StaticMeshVertexData"; } virtual std::string getTypeName() const override { return "StaticMeshVertexData"; }
void registerStaticMesh(const Array<OMesh>& meshes, const Component::Transform& transform); void registerStaticMesh(const Array<OMesh>& meshes, const Component::Transform& transform);
constexpr const Array<StaticMatData>& getStaticMeshes() const { return staticData; }
private: private:
virtual void resizeBuffers() override; virtual void resizeBuffers() override;
virtual void updateBuffers() override; virtual void updateBuffers() override;
Array<MeshletDescription> staticMeshlets; Array<StaticMatData> staticData;
std::mutex mutex; std::mutex mutex;
Gfx::OShaderBuffer positions; Gfx::OShaderBuffer positions;
+7 -3
View File
@@ -16,7 +16,7 @@ constexpr static uint64 NUM_DEFAULT_ELEMENTS = 1024 * 1024;
void VertexData::resetMeshData() void VertexData::resetMeshData()
{ {
std::unique_lock l(materialDataLock); std::unique_lock l(materialDataLock);
for (auto& [_, mat] : materialData) for (auto& mat : materialData)
{ {
mat.material->getDescriptorLayout()->reset(); mat.material->getDescriptorLayout()->reset();
} }
@@ -33,7 +33,11 @@ void VertexData::updateMesh(PMesh mesh, Component::Transform& transform)
std::unique_lock l(materialDataLock); std::unique_lock l(materialDataLock);
PMaterialInstance referencedInstance = mesh->referencedMaterial->getHandle(); PMaterialInstance referencedInstance = mesh->referencedMaterial->getHandle();
PMaterial mat = referencedInstance->getBaseMaterial(); PMaterial mat = referencedInstance->getBaseMaterial();
MaterialData& matData = materialData[mat->getName()]; if (materialData.size() <= mat->getId())
{
materialData.resize(mat->getId());
}
MaterialData& matData = materialData[mat->getId()];
matData.material = mat; matData.material = mat;
MaterialInstanceData& matInstanceData = matData.instances[referencedInstance->getId()]; MaterialInstanceData& matInstanceData = matData.instances[referencedInstance->getId()];
matInstanceData.descriptorOffset = instanceData.size(); matInstanceData.descriptorOffset = instanceData.size();
@@ -166,13 +170,13 @@ void VertexData::loadMesh(MeshId id, Array<uint32> loadedIndices, Array<Meshlet>
.vertexOffset = vertexOffset, .vertexOffset = vertexOffset,
.primitiveOffset = primitiveOffset, .primitiveOffset = primitiveOffset,
.color = Vector((float)rand() / RAND_MAX,(float)rand() / RAND_MAX,(float)rand() / RAND_MAX), .color = Vector((float)rand() / RAND_MAX,(float)rand() / RAND_MAX,(float)rand() / RAND_MAX),
.indicesOffset = (uint32)meshOffsets[id],
}); });
} }
meshData[id].add(MeshData{ meshData[id].add(MeshData{
.bounding = meshAABB,//.toSphere(), .bounding = meshAABB,//.toSphere(),
.numMeshlets = numMeshlets, .numMeshlets = numMeshlets,
.meshletOffset = meshletOffset, .meshletOffset = meshletOffset,
.indicesOffset = (uint32)meshOffsets[id],
}); });
currentMesh += numMeshlets; currentMesh += numMeshlets;
} }
+4 -6
View File
@@ -40,8 +40,6 @@ public:
uint32 meshletOffset = 0; uint32 meshletOffset = 0;
uint32 firstIndex = 0; uint32 firstIndex = 0;
uint32 numIndices = 0; uint32 numIndices = 0;
uint32 indicesOffset = 0;
uint32 pad0[3];
}; };
struct MaterialInstanceData struct MaterialInstanceData
{ {
@@ -53,7 +51,7 @@ public:
struct MaterialData struct MaterialData
{ {
PMaterial material; PMaterial material;
Map<uint64, MaterialInstanceData> instances; Array<MaterialInstanceData> instances;
}; };
void resetMeshData(); void resetMeshData();
void updateMesh(PMesh mesh, Component::Transform& transform); void updateMesh(PMesh mesh, Component::Transform& transform);
@@ -71,7 +69,7 @@ public:
Gfx::PIndexBuffer getIndexBuffer() { return indexBuffer; } Gfx::PIndexBuffer getIndexBuffer() { return indexBuffer; }
Gfx::PDescriptorLayout getInstanceDataLayout() { return instanceDataLayout; } Gfx::PDescriptorLayout getInstanceDataLayout() { return instanceDataLayout; }
Gfx::PDescriptorSet getInstanceDataSet() { return descriptorSet; } Gfx::PDescriptorSet getInstanceDataSet() { return descriptorSet; }
const Map<std::string, MaterialData>& getMaterialData() const { return materialData; } const Array<MaterialData>& getMaterialData() const { return materialData; }
const Array<MeshData>& getMeshData(MeshId id) { return meshData[id]; } const Array<MeshData>& getMeshData(MeshId id) { return meshData[id]; }
static List<VertexData*> getList(); static List<VertexData*> getList();
static VertexData* findByTypeName(std::string name); static VertexData* findByTypeName(std::string name);
@@ -89,10 +87,10 @@ protected:
uint32 vertexOffset; uint32 vertexOffset;
uint32 primitiveOffset; uint32 primitiveOffset;
Vector color; Vector color;
float pad; uint32 indicesOffset = 0;
}; };
std::mutex materialDataLock; std::mutex materialDataLock;
Map<std::string, MaterialData> materialData; Array<MaterialData> materialData;
std::mutex vertexDataLock; std::mutex vertexDataLock;
Map<MeshId, Array<MeshData>> meshData; Map<MeshId, Array<MeshData>> meshData;
Map<MeshId, uint64> meshOffsets; Map<MeshId, uint64> meshOffsets;
+15 -12
View File
@@ -207,16 +207,19 @@ void Buffer::createBuffer()
.usage = VMA_MEMORY_USAGE_AUTO, .usage = VMA_MEMORY_USAGE_AUTO,
}; };
buffers.add(); buffers.add();
vmaCreateBuffer(graphics->getAllocator(), &info, &allocInfo, &buffers.back().buffer, &buffers.back().allocation, if (size > 0)
&buffers.back().info); {
vmaGetAllocationMemoryProperties(graphics->getAllocator(), buffers.back().allocation, &buffers.back().properties); VK_CHECK(vmaCreateBuffer(graphics->getAllocator(), &info, &allocInfo, &buffers.back().buffer, &buffers.back().allocation,
if (!name.empty()) { &buffers.back().info));
VkDebugUtilsObjectNameInfoEXT nameInfo = { .sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT, vmaGetAllocationMemoryProperties(graphics->getAllocator(), buffers.back().allocation, &buffers.back().properties);
.pNext = nullptr, if (!name.empty()) {
.objectType = VK_OBJECT_TYPE_BUFFER, VkDebugUtilsObjectNameInfoEXT nameInfo = { .sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT,
.objectHandle = (uint64)buffers.back().buffer, .pNext = nullptr,
.pObjectName = this->name.c_str() }; .objectType = VK_OBJECT_TYPE_BUFFER,
graphics->vkSetDebugUtilsObjectNameEXT(&nameInfo); .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), : Gfx::UniformBuffer(graphics->getFamilyMapping(), createInfo.sourceData),
Vulkan::Buffer(graphics, createInfo.sourceData.size, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, currentOwner, Vulkan::Buffer(graphics, createInfo.sourceData.size, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, currentOwner,
createInfo.dynamic, createInfo.name) { createInfo.dynamic, createInfo.name) {
if (createInfo.sourceData.data != nullptr) { if (size > 0 && createInfo.sourceData.data != nullptr) {
void* data = map(); void* data = map();
std::memcpy(data, createInfo.sourceData.data, createInfo.sourceData.size); std::memcpy(data, createInfo.sourceData.data, createInfo.sourceData.size);
unmap(); unmap();
@@ -265,7 +268,7 @@ ShaderBuffer::ShaderBuffer(PGraphics graphics, const ShaderBufferCreateInfo& sou
: Gfx::ShaderBuffer(graphics->getFamilyMapping(), sourceData.numElements, sourceData.sourceData), : Gfx::ShaderBuffer(graphics->getFamilyMapping(), sourceData.numElements, sourceData.sourceData),
Vulkan::Buffer(graphics, sourceData.sourceData.size, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, currentOwner, Vulkan::Buffer(graphics, sourceData.sourceData.size, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, currentOwner,
sourceData.dynamic, sourceData.name) { sourceData.dynamic, sourceData.name) {
if (sourceData.sourceData.data != nullptr) { if (size > 0 && sourceData.sourceData.data != nullptr) {
void* data = map(); void* data = map();
std::memcpy(data, sourceData.sourceData.data, sourceData.sourceData.size); std::memcpy(data, sourceData.sourceData.data, sourceData.sourceData.size);
unmap(); unmap();
+6
View File
@@ -340,6 +340,12 @@ void RenderCommand::drawMesh(uint32 groupX, uint32 groupY, uint32 groupZ)
graphics->vkCmdDrawMeshTasksEXT(handle, groupX, groupY, 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) ComputeCommand::ComputeCommand(PGraphics graphics, VkCommandPool cmdPool)
: graphics(graphics) : graphics(graphics)
, owner(cmdPool) , owner(cmdPool)
+1
View File
@@ -82,6 +82,7 @@ public:
virtual void drawIndexed(uint32 indexCount, uint32 instanceCount, int32 firstIndex, uint32 vertexOffset, virtual void drawIndexed(uint32 indexCount, uint32 instanceCount, int32 firstIndex, uint32 vertexOffset,
uint32 firstInstance) override; uint32 firstInstance) override;
virtual void drawMesh(uint32 groupX, uint32 groupY, uint32 groupZ) 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: private:
PGraphicsPipeline pipeline; PGraphicsPipeline pipeline;
+1 -1
View File
@@ -14,7 +14,7 @@
std::this_thread::sleep_for(std::chrono::seconds(3)); \ std::this_thread::sleep_for(std::chrono::seconds(3)); \
} \ } \
std::cout << "Fatal : VkResult is " << res << " in " << __FILE__ << " at line " << __LINE__ << std::endl; \ 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); 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) void Graphics::vkSetDebugUtilsObjectNameEXT(VkDebugUtilsObjectNameInfoEXT* info)
{ {
VK_CHECK(setDebugUtilsObjectName(handle, info)); VK_CHECK(setDebugUtilsObjectName(handle, info));
@@ -617,28 +622,6 @@ void Graphics::createDevice(GraphicsInitializer initializer)
queues.add(new Queue(this, transferQueueInfo.familyIndex, transferQueueInfo.queueIndex)); 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.graphicsFamily = queues[graphicsQueue]->getFamilyIndex();
queueMapping.computeFamily = queues[computeQueue]->getFamilyIndex(); queueMapping.computeFamily = queues[computeQueue]->getFamilyIndex();
queueMapping.transferFamily = queues[transferQueue]->getFamilyIndex(); queueMapping.transferFamily = queues[transferQueue]->getFamilyIndex();
+2
View File
@@ -71,10 +71,12 @@ public:
virtual void resolveTexture(Gfx::PTexture source, Gfx::PTexture destination) override; virtual void resolveTexture(Gfx::PTexture source, Gfx::PTexture destination) override;
void vkCmdDrawMeshTasksEXT(VkCommandBuffer handle, uint32 groupX, uint32 groupY, uint32 groupZ); 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); void vkSetDebugUtilsObjectNameEXT(VkDebugUtilsObjectNameInfoEXT* info);
protected: protected:
PFN_vkCmdDrawMeshTasksEXT cmdDrawMeshTasks; PFN_vkCmdDrawMeshTasksEXT cmdDrawMeshTasks;
PFN_vkCmdDrawMeshTasksIndirectEXT cmdDrawMeshTasksIndirect;
PFN_vkSetDebugUtilsObjectNameEXT setDebugUtilsObjectName; PFN_vkSetDebugUtilsObjectNameEXT setDebugUtilsObjectName;
Array<const char *> getRequiredExtensions(); Array<const char *> getRequiredExtensions();
void initInstance(GraphicsInitializer initInfo); void initInstance(GraphicsInitializer initInfo);
+5
View File
@@ -9,6 +9,9 @@
using namespace Seele; using namespace Seele;
std::atomic_uint64_t Material::materialIdCounter = 0;
Array<PMaterial> Material::materials;
Material::Material() Material::Material()
{ {
} }
@@ -30,7 +33,9 @@ Material::Material(Gfx::PGraphics graphics,
, codeExpressions(std::move(expressions)) , codeExpressions(std::move(expressions))
, parameters(std::move(parameter)) , parameters(std::move(parameter))
, brdf(std::move(brdf)) , brdf(std::move(brdf))
, materialId(materialIdCounter++)
{ {
materials.add(this);
} }
Material::~Material() Material::~Material()
+5
View File
@@ -22,6 +22,8 @@ public:
Gfx::PDescriptorLayout getDescriptorLayout() { return layout; } Gfx::PDescriptorLayout getDescriptorLayout() { return layout; }
OMaterialInstance instantiate(); OMaterialInstance instantiate();
const std::string& getName() const { return materialName; } const std::string& getName() const { return materialName; }
constexpr const uint64 getId() const { return materialId; }
static constexpr const PMaterial findMaterialById(uint64 id) { return materials[id]; }
void save(ArchiveBuffer& buffer) const; void save(ArchiveBuffer& buffer) const;
void load(ArchiveBuffer& buffer); void load(ArchiveBuffer& buffer);
@@ -33,11 +35,14 @@ private:
uint32 uniformDataSize; uint32 uniformDataSize;
uint32 uniformBinding; uint32 uniformBinding;
uint64 instanceId; uint64 instanceId;
uint64 materialId;
Gfx::ODescriptorLayout layout; Gfx::ODescriptorLayout layout;
std::string materialName; std::string materialName;
Array<OShaderExpression> codeExpressions; Array<OShaderExpression> codeExpressions;
Array<std::string> parameters; Array<std::string> parameters;
MaterialNode brdf; MaterialNode brdf;
static std::atomic_uint64_t materialIdCounter;
static Array<PMaterial> materials;
}; };
DEFINE_REF(Material) DEFINE_REF(Material)
+4 -1
View File
@@ -18,6 +18,9 @@ void MeshUpdater::update(Component::Transform& transform, Component::Mesh& comp)
{ {
for (auto& mesh : comp.asset->meshes) for (auto& mesh : comp.asset->meshes)
{ {
mesh->vertexData->updateMesh(mesh, transform); if (!comp.isStatic)
{
mesh->vertexData->updateMesh(mesh, transform);
}
} }
} }
+2
View File
@@ -18,8 +18,10 @@ GameView::GameView(Gfx::PGraphics graphics, PWindow window, const ViewportCreate
, gameInterface(dllPath) , gameInterface(dllPath)
{ {
reloadGame(); reloadGame();
renderGraph.addPass(new StaticDepthPrepass(graphics, scene));
renderGraph.addPass(new DepthPrepass(graphics, scene)); renderGraph.addPass(new DepthPrepass(graphics, scene));
renderGraph.addPass(new LightCullingPass(graphics, scene)); renderGraph.addPass(new LightCullingPass(graphics, scene));
renderGraph.addPass(new StaticBasePass(graphics, scene));
renderGraph.addPass(new BasePass(graphics, scene)); renderGraph.addPass(new BasePass(graphics, scene));
//renderGraph.addPass(new DebugPass(graphics, scene)); //renderGraph.addPass(new DebugPass(graphics, scene));
//renderGraph.addPass(new SkyboxRenderPass(graphics, scene)); //renderGraph.addPass(new SkyboxRenderPass(graphics, scene));
+2
View File
@@ -6,6 +6,8 @@
#include "Graphics/RenderPass/BasePass.h" #include "Graphics/RenderPass/BasePass.h"
#include "Graphics/RenderPass/SkyboxRenderPass.h" #include "Graphics/RenderPass/SkyboxRenderPass.h"
#include "Graphics/RenderPass/DebugPass.h" #include "Graphics/RenderPass/DebugPass.h"
#include "Graphics/RenderPass/StaticDepthPrepass.h"
#include "Graphics/RenderPass/StaticBasePass.h"
#include "System/KeyboardInput.h" #include "System/KeyboardInput.h"
#ifdef WIN32 #ifdef WIN32
#include "Platform/Windows/GameInterface.h" // TODO #include "Platform/Windows/GameInterface.h" // TODO