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