From ad935311f0013e86b362075f2282df3468a15b57 Mon Sep 17 00:00:00 2001 From: nmzik Date: Mon, 7 Sep 2026 07:01:53 +0400 Subject: [PATCH] Revert "render: add depth attachment feedback support" --- src/graphics/host_gpu/graphicContext.h | 1 - .../host_gpu/renderer/image/image.cpp | 3 - .../renderer/pipeline/descriptors.cpp | 5 +- .../host_gpu/renderer/pipeline/shaders.cpp | 20 +- src/graphics/host_gpu/renderer/renderDraw.cpp | 15 +- .../presentation/window/vulkanWindow.cpp | 25 -- tests/ShaderRecompilerComputeTests.cpp | 234 +++++------------- 7 files changed, 74 insertions(+), 229 deletions(-) diff --git a/src/graphics/host_gpu/graphicContext.h b/src/graphics/host_gpu/graphicContext.h index 21be1c7f7..6631d3cfc 100644 --- a/src/graphics/host_gpu/graphicContext.h +++ b/src/graphics/host_gpu/graphicContext.h @@ -32,7 +32,6 @@ struct GraphicContext { bool rt_extensions_enabled = false; bool compute_subgroup_size_control_enabled = false; bool sample_rate_shading_enabled = false; - bool attachment_feedback_loop_enabled = false; bool mesh_shader_enabled = false; vk::PhysicalDeviceMeshShaderPropertiesEXT mesh_shader_properties = {}; uint32_t subgroup_size = 0; diff --git a/src/graphics/host_gpu/renderer/image/image.cpp b/src/graphics/host_gpu/renderer/image/image.cpp index c3d947123..7485e2eca 100644 --- a/src/graphics/host_gpu/renderer/image/image.cpp +++ b/src/graphics/host_gpu/renderer/image/image.cpp @@ -54,9 +54,6 @@ namespace { } if (DepthAspectTransferFormat(info.pixel_format) != vk::Format::eUndefined) { usage |= vk::ImageUsageFlagBits::eDepthStencilAttachment; - if (graphics.attachment_feedback_loop_enabled && (usage & vk::ImageUsageFlagBits::eSampled)) { - usage |= vk::ImageUsageFlagBits::eAttachmentFeedbackLoopEXT; - } return usage; } if (HasFormatFeature(properties, vk::FormatFeatureFlagBits::eColorAttachment)) { diff --git a/src/graphics/host_gpu/renderer/pipeline/descriptors.cpp b/src/graphics/host_gpu/renderer/pipeline/descriptors.cpp index 8944ea1d3..f90b7bf90 100644 --- a/src/graphics/host_gpu/renderer/pipeline/descriptors.cpp +++ b/src/graphics/host_gpu/renderer/pipeline/descriptors.cpp @@ -1007,13 +1007,12 @@ void RenderExecutor::CommitBindings(CommandBuffer& buffer, std::ranges::find(image.views, binding.image_view, &CachedImageView::view); EXIT_IF(storage || host_view == image.views.end()); const auto aspect = host_view->info.aspect; - const bool feedback = layout == vk::ImageLayout::eAttachmentFeedbackLoopOptimalEXT; const bool depth_read = - feedback || layout == vk::ImageLayout::eDepthReadOnlyOptimal || + layout == vk::ImageLayout::eDepthReadOnlyOptimal || layout == vk::ImageLayout::eDepthStencilReadOnlyOptimal || layout == vk::ImageLayout::eDepthReadOnlyStencilAttachmentOptimal; const bool stencil_read = - feedback || layout == vk::ImageLayout::eStencilReadOnlyOptimal || + layout == vk::ImageLayout::eStencilReadOnlyOptimal || layout == vk::ImageLayout::eDepthStencilReadOnlyOptimal || layout == vk::ImageLayout::eDepthAttachmentStencilReadOnlyOptimal; if ((aspect & vk::ImageAspectFlagBits::eDepth && !depth_read) || diff --git a/src/graphics/host_gpu/renderer/pipeline/shaders.cpp b/src/graphics/host_gpu/renderer/pipeline/shaders.cpp index 6b949a88d..12ff42ae2 100644 --- a/src/graphics/host_gpu/renderer/pipeline/shaders.cpp +++ b/src/graphics/host_gpu/renderer/pipeline/shaders.cpp @@ -702,7 +702,7 @@ void CreatePipelineInternal( depth_stencil_info.minDepthBounds = static_params.depth_min_bounds; depth_stencil_info.maxDepthBounds = static_params.depth_max_bounds; - std::vector dynamic_states { + const vk::DynamicState dynamic_states[] = { vk::DynamicState::eViewportWithCount, vk::DynamicState::eScissorWithCount, vk::DynamicState::eLineWidth, @@ -715,20 +715,22 @@ void CreatePipelineInternal( vk::DynamicState::eStencilReference, vk::DynamicState::eStencilWriteMask, vk::DynamicState::eBlendConstants, - }; #if !defined(__APPLE__) - if (rendering.color_count != 0) { - dynamic_states.push_back(vk::DynamicState::eColorWriteEnableEXT); + // Keep last so depth-only pipelines can omit this dynamic state. + vk::DynamicState::eColorWriteEnableEXT, // unsupported by MoltenVK; static mask instead +#endif + }; + auto dynamic_states_count = + static_cast(sizeof(dynamic_states) / sizeof(dynamic_states[0])); +#if !defined(__APPLE__) + if (rendering.color_count == 0) { + dynamic_states_count--; } #endif - if (graphics.attachment_feedback_loop_enabled) { - dynamic_states.push_back(vk::DynamicState::eAttachmentFeedbackLoopEnableEXT); - } - const auto dynamic_states_count = static_cast(dynamic_states.size()); vk::PipelineDynamicStateCreateInfo dynamic_state {}; dynamic_state.dynamicStateCount = dynamic_states_count; - dynamic_state.pDynamicStates = dynamic_states.data(); + dynamic_state.pDynamicStates = dynamic_states; vk::GraphicsPipelineCreateInfo pipeline_info {}; vk::PipelineRenderingCreateInfo rendering_info {}; diff --git a/src/graphics/host_gpu/renderer/renderDraw.cpp b/src/graphics/host_gpu/renderer/renderDraw.cpp index 3a9b022a2..07b398233 100644 --- a/src/graphics/host_gpu/renderer/renderDraw.cpp +++ b/src/graphics/host_gpu/renderer/renderDraw.cpp @@ -568,12 +568,7 @@ RenderState RenderExecutor::AcquireRenderTargets(CommandBuffer& buffer, RenderCo EXIT("mixed color/depth sample counts are unsupported: %u and %u\n", attachment_samples, depth.desc.info.samples); } - const bool feedback = image.binding.is_bound && !depth_attachment_read_only(depth); - if (feedback && !m_context.GetGraphics().attachment_feedback_loop_enabled) { - EXIT("depth attachment feedback loop is not supported by the host\n"); - } - const auto layout = feedback ? vk::ImageLayout::eAttachmentFeedbackLoopOptimalEXT - : depth_attachment_layout(depth); + const auto layout = depth_attachment_layout(depth); // The attachment store writes even when guest depth/stencil tests do not. const auto access = vk::AccessFlagBits2::eDepthStencilAttachmentRead | vk::AccessFlagBits2::eDepthStencilAttachmentWrite; @@ -1148,14 +1143,6 @@ void RenderExecutor::ExecutePreparedDraw(uint64_t submit_id, CommandBuffer& buff SetGraphicsDynamicParams(buffer, vk_buffer, state.vs_input_info, state.color_info, state.color_count, state.depth_info); - if (m_context.GetGraphics().attachment_feedback_loop_enabled) { - const auto aspects = - rendering.depth_stencil_attachment.image_layout == - vk::ImageLayout::eAttachmentFeedbackLoopOptimalEXT - ? ImageViewOps::DepthAspectMask(state.depth_info.desc.view_info.format) - : vk::ImageAspectFlags {}; - vk_buffer.setAttachmentFeedbackLoopEnableEXT(aspects); - } LogDrawPhase(draw.name, "BeginRendering"); if (set_auto_debug) { diff --git a/src/graphics/presentation/window/vulkanWindow.cpp b/src/graphics/presentation/window/vulkanWindow.cpp index b0aca8ab8..96707c49f 100644 --- a/src/graphics/presentation/window/vulkanWindow.cpp +++ b/src/graphics/presentation/window/vulkanWindow.cpp @@ -623,22 +623,7 @@ static vk::Device VulkanCreateDevice(vk::PhysicalDevice physical_device, const V supported_features2.sType = vk::StructureType::ePhysicalDeviceFeatures2; supported_features2.pNext = mesh_extension ? static_cast(&supported_mesh) : static_cast(&supported_features13); - const bool feedback_extensions = - HasExtension(device_extensions, VK_EXT_ATTACHMENT_FEEDBACK_LOOP_LAYOUT_EXTENSION_NAME) && - HasExtension(device_extensions, VK_EXT_ATTACHMENT_FEEDBACK_LOOP_DYNAMIC_STATE_EXTENSION_NAME); - vk::PhysicalDeviceAttachmentFeedbackLoopLayoutFeaturesEXT feedback_layout {}; - vk::PhysicalDeviceAttachmentFeedbackLoopDynamicStateFeaturesEXT feedback_dynamic {}; - if (feedback_extensions) { - feedback_dynamic.pNext = supported_features2.pNext; - feedback_layout.pNext = &feedback_dynamic; - supported_features2.pNext = &feedback_layout; - } physical_device.getFeatures2(&supported_features2); - graphics.attachment_feedback_loop_enabled = - feedback_extensions && feedback_layout.attachmentFeedbackLoopLayout && - feedback_dynamic.attachmentFeedbackLoopDynamicState; - LOGF("Vulkan attachment feedback loop: %s\n", - graphics.attachment_feedback_loop_enabled ? "true" : "false"); graphics.mesh_shader_enabled = mesh_extension && supported_mesh.meshShader; if (graphics.mesh_shader_enabled) { vk::PhysicalDeviceProperties2 properties {}; @@ -746,11 +731,6 @@ static vk::Device VulkanCreateDevice(vk::PhysicalDevice physical_device, const V create_info.sType = vk::StructureType::eDeviceCreateInfo; create_info.pNext = mesh_extension ? static_cast(&mesh_features) : static_cast(&features13); - if (graphics.attachment_feedback_loop_enabled) { - feedback_dynamic.pNext = - mesh_extension ? static_cast(&mesh_features) : static_cast(&features13); - create_info.pNext = &feedback_layout; - } create_info.flags = {}; create_info.pQueueCreateInfos = &queue_create_info; create_info.queueCreateInfoCount = 1; @@ -1137,11 +1117,6 @@ void WindowContext::CreateVulkan() { device_extensions.push_back(extension); } } - if (HasExtension(available_extensions, VK_EXT_ATTACHMENT_FEEDBACK_LOOP_LAYOUT_EXTENSION_NAME) && - HasExtension(available_extensions, VK_EXT_ATTACHMENT_FEEDBACK_LOOP_DYNAMIC_STATE_EXTENSION_NAME)) { - device_extensions.push_back(VK_EXT_ATTACHMENT_FEEDBACK_LOOP_LAYOUT_EXTENSION_NAME); - device_extensions.push_back(VK_EXT_ATTACHMENT_FEEDBACK_LOOP_DYNAMIC_STATE_EXTENSION_NAME); - } } VulkanInitSubgroupSizeControl(graphic_ctx.physical_device, graphic_ctx); diff --git a/tests/ShaderRecompilerComputeTests.cpp b/tests/ShaderRecompilerComputeTests.cpp index c57212fe6..01bf9d256 100644 --- a/tests/ShaderRecompilerComputeTests.cpp +++ b/tests/ShaderRecompilerComputeTests.cpp @@ -478,14 +478,6 @@ struct RenderExecutorTestAccess { return pipeline; } - static void CommitBindings(RenderExecutor &executor, CommandBuffer &buffer, - const PipelineCache::Pipeline &pipeline, - PreparedBindings &vertex, PreparedBindings &pixel) { - std::array stages{&vertex, &pixel}; - executor.CommitBindings(buffer, vk::PipelineBindPoint::eGraphics, pipeline, - stages); - } - static void DestroyDescriptorPipelines( RenderExecutor &executor, std::span pipelines) { @@ -1198,7 +1190,6 @@ struct GraphicsCase { vk::SampleCountFlagBits samples = vk::SampleCountFlagBits::e1; bool pixel_position_w = false; float vertex_clip_w = 1.0f; - bool pixel_depth_export = false; }; struct CompiledShader { @@ -1543,7 +1534,6 @@ CompiledShader CompileFragmentCase(const GraphicsCase &test) { pixel_info.ps_ancillary = test.pixel_ancillary; pixel_info.ps_front_face = test.pixel_front_face; pixel_info.ps_pos_w = test.pixel_position_w; - pixel_info.ps_depth_export_enable = test.pixel_depth_export; pixel_info.ps_system_input_base = 2; for (u32 i = 0; i < std::size(pixel_info.interpolator_settings); i++) { pixel_info.interpolator_settings[i] = i; @@ -8107,13 +8097,10 @@ public: } std::vector ReadCachedTexel(const char *name, RenderContext &context, - ImageId id, vk::Offset3D offset = {}, - vk::Extent3D extent = {1, 1, 1}) { + ImageId id, vk::Offset3D offset = {}) { auto &scheduler = context.GetCommandScheduler(); auto &image = context.GetTextureCache().GetImage(id); - const auto bytes = image.info.bytes_per_block * extent.width * - extent.height * extent.depth; - auto probe = CreateHostBuffer(name, bytes, + auto probe = CreateHostBuffer(name, image.info.bytes_per_block, vk::BufferUsageFlagBits::eTransferDst, {}); scheduler.Current().EndRendering(); image.Transit(vk::ImageLayout::eTransferSrcOptimal, @@ -8122,7 +8109,7 @@ public: vk::BufferImageCopy copy{}; copy.imageSubresource = {vk::ImageAspectFlagBits::eColor, 0, 0, 1}; copy.imageOffset = offset; - copy.imageExtent = extent; + copy.imageExtent = vk::Extent3D{1, 1, 1}; scheduler.Current().Handle().copyImageToBuffer( image.backing.image, vk::ImageLayout::eTransferSrcOptimal, probe.buffer, 1, ©); @@ -8138,7 +8125,7 @@ public: vk::PipelineStageFlagBits::eHost, {}, 0, nullptr, 1, &barrier, 0, nullptr); scheduler.Finish(); - auto result = ReadBuffer(name, probe, bytes / 4); + auto result = ReadBuffer(name, probe, image.info.bytes_per_block / 4); DestroyBuffer(&probe); return result; } @@ -11374,12 +11361,9 @@ public: m_device.destroyShaderModule(module, nullptr); } - void CheckRasterization(bool depth_feedback) { - const char *name = depth_feedback ? "DepthAttachmentFeedback" - : "PolygonModeRasterization"; - const uint32_t extent = depth_feedback ? 1 : 32; - constexpr uintptr_t depth_address = 0x0000000204400000ull; - constexpr uint64_t allocation_size = 0x20000; + void CheckPolygonModeRasterization() { + constexpr const char *name = "PolygonModeRasterization"; + constexpr uint32_t extent = 32; EnsureRuntimeContext(); RenderContext context(m_runtime_context); auto &scheduler = context.GetCommandScheduler(); @@ -11388,69 +11372,10 @@ public: HW::Shader shaders{}; registers.SetRenderTargetMask(0xf); scheduler.Begin(registers, user_config, shaders); - auto &resources = context.GetGpuResources(); - auto &cache = context.GetTextureCache(); - auto &executor = context.GetRenderExecutor(); - int64_t direct_offset = -1; - RenderDepthInfo depth{}; - Require(name, "direct allocation", - Libs::LibKernel::Memory::KernelAllocateDirectMemory( - 0, Libs::LibKernel::Memory::KernelGetDirectMemorySize(), - allocation_size, allocation_size, 0, &direct_offset) == 0, - "depth allocation failed"); - void *mapped = reinterpret_cast(depth_address); - Require(name, "direct mapping", - Libs::LibKernel::Memory::KernelMapDirectMemory( - &mapped, allocation_size, 0x3, 0x10, direct_offset, - allocation_size) == 0 && - mapped == reinterpret_cast(depth_address), - "depth mapping failed"); - std::memset(mapped, 0, allocation_size); - const float initial_depth = 0.25f; - std::memcpy(mapped, &initial_depth, sizeof(initial_depth)); - resources.MapMemory(depth_address, allocation_size); - if (depth_feedback) { - depth.desc.type = BindingType::DepthTarget; - depth.desc.info.data = {depth_address, 256}; - depth.desc.info.pixel_format = vk::Format::eD32Sfloat; - depth.desc.info.guest_format = Prospero::BufferFormat::k32Float; - depth.desc.info.extent = {1, 1, 1}; - depth.desc.info.pitch = 64; - depth.desc.info.bytes_per_block = 4; - depth.desc.info.tile_mode = Prospero::TileMode::kLinear; - depth.desc.info.mip_layout[0] = {0, 256, 64, 1}; - depth.desc.view_info.format = depth.desc.info.pixel_format; - depth.desc.view_info.aspect = vk::ImageAspectFlagBits::eDepth; - depth.desc.view_info.usage = vk::ImageUsageFlagBits::eDepthStencilAttachment; - depth.depth_test_enable = depth.depth_write_enable = true; - depth.depth_compare_op = vk::CompareOp::eAlways; - depth.image_id = cache.FindImage(depth.desc); - } GraphicsCase test; test.name = name; - test.pixel_depth_export = depth_feedback; - if (depth_feedback) { - const ShaderTextureResource descriptor{{ - static_cast(depth_address >> 8u), - static_cast(Prospero::BufferFormat::k32Float) << 20u, 0, - DstSel(4, 4, 4, 4) | - (static_cast(Prospero::ImageType::kColor2D) << 28u), - 0, 0, 0, 0}}; - test.has_user_data = true; - std::copy_n(descriptor.fields, 8, test.user_data.begin()); - // One texel and one fragment: the sample is the current attachment pixel. - AppendVMovLiteral(&test.fragment_code, 20, 0x3f000000u); - AppendVMovLiteral(&test.fragment_code, 21, 0x3f000000u); - test.fragment_code.push_back(EncodeMimg0(0x27, 1)); - test.fragment_code.push_back(EncodeMimg1(0, 20, 0, 2)); - AppendVMovLiteral(&test.fragment_code, 1, 0x3e800000u); - test.fragment_code.push_back(EncodeVop2(0x03, 1, Vgpr(0), 1)); - test.fragment_code.push_back(EncodeExp0(0x08, 0x1, false)); - test.fragment_code.push_back(EncodeExp1(1, 1, 1, 1)); - } else { - AppendVMovLiteral(&test.fragment_code, 0, 0x3f800000u); - } + AppendVMovLiteral(&test.fragment_code, 0, 0x3f800000u); test.fragment_code.push_back(EncodeExp0(0x00, 0xf)); test.fragment_code.push_back(EncodeExp1(0, 0, 0, 0)); AppendEnd(&test.fragment_code); @@ -11483,12 +11408,8 @@ public: } ShaderPixelInputInfo pixel{}; pixel.stage.program = &pixel_program; - pixel.stage.resources = std::move(fragment.resources); RenderColorInfo color{}; - color.desc.type = BindingType::RenderTarget; - color.desc.info.data = {depth_address + 0x10000, extent * extent * 16}; - color.desc.info.mip_layout[0] = {0, color.desc.info.data.size, extent, extent}; color.desc.info.pixel_format = vk::Format::eR32G32B32A32Sfloat; color.desc.info.guest_format = Prospero::BufferFormat::k32_32_32_32Float; color.desc.info.extent = {extent, extent, 1}; @@ -11496,7 +11417,14 @@ public: color.desc.info.bytes_per_block = 16; color.desc.view_info.format = color.desc.info.pixel_format; color.desc.view_info.usage = vk::ImageUsageFlagBits::eColorAttachment; - color.image_id = cache.FindImage(color.desc); + auto &cache = context.GetTextureCache(); + color.image_id = TextureCacheTestAccess::InsertImage(cache, color.desc.info); + auto &native = cache.GetImage(color.image_id); + Image target{}; + target.image = native.backing.image; + target.view = native.FindView(color.desc.view_info); + target.width = target.height = extent; + target.dwords_per_pixel = 4; const std::array vertices{ -0.75f, -0.75f, 1, 1, 1, 1, 0.75f, -0.75f, 1, 1, 1, 1, 0.0f, 0.75f, 1, 1, 1, 1}; @@ -11511,89 +11439,64 @@ public: mode.polymode_back_ptype = back; registers.SetModeControl(mode); return context.GetPipelineCache().CreateGraphicsPipeline( - std::span{&color, 1u}, depth, vertex, scheduler.Current(), &pixel, + std::span{&color, 1u}, {}, vertex, scheduler.Current(), &pixel, vk::PrimitiveTopology::eTriangleList, false, vertex_shader, pixel_shader); }; auto &filled = pipeline(true, 2, 2); + auto &wireframe = pipeline(true, 1, 1); + Require(name, "pipeline cache", filled.pipeline != wireframe.pipeline && + pipeline(true, 2, 2).pipeline == filled.pipeline && + pipeline(false, 1, 0).pipeline == filled.pipeline, + "polygon mode was lost from the cache key or dormant face modes were applied"); const auto draw = [&](const PipelineCache::Pipeline &selected) { - RenderExecutorTestAccess::BindRenderTarget(executor, color.image_id); - if (depth.image_id) { - RenderExecutorTestAccess::BindRenderTarget(executor, depth.image_id); - } - auto bindings = RenderExecutorTestAccess::PrepareGraphicsBindings( - executor, vertex.stage, pixel.stage, true); - Require(name, "sampled attachment identity", - !depth_feedback || bindings.pixel->images[0].image_id == depth.image_id, - "the fragment must sample the depth attachment's native image"); - auto &command = scheduler.Current(); - auto rendering = RenderExecutorTestAccess::AcquireRenderTargets( - executor, command, &color, 1, depth); - RenderExecutorTestAccess::CommitBindings( - executor, command, selected, bindings.vertex, *bindings.pixel); - rendering.color_attachments[0].is_clear = true; - command.BeginRendering(rendering); - auto cmd = command.Handle(); + auto cmd = BeginCommands(name, "rasterization"); + AddImageBarrier(cmd, target.image, target.layout, vk::ImageLayout::eGeneral, + vk::PipelineStageFlagBits::eAllCommands, + vk::PipelineStageFlagBits::eColorAttachmentOutput, + vk::AccessFlagBits::eMemoryRead | vk::AccessFlagBits::eMemoryWrite, + vk::AccessFlagBits::eColorAttachmentWrite); + vk::RenderingAttachmentInfo attachment{}; + attachment.imageView = target.view; + attachment.imageLayout = vk::ImageLayout::eGeneral; + attachment.loadOp = vk::AttachmentLoadOp::eClear; + attachment.storeOp = vk::AttachmentStoreOp::eStore; + vk::RenderingInfo rendering{}; + rendering.renderArea.extent = {extent, extent}; + rendering.layerCount = 1; + rendering.colorAttachmentCount = 1; + rendering.pColorAttachments = &attachment; + cmd.beginRendering(rendering); cmd.bindPipeline(vk::PipelineBindPoint::eGraphics, selected.pipeline); - const vk::Viewport viewport{0, 0, static_cast(extent), - static_cast(extent), 0, 1}; + const vk::Viewport viewport{0, 0, extent, extent, 0, 1}; const vk::Rect2D scissor{{0, 0}, {extent, extent}}; cmd.setViewportWithCount(1, &viewport); cmd.setScissorWithCount(1, &scissor); cmd.setLineWidth(1); - cmd.setDepthTestEnable(depth.depth_test_enable); - cmd.setDepthWriteEnable(depth.depth_write_enable); + cmd.setDepthTestEnable(false); + cmd.setDepthWriteEnable(false); cmd.setDepthCompareOp(vk::CompareOp::eAlways); cmd.setDepthBiasEnable(false); const vk::Bool32 write = true; cmd.setColorWriteEnableEXT(1, &write); - cmd.setAttachmentFeedbackLoopEnableEXT( - depth_feedback ? vk::ImageAspectFlags{vk::ImageAspectFlagBits::eDepth} - : vk::ImageAspectFlags{}); const vk::DeviceSize offset = 0; cmd.bindVertexBuffers(0, 1, &buffer.buffer, &offset); cmd.draw(3, 1, 0, 0); - command.EndRendering(); - RenderExecutorTestAccess::ResetBindings(executor); + cmd.endRendering(); + EndSubmitAndFree(name, "rasterization", cmd); + target.layout = vk::ImageLayout::eGeneral; + return ReadImage(name, &target); }; - const auto read_color = [&] { - return ReadCachedTexel(name, context, color.image_id, {}, {extent, extent, 1}); - }; - draw(filled); - const auto solid_pixels = read_color(); - if (depth_feedback) { - Require(name, "initial depth sample", solid_pixels[0] == 0x3e800000u, - "the first fragment did not sample the attachment's initial depth"); - // Consecutive draws in the same submission must see each earlier depth write. - draw(filled); - draw(filled); - const auto repeated_pixels = read_color(); - Require(name, "repeated depth writes", repeated_pixels[0] == 0x3f400000u, - "depth feedback expected 0.75, received " + - std::to_string(std::bit_cast(repeated_pixels[0]))); - } else { - auto &wireframe = pipeline(true, 1, 1); - Require(name, "pipeline cache", filled.pipeline != wireframe.pipeline && - pipeline(true, 2, 2).pipeline == filled.pipeline && - pipeline(false, 1, 0).pipeline == filled.pipeline, - "polygon mode was lost from the cache key or dormant face modes were applied"); - draw(wireframe); - const auto line_pixels = read_color(); - const auto interior = 4 * (16 * extent + 16); - Require(name, "GPU coverage", solid_pixels[interior] == 0x3f800000u && - line_pixels[interior] == 0 && - std::ranges::any_of(line_pixels, [](u32 value) { return value == 0x3f800000u; }), - "wireframe did not preserve triangle edges while leaving its interior empty"); - } - resources.UnmapMemory(depth_address, allocation_size); + const auto solid_pixels = draw(filled); + const auto line_pixels = draw(wireframe); + const auto interior = 4 * (16 * extent + 16); + Require(name, "GPU coverage", solid_pixels[interior] == 0x3f800000u && + line_pixels[interior] == 0 && + std::ranges::any_of(line_pixels, [](u32 value) { return value == 0x3f800000u; }), + "wireframe did not preserve triangle edges while leaving its interior empty"); scheduler.Finish(); DestroyBuffer(&buffer); m_device.destroyShaderModule(pixel_shader.module); m_device.destroyShaderModule(vertex_shader.module); - Require(name, "release depth memory", - Libs::LibKernel::Memory::KernelMunmap(depth_address, allocation_size) == 0 && - Libs::LibKernel::Memory::KernelReleaseDirectMemory( - direct_offset, allocation_size) == 0, - "depth mapping or allocation release failed"); std::printf("[gpu] %-32s ok\n", name); } @@ -12893,7 +12796,6 @@ private: m_runtime_context.physical_device_memory_properties = m_memory_properties; m_runtime_context.queue_family = m_queue_family; m_runtime_context.queue = m_queue; - m_runtime_context.attachment_feedback_loop_enabled = true; VmaVulkanFunctions functions{}; functions.vkGetInstanceProcAddr = @@ -13002,13 +12904,9 @@ private: available_clip_control.pNext = &available_depth_clip; vk::PhysicalDeviceColorWriteEnableFeaturesEXT available_color_write{}; available_color_write.pNext = &available_clip_control; - vk::PhysicalDeviceAttachmentFeedbackLoopLayoutFeaturesEXT available_feedback_layout{}; - available_feedback_layout.pNext = &available_color_write; - vk::PhysicalDeviceAttachmentFeedbackLoopDynamicStateFeaturesEXT available_feedback_dynamic{}; - available_feedback_dynamic.pNext = &available_feedback_layout; vk::PhysicalDeviceFeatures2 available_features2{}; available_features2.sType = vk::StructureType::ePhysicalDeviceFeatures2; - available_features2.pNext = &available_feedback_dynamic; + available_features2.pNext = &available_color_write; m_physical_device.getFeatures2(&available_features2); Require("VulkanHarness", "dispatch", available_features.shaderStorageImageWriteWithoutFormat == true, @@ -13038,9 +12936,7 @@ private: "vertex layer output is not supported"); Require("VulkanHarness", "graphics", available_features.fillModeNonSolid && available_depth_clip.depthClipEnable && available_clip_control.depthClipControl && - available_color_write.colorWriteEnable && - available_feedback_layout.attachmentFeedbackLoopLayout && - available_feedback_dynamic.attachmentFeedbackLoopDynamicState, + available_color_write.colorWriteEnable, "production rasterization features are not supported"); float priority = 1.0f; @@ -13082,13 +12978,7 @@ private: vk::PhysicalDeviceColorWriteEnableFeaturesEXT color_write{}; color_write.pNext = &clip_control; color_write.colorWriteEnable = true; - vk::PhysicalDeviceAttachmentFeedbackLoopLayoutFeaturesEXT feedback_layout{}; - feedback_layout.pNext = &color_write; - feedback_layout.attachmentFeedbackLoopLayout = true; - vk::PhysicalDeviceAttachmentFeedbackLoopDynamicStateFeaturesEXT feedback_dynamic{}; - feedback_dynamic.pNext = &feedback_layout; - feedback_dynamic.attachmentFeedbackLoopDynamicState = true; - device_info.pNext = &feedback_dynamic; + device_info.pNext = &color_write; vk::PhysicalDeviceFeatures device_features{}; device_features.shaderStorageImageWriteWithoutFormat = true; device_features.shaderImageGatherExtended = true; @@ -13102,9 +12992,7 @@ private: VK_KHR_FRAGMENT_SHADER_BARYCENTRIC_EXTENSION_NAME, VK_EXT_DEPTH_CLIP_ENABLE_EXTENSION_NAME, VK_EXT_DEPTH_CLIP_CONTROL_EXTENSION_NAME, - VK_EXT_COLOR_WRITE_ENABLE_EXTENSION_NAME, - VK_EXT_ATTACHMENT_FEEDBACK_LOOP_LAYOUT_EXTENSION_NAME, - VK_EXT_ATTACHMENT_FEEDBACK_LOOP_DYNAMIC_STATE_EXTENSION_NAME}; + VK_EXT_COLOR_WRITE_ENABLE_EXTENSION_NAME}; device_info.enabledExtensionCount = std::size(device_extensions); device_info.ppEnabledExtensionNames = device_extensions; RequireVk("VulkanHarness", "dispatch", @@ -28228,7 +28116,7 @@ int main(int argc, char **argv) { CheckDepthAttachmentWrites(); CheckDynamicRenderingState(); VulkanHarness vulkan; - vulkan.CheckRasterization(false); + vulkan.CheckPolygonModeRasterization(); vulkan.CheckRenderExecutorColor1DDiscovery(); vulkan.CheckRenderExecutorColorVolumeDiscovery(); vulkan.CheckRenderExecutorDccFixedClearFloat(); @@ -28241,7 +28129,7 @@ int main(int argc, char **argv) { } if (argc == 2 && std::strcmp(argv[1], "--polygon-mode-only") == 0) { VulkanHarness vulkan; - vulkan.CheckRasterization(false); + vulkan.CheckPolygonModeRasterization(); return 0; } if (argc == 2 && std::strcmp(argv[1], "--htile-clear-only") == 0) { @@ -28293,7 +28181,6 @@ int main(int argc, char **argv) { CheckSampledDepthResource(); CheckDepthTextureEncoding(vulkan.RuntimeRenderer()); vulkan.CheckComparisonDepthTexture(); - vulkan.CheckRasterization(true); RunCase(nullptr, ImageSampleA16CompareBiasRdna2AddressOrder()); return 0; } @@ -28374,7 +28261,6 @@ int main(int argc, char **argv) { CheckSampledDepthResource(); CheckDepthTextureEncoding(vulkan.RuntimeRenderer()); vulkan.CheckComparisonDepthTexture(); - vulkan.CheckRasterization(true); CheckBasicStorageTextureDescriptor(); CheckStorageTextureLinearUploadLayout(); CheckStorageTextureDepthTileUploadLayout(); @@ -28443,7 +28329,7 @@ int main(int argc, char **argv) { vulkan.CheckRenderExecutorStencilBindingDiscovery(); vulkan.CheckUnifiedTextureCacheFlow(); vulkan.CheckBgra16Readback(); - vulkan.CheckRasterization(false); + vulkan.CheckPolygonModeRasterization(); vulkan.CheckBufferCacheDirtyGarbageCollection(); #endif vulkan.CheckUnifiedImageViewCache();