Staging before meshlet linearization
This commit is contained in:
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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];
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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
@@ -5,250 +5,244 @@
|
|||||||
|
|
||||||
namespace Seele
|
namespace Seele
|
||||||
{
|
{
|
||||||
struct GraphicsInitializer
|
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)
|
|
||||||
{
|
{
|
||||||
}
|
const char* applicationName;
|
||||||
};
|
const char* engineName;
|
||||||
struct WindowCreateInfo
|
const char* windowLayoutFile;
|
||||||
{
|
/**
|
||||||
int32 width;
|
* layers defines the enabled Vulkan layers used in the instance,
|
||||||
int32 height;
|
* if ENABLE_VALIDATION is defined, standard validation is already enabled
|
||||||
const char *title;
|
* not yet implemented
|
||||||
Gfx::SeFormat preferredFormat = Gfx::SE_FORMAT_B8G8R8A8_UNORM;
|
*/
|
||||||
void *windowHandle;
|
Array<const char*> layers;
|
||||||
};
|
Array<const char*> instanceExtensions;
|
||||||
struct ViewportCreateInfo
|
Array<const char*> deviceExtensions;
|
||||||
{
|
|
||||||
URect dimensions;
|
void* windowHandle;
|
||||||
float fieldOfView = 1.222f; // 70 deg
|
GraphicsInitializer()
|
||||||
Gfx::SeSampleCountFlags numSamples;
|
: applicationName("SeeleEngine")
|
||||||
};
|
, engineName("SeeleEngine")
|
||||||
// doesnt own the data, only proxy it
|
, windowLayoutFile(nullptr)
|
||||||
struct DataSource
|
, layers{ "VK_LAYER_LUNARG_monitor" }
|
||||||
{
|
, instanceExtensions{}
|
||||||
uint64 size = 0;
|
, deviceExtensions{ "VK_KHR_swapchain" }
|
||||||
uint64 offset = 0;
|
, windowHandle(nullptr)
|
||||||
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
|
||||||
|
|||||||
@@ -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*>&)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
using namespace Seele;
|
using namespace Seele;
|
||||||
|
|
||||||
DepthPrepass::DepthPrepass(Gfx::PGraphics graphics, PScene scene)
|
DepthPrepass::DepthPrepass(Gfx::PGraphics graphics, PScene scene)
|
||||||
: RenderPass(graphics, scene)
|
: RenderPass(graphics, scene)
|
||||||
{
|
{
|
||||||
depthPrepassLayout = graphics->createPipelineLayout("DepthPrepassLayout");
|
depthPrepassLayout = graphics->createPipelineLayout("DepthPrepassLayout");
|
||||||
@@ -29,102 +29,104 @@ DepthPrepass::DepthPrepass(Gfx::PGraphics graphics, PScene scene)
|
|||||||
}
|
}
|
||||||
|
|
||||||
DepthPrepass::~DepthPrepass()
|
DepthPrepass::~DepthPrepass()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void DepthPrepass::beginFrame(const Component::Camera& cam)
|
void DepthPrepass::beginFrame(const Component::Camera& cam)
|
||||||
{
|
{
|
||||||
RenderPass::beginFrame(cam);
|
RenderPass::beginFrame(cam);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DepthPrepass::render()
|
void DepthPrepass::render()
|
||||||
{
|
{
|
||||||
graphics->beginRenderPass(renderPass);
|
graphics->beginRenderPass(renderPass);
|
||||||
Array<Gfx::ORenderCommand> commands;
|
Array<Gfx::ORenderCommand> commands;
|
||||||
|
|
||||||
// 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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -132,14 +134,48 @@ void DepthPrepass::render()
|
|||||||
graphics->endRenderPass();
|
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;
|
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;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -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),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -257,7 +286,7 @@ void StaticMeshVertexData::resizeBuffers()
|
|||||||
texCoords[i] = graphics->createShaderBuffer(createInfo);
|
texCoords[i] = graphics->createShaderBuffer(createInfo);
|
||||||
texCoordsData[i].resize(verticesAllocated);
|
texCoordsData[i].resize(verticesAllocated);
|
||||||
}
|
}
|
||||||
|
|
||||||
positionData.resize(verticesAllocated);
|
positionData.resize(verticesAllocated);
|
||||||
normalData.resize(verticesAllocated);
|
normalData.resize(verticesAllocated);
|
||||||
tangentData.resize(verticesAllocated);
|
tangentData.resize(verticesAllocated);
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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(); \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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));
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user