Skip to content

Commit

Permalink
Add a wrapper around VKRPipelineLayout / descsetlayout
Browse files Browse the repository at this point in the history
  • Loading branch information
hrydgard committed Oct 8, 2023
1 parent 5bb1db5 commit dbe395d
Show file tree
Hide file tree
Showing 9 changed files with 66 additions and 40 deletions.
4 changes: 2 additions & 2 deletions Common/GPU/Vulkan/VulkanQueueRunner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1241,7 +1241,7 @@ void VulkanQueueRunner::PerformRenderPass(const VKRStep &step, VkCommandBuffer c

if (pipeline != VK_NULL_HANDLE) {
vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
pipelineLayout = c.pipeline.pipelineLayout;
pipelineLayout = c.pipeline.pipelineLayout->pipelineLayout;
lastGraphicsPipeline = graphicsPipeline;
pipelineOK = true;
} else {
Expand All @@ -1263,7 +1263,7 @@ void VulkanQueueRunner::PerformRenderPass(const VKRStep &step, VkCommandBuffer c
VkPipeline pipeline = computePipeline->pipeline->BlockUntilReady();
if (pipeline != VK_NULL_HANDLE) {
vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline);
pipelineLayout = c.pipeline.pipelineLayout;
pipelineLayout = c.pipeline.pipelineLayout->pipelineLayout;
lastComputePipeline = computePipeline;
}
}
Expand Down
7 changes: 4 additions & 3 deletions Common/GPU/Vulkan/VulkanQueueRunner.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ class VKRFramebuffer;
struct VKRGraphicsPipeline;
struct VKRComputePipeline;
struct VKRImage;
struct VKRPipelineLayout;
struct FrameData;

enum {
Expand Down Expand Up @@ -58,15 +59,15 @@ struct VkRenderData {
union {
struct {
VkPipeline pipeline;
VkPipelineLayout pipelineLayout;
VKRPipelineLayout *pipelineLayout;
} pipeline;
struct {
VKRGraphicsPipeline *pipeline;
VkPipelineLayout pipelineLayout;
VKRPipelineLayout *pipelineLayout;
} graphics_pipeline;
struct {
VKRComputePipeline *pipeline;
VkPipelineLayout pipelineLayout;
VKRPipelineLayout *pipelineLayout;
} compute_pipeline;
struct {
VkDescriptorSet ds;
Expand Down
4 changes: 2 additions & 2 deletions Common/GPU/Vulkan/VulkanRenderManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ bool VKRGraphicsPipeline::Create(VulkanContext *vulkan, VkRenderPass compatibleR
pipe.pDynamicState = &desc->ds;
pipe.pInputAssemblyState = &inputAssembly;
pipe.pMultisampleState = &ms;
pipe.layout = desc->pipelineLayout;
pipe.layout = desc->pipelineLayout->pipelineLayout;
pipe.basePipelineHandle = VK_NULL_HANDLE;
pipe.basePipelineIndex = 0;
pipe.subpass = 0;
Expand Down Expand Up @@ -192,7 +192,7 @@ void VKRGraphicsPipeline::DestroyVariantsInstant(VkDevice device) {

VKRGraphicsPipeline::~VKRGraphicsPipeline() {
// This is called from the callbacked queued in QueueForDeletion.
// Here we are free to directly delete stuff, don't need to queue.
// When we reach here, we should already be empty, so let's assert on that.
for (size_t i = 0; i < (size_t)RenderPassType::TYPE_COUNT; i++) {
_assert_(!pipeline[i]);
}
Expand Down
28 changes: 25 additions & 3 deletions Common/GPU/Vulkan/VulkanRenderManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ class VKRGraphicsPipelineDesc : public Draw::RefCountedObject {
VkPipelineVertexInputStateCreateInfo vis{ VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO };
VkPipelineViewportStateCreateInfo views{ VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO };

VkPipelineLayout pipelineLayout = VK_NULL_HANDLE;
VKRPipelineLayout *pipelineLayout = nullptr;

// Does not include the render pass type, it's passed in separately since the
// desc is persistent.
Expand Down Expand Up @@ -168,6 +168,21 @@ struct VKRComputePipeline {
}
};

struct VKRPipelineLayout {
~VKRPipelineLayout() {
_assert_(!pipelineLayout && !descriptorSetLayout);
}

void Destroy(VulkanContext *vulkan) {
vulkan->Delete().QueueDeletePipelineLayout(pipelineLayout);
vulkan->Delete().QueueDeleteDescriptorSetLayout(descriptorSetLayout);
}

VkPipelineLayout pipelineLayout;
VkDescriptorSetLayout descriptorSetLayout; // only support 1 for now.
int pushConstSize;
};

struct CompileQueueEntry {
CompileQueueEntry(VKRGraphicsPipeline *p, VkRenderPass _compatibleRenderPass, RenderPassType _renderPassType, VkSampleCountFlagBits _sampleCount)
: type(Type::GRAPHICS), graphics(p), compatibleRenderPass(_compatibleRenderPass), renderPassType(_renderPassType), sampleCount(_sampleCount) {}
Expand Down Expand Up @@ -237,6 +252,13 @@ class VulkanRenderManager {
// WARNING: desc must stick around during the lifetime of the pipeline! It's not enough to build it on the stack and drop it.
VKRGraphicsPipeline *CreateGraphicsPipeline(VKRGraphicsPipelineDesc *desc, PipelineFlags pipelineFlags, uint32_t variantBitmask, VkSampleCountFlagBits sampleCount, bool cacheLoad, const char *tag);
VKRComputePipeline *CreateComputePipeline(VKRComputePipelineDesc *desc);

VKRPipelineLayout *CreatePipelineLayout(VkPipelineLayout pipelineLayout, VkDescriptorSetLayout descSetLayout) {
VKRPipelineLayout *layout = new VKRPipelineLayout();
layout->pipelineLayout = pipelineLayout;
layout->descriptorSetLayout = descSetLayout;
return layout;
}

void ReportBadStateForDraw();

Expand All @@ -249,7 +271,7 @@ class VulkanRenderManager {
// This is the first call in a draw operation. Instead of asserting like we used to, you can now check the
// return value and skip the draw if we're in a bad state. In that case, call ReportBadState.
// The old assert wasn't very helpful in figuring out what caused it anyway...
bool BindPipeline(VKRGraphicsPipeline *pipeline, PipelineFlags flags, VkPipelineLayout pipelineLayout) {
bool BindPipeline(VKRGraphicsPipeline *pipeline, PipelineFlags flags, VKRPipelineLayout *pipelineLayout) {
_dbg_assert_(curRenderStep_ && curRenderStep_->stepType == VKRStepType::RENDER && pipeline != nullptr);
if (!curRenderStep_ || curRenderStep_->stepType != VKRStepType::RENDER) {
return false;
Expand All @@ -267,7 +289,7 @@ class VulkanRenderManager {
return true;
}

void BindPipeline(VKRComputePipeline *pipeline, PipelineFlags flags, VkPipelineLayout pipelineLayout) {
void BindPipeline(VKRComputePipeline *pipeline, PipelineFlags flags, VKRPipelineLayout *pipelineLayout) {
_dbg_assert_(curRenderStep_ && curRenderStep_->stepType == VKRStepType::RENDER);
_dbg_assert_(pipeline != nullptr);
VkRenderData &data = curRenderStep_->commands.push_uninitialized();
Expand Down
22 changes: 12 additions & 10 deletions Common/GPU/Vulkan/thin3d_vulkan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -546,8 +546,7 @@ class VKContext : public DrawContext {
AutoRef<VKBuffer> curIBuffer_;
int curIBufferOffset_ = 0;

VkDescriptorSetLayout descriptorSetLayout_ = VK_NULL_HANDLE;
VkPipelineLayout pipelineLayout_ = VK_NULL_HANDLE;
VKRPipelineLayout *pipelineLayout_ = nullptr;
VkPipelineCache pipelineCache_ = VK_NULL_HANDLE;
AutoRef<VKFramebuffer> curFramebuffer_;

Expand Down Expand Up @@ -1077,24 +1076,28 @@ VKContext::VKContext(VulkanContext *vulkan, bool useRenderThread)
bindings[i + 1].binding = i + 1;
}

VkDescriptorSetLayout descSetLayout;
VkDescriptorSetLayoutCreateInfo dsl = { VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO };
dsl.bindingCount = ARRAY_SIZE(bindings);
dsl.pBindings = bindings;
VkResult res = vkCreateDescriptorSetLayout(device_, &dsl, nullptr, &descriptorSetLayout_);
VkResult res = vkCreateDescriptorSetLayout(device_, &dsl, nullptr, &descSetLayout);
_assert_(VK_SUCCESS == res);

vulkan_->SetDebugName(descriptorSetLayout_, VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT, "thin3d_d_layout");
vulkan_->SetDebugName(descSetLayout, VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT, "thin3d_d_layout");

VkPipelineLayout pipelineLayout;
VkPipelineLayoutCreateInfo pl = { VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO };
pl.pPushConstantRanges = nullptr;
pl.pushConstantRangeCount = 0;
VkDescriptorSetLayout setLayouts[1] = { descriptorSetLayout_ };
VkDescriptorSetLayout setLayouts[1] = { descSetLayout };
pl.setLayoutCount = ARRAY_SIZE(setLayouts);
pl.pSetLayouts = setLayouts;
res = vkCreatePipelineLayout(device_, &pl, nullptr, &pipelineLayout_);
res = vkCreatePipelineLayout(device_, &pl, nullptr, &pipelineLayout);
_assert_(VK_SUCCESS == res);

vulkan_->SetDebugName(pipelineLayout_, VK_OBJECT_TYPE_PIPELINE_LAYOUT, "thin3d_p_layout");
vulkan_->SetDebugName(pipelineLayout, VK_OBJECT_TYPE_PIPELINE_LAYOUT, "thin3d_p_layout");

pipelineLayout_ = renderManager_.CreatePipelineLayout(pipelineLayout, descSetLayout);

VkPipelineCacheCreateInfo pc{ VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO };
res = vkCreatePipelineCache(vulkan_->GetDevice(), &pc, nullptr, &pipelineCache_);
Expand All @@ -1111,8 +1114,7 @@ VKContext::~VKContext() {
}
push_->Destroy();
delete push_;
vulkan_->Delete().QueueDeleteDescriptorSetLayout(descriptorSetLayout_);
vulkan_->Delete().QueueDeletePipelineLayout(pipelineLayout_);
pipelineLayout_->Destroy(vulkan_);
vulkan_->Delete().QueueDeletePipelineCache(pipelineCache_);
}

Expand Down Expand Up @@ -1181,7 +1183,7 @@ VkDescriptorSet VKContext::GetOrCreateDescriptorSet(VkBuffer buf) {
return iter->second;
}

VkDescriptorSet descSet = frame->descriptorPool.Allocate(1, &descriptorSetLayout_, "thin3d_descset");
VkDescriptorSet descSet = frame->descriptorPool.Allocate(1, &pipelineLayout_->descriptorSetLayout, "thin3d_descset");
if (descSet == VK_NULL_HANDLE) {
ERROR_LOG(G3D, "GetOrCreateDescriptorSet failed");
return VK_NULL_HANDLE;
Expand Down
24 changes: 14 additions & 10 deletions GPU/Vulkan/DrawEngineVulkan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,12 +127,13 @@ void DrawEngineVulkan::InitDeviceObjects() {
VulkanContext *vulkan = (VulkanContext *)draw_->GetNativeObject(Draw::NativeObject::CONTEXT);
VkDevice device = vulkan->GetDevice();

VkDescriptorSetLayout descriptorSetLayout;
VkDescriptorSetLayoutCreateInfo dsl{ VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO };
dsl.bindingCount = ARRAY_SIZE(bindings);
dsl.pBindings = bindings;
VkResult res = vkCreateDescriptorSetLayout(device, &dsl, nullptr, &descriptorSetLayout_);
VkResult res = vkCreateDescriptorSetLayout(device, &dsl, nullptr, &descriptorSetLayout);
_dbg_assert_(VK_SUCCESS == res);
vulkan->SetDebugName(descriptorSetLayout_, VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT, "drawengine_d_layout");
vulkan->SetDebugName(descriptorSetLayout, VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT, "drawengine_d_layout");

static constexpr int DEFAULT_DESC_POOL_SIZE = 512;
std::vector<VkDescriptorPoolSize> dpTypes;
Expand Down Expand Up @@ -168,15 +169,20 @@ void DrawEngineVulkan::InitDeviceObjects() {
VkPipelineLayoutCreateInfo pl{ VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO };
pl.pPushConstantRanges = nullptr;
pl.pushConstantRangeCount = 0;
VkDescriptorSetLayout layouts[1] = { descriptorSetLayout_};
VkDescriptorSetLayout layouts[1] = { descriptorSetLayout };
pl.setLayoutCount = ARRAY_SIZE(layouts);
pl.pSetLayouts = layouts;
pl.flags = 0;

res = vkCreatePipelineLayout(device, &pl, nullptr, &pipelineLayout_);
VkPipelineLayout pipelineLayout;
res = vkCreatePipelineLayout(device, &pl, nullptr, &pipelineLayout);
_dbg_assert_(VK_SUCCESS == res);

vulkan->SetDebugName(pipelineLayout_, VK_OBJECT_TYPE_PIPELINE_LAYOUT, "drawengine_p_layout");
vulkan->SetDebugName(pipelineLayout, VK_OBJECT_TYPE_PIPELINE_LAYOUT, "drawengine_p_layout");

VulkanRenderManager *renderManager = (VulkanRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER);

pipelineLayout_ = renderManager->CreatePipelineLayout(pipelineLayout, descriptorSetLayout);

VkSamplerCreateInfo samp{ VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO };
samp.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
Expand All @@ -193,6 +199,7 @@ void DrawEngineVulkan::InitDeviceObjects() {
res = vkCreateSampler(device, &samp, nullptr, &nullSampler_);
_dbg_assert_(VK_SUCCESS == res);


vertexCache_ = new VulkanPushBuffer(vulkan, "pushVertexCache", VERTEX_CACHE_SIZE, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);

tessDataTransferVulkan = new TessellationDataTransferVulkan(vulkan);
Expand Down Expand Up @@ -246,10 +253,7 @@ void DrawEngineVulkan::DestroyDeviceObjects() {
vulkan->Delete().QueueDeleteSampler(samplerSecondaryLinear_);
if (nullSampler_ != VK_NULL_HANDLE)
vulkan->Delete().QueueDeleteSampler(nullSampler_);
if (pipelineLayout_ != VK_NULL_HANDLE)
vulkan->Delete().QueueDeletePipelineLayout(pipelineLayout_);
if (descriptorSetLayout_ != VK_NULL_HANDLE)
vulkan->Delete().QueueDeleteDescriptorSetLayout(descriptorSetLayout_);
pipelineLayout_->Destroy(vulkan);
if (vertexCache_) {
vertexCache_->Destroy(vulkan);
delete vertexCache_;
Expand Down Expand Up @@ -391,7 +395,7 @@ VkDescriptorSet DrawEngineVulkan::GetOrCreateDescriptorSet(VkImageView imageView

// Didn't find one in the frame descriptor set cache, let's make a new one.
// We wipe the cache on every frame.
VkDescriptorSet desc = frame.descPool.Allocate(1, &descriptorSetLayout_, "game_descset");
VkDescriptorSet desc = frame.descPool.Allocate(1, &pipelineLayout_->descriptorSetLayout, "game_descset");

// Even in release mode, this is bad.
_assert_msg_(desc != VK_NULL_HANDLE, "Ran out of descriptor space in pool. sz=%d", (int)frame.descSets.size());
Expand Down
7 changes: 2 additions & 5 deletions GPU/Vulkan/DrawEngineVulkan.h
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ class DrawEngineVulkan : public DrawEngineCommon {
DoFlush();
}

VkPipelineLayout GetPipelineLayout() const {
VKRPipelineLayout *GetPipelineLayout() const {
return pipelineLayout_;
}

Expand Down Expand Up @@ -244,10 +244,7 @@ class DrawEngineVulkan : public DrawEngineCommon {
Draw::DrawContext *draw_;

// We use a shared descriptor set layouts for all PSP draws.
// Descriptors created from descriptorSetLayout_ is rebound all the time at set 1.
VkDescriptorSetLayout descriptorSetLayout_;

VkPipelineLayout pipelineLayout_;
VKRPipelineLayout *pipelineLayout_;
VulkanPipeline *lastPipeline_;
VkDescriptorSet lastDs_ = VK_NULL_HANDLE;

Expand Down
6 changes: 3 additions & 3 deletions GPU/Vulkan/PipelineManagerVulkan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ static std::string CutFromMain(std::string str) {
}

static VulkanPipeline *CreateVulkanPipeline(VulkanRenderManager *renderManager, VkPipelineCache pipelineCache,
VkPipelineLayout layout, PipelineFlags pipelineFlags, VkSampleCountFlagBits sampleCount, const VulkanPipelineRasterStateKey &key,
VKRPipelineLayout *layout, PipelineFlags pipelineFlags, VkSampleCountFlagBits sampleCount, const VulkanPipelineRasterStateKey &key,
const DecVtxFormat *decFmt, VulkanVertexShader *vs, VulkanFragmentShader *fs, VulkanGeometryShader *gs, bool useHwTransform, u32 variantBitmask, bool cacheLoad) {
_assert_(fs && vs);

Expand Down Expand Up @@ -351,7 +351,7 @@ static VulkanPipeline *CreateVulkanPipeline(VulkanRenderManager *renderManager,
return vulkanPipeline;
}

VulkanPipeline *PipelineManagerVulkan::GetOrCreatePipeline(VulkanRenderManager *renderManager, VkPipelineLayout layout, const VulkanPipelineRasterStateKey &rasterKey, const DecVtxFormat *decFmt, VulkanVertexShader *vs, VulkanFragmentShader *fs, VulkanGeometryShader *gs, bool useHwTransform, u32 variantBitmask, int multiSampleLevel, bool cacheLoad) {
VulkanPipeline *PipelineManagerVulkan::GetOrCreatePipeline(VulkanRenderManager *renderManager, VKRPipelineLayout *layout, const VulkanPipelineRasterStateKey &rasterKey, const DecVtxFormat *decFmt, VulkanVertexShader *vs, VulkanFragmentShader *fs, VulkanGeometryShader *gs, bool useHwTransform, u32 variantBitmask, int multiSampleLevel, bool cacheLoad) {
if (!pipelineCache_) {
VkPipelineCacheCreateInfo pc{ VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO };
VkResult res = vkCreatePipelineCache(vulkan_->GetDevice(), &pc, nullptr, &pipelineCache_);
Expand Down Expand Up @@ -717,7 +717,7 @@ void PipelineManagerVulkan::SavePipelineCache(FILE *file, bool saveRawPipelineCa
}
}

bool PipelineManagerVulkan::LoadPipelineCache(FILE *file, bool loadRawPipelineCache, ShaderManagerVulkan *shaderManager, Draw::DrawContext *drawContext, VkPipelineLayout layout, int multiSampleLevel) {
bool PipelineManagerVulkan::LoadPipelineCache(FILE *file, bool loadRawPipelineCache, ShaderManagerVulkan *shaderManager, Draw::DrawContext *drawContext, VKRPipelineLayout *layout, int multiSampleLevel) {
VulkanRenderManager *rm = (VulkanRenderManager *)drawContext->GetNativeObject(Draw::NativeObject::RENDER_MANAGER);
VulkanQueueRunner *queueRunner = rm->GetQueueRunner();

Expand Down
4 changes: 2 additions & 2 deletions GPU/Vulkan/PipelineManagerVulkan.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ class PipelineManagerVulkan {
~PipelineManagerVulkan();

// variantMask is only used when loading pipelines from cache.
VulkanPipeline *GetOrCreatePipeline(VulkanRenderManager *renderManager, VkPipelineLayout layout, const VulkanPipelineRasterStateKey &rasterKey, const DecVtxFormat *decFmt, VulkanVertexShader *vs, VulkanFragmentShader *fs, VulkanGeometryShader *gs, bool useHwTransform, u32 variantMask, int multiSampleLevel, bool cacheLoad);
VulkanPipeline *GetOrCreatePipeline(VulkanRenderManager *renderManager, VKRPipelineLayout *layout, const VulkanPipelineRasterStateKey &rasterKey, const DecVtxFormat *decFmt, VulkanVertexShader *vs, VulkanFragmentShader *fs, VulkanGeometryShader *gs, bool useHwTransform, u32 variantMask, int multiSampleLevel, bool cacheLoad);
int GetNumPipelines() const { return (int)pipelines_.size(); }

void Clear();
Expand All @@ -100,7 +100,7 @@ class PipelineManagerVulkan {

// Saves data for faster creation next time.
void SavePipelineCache(FILE *file, bool saveRawPipelineCache, ShaderManagerVulkan *shaderManager, Draw::DrawContext *drawContext);
bool LoadPipelineCache(FILE *file, bool loadRawPipelineCache, ShaderManagerVulkan *shaderManager, Draw::DrawContext *drawContext, VkPipelineLayout layout, int multiSampleLevel);
bool LoadPipelineCache(FILE *file, bool loadRawPipelineCache, ShaderManagerVulkan *shaderManager, Draw::DrawContext *drawContext, VKRPipelineLayout *layout, int multiSampleLevel);

private:
DenseHashMap<VulkanPipelineKey, VulkanPipeline *> pipelines_;
Expand Down

0 comments on commit dbe395d

Please sign in to comment.