Vulkan: Fix a validation error + minor code refactor

We were using VK_EXT_DEPTH_CLIP_ENABLE but didn't actually request it.

Also fixed an assert when closing Cemu caused by incorrectly tracking the number of allocated pipelines
This commit is contained in:
Exzap 2025-04-15 21:10:11 +02:00
parent c4eab08f30
commit cd6eb1097b
8 changed files with 73 additions and 63 deletions

View file

@ -221,11 +221,14 @@ public:
VKRObjectPipeline();
~VKRObjectPipeline() override;
void setPipeline(VkPipeline newPipeline);
void SetPipeline(VkPipeline newPipeline);
VkPipeline GetPipeline() const { return m_pipeline; }
VkPipeline pipeline = VK_NULL_HANDLE;
VkDescriptorSetLayout vertexDSL = VK_NULL_HANDLE, pixelDSL = VK_NULL_HANDLE, geometryDSL = VK_NULL_HANDLE;
VkPipelineLayout pipeline_layout = VK_NULL_HANDLE;
VkDescriptorSetLayout m_vertexDSL = VK_NULL_HANDLE, m_pixelDSL = VK_NULL_HANDLE, m_geometryDSL = VK_NULL_HANDLE;
VkPipelineLayout m_pipelineLayout = VK_NULL_HANDLE;
private:
VkPipeline m_pipeline = VK_NULL_HANDLE;
};
class VKRObjectDescriptorSet : public VKRDestructibleObject

View file

@ -26,7 +26,6 @@ PipelineInfo::PipelineInfo(uint64 minimalStateHash, uint64 pipelineHash, LatteFe
// init VKRObjPipeline
m_vkrObjPipeline = new VKRObjectPipeline();
m_vkrObjPipeline->pipeline = VK_NULL_HANDLE;
// track dependency with shaders
if (vertexShaderVk)

View file

@ -558,8 +558,8 @@ void PipelineCompiler::InitRasterizerState(const LatteContextRegister& latteRegi
rasterizerExt.flags = 0;
rasterizer.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
rasterizer.pNext = &rasterizerExt;
rasterizer.rasterizerDiscardEnable = LatteGPUState.contextNew.PA_CL_CLIP_CNTL.get_DX_RASTERIZATION_KILL();
rasterizer.pNext = VulkanRenderer::GetInstance()->m_featureControl.deviceExtensions.depth_clip_enable ? &rasterizerExt : nullptr;
// GX2SetSpecialState(0, true) workaround
if (!LatteGPUState.contextNew.PA_CL_VTE_CNTL.get_VPORT_X_OFFSET_ENA())
rasterizer.rasterizerDiscardEnable = false;
@ -730,7 +730,7 @@ void PipelineCompiler::InitDescriptorSetLayouts(VulkanRenderer* vkRenderer, Pipe
{
cemu_assert_debug(descriptorSetLayoutCount == 0);
CreateDescriptorSetLayout(vkRenderer, vertexShader, descriptorSetLayout[descriptorSetLayoutCount], vkrPipelineInfo);
vkObjPipeline->vertexDSL = descriptorSetLayout[descriptorSetLayoutCount];
vkObjPipeline->m_vertexDSL = descriptorSetLayout[descriptorSetLayoutCount];
descriptorSetLayoutCount++;
}
@ -738,7 +738,7 @@ void PipelineCompiler::InitDescriptorSetLayouts(VulkanRenderer* vkRenderer, Pipe
{
cemu_assert_debug(descriptorSetLayoutCount == 1);
CreateDescriptorSetLayout(vkRenderer, pixelShader, descriptorSetLayout[descriptorSetLayoutCount], vkrPipelineInfo);
vkObjPipeline->pixelDSL = descriptorSetLayout[descriptorSetLayoutCount];
vkObjPipeline->m_pixelDSL = descriptorSetLayout[descriptorSetLayoutCount];
descriptorSetLayoutCount++;
}
else if (geometryShader)
@ -757,7 +757,7 @@ void PipelineCompiler::InitDescriptorSetLayouts(VulkanRenderer* vkRenderer, Pipe
{
cemu_assert_debug(descriptorSetLayoutCount == 2);
CreateDescriptorSetLayout(vkRenderer, geometryShader, descriptorSetLayout[descriptorSetLayoutCount], vkrPipelineInfo);
vkObjPipeline->geometryDSL = descriptorSetLayout[descriptorSetLayoutCount];
vkObjPipeline->m_geometryDSL = descriptorSetLayout[descriptorSetLayoutCount];
descriptorSetLayoutCount++;
}
}
@ -918,7 +918,7 @@ bool PipelineCompiler::InitFromCurrentGPUState(PipelineInfo* pipelineInfo, const
pipelineLayoutInfo.pPushConstantRanges = nullptr;
pipelineLayoutInfo.pushConstantRangeCount = 0;
VkResult result = vkCreatePipelineLayout(vkRenderer->m_logicalDevice, &pipelineLayoutInfo, nullptr, &m_pipeline_layout);
VkResult result = vkCreatePipelineLayout(vkRenderer->m_logicalDevice, &pipelineLayoutInfo, nullptr, &m_pipelineLayout);
if (result != VK_SUCCESS)
{
cemuLog_log(LogType::Force, "Failed to create pipeline layout: {}", result);
@ -936,7 +936,7 @@ bool PipelineCompiler::InitFromCurrentGPUState(PipelineInfo* pipelineInfo, const
// ##########################################################################################################################################
pipelineInfo->m_vkrObjPipeline->pipeline_layout = m_pipeline_layout;
pipelineInfo->m_vkrObjPipeline->m_pipelineLayout = m_pipelineLayout;
// increment ref counter for vkrObjPipeline and renderpass object to make sure they dont get released while we are using them
m_vkrObjPipeline->incRef();
@ -989,7 +989,7 @@ bool PipelineCompiler::Compile(bool forceCompile, bool isRenderThread, bool show
pipelineInfo.pRasterizationState = &rasterizer;
pipelineInfo.pMultisampleState = &multisampling;
pipelineInfo.pColorBlendState = &colorBlending;
pipelineInfo.layout = m_pipeline_layout;
pipelineInfo.layout = m_pipelineLayout;
pipelineInfo.renderPass = m_renderPassObj->m_renderPass;
pipelineInfo.pDepthStencilState = &depthStencilState;
pipelineInfo.subpass = 0;
@ -1037,7 +1037,7 @@ bool PipelineCompiler::Compile(bool forceCompile, bool isRenderThread, bool show
}
else if (result == VK_SUCCESS)
{
m_vkrObjPipeline->setPipeline(pipeline);
m_vkrObjPipeline->SetPipeline(pipeline);
}
else
{

View file

@ -41,7 +41,7 @@ public:
bool InitFromCurrentGPUState(PipelineInfo* pipelineInfo, const LatteContextRegister& latteRegister, VKRObjectRenderPass* renderPassObj);
void TrackAsCached(uint64 baseHash, uint64 pipelineStateHash); // stores pipeline to permanent cache if not yet cached. Must be called synchronously from render thread due to dependency on GPU state
VkPipelineLayout m_pipeline_layout;
VkPipelineLayout m_pipelineLayout;
VKRObjectRenderPass* m_renderPassObj{};
/* shader stages */

View file

@ -49,7 +49,8 @@ const std::vector<const char*> kOptionalDeviceExtensions =
VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME,
VK_KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME,
VK_KHR_PRESENT_WAIT_EXTENSION_NAME,
VK_KHR_PRESENT_ID_EXTENSION_NAME
VK_KHR_PRESENT_ID_EXTENSION_NAME,
VK_EXT_DEPTH_CLIP_ENABLE_EXTENSION_NAME
};
const std::vector<const char*> kRequiredDeviceExtensions =
@ -82,8 +83,6 @@ VKAPI_ATTR VkBool32 VKAPI_CALL DebugUtilsCallback(VkDebugUtilsMessageSeverityFla
if (strstr(pCallbackData->pMessage, "Number of currently valid sampler objects is not less than the maximum allowed"))
return VK_FALSE;
assert_dbg();
#endif
cemuLog_log(LogType::Force, (char*)pCallbackData->pMessage);
@ -314,7 +313,10 @@ void VulkanRenderer::GetDeviceFeatures()
cemuLog_log(LogType::Force, "VK_EXT_custom_border_color not supported. Cannot emulate arbitrary border color");
}
}
if (!m_featureControl.deviceExtensions.depth_clip_enable)
{
cemuLog_log(LogType::Force, "VK_EXT_depth_clip_enable not supported");
}
// get limits
m_featureControl.limits.minUniformBufferOffsetAlignment = std::max(prop2.properties.limits.minUniformBufferOffsetAlignment, (VkDeviceSize)4);
m_featureControl.limits.nonCoherentAtomSize = std::max(prop2.properties.limits.nonCoherentAtomSize, (VkDeviceSize)4);
@ -1118,10 +1120,13 @@ VkDeviceCreateInfo VulkanRenderer::CreateDeviceCreateInfo(const std::vector<VkDe
used_extensions.emplace_back(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME);
if (m_featureControl.deviceExtensions.shader_float_controls)
used_extensions.emplace_back(VK_KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME);
if (m_featureControl.deviceExtensions.depth_clip_enable)
used_extensions.emplace_back(VK_EXT_DEPTH_CLIP_ENABLE_EXTENSION_NAME);
if (m_featureControl.deviceExtensions.present_wait)
{
used_extensions.emplace_back(VK_KHR_PRESENT_ID_EXTENSION_NAME);
if (m_featureControl.deviceExtensions.present_wait)
used_extensions.emplace_back(VK_KHR_PRESENT_WAIT_EXTENSION_NAME);
}
VkDeviceCreateInfo createInfo{};
createInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
@ -1218,6 +1223,7 @@ bool VulkanRenderer::CheckDeviceExtensionSupport(const VkPhysicalDevice device,
info.deviceExtensions.synchronization2 = isExtensionAvailable(VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME);
info.deviceExtensions.shader_float_controls = isExtensionAvailable(VK_KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME);
info.deviceExtensions.dynamic_rendering = false; // isExtensionAvailable(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME);
info.deviceExtensions.depth_clip_enable = isExtensionAvailable(VK_EXT_DEPTH_CLIP_ENABLE_EXTENSION_NAME);
// dynamic rendering doesn't provide any benefits for us right now. Driver implementations are very unoptimized as of Feb 2022
info.deviceExtensions.present_wait = isExtensionAvailable(VK_KHR_PRESENT_WAIT_EXTENSION_NAME) && isExtensionAvailable(VK_KHR_PRESENT_ID_EXTENSION_NAME);
@ -4112,33 +4118,36 @@ VKRObjectFramebuffer::~VKRObjectFramebuffer()
VKRObjectPipeline::VKRObjectPipeline()
{
// todo
}
void VKRObjectPipeline::setPipeline(VkPipeline newPipeline)
void VKRObjectPipeline::SetPipeline(VkPipeline newPipeline)
{
cemu_assert_debug(pipeline == VK_NULL_HANDLE);
pipeline = newPipeline;
if(newPipeline != VK_NULL_HANDLE)
if (m_pipeline == newPipeline)
return;
cemu_assert_debug(m_pipeline == VK_NULL_HANDLE); // replacing an already assigned pipeline is not intended
if(m_pipeline == VK_NULL_HANDLE && newPipeline != VK_NULL_HANDLE)
performanceMonitor.vk.numGraphicPipelines.increment();
else if(m_pipeline != VK_NULL_HANDLE && newPipeline == VK_NULL_HANDLE)
performanceMonitor.vk.numGraphicPipelines.decrement();
m_pipeline = newPipeline;
}
VKRObjectPipeline::~VKRObjectPipeline()
{
auto vkr = VulkanRenderer::GetInstance();
if (pipeline != VK_NULL_HANDLE)
if (m_pipeline != VK_NULL_HANDLE)
{
vkDestroyPipeline(vkr->GetLogicalDevice(), pipeline, nullptr);
vkDestroyPipeline(vkr->GetLogicalDevice(), m_pipeline, nullptr);
performanceMonitor.vk.numGraphicPipelines.decrement();
}
if (vertexDSL != VK_NULL_HANDLE)
vkDestroyDescriptorSetLayout(vkr->GetLogicalDevice(), vertexDSL, nullptr);
if (pixelDSL != VK_NULL_HANDLE)
vkDestroyDescriptorSetLayout(vkr->GetLogicalDevice(), pixelDSL, nullptr);
if (geometryDSL != VK_NULL_HANDLE)
vkDestroyDescriptorSetLayout(vkr->GetLogicalDevice(), geometryDSL, nullptr);
if (pipeline_layout != VK_NULL_HANDLE)
vkDestroyPipelineLayout(vkr->GetLogicalDevice(), pipeline_layout, nullptr);
if (m_vertexDSL != VK_NULL_HANDLE)
vkDestroyDescriptorSetLayout(vkr->GetLogicalDevice(), m_vertexDSL, nullptr);
if (m_pixelDSL != VK_NULL_HANDLE)
vkDestroyDescriptorSetLayout(vkr->GetLogicalDevice(), m_pixelDSL, nullptr);
if (m_geometryDSL != VK_NULL_HANDLE)
vkDestroyDescriptorSetLayout(vkr->GetLogicalDevice(), m_geometryDSL, nullptr);
if (m_pipelineLayout != VK_NULL_HANDLE)
vkDestroyPipelineLayout(vkr->GetLogicalDevice(), m_pipelineLayout, nullptr);
}
VKRObjectDescriptorSet::VKRObjectDescriptorSet()

View file

@ -452,6 +452,7 @@ private:
bool dynamic_rendering = false; // VK_KHR_dynamic_rendering
bool shader_float_controls = false; // VK_KHR_shader_float_controls
bool present_wait = false; // VK_KHR_present_wait
bool depth_clip_enable = false; // VK_EXT_depth_clip_enable
}deviceExtensions;
struct

View file

@ -603,7 +603,7 @@ VkDescriptorSetInfo* VulkanRenderer::draw_getOrCreateDescriptorSet(PipelineInfo*
const auto it = pipeline_info->vertex_ds_cache.find(stateHash);
if (it != pipeline_info->vertex_ds_cache.cend())
return it->second;
descriptor_set_layout = pipeline_info->m_vkrObjPipeline->vertexDSL;
descriptor_set_layout = pipeline_info->m_vkrObjPipeline->m_vertexDSL;
break;
}
case LatteConst::ShaderType::Pixel:
@ -611,7 +611,7 @@ VkDescriptorSetInfo* VulkanRenderer::draw_getOrCreateDescriptorSet(PipelineInfo*
const auto it = pipeline_info->pixel_ds_cache.find(stateHash);
if (it != pipeline_info->pixel_ds_cache.cend())
return it->second;
descriptor_set_layout = pipeline_info->m_vkrObjPipeline->pixelDSL;
descriptor_set_layout = pipeline_info->m_vkrObjPipeline->m_pixelDSL;
break;
}
case LatteConst::ShaderType::Geometry:
@ -619,7 +619,7 @@ VkDescriptorSetInfo* VulkanRenderer::draw_getOrCreateDescriptorSet(PipelineInfo*
const auto it = pipeline_info->geometry_ds_cache.find(stateHash);
if (it != pipeline_info->geometry_ds_cache.cend())
return it->second;
descriptor_set_layout = pipeline_info->m_vkrObjPipeline->geometryDSL;
descriptor_set_layout = pipeline_info->m_vkrObjPipeline->m_geometryDSL;
break;
}
default:
@ -1481,8 +1481,7 @@ void VulkanRenderer::draw_execute(uint32 baseVertex, uint32 baseInstance, uint32
}
auto vkObjPipeline = pipeline_info->m_vkrObjPipeline;
if (vkObjPipeline->pipeline == VK_NULL_HANDLE)
if (vkObjPipeline->GetPipeline() == VK_NULL_HANDLE)
{
// invalid/uninitialized pipeline
m_state.activeVertexDS = nullptr;
@ -1509,11 +1508,11 @@ void VulkanRenderer::draw_execute(uint32 baseVertex, uint32 baseInstance, uint32
draw_setRenderPass();
if (m_state.currentPipeline != vkObjPipeline->pipeline)
if (m_state.currentPipeline != vkObjPipeline->GetPipeline())
{
vkCmdBindPipeline(m_state.currentCommandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, vkObjPipeline->pipeline);
vkCmdBindPipeline(m_state.currentCommandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, vkObjPipeline->GetPipeline());
vkObjPipeline->flagForCurrentCommandBuffer();
m_state.currentPipeline = vkObjPipeline->pipeline;
m_state.currentPipeline = vkObjPipeline->GetPipeline();
// depth bias
if (pipeline_info->usesDepthBias)
draw_updateDepthBias(true);
@ -1545,7 +1544,7 @@ void VulkanRenderer::draw_execute(uint32 baseVertex, uint32 baseInstance, uint32
dsArray[1] = pixelDS->m_vkObjDescriptorSet->descriptorSet;
vkCmdBindDescriptorSets(m_state.currentCommandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS,
vkObjPipeline->pipeline_layout, 0, 2, dsArray, numDynOffsetsVS + numDynOffsetsPS,
vkObjPipeline->m_pipelineLayout, 0, 2, dsArray, numDynOffsetsVS + numDynOffsetsPS,
dynamicOffsets);
}
else if (vertexDS)
@ -1554,7 +1553,7 @@ void VulkanRenderer::draw_execute(uint32 baseVertex, uint32 baseInstance, uint32
draw_prepareDynamicOffsetsForDescriptorSet(VulkanRendererConst::SHADER_STAGE_INDEX_VERTEX, dynamicOffsets, numDynOffsets,
pipeline_info);
vkCmdBindDescriptorSets(m_state.currentCommandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS,
vkObjPipeline->pipeline_layout, 0, 1, &vertexDS->m_vkObjDescriptorSet->descriptorSet, numDynOffsets,
vkObjPipeline->m_pipelineLayout, 0, 1, &vertexDS->m_vkObjDescriptorSet->descriptorSet, numDynOffsets,
dynamicOffsets);
}
else if (pixelDS)
@ -1563,7 +1562,7 @@ void VulkanRenderer::draw_execute(uint32 baseVertex, uint32 baseInstance, uint32
draw_prepareDynamicOffsetsForDescriptorSet(VulkanRendererConst::SHADER_STAGE_INDEX_FRAGMENT, dynamicOffsets, numDynOffsets,
pipeline_info);
vkCmdBindDescriptorSets(m_state.currentCommandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS,
vkObjPipeline->pipeline_layout, 1, 1, &pixelDS->m_vkObjDescriptorSet->descriptorSet, numDynOffsets,
vkObjPipeline->m_pipelineLayout, 1, 1, &pixelDS->m_vkObjDescriptorSet->descriptorSet, numDynOffsets,
dynamicOffsets);
}
if (geometryDS)
@ -1572,7 +1571,7 @@ void VulkanRenderer::draw_execute(uint32 baseVertex, uint32 baseInstance, uint32
draw_prepareDynamicOffsetsForDescriptorSet(VulkanRendererConst::SHADER_STAGE_INDEX_GEOMETRY, dynamicOffsets, numDynOffsets,
pipeline_info);
vkCmdBindDescriptorSets(m_state.currentCommandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS,
vkObjPipeline->pipeline_layout, 2, 1, &geometryDS->m_vkObjDescriptorSet->descriptorSet, numDynOffsets,
vkObjPipeline->m_pipelineLayout, 2, 1, &geometryDS->m_vkObjDescriptorSet->descriptorSet, numDynOffsets,
dynamicOffsets);
}

View file

@ -357,7 +357,7 @@ CopySurfacePipelineInfo* VulkanRenderer::copySurface_getOrCreateGraphicsPipeline
layoutInfo.bindingCount = (uint32_t)descriptorSetLayoutBindings.size();
layoutInfo.pBindings = descriptorSetLayoutBindings.data();
if (vkCreateDescriptorSetLayout(m_logicalDevice, &layoutInfo, nullptr, &vkObjPipeline->pixelDSL) != VK_SUCCESS)
if (vkCreateDescriptorSetLayout(m_logicalDevice, &layoutInfo, nullptr, &vkObjPipeline->m_pixelDSL) != VK_SUCCESS)
UnrecoverableError(fmt::format("Failed to create descriptor set layout for surface copy shader").c_str());
// ##########################################################################################################################################
@ -370,15 +370,15 @@ CopySurfacePipelineInfo* VulkanRenderer::copySurface_getOrCreateGraphicsPipeline
VkPipelineLayoutCreateInfo pipelineLayoutInfo{};
pipelineLayoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
pipelineLayoutInfo.setLayoutCount = 1;
pipelineLayoutInfo.pSetLayouts = &vkObjPipeline->pixelDSL;
pipelineLayoutInfo.pSetLayouts = &vkObjPipeline->m_pixelDSL;
pipelineLayoutInfo.pPushConstantRanges = &pushConstantRange;
pipelineLayoutInfo.pushConstantRangeCount = 1;
VkResult result = vkCreatePipelineLayout(m_logicalDevice, &pipelineLayoutInfo, nullptr, &vkObjPipeline->pipeline_layout);
VkResult result = vkCreatePipelineLayout(m_logicalDevice, &pipelineLayoutInfo, nullptr, &vkObjPipeline->m_pipelineLayout);
if (result != VK_SUCCESS)
{
cemuLog_log(LogType::Force, "Failed to create pipeline layout: {}", result);
vkObjPipeline->pipeline = VK_NULL_HANDLE;
vkObjPipeline->SetPipeline(VK_NULL_HANDLE);
return copyPipeline;
}
@ -425,7 +425,7 @@ CopySurfacePipelineInfo* VulkanRenderer::copySurface_getOrCreateGraphicsPipeline
pipelineInfo.pRasterizationState = &rasterizer;
pipelineInfo.pMultisampleState = &multisampling;
pipelineInfo.pColorBlendState = state.destinationTexture->isDepth?nullptr:&colorBlending;
pipelineInfo.layout = vkObjPipeline->pipeline_layout;
pipelineInfo.layout = vkObjPipeline->m_pipelineLayout;
pipelineInfo.renderPass = copyPipeline->vkObjRenderPass->m_renderPass;
pipelineInfo.pDepthStencilState = &depthStencilState;
pipelineInfo.subpass = 0;
@ -434,17 +434,16 @@ CopySurfacePipelineInfo* VulkanRenderer::copySurface_getOrCreateGraphicsPipeline
copyPipeline->vkObjPipeline = vkObjPipeline;
result = vkCreateGraphicsPipelines(m_logicalDevice, m_pipeline_cache, 1, &pipelineInfo, nullptr, &copyPipeline->vkObjPipeline->pipeline);
VkPipeline pipeline = VK_NULL_HANDLE;
result = vkCreateGraphicsPipelines(m_logicalDevice, m_pipeline_cache, 1, &pipelineInfo, nullptr, &pipeline);
if (result != VK_SUCCESS)
{
copyPipeline->vkObjPipeline->SetPipeline(nullptr);
cemuLog_log(LogType::Force, "Failed to create graphics pipeline for surface copy. Error {} Info:", (sint32)result);
cemu_assert_debug(false);
copyPipeline->vkObjPipeline->pipeline = VK_NULL_HANDLE;
cemu_assert_suspicious();
}
//performanceMonitor.vk.numGraphicPipelines.increment();
//m_pipeline_cache_semaphore.notify();
else
copyPipeline->vkObjPipeline->SetPipeline(pipeline);
return copyPipeline;
}
@ -522,7 +521,7 @@ VKRObjectDescriptorSet* VulkanRenderer::surfaceCopy_getOrCreateDescriptorSet(VkC
allocInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
allocInfo.descriptorPool = m_descriptorPool;
allocInfo.descriptorSetCount = 1;
allocInfo.pSetLayouts = &(pipelineInfo->vkObjPipeline->pixelDSL);
allocInfo.pSetLayouts = &pipelineInfo->vkObjPipeline->m_pixelDSL;
if (vkAllocateDescriptorSets(m_logicalDevice, &allocInfo, &vkObjDescriptorSet->descriptorSet) != VK_SUCCESS)
{
@ -644,7 +643,7 @@ void VulkanRenderer::surfaceCopy_viaDrawcall(LatteTextureVk* srcTextureVk, sint3
pushConstantData.srcTexelOffset[0] = 0;
pushConstantData.srcTexelOffset[1] = 0;
vkCmdPushConstants(m_state.currentCommandBuffer, copySurfacePipelineInfo->vkObjPipeline->pipeline_layout, VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(pushConstantData), &pushConstantData);
vkCmdPushConstants(m_state.currentCommandBuffer, copySurfacePipelineInfo->vkObjPipeline->m_pipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(pushConstantData), &pushConstantData);
// draw
VkRenderPassBeginInfo renderPassInfo{};
@ -680,13 +679,13 @@ void VulkanRenderer::surfaceCopy_viaDrawcall(LatteTextureVk* srcTextureVk, sint3
vkCmdBeginRenderPass(m_state.currentCommandBuffer, &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE);
vkCmdBindPipeline(m_state.currentCommandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, copySurfacePipelineInfo->vkObjPipeline->pipeline);
vkCmdBindPipeline(m_state.currentCommandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, copySurfacePipelineInfo->vkObjPipeline->GetPipeline());
copySurfacePipelineInfo->vkObjPipeline->flagForCurrentCommandBuffer();
m_state.currentPipeline = copySurfacePipelineInfo->vkObjPipeline->pipeline;
m_state.currentPipeline = copySurfacePipelineInfo->vkObjPipeline->GetPipeline();
vkCmdBindDescriptorSets(m_state.currentCommandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS,
copySurfacePipelineInfo->vkObjPipeline->pipeline_layout, 0, 1, &vkObjDescriptorSet->descriptorSet, 0, nullptr);
copySurfacePipelineInfo->vkObjPipeline->m_pipelineLayout, 0, 1, &vkObjDescriptorSet->descriptorSet, 0, nullptr);
vkObjDescriptorSet->flagForCurrentCommandBuffer();
vkCmdDraw(m_state.currentCommandBuffer, 6, 1, 0, 0);