[gl, vk, spv] Added component type handling for texture buffers and resolve pixel format variants

This commit is contained in:
CamilleLaVey 2025-11-30 17:41:38 -04:00 committed by lizzie
parent 69f6a0573c
commit 7786d69036
10 changed files with 372 additions and 5 deletions

View file

@ -23,6 +23,7 @@
#include "video_core/vulkan_common/vulkan_wrapper.h"
#include "video_core/gpu_logging/gpu_logging.h"
#include "common/settings.h"
#include <optional>
namespace Vulkan {
@ -43,6 +44,38 @@ ComputePipeline::ComputePipeline(const Device& device_, vk::PipelineCache& pipel
if (shader_notify) {
shader_notify->MarkShaderBuilding();
}
std::optional<VideoCore::Surface::PixelFormatNumeric>
NumericFromComponentType(Shader::SamplerComponentType component_type) {
using VideoCore::Surface::PixelFormatNumeric;
switch (component_type) {
case Shader::SamplerComponentType::Float:
return PixelFormatNumeric::Float;
case Shader::SamplerComponentType::Sint:
return PixelFormatNumeric::Sint;
case Shader::SamplerComponentType::Uint:
return PixelFormatNumeric::Uint;
default:
return std::nullopt;
}
}
VideoCore::Surface::PixelFormat ResolveTexelBufferFormat(
VideoCore::Surface::PixelFormat format, Shader::SamplerComponentType component_type) {
const auto desired_numeric = NumericFromComponentType(component_type);
if (!desired_numeric) {
return format;
}
const auto current_numeric = VideoCore::Surface::GetPixelFormatNumericType(format);
if (*desired_numeric == current_numeric) {
return format;
}
if (const auto variant =
VideoCore::Surface::FindPixelFormatVariant(format, *desired_numeric)) {
return *variant;
}
return format;
}
std::copy_n(info.constant_buffer_used_sizes.begin(), uniform_buffer_sizes.size(),
uniform_buffer_sizes.begin());
@ -193,8 +226,12 @@ void ComputePipeline::Configure(Tegra::Engines::KeplerCompute& kepler_compute,
is_written = desc.is_written;
}
ImageView& image_view = texture_cache.GetImageView(views[index].id);
VideoCore::Surface::PixelFormat buffer_format = image_view.format;
if constexpr (!is_image) {
buffer_format = ResolveTexelBufferFormat(buffer_format, desc.component_type);
}
buffer_cache.BindComputeTextureBuffer(index, image_view.GpuAddr(),
image_view.BufferSize(), image_view.format,
image_view.BufferSize(), buffer_format,
is_written, is_image);
++index;
}

View file

@ -6,6 +6,7 @@
#include <algorithm>
#include <array>
#include <optional>
#include <iostream>
#include <span>
@ -65,6 +66,37 @@ DescriptorLayoutBuilder MakeBuilder(const Device& device, std::span<const Shader
};
builder.Add(infos[index], stages.at(index));
}
std::optional<VideoCore::Surface::PixelFormatNumeric>
NumericFromComponentType(Shader::SamplerComponentType component_type) {
using VideoCore::Surface::PixelFormatNumeric;
switch (component_type) {
case Shader::SamplerComponentType::Float:
return PixelFormatNumeric::Float;
case Shader::SamplerComponentType::Sint:
return PixelFormatNumeric::Sint;
case Shader::SamplerComponentType::Uint:
return PixelFormatNumeric::Uint;
default:
return std::nullopt;
}
}
VideoCore::Surface::PixelFormat ResolveTexelBufferFormat(
VideoCore::Surface::PixelFormat format, Shader::SamplerComponentType component_type) {
const auto desired_numeric = NumericFromComponentType(component_type);
if (!desired_numeric) {
return format;
}
const auto current_numeric = VideoCore::Surface::GetPixelFormatNumericType(format);
if (*desired_numeric == current_numeric) {
return format;
}
if (const auto variant =
VideoCore::Surface::FindPixelFormatVariant(format, *desired_numeric)) {
return *variant;
}
return format;
}
return builder;
}
@ -428,8 +460,12 @@ bool GraphicsPipeline::ConfigureImpl(bool is_indexed) {
is_written = desc.is_written;
}
ImageView& image_view{texture_cache.GetImageView(texture_buffer_it->id)};
VideoCore::Surface::PixelFormat buffer_format = image_view.format;
if constexpr (!is_image) {
buffer_format = ResolveTexelBufferFormat(buffer_format, desc.component_type);
}
buffer_cache.BindGraphicsTextureBuffer(stage, index, image_view.GpuAddr(),
image_view.BufferSize(), image_view.format,
image_view.BufferSize(), buffer_format,
is_written, is_image);
++index;
++texture_buffer_it;

View file

@ -50,6 +50,7 @@ using VideoCore::Surface::HasAlpha;
using VideoCore::Surface::IsPixelFormatASTC;
using VideoCore::Surface::IsPixelFormatInteger;
using VideoCore::Surface::SurfaceType;
using VideoCore::Surface::PixelFormatNumeric;
namespace {
constexpr VkBorderColor ConvertBorderColor(const std::array<float, 4>& color) {
@ -2398,6 +2399,19 @@ std::optional<u32> ImageView::LayerCountOverride(Shader::TextureType texture_typ
default:
return std::nullopt;
}
std::optional<PixelFormatNumeric> ComponentNumericType(Shader::SamplerComponentType component) {
switch (component) {
case Shader::SamplerComponentType::Float:
return PixelFormatNumeric::Float;
case Shader::SamplerComponentType::Sint:
return PixelFormatNumeric::Sint;
case Shader::SamplerComponentType::Uint:
return PixelFormatNumeric::Uint;
default:
return std::nullopt;
}
}
}
VkImageView ImageView::DepthView() {
@ -2465,7 +2479,29 @@ VkImageView ImageView::SampledView(Shader::TextureType texture_type,
default:
break;
}
return Handle(texture_type);
const auto desired_numeric = ComponentNumericType(component_type);
if (!desired_numeric) {
return Handle(texture_type);
}
const PixelFormatNumeric current_numeric =
VideoCore::Surface::GetPixelFormatNumericType(format);
if (*desired_numeric == current_numeric) {
return Handle(texture_type);
}
const auto remapped_format =
VideoCore::Surface::FindPixelFormatVariant(format, *desired_numeric);
if (!remapped_format) {
return Handle(texture_type);
}
auto& cached_view = sampled_component_views[static_cast<size_t>(*desired_numeric)]
[static_cast<size_t>(texture_type)];
if (cached_view) {
return *cached_view;
}
const auto& info =
MaxwellToVK::SurfaceFormat(*device, FormatType::Optimal, true, *remapped_format);
cached_view = MakeView(info.format, VK_IMAGE_ASPECT_COLOR_BIT, texture_type);
return *cached_view;
}
VkImageView ImageView::StorageView(Shader::TextureType texture_type,