Caching descriptor set updates
This commit is contained in:
Vendored
+1
-1
Submodule external/slang updated: 52b5bb43fd...539b91cb03
@@ -15,10 +15,10 @@ void computeFrustums(ComputeShaderInput in)
|
|||||||
{
|
{
|
||||||
float3 origin = float3(0, 0, 0);
|
float3 origin = float3(0, 0, 0);
|
||||||
float3 corners[4] = {
|
float3 corners[4] = {
|
||||||
screenToView(float4(float2(in.dispatchThreadID.x + 0, in.dispatchThreadID.y + 0) * BLOCK_SIZE, -1.0f, 1.0f)).xyz,
|
screenToWorld(float4(float2(in.dispatchThreadID.x + 0, in.dispatchThreadID.y + 0) * BLOCK_SIZE, -1.0f, 1.0f)).xyz,
|
||||||
screenToView(float4(float2(in.dispatchThreadID.x + 1, in.dispatchThreadID.y + 0) * BLOCK_SIZE, -1.0f, 1.0f)).xyz,
|
screenToWorld(float4(float2(in.dispatchThreadID.x + 1, in.dispatchThreadID.y + 0) * BLOCK_SIZE, -1.0f, 1.0f)).xyz,
|
||||||
screenToView(float4(float2(in.dispatchThreadID.x + 0, in.dispatchThreadID.y + 1) * BLOCK_SIZE, -1.0f, 1.0f)).xyz,
|
screenToWorld(float4(float2(in.dispatchThreadID.x + 0, in.dispatchThreadID.y + 1) * BLOCK_SIZE, -1.0f, 1.0f)).xyz,
|
||||||
screenToView(float4(float2(in.dispatchThreadID.x + 1, in.dispatchThreadID.y + 1) * BLOCK_SIZE, -1.0f, 1.0f)).xyz
|
screenToWorld(float4(float2(in.dispatchThreadID.x + 1, in.dispatchThreadID.y + 1) * BLOCK_SIZE, -1.0f, 1.0f)).xyz
|
||||||
};
|
};
|
||||||
Frustum frustum;
|
Frustum frustum;
|
||||||
frustum.sides[0] = computePlane(origin, corners[2], corners[0]);
|
frustum.sides[0] = computePlane(origin, corners[2], corners[0]);
|
||||||
|
|||||||
@@ -29,7 +29,6 @@ groupshared uint uMinDepth;
|
|||||||
groupshared uint uMaxDepth;
|
groupshared uint uMaxDepth;
|
||||||
|
|
||||||
groupshared Frustum groupFrustum;
|
groupshared Frustum groupFrustum;
|
||||||
groupshared float4x4 viewMatrix;
|
|
||||||
|
|
||||||
groupshared uint oLightCount;
|
groupshared uint oLightCount;
|
||||||
groupshared uint oLightIndexStartOffset;
|
groupshared uint oLightIndexStartOffset;
|
||||||
@@ -70,7 +69,6 @@ void cullLights(ComputeShaderInput in)
|
|||||||
uint uDepth = asuint(fDepth);
|
uint uDepth = asuint(fDepth);
|
||||||
if(in.groupIndex == 0)
|
if(in.groupIndex == 0)
|
||||||
{
|
{
|
||||||
viewMatrix = pViewParams.viewMatrix;
|
|
||||||
uMinDepth = 0xffffffff;
|
uMinDepth = 0xffffffff;
|
||||||
uMaxDepth = 0x0;
|
uMaxDepth = 0x0;
|
||||||
oLightCount = 0;
|
oLightCount = 0;
|
||||||
@@ -88,20 +86,23 @@ void cullLights(ComputeShaderInput in)
|
|||||||
float fMinDepth = asfloat(uMinDepth);
|
float fMinDepth = asfloat(uMinDepth);
|
||||||
float fMaxDepth = asfloat(uMaxDepth);
|
float fMaxDepth = asfloat(uMaxDepth);
|
||||||
|
|
||||||
float minDepthVS = clipToView(float4(0, 0, fMinDepth, 1)).z;
|
float minDepthWS = clipToWorld(float4(0, 0, fMinDepth, 1)).z;
|
||||||
float maxDepthVS = clipToView(float4(0, 0, fMaxDepth, 1)).z;
|
float maxDepthWS = clipToWorld(float4(0, 0, fMaxDepth, 1)).z;
|
||||||
float nearClipVS = clipToView(float4(0, 0, 0, 1)).z;
|
float nearClipWS = clipToWorld(float4(0, 0, 0, 1)).z;
|
||||||
|
|
||||||
Plane minPlane = {float3(0, 0, -1), -minDepthVS};
|
Plane minPlane = {float3(0, 0, -1), -minDepthWS};
|
||||||
|
|
||||||
for ( uint i = in.groupIndex; i < pLightEnv.numPointLights; i += BLOCK_SIZE * BLOCK_SIZE )
|
for ( uint i = in.groupIndex; i < pLightEnv.numPointLights; i += BLOCK_SIZE * BLOCK_SIZE )
|
||||||
{
|
{
|
||||||
PointLight light = pLightEnv.pointLights[i];
|
PointLight light = pLightEnv.pointLights[i];
|
||||||
float3 light_VS = mul(viewMatrix, float4(light.position_WS.xyz, 1.0f)).xyz;
|
#ifdef LIGHT_CULLING
|
||||||
//if(light.insideFrustum(groupFrustum, light_VS, nearClipVS, maxDepthVS))
|
if(light.insideFrustum(groupFrustum, light.getPosition(), nearClipWS, maxDepthWS))
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
tAppendLight(i);
|
tAppendLight(i);
|
||||||
//if(!light.insidePlane(minPlane, light_VS))
|
#ifdef LIGHT_CULLING
|
||||||
|
if(!light.insidePlane(minPlane, light.getPosition()))
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
oAppendLight(i);
|
oAppendLight(i);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,6 +48,13 @@ float4 clipToView(float4 clip)
|
|||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float4 clipToWorld(float4 clip)
|
||||||
|
{
|
||||||
|
float4 view = clipToView(clip);
|
||||||
|
|
||||||
|
return viewToWorld(view);
|
||||||
|
}
|
||||||
|
|
||||||
float4 screenToView(float4 screen)
|
float4 screenToView(float4 screen)
|
||||||
{
|
{
|
||||||
float2 texCoord = screen.xy / pViewParams.screenDimensions;
|
float2 texCoord = screen.xy / pViewParams.screenDimensions;
|
||||||
|
|||||||
@@ -52,6 +52,10 @@ struct PointLight : ILightEnv
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
float3 getPosition()
|
||||||
|
{
|
||||||
|
return position_WS.xyz;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct LightEnv
|
struct LightEnv
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ void MeshLoader::importAsset(MeshImportArgs args)
|
|||||||
PMeshAsset ref = asset;
|
PMeshAsset ref = asset;
|
||||||
asset->setStatus(Asset::Status::Loading);
|
asset->setStatus(Asset::Status::Loading);
|
||||||
AssetRegistry::get().registerMesh(std::move(asset));
|
AssetRegistry::get().registerMesh(std::move(asset));
|
||||||
import(args, ref);
|
import(args, ref);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -58,6 +58,10 @@ int main() {
|
|||||||
AssetImporter::importMesh(MeshImportArgs{
|
AssetImporter::importMesh(MeshImportArgs{
|
||||||
.filePath = sourcePath / "import/models/cube.fbx",
|
.filePath = sourcePath / "import/models/cube.fbx",
|
||||||
});
|
});
|
||||||
|
//AssetImporter::importMesh(MeshImportArgs{
|
||||||
|
// .filePath = sourcePath / "import/models/greek-temple/source/greek-temple.fbx",
|
||||||
|
// .importPath = "temple"
|
||||||
|
// });
|
||||||
AssetImporter::importMesh(MeshImportArgs{
|
AssetImporter::importMesh(MeshImportArgs{
|
||||||
.filePath = sourcePath / "import/models/after-the-rain-vr-sound/source/Whitechapel.fbx",
|
.filePath = sourcePath / "import/models/after-the-rain-vr-sound/source/Whitechapel.fbx",
|
||||||
.importPath = "Whitechapel"
|
.importPath = "Whitechapel"
|
||||||
|
|||||||
@@ -8,6 +8,8 @@
|
|||||||
|
|
||||||
using namespace Seele;
|
using namespace Seele;
|
||||||
|
|
||||||
|
extern bool useLightCulling;
|
||||||
|
|
||||||
LightCullingPass::LightCullingPass(Gfx::PGraphics graphics, PScene scene)
|
LightCullingPass::LightCullingPass(Gfx::PGraphics graphics, PScene scene)
|
||||||
: RenderPass(graphics, scene)
|
: RenderPass(graphics, scene)
|
||||||
{
|
{
|
||||||
@@ -63,7 +65,14 @@ void LightCullingPass::render()
|
|||||||
cullingDescriptorSet->updateTexture(6, Gfx::PTexture2D(tLightGrid));
|
cullingDescriptorSet->updateTexture(6, Gfx::PTexture2D(tLightGrid));
|
||||||
cullingDescriptorSet->writeChanges();
|
cullingDescriptorSet->writeChanges();
|
||||||
Gfx::OComputeCommand computeCommand = graphics->createComputeCommand("CullingCommand");
|
Gfx::OComputeCommand computeCommand = graphics->createComputeCommand("CullingCommand");
|
||||||
computeCommand->bindPipeline(cullingPipeline);
|
if (useLightCulling)
|
||||||
|
{
|
||||||
|
computeCommand->bindPipeline(cullingEnabledPipeline);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
computeCommand->bindPipeline(cullingPipeline);
|
||||||
|
}
|
||||||
computeCommand->bindDescriptor({ viewParamsSet, dispatchParamsSet, cullingDescriptorSet, lightEnv->getDescriptorSet() });
|
computeCommand->bindDescriptor({ viewParamsSet, dispatchParamsSet, cullingDescriptorSet, lightEnv->getDescriptorSet() });
|
||||||
computeCommand->dispatch(dispatchParams.numThreadGroups.x, dispatchParams.numThreadGroups.y, dispatchParams.numThreadGroups.z);
|
computeCommand->dispatch(dispatchParams.numThreadGroups.x, dispatchParams.numThreadGroups.y, dispatchParams.numThreadGroups.z);
|
||||||
Array<Gfx::OComputeCommand> commands;
|
Array<Gfx::OComputeCommand> commands;
|
||||||
@@ -120,25 +129,50 @@ void LightCullingPass::publishOutputs()
|
|||||||
|
|
||||||
lightEnv = scene->getLightEnvironment();
|
lightEnv = scene->getLightEnvironment();
|
||||||
|
|
||||||
cullingLayout = graphics->createPipelineLayout("CullingLayout");
|
{
|
||||||
cullingLayout->addDescriptorLayout(viewParamsLayout);
|
cullingLayout = graphics->createPipelineLayout("CullingLayout");
|
||||||
cullingLayout->addDescriptorLayout(dispatchParamsLayout);
|
cullingLayout->addDescriptorLayout(viewParamsLayout);
|
||||||
cullingLayout->addDescriptorLayout(cullingDescriptorLayout);
|
cullingLayout->addDescriptorLayout(dispatchParamsLayout);
|
||||||
cullingLayout->addDescriptorLayout(lightEnv->getDescriptorLayout());
|
cullingLayout->addDescriptorLayout(cullingDescriptorLayout);
|
||||||
|
cullingLayout->addDescriptorLayout(lightEnv->getDescriptorLayout());
|
||||||
|
|
||||||
ShaderCreateInfo createInfo = {
|
ShaderCreateInfo createInfo = {
|
||||||
.name = "Culling",
|
.name = "Culling",
|
||||||
.mainModule = "LightCulling",
|
.mainModule = "LightCulling",
|
||||||
.entryPoint = "cullLights",
|
.entryPoint = "cullLights",
|
||||||
.rootSignature = cullingLayout,
|
.rootSignature = cullingLayout,
|
||||||
};
|
};
|
||||||
cullingShader = graphics->createComputeShader(createInfo);
|
cullingShader = graphics->createComputeShader(createInfo);
|
||||||
cullingLayout->create();
|
cullingLayout->create();
|
||||||
|
|
||||||
Gfx::ComputePipelineCreateInfo pipelineInfo;
|
Gfx::ComputePipelineCreateInfo pipelineInfo;
|
||||||
pipelineInfo.computeShader = cullingShader;
|
pipelineInfo.computeShader = cullingShader;
|
||||||
pipelineInfo.pipelineLayout = std::move(cullingLayout);
|
pipelineInfo.pipelineLayout = std::move(cullingLayout);
|
||||||
cullingPipeline = graphics->createComputePipeline(std::move(pipelineInfo));
|
cullingPipeline = graphics->createComputePipeline(std::move(pipelineInfo));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
cullingEnableLayout = graphics->createPipelineLayout("CullingEnabledLayout");
|
||||||
|
cullingEnableLayout->addDescriptorLayout(viewParamsLayout);
|
||||||
|
cullingEnableLayout->addDescriptorLayout(dispatchParamsLayout);
|
||||||
|
cullingEnableLayout->addDescriptorLayout(cullingDescriptorLayout);
|
||||||
|
cullingEnableLayout->addDescriptorLayout(lightEnv->getDescriptorLayout());
|
||||||
|
|
||||||
|
ShaderCreateInfo createInfo = {
|
||||||
|
.name = "Culling",
|
||||||
|
.mainModule = "LightCulling",
|
||||||
|
.entryPoint = "cullLights",
|
||||||
|
.rootSignature = cullingEnableLayout,
|
||||||
|
};
|
||||||
|
createInfo.defines["LIGHT_CULLING"] = "1";
|
||||||
|
cullingEnabledShader = graphics->createComputeShader(createInfo);
|
||||||
|
cullingEnableLayout->create();
|
||||||
|
|
||||||
|
Gfx::ComputePipelineCreateInfo pipelineInfo;
|
||||||
|
pipelineInfo.computeShader = cullingShader;
|
||||||
|
pipelineInfo.pipelineLayout = std::move(cullingEnableLayout);
|
||||||
|
cullingEnabledPipeline = graphics->createComputePipeline(std::move(pipelineInfo));
|
||||||
|
}
|
||||||
|
|
||||||
uint32 counterReset = 0;
|
uint32 counterReset = 0;
|
||||||
ShaderBufferCreateInfo structInfo = {
|
ShaderBufferCreateInfo structInfo = {
|
||||||
|
|||||||
@@ -60,9 +60,12 @@ private:
|
|||||||
Gfx::OTexture2D tLightGrid;
|
Gfx::OTexture2D tLightGrid;
|
||||||
Gfx::PDescriptorSet cullingDescriptorSet;
|
Gfx::PDescriptorSet cullingDescriptorSet;
|
||||||
Gfx::ODescriptorLayout cullingDescriptorLayout;
|
Gfx::ODescriptorLayout cullingDescriptorLayout;
|
||||||
Gfx::OComputeShader cullingShader;
|
|
||||||
Gfx::PComputePipeline cullingPipeline;
|
|
||||||
Gfx::OPipelineLayout cullingLayout;
|
Gfx::OPipelineLayout cullingLayout;
|
||||||
|
Gfx::OPipelineLayout cullingEnableLayout;
|
||||||
|
Gfx::OComputeShader cullingShader;
|
||||||
|
Gfx::OComputeShader cullingEnabledShader;
|
||||||
|
Gfx::PComputePipeline cullingPipeline;
|
||||||
|
Gfx::PComputePipeline cullingEnabledPipeline;
|
||||||
};
|
};
|
||||||
DEFINE_REF(LightCullingPass)
|
DEFINE_REF(LightCullingPass)
|
||||||
} // namespace Seele
|
} // namespace Seele
|
||||||
|
|||||||
@@ -12,81 +12,81 @@ DescriptorLayout::DescriptorLayout(PGraphics graphics, const std::string& name)
|
|||||||
|
|
||||||
DescriptorLayout::~DescriptorLayout() {
|
DescriptorLayout::~DescriptorLayout() {
|
||||||
graphics->getDestructionManager()->queueResourceForDestruction(std::move(pool));
|
graphics->getDestructionManager()->queueResourceForDestruction(std::move(pool));
|
||||||
if (layoutHandle != VK_NULL_HANDLE) {
|
if (layoutHandle != VK_NULL_HANDLE) {
|
||||||
vkDestroyDescriptorSetLayout(graphics->getDevice(), layoutHandle, nullptr);
|
vkDestroyDescriptorSetLayout(graphics->getDevice(), layoutHandle, nullptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DescriptorLayout::create() {
|
void DescriptorLayout::create() {
|
||||||
if (layoutHandle != VK_NULL_HANDLE) {
|
if (layoutHandle != VK_NULL_HANDLE) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
bindings.resize(descriptorBindings.size());
|
bindings.resize(descriptorBindings.size());
|
||||||
Array<VkDescriptorBindingFlags> bindingFlags(descriptorBindings.size());
|
Array<VkDescriptorBindingFlags> bindingFlags(descriptorBindings.size());
|
||||||
for (size_t i = 0; i < descriptorBindings.size(); ++i) {
|
for (size_t i = 0; i < descriptorBindings.size(); ++i) {
|
||||||
const Gfx::DescriptorBinding& gfxBinding = descriptorBindings[i];
|
const Gfx::DescriptorBinding& gfxBinding = descriptorBindings[i];
|
||||||
bindings[i] = {
|
bindings[i] = {
|
||||||
.binding = gfxBinding.binding,
|
.binding = gfxBinding.binding,
|
||||||
.descriptorType = cast(gfxBinding.descriptorType),
|
.descriptorType = cast(gfxBinding.descriptorType),
|
||||||
.descriptorCount = gfxBinding.descriptorCount,
|
.descriptorCount = gfxBinding.descriptorCount,
|
||||||
.stageFlags = gfxBinding.shaderStages,
|
.stageFlags = gfxBinding.shaderStages,
|
||||||
.pImmutableSamplers = nullptr,
|
.pImmutableSamplers = nullptr,
|
||||||
|
};
|
||||||
|
bindingFlags[i] = gfxBinding.bindingFlags;
|
||||||
|
}
|
||||||
|
VkDescriptorSetLayoutBindingFlagsCreateInfo bindingFlagsInfo = {
|
||||||
|
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO,
|
||||||
|
.pNext = nullptr,
|
||||||
|
.bindingCount = static_cast<uint32>(bindingFlags.size()),
|
||||||
|
.pBindingFlags = bindingFlags.data(),
|
||||||
};
|
};
|
||||||
bindingFlags[i] = gfxBinding.bindingFlags;
|
VkDescriptorSetLayoutCreateInfo createInfo = {
|
||||||
}
|
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
|
||||||
VkDescriptorSetLayoutBindingFlagsCreateInfo bindingFlagsInfo = {
|
.pNext = &bindingFlagsInfo,
|
||||||
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO,
|
.flags = 0,
|
||||||
.pNext = nullptr,
|
.bindingCount = (uint32)bindings.size(),
|
||||||
.bindingCount = static_cast<uint32>(bindingFlags.size()),
|
.pBindings = bindings.data(),
|
||||||
.pBindingFlags = bindingFlags.data(),
|
};
|
||||||
};
|
VK_CHECK(vkCreateDescriptorSetLayout(graphics->getDevice(), &createInfo, nullptr, &layoutHandle));
|
||||||
VkDescriptorSetLayoutCreateInfo createInfo = {
|
|
||||||
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
|
|
||||||
.pNext = &bindingFlagsInfo,
|
|
||||||
.flags = 0,
|
|
||||||
.bindingCount = (uint32)bindings.size(),
|
|
||||||
.pBindings = bindings.data(),
|
|
||||||
};
|
|
||||||
VK_CHECK(vkCreateDescriptorSetLayout(graphics->getDevice(), &createInfo, nullptr, &layoutHandle));
|
|
||||||
|
|
||||||
pool = new DescriptorPool(graphics, this);
|
pool = new DescriptorPool(graphics, this);
|
||||||
|
|
||||||
hash = CRC::Calculate(bindings.data(), sizeof(VkDescriptorSetLayoutBinding) * bindings.size(), CRC::CRC_32());
|
hash = CRC::Calculate(bindings.data(), sizeof(VkDescriptorSetLayoutBinding) * bindings.size(), CRC::CRC_32());
|
||||||
}
|
}
|
||||||
|
|
||||||
DescriptorPool::DescriptorPool(PGraphics graphics, PDescriptorLayout layout)
|
DescriptorPool::DescriptorPool(PGraphics graphics, PDescriptorLayout layout)
|
||||||
: CommandBoundResource(graphics)
|
: CommandBoundResource(graphics)
|
||||||
, graphics(graphics)
|
, graphics(graphics)
|
||||||
, layout(layout) {
|
, layout(layout) {
|
||||||
for (uint32 i = 0; i < cachedHandles.size(); ++i) {
|
for (uint32 i = 0; i < cachedHandles.size(); ++i) {
|
||||||
cachedHandles[i] = nullptr;
|
cachedHandles[i] = nullptr;
|
||||||
}
|
|
||||||
|
|
||||||
uint32 perTypeSizes[VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT]; // TODO: FIX ENUM
|
|
||||||
std::memset(perTypeSizes, 0, sizeof(perTypeSizes));
|
|
||||||
for (uint32 i = 0; i < layout->getBindings().size(); ++i) {
|
|
||||||
auto& binding = layout->getBindings()[i];
|
|
||||||
int typeIndex = binding.descriptorType;
|
|
||||||
perTypeSizes[typeIndex] += 256;
|
|
||||||
}
|
|
||||||
Array<VkDescriptorPoolSize> poolSizes;
|
|
||||||
for (uint32 i = 0; i < VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT; ++i) {
|
|
||||||
if (perTypeSizes[i] > 0) {
|
|
||||||
VkDescriptorPoolSize size;
|
|
||||||
size.descriptorCount = perTypeSizes[i];
|
|
||||||
size.type = (VkDescriptorType)i;
|
|
||||||
poolSizes.add(size);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
VkDescriptorPoolCreateInfo createInfo = {
|
uint32 perTypeSizes[VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT]; // TODO: FIX ENUM
|
||||||
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
|
std::memset(perTypeSizes, 0, sizeof(perTypeSizes));
|
||||||
.pNext = nullptr,
|
for (uint32 i = 0; i < layout->getBindings().size(); ++i) {
|
||||||
.flags = 0,
|
auto& binding = layout->getBindings()[i];
|
||||||
.maxSets = maxSets * Gfx::numFramesBuffered,
|
int typeIndex = binding.descriptorType;
|
||||||
.poolSizeCount = (uint32)poolSizes.size(),
|
perTypeSizes[typeIndex] += 256;
|
||||||
.pPoolSizes = poolSizes.data(),
|
}
|
||||||
};
|
Array<VkDescriptorPoolSize> poolSizes;
|
||||||
VK_CHECK(vkCreateDescriptorPool(graphics->getDevice(), &createInfo, nullptr, &poolHandle));
|
for (uint32 i = 0; i < VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT; ++i) {
|
||||||
|
if (perTypeSizes[i] > 0) {
|
||||||
|
VkDescriptorPoolSize size;
|
||||||
|
size.descriptorCount = perTypeSizes[i];
|
||||||
|
size.type = (VkDescriptorType)i;
|
||||||
|
poolSizes.add(size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
VkDescriptorPoolCreateInfo createInfo = {
|
||||||
|
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
|
||||||
|
.pNext = nullptr,
|
||||||
|
.flags = 0,
|
||||||
|
.maxSets = maxSets * Gfx::numFramesBuffered,
|
||||||
|
.poolSizeCount = (uint32)poolSizes.size(),
|
||||||
|
.pPoolSizes = poolSizes.data(),
|
||||||
|
};
|
||||||
|
VK_CHECK(vkCreateDescriptorPool(graphics->getDevice(), &createInfo, nullptr, &poolHandle));
|
||||||
}
|
}
|
||||||
|
|
||||||
DescriptorPool::~DescriptorPool() {
|
DescriptorPool::~DescriptorPool() {
|
||||||
@@ -104,66 +104,66 @@ DescriptorPool::~DescriptorPool() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Gfx::PDescriptorSet DescriptorPool::allocateDescriptorSet() {
|
Gfx::PDescriptorSet DescriptorPool::allocateDescriptorSet() {
|
||||||
VkDescriptorSetLayout layoutHandle = layout->getHandle();
|
VkDescriptorSetLayout layoutHandle = layout->getHandle();
|
||||||
VkDescriptorSetVariableDescriptorCountAllocateInfo setCounts = {
|
VkDescriptorSetVariableDescriptorCountAllocateInfo setCounts = {
|
||||||
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO,
|
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO,
|
||||||
.pNext = nullptr,
|
.pNext = nullptr,
|
||||||
.descriptorSetCount = 1,
|
.descriptorSetCount = 1,
|
||||||
};
|
};
|
||||||
VkDescriptorSetAllocateInfo allocInfo = {
|
VkDescriptorSetAllocateInfo allocInfo = {
|
||||||
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
|
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
|
||||||
.pNext = nullptr,
|
.pNext = nullptr,
|
||||||
.descriptorPool = poolHandle,
|
.descriptorPool = poolHandle,
|
||||||
.descriptorSetCount = 1,
|
.descriptorSetCount = 1,
|
||||||
.pSetLayouts = &layoutHandle,
|
.pSetLayouts = &layoutHandle,
|
||||||
};
|
};
|
||||||
uint32 counts = 0;
|
uint32 counts = 0;
|
||||||
for (const auto& binding : layout->bindings) {
|
for (const auto& binding : layout->bindings) {
|
||||||
if (binding.descriptorCount > 0) {
|
if (binding.descriptorCount > 0) {
|
||||||
counts = binding.descriptorCount;
|
counts = binding.descriptorCount;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
if (layout->bindings.size() > 0) {
|
||||||
if (layout->bindings.size() > 0) {
|
setCounts.pDescriptorCounts = &counts;
|
||||||
setCounts.pDescriptorCounts = &counts;
|
allocInfo.pNext = &setCounts;
|
||||||
allocInfo.pNext = &setCounts;
|
|
||||||
}
|
|
||||||
for (uint32 setIndex = 0; setIndex < cachedHandles.size(); ++setIndex) {
|
|
||||||
if (cachedHandles[setIndex] == nullptr) {
|
|
||||||
cachedHandles[setIndex] = new DescriptorSet(graphics, this);
|
|
||||||
}
|
}
|
||||||
if (cachedHandles[setIndex]->isCurrentlyBound() || cachedHandles[setIndex]->isCurrentlyInUse()) {
|
for (uint32 setIndex = 0; setIndex < cachedHandles.size(); ++setIndex) {
|
||||||
// Currently in use, skip
|
if (cachedHandles[setIndex] == nullptr) {
|
||||||
continue;
|
cachedHandles[setIndex] = new DescriptorSet(graphics, this);
|
||||||
}
|
}
|
||||||
if (cachedHandles[setIndex]->getHandle() == VK_NULL_HANDLE) {
|
if (cachedHandles[setIndex]->isCurrentlyBound() || cachedHandles[setIndex]->isCurrentlyInUse()) {
|
||||||
// If it hasnt been initialized, allocate it
|
// Currently in use, skip
|
||||||
VK_CHECK(vkAllocateDescriptorSets(graphics->getDevice(), &allocInfo, &cachedHandles[setIndex]->setHandle));
|
continue;
|
||||||
}
|
}
|
||||||
cachedHandles[setIndex]->allocate();
|
if (cachedHandles[setIndex]->getHandle() == VK_NULL_HANDLE) {
|
||||||
|
// If it hasnt been initialized, allocate it
|
||||||
|
VK_CHECK(vkAllocateDescriptorSets(graphics->getDevice(), &allocInfo, &cachedHandles[setIndex]->setHandle));
|
||||||
|
}
|
||||||
|
cachedHandles[setIndex]->allocate();
|
||||||
|
|
||||||
PDescriptorSet vulkanSet = cachedHandles[setIndex];
|
PDescriptorSet vulkanSet = cachedHandles[setIndex];
|
||||||
|
|
||||||
// Found set, stop searching
|
// Found set, stop searching
|
||||||
return vulkanSet;
|
return vulkanSet;
|
||||||
}
|
}
|
||||||
if (nextAlloc == nullptr) {
|
if (nextAlloc == nullptr) {
|
||||||
nextAlloc = new DescriptorPool(graphics, layout);
|
nextAlloc = new DescriptorPool(graphics, layout);
|
||||||
}
|
}
|
||||||
// std::cout << "Out of descriptors, forwarding" << std::endl;
|
// std::cout << "Out of descriptors, forwarding" << std::endl;
|
||||||
return nextAlloc->allocateDescriptorSet();
|
return nextAlloc->allocateDescriptorSet();
|
||||||
// throw std::logic_error("Out of descriptor sets");
|
// throw std::logic_error("Out of descriptor sets");
|
||||||
}
|
}
|
||||||
|
|
||||||
void DescriptorPool::reset() {
|
void DescriptorPool::reset() {
|
||||||
for (uint32 i = 0; i < cachedHandles.size(); ++i) {
|
for (uint32 i = 0; i < cachedHandles.size(); ++i) {
|
||||||
if (cachedHandles[i] == nullptr) {
|
if (cachedHandles[i] == nullptr) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
cachedHandles[i]->free();
|
||||||
|
}
|
||||||
|
if (nextAlloc != nullptr) {
|
||||||
|
nextAlloc->reset();
|
||||||
}
|
}
|
||||||
cachedHandles[i]->free();
|
|
||||||
}
|
|
||||||
if (nextAlloc != nullptr) {
|
|
||||||
nextAlloc->reset();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DescriptorSet::DescriptorSet(PGraphics graphics, PDescriptorPool owner)
|
DescriptorSet::DescriptorSet(PGraphics graphics, PDescriptorPool owner)
|
||||||
@@ -184,51 +184,65 @@ DescriptorSet::~DescriptorSet()
|
|||||||
}
|
}
|
||||||
|
|
||||||
void DescriptorSet::updateBuffer(uint32_t binding, Gfx::PUniformBuffer uniformBuffer) {
|
void DescriptorSet::updateBuffer(uint32_t binding, Gfx::PUniformBuffer uniformBuffer) {
|
||||||
PUniformBuffer vulkanBuffer = uniformBuffer.cast<UniformBuffer>();
|
PUniformBuffer vulkanBuffer = uniformBuffer.cast<UniformBuffer>();
|
||||||
bufferInfos.add(VkDescriptorBufferInfo{
|
if (boundResources[binding] == vulkanBuffer->getAlloc())
|
||||||
.buffer = vulkanBuffer->getHandle(),
|
{
|
||||||
.offset = 0,
|
return;
|
||||||
.range = vulkanBuffer->getSize(),
|
}
|
||||||
});
|
|
||||||
|
|
||||||
writeDescriptors.add(VkWriteDescriptorSet{
|
bufferInfos.add(VkDescriptorBufferInfo{
|
||||||
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
.buffer = vulkanBuffer->getHandle(),
|
||||||
.pNext = nullptr,
|
.offset = 0,
|
||||||
.dstSet = setHandle,
|
.range = vulkanBuffer->getSize(),
|
||||||
.dstBinding = binding,
|
});
|
||||||
.dstArrayElement = 0,
|
|
||||||
.descriptorCount = 1,
|
|
||||||
.descriptorType = cast(layout->getBindings()[binding].descriptorType),
|
|
||||||
.pBufferInfo = &bufferInfos.back(),
|
|
||||||
});
|
|
||||||
|
|
||||||
boundResources[binding] = vulkanBuffer->getAlloc();
|
writeDescriptors.add(VkWriteDescriptorSet{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||||
|
.pNext = nullptr,
|
||||||
|
.dstSet = setHandle,
|
||||||
|
.dstBinding = binding,
|
||||||
|
.dstArrayElement = 0,
|
||||||
|
.descriptorCount = 1,
|
||||||
|
.descriptorType = cast(layout->getBindings()[binding].descriptorType),
|
||||||
|
.pBufferInfo = &bufferInfos.back(),
|
||||||
|
});
|
||||||
|
|
||||||
|
boundResources[binding] = vulkanBuffer->getAlloc();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DescriptorSet::updateBuffer(uint32_t binding, Gfx::PShaderBuffer shaderBuffer) {
|
void DescriptorSet::updateBuffer(uint32_t binding, Gfx::PShaderBuffer shaderBuffer) {
|
||||||
PShaderBuffer vulkanBuffer = shaderBuffer.cast<ShaderBuffer>();
|
PShaderBuffer vulkanBuffer = shaderBuffer.cast<ShaderBuffer>();
|
||||||
|
if (boundResources[binding] == vulkanBuffer->getAlloc())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
bufferInfos.add(VkDescriptorBufferInfo{
|
bufferInfos.add(VkDescriptorBufferInfo{
|
||||||
.buffer = vulkanBuffer->getHandle(),
|
.buffer = vulkanBuffer->getHandle(),
|
||||||
.offset = 0,
|
.offset = 0,
|
||||||
.range = vulkanBuffer->getSize(),
|
.range = vulkanBuffer->getSize(),
|
||||||
});
|
});
|
||||||
writeDescriptors.add(VkWriteDescriptorSet{
|
writeDescriptors.add(VkWriteDescriptorSet{
|
||||||
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||||
.pNext = nullptr,
|
.pNext = nullptr,
|
||||||
.dstSet = setHandle,
|
.dstSet = setHandle,
|
||||||
.dstBinding = binding,
|
.dstBinding = binding,
|
||||||
.dstArrayElement = 0,
|
.dstArrayElement = 0,
|
||||||
.descriptorCount = 1,
|
.descriptorCount = 1,
|
||||||
.descriptorType = cast(layout->getBindings()[binding].descriptorType),
|
.descriptorType = cast(layout->getBindings()[binding].descriptorType),
|
||||||
.pBufferInfo = &bufferInfos.back(),
|
.pBufferInfo = &bufferInfos.back(),
|
||||||
});
|
});
|
||||||
|
|
||||||
boundResources[binding] = vulkanBuffer->getAlloc();
|
boundResources[binding] = vulkanBuffer->getAlloc();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DescriptorSet::updateBuffer(uint32_t binding, uint32 index, Gfx::PShaderBuffer shaderBuffer) {
|
void DescriptorSet::updateBuffer(uint32_t binding, uint32 index, Gfx::PShaderBuffer shaderBuffer) {
|
||||||
PShaderBuffer vulkanBuffer = shaderBuffer.cast<ShaderBuffer>();
|
PShaderBuffer vulkanBuffer = shaderBuffer.cast<ShaderBuffer>();
|
||||||
|
if (boundResources[binding] == vulkanBuffer->getAlloc())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
bufferInfos.add(VkDescriptorBufferInfo{
|
bufferInfos.add(VkDescriptorBufferInfo{
|
||||||
.buffer = vulkanBuffer->getHandle(),
|
.buffer = vulkanBuffer->getHandle(),
|
||||||
.offset = 0,
|
.offset = 0,
|
||||||
@@ -250,98 +264,111 @@ void DescriptorSet::updateBuffer(uint32_t binding, uint32 index, Gfx::PShaderBuf
|
|||||||
}
|
}
|
||||||
|
|
||||||
void DescriptorSet::updateSampler(uint32_t binding, Gfx::PSampler samplerState) {
|
void DescriptorSet::updateSampler(uint32_t binding, Gfx::PSampler samplerState) {
|
||||||
PSampler vulkanSampler = samplerState.cast<Sampler>();
|
PSampler vulkanSampler = samplerState.cast<Sampler>();
|
||||||
|
if (boundResources[binding] == vulkanSampler->getHandle())
|
||||||
imageInfos.add(VkDescriptorImageInfo{
|
{
|
||||||
.sampler = vulkanSampler->getSampler(),
|
return;
|
||||||
.imageView = VK_NULL_HANDLE,
|
|
||||||
.imageLayout = VK_IMAGE_LAYOUT_UNDEFINED,
|
|
||||||
});
|
|
||||||
|
|
||||||
writeDescriptors.add(VkWriteDescriptorSet{
|
|
||||||
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
|
||||||
.pNext = nullptr,
|
|
||||||
.dstSet = setHandle,
|
|
||||||
.dstBinding = binding,
|
|
||||||
.dstArrayElement = 0,
|
|
||||||
.descriptorCount = 1,
|
|
||||||
.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER,
|
|
||||||
.pImageInfo = &imageInfos.back(),
|
|
||||||
});
|
|
||||||
|
|
||||||
boundResources[binding] = vulkanSampler->getHandle();
|
|
||||||
}
|
|
||||||
|
|
||||||
void DescriptorSet::updateTexture(uint32_t binding, Gfx::PTexture texture, Gfx::PSampler samplerState) {
|
|
||||||
TextureBase* vulkanTexture = texture.cast<TextureBase>().getHandle();
|
|
||||||
|
|
||||||
// It is assumed that the image is in the correct layout
|
|
||||||
imageInfos.add(VkDescriptorImageInfo{
|
|
||||||
.sampler = samplerState != nullptr ? samplerState.cast<Sampler>()->getSampler() : VK_NULL_HANDLE,
|
|
||||||
.imageView = vulkanTexture->getView(),
|
|
||||||
.imageLayout = cast(vulkanTexture->getLayout()),
|
|
||||||
});
|
|
||||||
VkDescriptorType descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
|
|
||||||
if (samplerState != nullptr) {
|
|
||||||
descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
|
||||||
} else if (vulkanTexture->getUsage() & VK_IMAGE_USAGE_STORAGE_BIT) {
|
|
||||||
descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
|
|
||||||
}
|
|
||||||
writeDescriptors.add(VkWriteDescriptorSet{
|
|
||||||
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
|
||||||
.pNext = nullptr,
|
|
||||||
.dstSet = setHandle,
|
|
||||||
.dstBinding = binding,
|
|
||||||
.dstArrayElement = 0,
|
|
||||||
.descriptorCount = 1,
|
|
||||||
.descriptorType = descriptorType,
|
|
||||||
.pImageInfo = &imageInfos.back(),
|
|
||||||
});
|
|
||||||
|
|
||||||
boundResources[binding] = vulkanTexture->getHandle();
|
|
||||||
}
|
|
||||||
void DescriptorSet::updateTextureArray(uint32_t binding, Array<Gfx::PTexture> textures) {
|
|
||||||
// maybe make this a parameter?
|
|
||||||
uint32 arrayElement = 0;
|
|
||||||
boundResources.resize(binding + textures.size());
|
|
||||||
for (auto& gfxTexture : textures) {
|
|
||||||
TextureBase* vulkanTexture = gfxTexture.cast<TextureBase>().getHandle();
|
|
||||||
imageInfos.add(VkDescriptorImageInfo{
|
|
||||||
.sampler = VK_NULL_HANDLE,
|
|
||||||
.imageView = vulkanTexture->getView(),
|
|
||||||
.imageLayout = cast(vulkanTexture->getLayout()),
|
|
||||||
});
|
|
||||||
|
|
||||||
VkDescriptorType descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
|
|
||||||
if (vulkanTexture->getUsage() & VK_IMAGE_USAGE_STORAGE_BIT) {
|
|
||||||
descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
|
|
||||||
}
|
}
|
||||||
boundResources[binding + arrayElement] = vulkanTexture->getHandle();
|
|
||||||
|
imageInfos.add(VkDescriptorImageInfo{
|
||||||
|
.sampler = vulkanSampler->getSampler(),
|
||||||
|
.imageView = VK_NULL_HANDLE,
|
||||||
|
.imageLayout = VK_IMAGE_LAYOUT_UNDEFINED,
|
||||||
|
});
|
||||||
|
|
||||||
writeDescriptors.add(VkWriteDescriptorSet{
|
writeDescriptors.add(VkWriteDescriptorSet{
|
||||||
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||||
.pNext = nullptr,
|
.pNext = nullptr,
|
||||||
.dstSet = setHandle,
|
.dstSet = setHandle,
|
||||||
.dstBinding = binding,
|
.dstBinding = binding,
|
||||||
.dstArrayElement = arrayElement++,
|
.dstArrayElement = 0,
|
||||||
|
.descriptorCount = 1,
|
||||||
|
.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER,
|
||||||
|
.pImageInfo = &imageInfos.back(),
|
||||||
|
});
|
||||||
|
|
||||||
|
boundResources[binding] = vulkanSampler->getHandle();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DescriptorSet::updateTexture(uint32_t binding, Gfx::PTexture texture, Gfx::PSampler samplerState) {
|
||||||
|
TextureBase* vulkanTexture = texture.cast<TextureBase>().getHandle();
|
||||||
|
if (boundResources[binding] == vulkanTexture->getHandle())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// It is assumed that the image is in the correct layout
|
||||||
|
imageInfos.add(VkDescriptorImageInfo{
|
||||||
|
.sampler = samplerState != nullptr ? samplerState.cast<Sampler>()->getSampler() : VK_NULL_HANDLE,
|
||||||
|
.imageView = vulkanTexture->getView(),
|
||||||
|
.imageLayout = cast(vulkanTexture->getLayout()),
|
||||||
|
});
|
||||||
|
VkDescriptorType descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
|
||||||
|
if (samplerState != nullptr) {
|
||||||
|
descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
||||||
|
}
|
||||||
|
else if (vulkanTexture->getUsage() & VK_IMAGE_USAGE_STORAGE_BIT) {
|
||||||
|
descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
|
||||||
|
}
|
||||||
|
writeDescriptors.add(VkWriteDescriptorSet{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||||
|
.pNext = nullptr,
|
||||||
|
.dstSet = setHandle,
|
||||||
|
.dstBinding = binding,
|
||||||
|
.dstArrayElement = 0,
|
||||||
.descriptorCount = 1,
|
.descriptorCount = 1,
|
||||||
.descriptorType = descriptorType,
|
.descriptorType = descriptorType,
|
||||||
.pImageInfo = &imageInfos.back(),
|
.pImageInfo = &imageInfos.back(),
|
||||||
});
|
});
|
||||||
vulkanTexture->getHandle()->bind();
|
|
||||||
}
|
boundResources[binding] = vulkanTexture->getHandle();
|
||||||
|
}
|
||||||
|
void DescriptorSet::updateTextureArray(uint32_t binding, Array<Gfx::PTexture> textures) {
|
||||||
|
// maybe make this a parameter?
|
||||||
|
uint32 arrayElement = 0;
|
||||||
|
boundResources.resize(binding + textures.size());
|
||||||
|
for (auto& gfxTexture : textures) {
|
||||||
|
TextureBase* vulkanTexture = gfxTexture.cast<TextureBase>().getHandle();
|
||||||
|
if (boundResources[binding + arrayElement] == vulkanTexture->getHandle())
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
imageInfos.add(VkDescriptorImageInfo{
|
||||||
|
.sampler = VK_NULL_HANDLE,
|
||||||
|
.imageView = vulkanTexture->getView(),
|
||||||
|
.imageLayout = cast(vulkanTexture->getLayout()),
|
||||||
|
});
|
||||||
|
|
||||||
|
VkDescriptorType descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
|
||||||
|
if (vulkanTexture->getUsage() & VK_IMAGE_USAGE_STORAGE_BIT) {
|
||||||
|
descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
|
||||||
|
}
|
||||||
|
boundResources[binding + arrayElement] = vulkanTexture->getHandle();
|
||||||
|
writeDescriptors.add(VkWriteDescriptorSet{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||||
|
.pNext = nullptr,
|
||||||
|
.dstSet = setHandle,
|
||||||
|
.dstBinding = binding,
|
||||||
|
.dstArrayElement = arrayElement++,
|
||||||
|
.descriptorCount = 1,
|
||||||
|
.descriptorType = descriptorType,
|
||||||
|
.pImageInfo = &imageInfos.back(),
|
||||||
|
});
|
||||||
|
vulkanTexture->getHandle()->bind();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DescriptorSet::writeChanges() {
|
void DescriptorSet::writeChanges() {
|
||||||
if (writeDescriptors.size() > 0) {
|
if (writeDescriptors.size() > 0) {
|
||||||
if (isCurrentlyBound()) {
|
if (isCurrentlyBound()) {
|
||||||
std::cout << "Descriptor currently bound, allocate a new one instead" << std::endl;
|
std::cout << "Descriptor currently bound, allocate a new one instead" << std::endl;
|
||||||
assert(!isCurrentlyBound());
|
assert(!isCurrentlyBound());
|
||||||
|
}
|
||||||
|
vkUpdateDescriptorSets(graphics->getDevice(), (uint32)writeDescriptors.size(), writeDescriptors.data(), 0, nullptr);
|
||||||
|
writeDescriptors.clear();
|
||||||
|
imageInfos.clear();
|
||||||
|
bufferInfos.clear();
|
||||||
}
|
}
|
||||||
vkUpdateDescriptorSets(graphics->getDevice(), (uint32)writeDescriptors.size(), writeDescriptors.data(), 0, nullptr);
|
|
||||||
writeDescriptors.clear();
|
|
||||||
imageInfos.clear();
|
|
||||||
bufferInfos.clear();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PipelineLayout::PipelineLayout(PGraphics graphics, const std::string& name, Gfx::PPipelineLayout baseLayout)
|
PipelineLayout::PipelineLayout(PGraphics graphics, const std::string& name, Gfx::PPipelineLayout baseLayout)
|
||||||
@@ -353,46 +380,46 @@ std::mutex layoutLock;
|
|||||||
Map<uint32, VkPipelineLayout> cachedLayouts;
|
Map<uint32, VkPipelineLayout> cachedLayouts;
|
||||||
|
|
||||||
void PipelineLayout::create() {
|
void PipelineLayout::create() {
|
||||||
for (auto [name, desc] : descriptorSetLayouts) {
|
for (auto [name, desc] : descriptorSetLayouts) {
|
||||||
PDescriptorLayout layout = desc.cast<DescriptorLayout>();
|
PDescriptorLayout layout = desc.cast<DescriptorLayout>();
|
||||||
layout->create();
|
layout->create();
|
||||||
uint32 parameterIndex = parameterMapping[layout->getName()];
|
uint32 parameterIndex = parameterMapping[layout->getName()];
|
||||||
if (parameterIndex >= vulkanDescriptorLayouts.size())
|
if (parameterIndex >= vulkanDescriptorLayouts.size())
|
||||||
{
|
{
|
||||||
vulkanDescriptorLayouts.resize(parameterIndex + 1);
|
vulkanDescriptorLayouts.resize(parameterIndex + 1);
|
||||||
|
}
|
||||||
|
vulkanDescriptorLayouts[parameterIndex] = layout->getHandle();
|
||||||
}
|
}
|
||||||
vulkanDescriptorLayouts[parameterIndex] = layout->getHandle();
|
|
||||||
}
|
|
||||||
|
|
||||||
Array<VkPushConstantRange> vkPushConstants(pushConstants.size());
|
Array<VkPushConstantRange> vkPushConstants(pushConstants.size());
|
||||||
for (size_t i = 0; i < pushConstants.size(); i++) {
|
for (size_t i = 0; i < pushConstants.size(); i++) {
|
||||||
vkPushConstants[i].offset = pushConstants[i].offset;
|
vkPushConstants[i].offset = pushConstants[i].offset;
|
||||||
vkPushConstants[i].size = pushConstants[i].size;
|
vkPushConstants[i].size = pushConstants[i].size;
|
||||||
vkPushConstants[i].stageFlags = pushConstants[i].stageFlags;
|
vkPushConstants[i].stageFlags = pushConstants[i].stageFlags;
|
||||||
}
|
}
|
||||||
|
|
||||||
VkPipelineLayoutCreateInfo createInfo = {
|
VkPipelineLayoutCreateInfo createInfo = {
|
||||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
|
||||||
.pNext = nullptr,
|
.pNext = nullptr,
|
||||||
.flags = 0,
|
.flags = 0,
|
||||||
.setLayoutCount = (uint32)vulkanDescriptorLayouts.size(),
|
.setLayoutCount = (uint32)vulkanDescriptorLayouts.size(),
|
||||||
.pSetLayouts = vulkanDescriptorLayouts.data(),
|
.pSetLayouts = vulkanDescriptorLayouts.data(),
|
||||||
.pushConstantRangeCount = (uint32)vkPushConstants.size(),
|
.pushConstantRangeCount = (uint32)vkPushConstants.size(),
|
||||||
.pPushConstantRanges = vkPushConstants.data(),
|
.pPushConstantRanges = vkPushConstants.data(),
|
||||||
};
|
};
|
||||||
|
|
||||||
layoutHash = CRC::Calculate(createInfo.pPushConstantRanges,
|
layoutHash = CRC::Calculate(createInfo.pPushConstantRanges,
|
||||||
sizeof(VkPushConstantRange) * createInfo.pushConstantRangeCount, CRC::CRC_32());
|
sizeof(VkPushConstantRange) * createInfo.pushConstantRangeCount, CRC::CRC_32());
|
||||||
layoutHash = CRC::Calculate(createInfo.pSetLayouts, sizeof(VkDescriptorSetLayout) * createInfo.setLayoutCount,
|
layoutHash = CRC::Calculate(createInfo.pSetLayouts, sizeof(VkDescriptorSetLayout) * createInfo.setLayoutCount,
|
||||||
CRC::CRC_32(), layoutHash);
|
CRC::CRC_32(), layoutHash);
|
||||||
|
|
||||||
std::unique_lock l(layoutLock);
|
std::unique_lock l(layoutLock);
|
||||||
if (cachedLayouts.contains(layoutHash)) {
|
if (cachedLayouts.contains(layoutHash)) {
|
||||||
// std::cout << "New Layout" << std::endl;
|
// std::cout << "New Layout" << std::endl;
|
||||||
layoutHandle = cachedLayouts[layoutHash];
|
layoutHandle = cachedLayouts[layoutHash];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
VK_CHECK(vkCreatePipelineLayout(graphics->getDevice(), &createInfo, nullptr, &layoutHandle));
|
VK_CHECK(vkCreatePipelineLayout(graphics->getDevice(), &createInfo, nullptr, &layoutHandle));
|
||||||
cachedLayouts[layoutHash] = layoutHandle;
|
cachedLayouts[layoutHash] = layoutHandle;
|
||||||
}
|
}
|
||||||
@@ -17,7 +17,7 @@ Shader::Shader(PGraphics graphics, VkShaderStageFlags stage)
|
|||||||
|
|
||||||
Shader::~Shader()
|
Shader::~Shader()
|
||||||
{
|
{
|
||||||
if(module != VK_NULL_HANDLE)
|
if (module != VK_NULL_HANDLE)
|
||||||
{
|
{
|
||||||
vkDestroyShaderModule(graphics->getDevice(), module, nullptr);
|
vkDestroyShaderModule(graphics->getDevice(), module, nullptr);
|
||||||
}
|
}
|
||||||
@@ -30,9 +30,9 @@ uint32 Seele::Vulkan::Shader::getShaderHash() const
|
|||||||
|
|
||||||
void Shader::create(ShaderCreateInfo createInfo)
|
void Shader::create(ShaderCreateInfo createInfo)
|
||||||
{
|
{
|
||||||
Map<std::string, uint32> paramMapping;
|
Map<std::string, uint32> paramMapping;
|
||||||
Slang::ComPtr<slang::IBlob> kernelBlob = generateShader(createInfo, SLANG_SPIRV, paramMapping);
|
Slang::ComPtr<slang::IBlob> kernelBlob = generateShader(createInfo, SLANG_SPIRV, paramMapping);
|
||||||
createInfo.rootSignature->addMapping(paramMapping);
|
createInfo.rootSignature->addMapping(paramMapping);
|
||||||
VkShaderModuleCreateInfo moduleInfo =
|
VkShaderModuleCreateInfo moduleInfo =
|
||||||
{
|
{
|
||||||
.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,
|
.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,
|
||||||
|
|||||||
@@ -114,7 +114,7 @@ void Window::pollInput()
|
|||||||
|
|
||||||
void Window::beginFrame()
|
void Window::beginFrame()
|
||||||
{
|
{
|
||||||
imageAvailableFences[currentSemaphoreIndex]->wait(100000000);
|
imageAvailableFences[currentSemaphoreIndex]->wait(10000000000);
|
||||||
imageAvailableFences[currentSemaphoreIndex]->reset();
|
imageAvailableFences[currentSemaphoreIndex]->reset();
|
||||||
vkAcquireNextImageKHR(graphics->getDevice(), swapchain, std::numeric_limits<uint64>::max(), imageAvailableSemaphores[currentSemaphoreIndex]->getHandle(), imageAvailableFences[currentSemaphoreIndex]->getHandle(), ¤tImageIndex);
|
vkAcquireNextImageKHR(graphics->getDevice(), swapchain, std::numeric_limits<uint64>::max(), imageAvailableSemaphores[currentSemaphoreIndex]->getHandle(), imageAvailableFences[currentSemaphoreIndex]->getHandle(), ¤tImageIndex);
|
||||||
graphics->getGraphicsCommands()->getCommands()->waitForSemaphore(VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, imageAvailableSemaphores[currentSemaphoreIndex]);
|
graphics->getGraphicsCommands()->getCommands()->waitForSemaphore(VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, imageAvailableSemaphores[currentSemaphoreIndex]);
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ Slang::ComPtr<slang::IBlob> Seele::generateShader(const ShaderCreateInfo& create
|
|||||||
option[2].value.intValue0 = SLANG_DEBUG_INFO_LEVEL_NONE;
|
option[2].value.intValue0 = SLANG_DEBUG_INFO_LEVEL_NONE;
|
||||||
option[3].name = slang::CompilerOptionName::DebugInformationFormat;
|
option[3].name = slang::CompilerOptionName::DebugInformationFormat;
|
||||||
option[3].value.kind = slang::CompilerOptionValueKind::Int;
|
option[3].value.kind = slang::CompilerOptionValueKind::Int;
|
||||||
option[3].value.intValue0 = SLANG_DEBUG_INFO_FORMAT_PDB;
|
option[3].value.intValue0 = SLANG_DEBUG_INFO_FORMAT_DEFAULT;
|
||||||
|
|
||||||
sessionDesc.compilerOptionEntries = option.data();
|
sessionDesc.compilerOptionEntries = option.data();
|
||||||
sessionDesc.compilerOptionEntryCount = option.size();
|
sessionDesc.compilerOptionEntryCount = option.size();
|
||||||
|
|||||||
@@ -104,6 +104,16 @@ public:
|
|||||||
return object <=> rhs.object;
|
return object <=> rhs.object;
|
||||||
}
|
}
|
||||||
template<typename F>
|
template<typename F>
|
||||||
|
constexpr bool operator==(const RefPtr<F>& rhs) const noexcept
|
||||||
|
{
|
||||||
|
return object == rhs.getHandle();
|
||||||
|
}
|
||||||
|
template<typename F>
|
||||||
|
constexpr auto operator<=>(const RefPtr<F>& rhs) const noexcept
|
||||||
|
{
|
||||||
|
return object <=> rhs.getHandle();
|
||||||
|
}
|
||||||
|
template<typename F>
|
||||||
constexpr operator RefPtr<F>()
|
constexpr operator RefPtr<F>()
|
||||||
{
|
{
|
||||||
return RefPtr<F>(static_cast<F*>(object));
|
return RefPtr<F>(static_cast<F*>(object));
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ using namespace Seele;
|
|||||||
|
|
||||||
bool usePositionOnly = false;
|
bool usePositionOnly = false;
|
||||||
bool useViewCulling = false;
|
bool useViewCulling = false;
|
||||||
|
bool useLightCulling = false;
|
||||||
|
|
||||||
GameView::GameView(Gfx::PGraphics graphics, PWindow window, const ViewportCreateInfo &createInfo, std::string dllPath)
|
GameView::GameView(Gfx::PGraphics graphics, PWindow window, const ViewportCreateInfo &createInfo, std::string dllPath)
|
||||||
: View(graphics, window, createInfo, "Game")
|
: View(graphics, window, createInfo, "Game")
|
||||||
@@ -103,19 +104,18 @@ void GameView::keyCallback(KeyCode code, InputAction action, KeyModifier modifie
|
|||||||
keyboardSystem->keyCallback(code, action, modifier);
|
keyboardSystem->keyCallback(code, action, modifier);
|
||||||
if (code == KeyCode::KEY_P && action == InputAction::RELEASE)
|
if (code == KeyCode::KEY_P && action == InputAction::RELEASE)
|
||||||
{
|
{
|
||||||
usePositionOnly = true;
|
usePositionOnly = !usePositionOnly;
|
||||||
|
std::cout << "Use Pos only " << usePositionOnly << std::endl;
|
||||||
}
|
}
|
||||||
if (code == KeyCode::KEY_O && action == InputAction::RELEASE)
|
if (code == KeyCode::KEY_O && action == InputAction::RELEASE)
|
||||||
{
|
{
|
||||||
usePositionOnly = false;
|
useViewCulling = !useViewCulling;
|
||||||
|
std::cout << "Use View Culling " << useViewCulling << std::endl;
|
||||||
}
|
}
|
||||||
if (code == KeyCode::KEY_L && action == InputAction::RELEASE)
|
if (code == KeyCode::KEY_L && action == InputAction::RELEASE)
|
||||||
{
|
{
|
||||||
useViewCulling = true;
|
useLightCulling = !useLightCulling;
|
||||||
}
|
std::cout << "Use Light Culling " << useLightCulling << std::endl;
|
||||||
if (code == KeyCode::KEY_K && action == InputAction::RELEASE)
|
|
||||||
{
|
|
||||||
useViewCulling = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user