From c66060be103481295f08d45527438fcfecca7311 Mon Sep 17 00:00:00 2001 From: nmzik Date: Sat, 5 Sep 2026 14:36:52 +0400 Subject: [PATCH] render: simplify pipeline setup --- .../renderer/pipeline/descriptors.cpp | 21 ++- .../renderer/pipeline/pipelineCache.cpp | 19 +-- .../host_gpu/renderer/pipeline/shaders.cpp | 152 ++++-------------- src/graphics/host_gpu/renderer/renderDraw.cpp | 13 +- 4 files changed, 53 insertions(+), 152 deletions(-) diff --git a/src/graphics/host_gpu/renderer/pipeline/descriptors.cpp b/src/graphics/host_gpu/renderer/pipeline/descriptors.cpp index ff376809a..767ca27c8 100644 --- a/src/graphics/host_gpu/renderer/pipeline/descriptors.cpp +++ b/src/graphics/host_gpu/renderer/pipeline/descriptors.cpp @@ -76,10 +76,14 @@ uint32_t NativeDescriptorCount(const ShaderRecompiler::IR::DescriptorBinding& bi } vk::DescriptorImageInfo MakeImageInfo(const TextureBinding& texture, uint32_t element) { - const auto view = - texture.mip_views.empty() - ? (element == 0u ? texture.image_view : vk::ImageView {}) - : (element < texture.mip_views.size() ? texture.mip_views[element] : vk::ImageView {}); + vk::ImageView view = nullptr; + if (texture.mip_views.empty()) { + if (element == 0u) { + view = texture.image_view; + } + } else if (element < texture.mip_views.size()) { + view = texture.mip_views[element]; + } EXIT_IF(!texture.image_id || view == nullptr || texture.layout == vk::ImageLayout::eUndefined); return {nullptr, view, texture.layout}; } @@ -171,11 +175,16 @@ static BufferView NativeStorageBuffer(RenderContext& if (resource.formatted && resource.written) { context.GetTextureCache().InvalidateMemoryFromGPU(address, size); } + const char* access = "Read"; + if (resource.written && resource.read) { + access = "ReadWrite"; + } else if (resource.written) { + access = "Write"; + } SetVulkanObjectNameF( graphics.device, result.buffer, "Kyty.{}.StorageBuffer[slot={} guest=0x{:016x} size=0x{:x} access={} formatted={}]", - ShaderStageResourceName(stage), slot, address, size, - resource.written ? (resource.read ? "ReadWrite" : "Write") : "Read", resource.formatted); + ShaderStageResourceName(stage), slot, address, size, access, resource.formatted); return result; } diff --git a/src/graphics/host_gpu/renderer/pipeline/pipelineCache.cpp b/src/graphics/host_gpu/renderer/pipeline/pipelineCache.cpp index c9fedbfdc..3a1faedc6 100644 --- a/src/graphics/host_gpu/renderer/pipeline/pipelineCache.cpp +++ b/src/graphics/host_gpu/renderer/pipeline/pipelineCache.cpp @@ -633,9 +633,6 @@ PipelineCache::GraphicsPipeline& PipelineCache::CreateGraphicsPipeline( const auto ps_id = ps_active ? pixel_program.id : 0; PipelineStaticParameters static_params {}; - GraphicsPipeline p {}; - p.ps_shader_id = ps_id; - p.vs_shader_id = vs_id; static_params.color_count = color_count; PipelineRenderingState rendering {}; @@ -723,8 +720,8 @@ PipelineCache::GraphicsPipeline& PipelineCache::CreateGraphicsPipeline( } GraphicsPipelineKey key {}; key.rendering = rendering; - key.vs_shader_id = p.vs_shader_id; - key.ps_shader_id = p.ps_shader_id; + key.vs_shader_id = vs_id; + key.ps_shader_id = ps_id; key.static_params = static_params; if (vs_input_info.stage.program->stage != ShaderType::Mesh) { EXIT_IF(vs_input_info.buffers_num < 0 || @@ -767,7 +764,9 @@ PipelineCache::GraphicsPipeline& PipelineCache::CreateGraphicsPipeline( static_cast(pixel_program.module)); } - auto cached = std::make_unique(p); + auto cached = std::make_unique(); + cached->ps_shader_id = ps_id; + cached->vs_shader_id = vs_id; LogPipelineTrace("CreatePipelineInternal begin", vs_id, ps_id); CreatePipelineInternal(m_graphics, *cached, rendering, key.vertex_input, vs_input_info, vertex_program.module, ps_input_info, pixel_program.module, @@ -792,11 +791,8 @@ PipelineCache::CreateComputePipeline(ShaderComputeInputInfo& input_info, Common::LockGuard lock(m_mutex); - ComputePipeline p {}; - p.cs_shader_id = compute_program.id; - ComputePipelineKey key {}; - key.cs_shader_id = p.cs_shader_id; + key.cs_shader_id = compute_program.id; if (auto iter = m_compute_pipelines.find(key); iter != m_compute_pipelines.end()) { return *iter->second; @@ -806,7 +802,8 @@ PipelineCache::CreateComputePipeline(ShaderComputeInputInfo& input_info, ShaderDbgDumpInputInfo(input_info); } - auto cached = std::make_unique(p); + auto cached = std::make_unique(); + cached->cs_shader_id = compute_program.id; CreatePipelineInternal(m_graphics, *cached, input_info, compute_program.module, m_driver_cache); EXIT_NOT_IMPLEMENTED(cached->pipeline == nullptr); diff --git a/src/graphics/host_gpu/renderer/pipeline/shaders.cpp b/src/graphics/host_gpu/renderer/pipeline/shaders.cpp index afb199ba9..f62ceec57 100644 --- a/src/graphics/host_gpu/renderer/pipeline/shaders.cpp +++ b/src/graphics/host_gpu/renderer/pipeline/shaders.cpp @@ -439,7 +439,6 @@ void CreatePipelineInternal( vk::ShaderModule tess_eval_shader_module = nullptr; vk::ShaderModuleCreateInfo create_info {}; - create_info.sType = vk::StructureType::eShaderModuleCreateInfo; vk::Result result {}; if (rect_list) { const auto shaders = @@ -469,32 +468,21 @@ void CreatePipelineInternal( rect_list && (tess_control_shader_module == nullptr || tess_eval_shader_module == nullptr)); vk::PipelineShaderStageCreateInfo vert_shader_stage_info {}; - - vert_shader_stage_info.sType = vk::StructureType::ePipelineShaderStageCreateInfo; - vert_shader_stage_info.pNext = nullptr; - vert_shader_stage_info.flags = {}; - vert_shader_stage_info.stage = vertex_stage; - vert_shader_stage_info.module = vertex_module; - vert_shader_stage_info.pName = "main"; - vert_shader_stage_info.pSpecializationInfo = nullptr; + vert_shader_stage_info.stage = vertex_stage; + vert_shader_stage_info.module = vertex_module; + vert_shader_stage_info.pName = "main"; vk::PipelineShaderStageCreateInfo frag_shader_stage_info {}; - frag_shader_stage_info.sType = vk::StructureType::ePipelineShaderStageCreateInfo; - frag_shader_stage_info.pNext = nullptr; - frag_shader_stage_info.flags = {}; - frag_shader_stage_info.stage = vk::ShaderStageFlagBits::eFragment; - frag_shader_stage_info.module = pixel_module; - frag_shader_stage_info.pName = "main"; - frag_shader_stage_info.pSpecializationInfo = nullptr; + frag_shader_stage_info.stage = vk::ShaderStageFlagBits::eFragment; + frag_shader_stage_info.module = pixel_module; + frag_shader_stage_info.pName = "main"; vk::PipelineShaderStageCreateInfo tess_control_shader_stage_info {}; - tess_control_shader_stage_info.sType = vk::StructureType::ePipelineShaderStageCreateInfo; tess_control_shader_stage_info.stage = vk::ShaderStageFlagBits::eTessellationControl; tess_control_shader_stage_info.module = tess_control_shader_module; tess_control_shader_stage_info.pName = "main"; vk::PipelineShaderStageCreateInfo tess_eval_shader_stage_info {}; - tess_eval_shader_stage_info.sType = vk::StructureType::ePipelineShaderStageCreateInfo; tess_eval_shader_stage_info.stage = vk::ShaderStageFlagBits::eTessellationEvaluation; tess_eval_shader_stage_info.module = tess_eval_shader_module; tess_eval_shader_stage_info.pName = "main"; @@ -639,35 +627,23 @@ void CreatePipelineInternal( } vk::PipelineVertexInputStateCreateInfo vertex_input_info {}; - vertex_input_info.sType = vk::StructureType::ePipelineVertexInputStateCreateInfo; - vertex_input_info.pNext = nullptr; - vertex_input_info.flags = {}; vertex_input_info.vertexBindingDescriptionCount = vertex_input.binding_count; vertex_input_info.pVertexBindingDescriptions = input_desc; vertex_input_info.vertexAttributeDescriptionCount = vertex_input.attribute_count; vertex_input_info.pVertexAttributeDescriptions = input_attr; vk::PipelineInputAssemblyStateCreateInfo input_assembly {}; - input_assembly.sType = vk::StructureType::ePipelineInputAssemblyStateCreateInfo; - input_assembly.pNext = nullptr; - input_assembly.flags = {}; input_assembly.topology = static_params.topology; input_assembly.primitiveRestartEnable = static_params.primitive_restart_enable ? VK_TRUE : VK_FALSE; vk::PipelineViewportDepthClipControlCreateInfoEXT depth_clip_control {}; - depth_clip_control.sType = vk::StructureType::ePipelineViewportDepthClipControlCreateInfoEXT; - depth_clip_control.pNext = nullptr; depth_clip_control.negativeOneToOne = (static_params.negative_one_to_one ? VK_TRUE : VK_FALSE); vk::PipelineViewportStateCreateInfo viewport_state {}; - viewport_state.sType = vk::StructureType::ePipelineViewportStateCreateInfo; viewport_state.pNext = &depth_clip_control; - viewport_state.flags = {}; viewport_state.viewportCount = 1; - viewport_state.pViewports = nullptr; viewport_state.scissorCount = 1; - viewport_state.pScissors = nullptr; vk::CullModeFlags cull_mode = vk::CullModeFlagBits::eNone; if (static_params.cull_back) { @@ -681,65 +657,28 @@ void CreatePipelineInternal( (static_params.face ? vk::FrontFace::eClockwise : vk::FrontFace::eCounterClockwise); vk::PipelineRasterizationDepthClipStateCreateInfoEXT clip_ext {}; - clip_ext.sType = vk::StructureType::ePipelineRasterizationDepthClipStateCreateInfoEXT; - clip_ext.pNext = nullptr; - clip_ext.flags = {}; clip_ext.depthClipEnable = static_params.depth_clip_enable ? VK_TRUE : VK_FALSE; vk::PipelineRasterizationStateCreateInfo rasterizer {}; - rasterizer.sType = vk::StructureType::ePipelineRasterizationStateCreateInfo; // MoltenVK lacks VK_EXT_depth_clip_enable; omit the depth-clip struct on macOS and accept // Vulkan's default depth clipping (enabled) instead of the PS5's clamp behavior. -#if defined(__APPLE__) - rasterizer.pNext = nullptr; -#else +#if !defined(__APPLE__) rasterizer.pNext = &clip_ext; #endif - rasterizer.flags = {}; - rasterizer.depthClampEnable = VK_FALSE; - rasterizer.rasterizerDiscardEnable = VK_FALSE; - rasterizer.polygonMode = vk::PolygonMode::eFill; - rasterizer.cullMode = cull_mode; - rasterizer.frontFace = front_face; - rasterizer.depthBiasEnable = VK_FALSE; - rasterizer.depthBiasConstantFactor = 0.0f; - rasterizer.depthBiasClamp = 0.0f; - rasterizer.depthBiasSlopeFactor = 0.0f; - rasterizer.lineWidth = 1.0f; + rasterizer.cullMode = cull_mode; + rasterizer.frontFace = front_face; + rasterizer.lineWidth = 1.0f; vk::PipelineMultisampleStateCreateInfo multisampling {}; - multisampling.sType = vk::StructureType::ePipelineMultisampleStateCreateInfo; - multisampling.pNext = nullptr; - multisampling.flags = {}; - multisampling.sampleShadingEnable = static_params.sample_shading_enable ? VK_TRUE : VK_FALSE; - multisampling.rasterizationSamples = vulkan_sample_count(static_params.samples); - multisampling.minSampleShading = 1.0f; - multisampling.pSampleMask = nullptr; - multisampling.alphaToCoverageEnable = VK_FALSE; - multisampling.alphaToOneEnable = VK_FALSE; + multisampling.sampleShadingEnable = static_params.sample_shading_enable ? VK_TRUE : VK_FALSE; + multisampling.rasterizationSamples = vulkan_sample_count(static_params.samples); + multisampling.minSampleShading = 1.0f; vk::PipelineColorBlendAttachmentState color_blend_attachment[RENDER_COLOR_ATTACHMENTS_MAX] = {}; for (uint32_t i = 0; i < static_params.color_count; i++) { - vk::ColorComponentFlags color_write_mask = {}; EXIT_NOT_IMPLEMENTED((static_params.color_mask[i] & ~0x0fu) != 0); - if ((static_params.color_mask[i] & 0x1u) != 0) { - color_write_mask |= - static_cast(vk::ColorComponentFlagBits::eR); - } - if ((static_params.color_mask[i] & 0x2u) != 0) { - color_write_mask |= - static_cast(vk::ColorComponentFlagBits::eG); - } - if ((static_params.color_mask[i] & 0x4u) != 0) { - color_write_mask |= - static_cast(vk::ColorComponentFlagBits::eB); - } - if ((static_params.color_mask[i] & 0x8u) != 0) { - color_write_mask |= - static_cast(vk::ColorComponentFlagBits::eA); - } - - color_blend_attachment[i].colorWriteMask = color_write_mask; + color_blend_attachment[i].colorWriteMask = + vk::ColorComponentFlags {static_params.color_mask[i]}; color_blend_attachment[i].blendEnable = (static_params.blend_enable[i] && !static_params.blend_bypass[i]) ? VK_TRUE : VK_FALSE; color_blend_attachment[i].srcColorBlendFactor = @@ -765,22 +704,15 @@ void CreatePipelineInternal( } vk::PipelineColorWriteCreateInfoEXT color_write {}; - color_write.sType = vk::StructureType::ePipelineColorWriteCreateInfoEXT; - color_write.pNext = nullptr; color_write.attachmentCount = static_params.color_count; color_write.pColorWriteEnables = color_write_enable; vk::PipelineColorBlendStateCreateInfo color_blending {}; - color_blending.sType = vk::StructureType::ePipelineColorBlendStateCreateInfo; // MoltenVK lacks VK_EXT_color_write_enable; drop the dynamic color-write struct on macOS // and rely on each attachment's static colorWriteMask (all channels enabled by default). -#if defined(__APPLE__) - color_blending.pNext = nullptr; -#else +#if !defined(__APPLE__) color_blending.pNext = &color_write; #endif - color_blending.flags = {}; - color_blending.logicOpEnable = VK_FALSE; color_blending.logicOp = vk::LogicOp::eCopy; color_blending.attachmentCount = static_params.color_count; color_blending.pAttachments = color_blend_attachment; @@ -798,9 +730,6 @@ void CreatePipelineInternal( ShaderRecompiler::IR::NativePushConstantSize}; vk::PipelineLayoutCreateInfo pipeline_layout_info {}; - pipeline_layout_info.sType = vk::StructureType::ePipelineLayoutCreateInfo; - pipeline_layout_info.pNext = nullptr; - pipeline_layout_info.flags = {}; pipeline_layout_info.setLayoutCount = 1; pipeline_layout_info.pSetLayouts = &pipeline.descriptor_set_layout; pipeline_layout_info.pushConstantRangeCount = 1; @@ -824,9 +753,6 @@ void CreatePipelineInternal( EXIT_NOT_IMPLEMENTED(pipeline.pipeline_layout == nullptr); vk::PipelineDepthStencilStateCreateInfo depth_stencil_info {}; - depth_stencil_info.sType = vk::StructureType::ePipelineDepthStencilStateCreateInfo; - depth_stencil_info.pNext = nullptr; - depth_stencil_info.flags = {}; depth_stencil_info.depthBoundsTestEnable = #if defined(__APPLE__) VK_FALSE; // MoltenVK lacks the depthBounds feature; depth-bounds testing is disabled @@ -872,41 +798,32 @@ void CreatePipelineInternal( #endif vk::PipelineDynamicStateCreateInfo dynamic_state {}; - dynamic_state.sType = vk::StructureType::ePipelineDynamicStateCreateInfo; - dynamic_state.pNext = nullptr; - dynamic_state.flags = {}; dynamic_state.dynamicStateCount = dynamic_states_count; dynamic_state.pDynamicStates = dynamic_states; vk::GraphicsPipelineCreateInfo pipeline_info {}; vk::PipelineRenderingCreateInfo rendering_info {}; - rendering_info.sType = vk::StructureType::ePipelineRenderingCreateInfo; rendering_info.colorAttachmentCount = rendering.color_count; rendering_info.pColorAttachmentFormats = rendering.color_formats.data(); rendering_info.depthAttachmentFormat = rendering.depth_format; rendering_info.stencilAttachmentFormat = rendering.stencil_format; - pipeline_info.sType = vk::StructureType::eGraphicsPipelineCreateInfo; pipeline_info.pNext = &rendering_info; - pipeline_info.flags = {}; pipeline_info.stageCount = shader_stage_count; pipeline_info.pStages = shader_stages; pipeline_info.pVertexInputState = mesh ? nullptr : &vertex_input_info; pipeline_info.pInputAssemblyState = mesh ? nullptr : &input_assembly; vk::PipelineTessellationStateCreateInfo tessellation_state {}; - tessellation_state.sType = vk::StructureType::ePipelineTessellationStateCreateInfo; tessellation_state.patchControlPoints = 3; pipeline_info.pTessellationState = (rect_list ? &tessellation_state : nullptr); pipeline_info.pViewportState = &viewport_state; pipeline_info.pRasterizationState = &rasterizer; pipeline_info.pMultisampleState = &multisampling; - pipeline_info.pDepthStencilState = (static_params.with_depth ? &depth_stencil_info : nullptr); - pipeline_info.pColorBlendState = &color_blending; - pipeline_info.pDynamicState = &dynamic_state; - pipeline_info.layout = pipeline.pipeline_layout; - pipeline_info.renderPass = nullptr; - pipeline_info.subpass = 0; - pipeline_info.basePipelineHandle = nullptr; - pipeline_info.basePipelineIndex = -1; + pipeline_info.pDepthStencilState = + (static_params.with_depth ? &depth_stencil_info : nullptr); + pipeline_info.pColorBlendState = &color_blending; + pipeline_info.pDynamicState = &dynamic_state; + pipeline_info.layout = pipeline.pipeline_layout; + pipeline_info.basePipelineIndex = -1; EXIT_IF(pipeline.pipeline != nullptr); @@ -945,19 +862,13 @@ void CreatePipelineInternal(GraphicContext& graphics, PipelineCache::ComputePipe vk::PipelineShaderStageCreateInfo comp_shader_stage_info {}; vk::PipelineShaderStageRequiredSubgroupSizeCreateInfo comp_subgroup_size {}; - comp_shader_stage_info.sType = vk::StructureType::ePipelineShaderStageCreateInfo; - comp_shader_stage_info.pNext = nullptr; - comp_shader_stage_info.flags = {}; - comp_shader_stage_info.stage = vk::ShaderStageFlagBits::eCompute; - comp_shader_stage_info.module = compute_module; - comp_shader_stage_info.pName = "main"; - comp_shader_stage_info.pSpecializationInfo = nullptr; + comp_shader_stage_info.stage = vk::ShaderStageFlagBits::eCompute; + comp_shader_stage_info.module = compute_module; + comp_shader_stage_info.pName = "main"; EXIT_IF(!input_info.stage); const auto wave_size = input_info.stage.program->wave_size; if (graphics.compute_subgroup_size_control_enabled && wave_size >= graphics.min_subgroup_size && wave_size <= graphics.max_subgroup_size) { - comp_subgroup_size.sType = - vk::StructureType::ePipelineShaderStageRequiredSubgroupSizeCreateInfo; comp_subgroup_size.requiredSubgroupSize = wave_size; comp_shader_stage_info.pNext = &comp_subgroup_size; } @@ -970,9 +881,6 @@ void CreatePipelineInternal(GraphicContext& graphics, PipelineCache::ComputePipe ShaderRecompiler::IR::NativePushConstantSize}; vk::PipelineLayoutCreateInfo pipeline_layout_info {}; - pipeline_layout_info.sType = vk::StructureType::ePipelineLayoutCreateInfo; - pipeline_layout_info.pNext = nullptr; - pipeline_layout_info.flags = {}; pipeline_layout_info.setLayoutCount = 1; pipeline_layout_info.pSetLayouts = &pipeline.descriptor_set_layout; pipeline_layout_info.pushConstantRangeCount = 1; @@ -991,13 +899,9 @@ void CreatePipelineInternal(GraphicContext& graphics, PipelineCache::ComputePipe EXIT_NOT_IMPLEMENTED(pipeline.pipeline_layout == nullptr); vk::ComputePipelineCreateInfo info {}; - info.sType = vk::StructureType::eComputePipelineCreateInfo; - info.pNext = nullptr; - info.flags = {}; - info.stage = comp_shader_stage_info; - info.layout = pipeline.pipeline_layout; - info.basePipelineHandle = nullptr; - info.basePipelineIndex = -1; + info.stage = comp_shader_stage_info; + info.layout = pipeline.pipeline_layout; + info.basePipelineIndex = -1; EXIT_IF(pipeline.pipeline != nullptr); diff --git a/src/graphics/host_gpu/renderer/renderDraw.cpp b/src/graphics/host_gpu/renderer/renderDraw.cpp index 06086e960..195044ded 100644 --- a/src/graphics/host_gpu/renderer/renderDraw.cpp +++ b/src/graphics/host_gpu/renderer/renderDraw.cpp @@ -999,16 +999,6 @@ static void RefreshShaders(CommandBuffer& buffer, const DrawCallInfo& draw, bool target_export_mapping, state.ps_active, state.vs_input_info, state.ps_input_info); } -static PreparedVertexBuffers PrepareVertexBuffers(uint64_t submit_id, CommandBuffer& buffer, - const DrawCallInfo& draw, - const ShaderVertexInputInfo& vs_input_info) { - EXIT_IF(draw.name == nullptr); - (void)submit_id; - - LogDrawPhase(draw.name, "PrepareVertexBuffers"); - return AcquireVertexBuffers(buffer, vs_input_info); -} - static PreparedIndexBuffer PrepareIndexBuffer(CommandBuffer& buffer, const DrawIndexBufferSource& source) { PreparedIndexBuffer prepared; @@ -1164,7 +1154,8 @@ void RenderExecutor::ExecutePreparedDraw(uint64_t submit_id, CommandBuffer& buff PreparedVertexBuffers vertex_bindings; PreparedIndexBuffer index_binding; if (!mesh_active) { - vertex_bindings = PrepareVertexBuffers(submit_id, buffer, draw, state.vs_input_info); + LogDrawPhase(draw.name, "PrepareVertexBuffers"); + vertex_bindings = AcquireVertexBuffers(buffer, state.vs_input_info); index_binding = PrepareIndexBuffer(buffer, index_source); } state.rendering =