[vk, rasterizer] Update sample location handling for MSAA configurations
This commit is contained in:
parent
75bfe1b4d8
commit
3b91d0b146
|
|
@ -765,13 +765,17 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) {
|
|||
key.state.alpha_to_one_enabled != 0 ? VK_TRUE : VK_FALSE,
|
||||
};
|
||||
|
||||
std::array<VkSampleLocationEXT, 16> default_sample_locations{};
|
||||
const auto [sample_grid_width, sample_grid_height] =
|
||||
VideoCommon::SampleLocationGridSize(msaa_mode);
|
||||
const u32 sample_count = static_cast<u32>(VideoCommon::NumSamples(msaa_mode));
|
||||
const u32 total_sample_locations = sample_count * sample_grid_width * sample_grid_height;
|
||||
std::array<VkSampleLocationEXT, VideoCommon::MaxSampleLocationSlots> default_sample_locations{};
|
||||
VkSampleLocationsInfoEXT sample_locations_info{
|
||||
.sType = VK_STRUCTURE_TYPE_SAMPLE_LOCATIONS_INFO_EXT,
|
||||
.pNext = nullptr,
|
||||
.sampleLocationsPerPixel = vk_samples,
|
||||
.sampleLocationGridSize = {1u, 1u},
|
||||
.sampleLocationsCount = static_cast<u32>(VideoCommon::NumSamples(msaa_mode)),
|
||||
.sampleLocationGridSize = {sample_grid_width, sample_grid_height},
|
||||
.sampleLocationsCount = total_sample_locations,
|
||||
.pSampleLocations = default_sample_locations.data(),
|
||||
};
|
||||
VkPipelineSampleLocationsStateCreateInfoEXT sample_locations_ci{
|
||||
|
|
@ -780,7 +784,7 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) {
|
|||
.sampleLocationsEnable = VK_FALSE,
|
||||
.sampleLocationsInfo = sample_locations_info,
|
||||
};
|
||||
if (device.IsExtSampleLocationsSupported() && sample_locations_info.sampleLocationsCount > 1 &&
|
||||
if (device.IsExtSampleLocationsSupported() && total_sample_locations > 0 &&
|
||||
device.SupportsSampleLocationsFor(vk_samples)) {
|
||||
sample_locations_ci.sampleLocationsEnable = VK_TRUE;
|
||||
sample_locations_ci.pNext = std::exchange(multisample_ci.pNext, &sample_locations_ci);
|
||||
|
|
|
|||
|
|
@ -1373,39 +1373,44 @@ void RasterizerVulkan::UpdateSampleLocations(Tegra::Engines::Maxwell3D::Regs& re
|
|||
|
||||
const auto msaa_mode = regs.anti_alias_samples_mode;
|
||||
const u32 sample_count = static_cast<u32>(VideoCommon::NumSamples(msaa_mode));
|
||||
if (sample_count <= 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
const VkSampleCountFlagBits vk_samples = MaxwellToVK::MsaaMode(msaa_mode);
|
||||
if (!device.SupportsSampleLocationsFor(vk_samples)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto [grid_width, grid_height] = VideoCommon::SampleLocationGridSize(msaa_mode);
|
||||
const u32 total_locations = sample_count * grid_width * grid_height;
|
||||
if (total_locations == 0 || total_locations > VideoCommon::MaxSampleLocationSlots) {
|
||||
LOG_WARNING(Render_Vulkan, "Unsupported sample-location grid configuration: samples={}, grid={}x{}",
|
||||
sample_count, grid_width, grid_height);
|
||||
return;
|
||||
}
|
||||
|
||||
const auto& props = device.SampleLocationProperties();
|
||||
std::array<VkSampleLocationEXT, 16> locations{};
|
||||
std::array<VkSampleLocationEXT, VideoCommon::MaxSampleLocationSlots> locations{};
|
||||
constexpr float unit = 1.0f / 16.0f;
|
||||
const auto clamp_coord = [&](float coord) {
|
||||
return std::clamp(coord, props.sampleLocationCoordinateRange[0],
|
||||
props.sampleLocationCoordinateRange[1]);
|
||||
};
|
||||
|
||||
for (u32 sample_index = 0; sample_index < sample_count; ++sample_index) {
|
||||
const auto& packed = regs.multisample_sample_locations[sample_index / 4];
|
||||
const auto [raw_x, raw_y] = packed.Location(sample_index % 4);
|
||||
for (u32 index = 0; index < total_locations; ++index) {
|
||||
const auto& packed = regs.multisample_sample_locations[index / 4];
|
||||
const auto [raw_x, raw_y] = packed.Location(index % 4);
|
||||
const float offset_x = static_cast<float>(static_cast<int>(raw_x) - 8);
|
||||
const float offset_y = static_cast<float>(static_cast<int>(raw_y) - 8);
|
||||
const float x = clamp_coord(offset_x * unit);
|
||||
const float y = clamp_coord(offset_y * unit);
|
||||
locations[sample_index] = VkSampleLocationEXT{.x = x, .y = y};
|
||||
locations[index] = VkSampleLocationEXT{.x = x, .y = y};
|
||||
}
|
||||
|
||||
VkSampleLocationsInfoEXT info{
|
||||
.sType = VK_STRUCTURE_TYPE_SAMPLE_LOCATIONS_INFO_EXT,
|
||||
.pNext = nullptr,
|
||||
.sampleLocationsPerPixel = vk_samples,
|
||||
.sampleLocationGridSize = {1u, 1u},
|
||||
.sampleLocationsCount = sample_count,
|
||||
.sampleLocationGridSize = {grid_width, grid_height},
|
||||
.sampleLocationsCount = total_locations,
|
||||
.pSampleLocations = nullptr,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,15 +1,22 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
#include <utility>
|
||||
|
||||
#include "common/assert.h"
|
||||
#include "common/common_types.h"
|
||||
#include "video_core/textures/texture.h"
|
||||
|
||||
namespace VideoCommon {
|
||||
|
||||
constexpr inline std::size_t MaxSampleLocationSlots = 16;
|
||||
|
||||
[[nodiscard]] inline std::pair<int, int> SamplesLog2(int num_samples) {
|
||||
switch (num_samples) {
|
||||
case 1:
|
||||
|
|
@ -95,4 +102,24 @@ namespace VideoCommon {
|
|||
return 1;
|
||||
}
|
||||
|
||||
// NVN guarantees up to sixteen programmable sample slots shared across a repeating pixel grid
|
||||
// (per the 0.7.0 addon release notes), so the grid dimensions shrink as MSAA increases.
|
||||
[[nodiscard]] inline std::pair<u32, u32> SampleLocationGridSize(Tegra::Texture::MsaaMode msaa_mode) {
|
||||
const int samples = NumSamples(msaa_mode);
|
||||
switch (samples) {
|
||||
case 1:
|
||||
return {4u, 4u};
|
||||
case 2:
|
||||
return {4u, 2u};
|
||||
case 4:
|
||||
return {2u, 2u};
|
||||
case 8:
|
||||
return {2u, 1u};
|
||||
case 16:
|
||||
return {1u, 1u};
|
||||
}
|
||||
ASSERT_MSG(false, "Unsupported sample count for grid size={}", samples);
|
||||
return {1u, 1u};
|
||||
}
|
||||
|
||||
} // namespace VideoCommon
|
||||
|
|
|
|||
Loading…
Reference in New Issue