Browse Source

[vk, rasterizer] Update sample location handling for MSAA configurations

eds-true-adreno-fixes
CamilleLaVey 4 weeks ago
committed by Caio Oliveira
parent
commit
aff095523d
No known key found for this signature in database GPG Key ID: AAAE6C7FD4186B0C
  1. 12
      src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp
  2. 25
      src/video_core/renderer_vulkan/vk_rasterizer.cpp
  3. 27
      src/video_core/texture_cache/samples_helper.h

12
src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp

@ -797,13 +797,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{
@ -812,7 +816,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);

25
src/video_core/renderer_vulkan/vk_rasterizer.cpp

@ -1384,39 +1384,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,
};

27
src/video_core/texture_cache/samples_helper.h

@ -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…
Cancel
Save