mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-06-13 22:23:15 +00:00
Provide custom border color to samplers (#3014)
Some checks are pending
Build and Release / reuse (push) Waiting to run
Build and Release / clang-format (push) Waiting to run
Build and Release / get-info (push) Waiting to run
Build and Release / windows-sdl (push) Blocked by required conditions
Build and Release / windows-qt (push) Blocked by required conditions
Build and Release / macos-sdl (push) Blocked by required conditions
Build and Release / macos-qt (push) Blocked by required conditions
Build and Release / linux-sdl (push) Blocked by required conditions
Build and Release / linux-qt (push) Blocked by required conditions
Build and Release / linux-sdl-gcc (push) Blocked by required conditions
Build and Release / linux-qt-gcc (push) Blocked by required conditions
Build and Release / pre-release (push) Blocked by required conditions
Some checks are pending
Build and Release / reuse (push) Waiting to run
Build and Release / clang-format (push) Waiting to run
Build and Release / get-info (push) Waiting to run
Build and Release / windows-sdl (push) Blocked by required conditions
Build and Release / windows-qt (push) Blocked by required conditions
Build and Release / macos-sdl (push) Blocked by required conditions
Build and Release / macos-qt (push) Blocked by required conditions
Build and Release / linux-sdl (push) Blocked by required conditions
Build and Release / linux-qt (push) Blocked by required conditions
Build and Release / linux-sdl-gcc (push) Blocked by required conditions
Build and Release / linux-qt-gcc (push) Blocked by required conditions
Build and Release / pre-release (push) Blocked by required conditions
This commit is contained in:
parent
790b54bf29
commit
4019319d92
6 changed files with 53 additions and 8 deletions
|
@ -608,6 +608,16 @@ struct Liverpool {
|
|||
}
|
||||
};
|
||||
|
||||
struct BorderColorBufferBase {
|
||||
u32 base_addr_lo;
|
||||
BitField<0, 8, u32> base_addr_hi;
|
||||
|
||||
template <typename T = VAddr>
|
||||
T Address() const {
|
||||
return std::bit_cast<T>(u64(base_addr_hi) << 40 | u64(base_addr_lo) << 8);
|
||||
}
|
||||
};
|
||||
|
||||
struct IndexBufferBase {
|
||||
BitField<0, 8, u32> base_addr_hi;
|
||||
u32 base_addr_lo;
|
||||
|
@ -1299,7 +1309,9 @@ struct Liverpool {
|
|||
Scissor screen_scissor;
|
||||
INSERT_PADDING_WORDS(0xA010 - 0xA00C - 2);
|
||||
DepthBuffer depth_buffer;
|
||||
INSERT_PADDING_WORDS(0xA080 - 0xA018);
|
||||
INSERT_PADDING_WORDS(8);
|
||||
BorderColorBufferBase ta_bc_base;
|
||||
INSERT_PADDING_WORDS(0xA080 - 0xA020 - 2);
|
||||
WindowOffset window_offset;
|
||||
ViewportScissor window_scissor;
|
||||
INSERT_PADDING_WORDS(0xA08E - 0xA081 - 2);
|
||||
|
@ -1626,6 +1638,7 @@ static_assert(GFX6_3D_REG_INDEX(depth_htile_data_base) == 0xA005);
|
|||
static_assert(GFX6_3D_REG_INDEX(screen_scissor) == 0xA00C);
|
||||
static_assert(GFX6_3D_REG_INDEX(depth_buffer.z_info) == 0xA010);
|
||||
static_assert(GFX6_3D_REG_INDEX(depth_buffer.depth_slice) == 0xA017);
|
||||
static_assert(GFX6_3D_REG_INDEX(ta_bc_base) == 0xA020);
|
||||
static_assert(GFX6_3D_REG_INDEX(window_offset) == 0xA080);
|
||||
static_assert(GFX6_3D_REG_INDEX(window_scissor) == 0xA081);
|
||||
static_assert(GFX6_3D_REG_INDEX(color_target_mask) == 0xA08E);
|
||||
|
|
|
@ -716,7 +716,7 @@ void Rasterizer::BindTextures(const Shader::Info& stage, Shader::Backend::Bindin
|
|||
ssharp.max_aniso.Assign(AmdGpu::AnisoRatio::One);
|
||||
}
|
||||
}
|
||||
const auto vk_sampler = texture_cache.GetSampler(ssharp);
|
||||
const auto vk_sampler = texture_cache.GetSampler(ssharp, liverpool->regs.ta_bc_base);
|
||||
image_infos.emplace_back(vk_sampler, VK_NULL_HANDLE, vk::ImageLayout::eGeneral);
|
||||
set_writes.push_back({
|
||||
.dstSet = VK_NULL_HANDLE,
|
||||
|
|
|
@ -9,7 +9,8 @@
|
|||
|
||||
namespace VideoCore {
|
||||
|
||||
Sampler::Sampler(const Vulkan::Instance& instance, const AmdGpu::Sampler& sampler) {
|
||||
Sampler::Sampler(const Vulkan::Instance& instance, const AmdGpu::Sampler& sampler,
|
||||
const AmdGpu::Liverpool::BorderColorBufferBase& border_color_base) {
|
||||
if (sampler.force_degamma) {
|
||||
LOG_WARNING(Render_Vulkan, "Texture requires gamma correction");
|
||||
}
|
||||
|
@ -20,7 +21,33 @@ Sampler::Sampler(const Vulkan::Instance& instance, const AmdGpu::Sampler& sample
|
|||
const float maxAnisotropy =
|
||||
anisotropyEnable ? std::clamp(sampler.MaxAniso(), 1.0f, instance.MaxSamplerAnisotropy())
|
||||
: 1.0f;
|
||||
auto borderColor = LiverpoolToVK::BorderColor(sampler.border_color_type);
|
||||
if (!instance.IsCustomBorderColorSupported()) {
|
||||
LOG_WARNING(Render_Vulkan, "Custom border color is not supported, falling back to black");
|
||||
borderColor = vk::BorderColor::eFloatOpaqueBlack;
|
||||
}
|
||||
|
||||
const auto customColor = [&]() -> std::optional<vk::SamplerCustomBorderColorCreateInfoEXT> {
|
||||
if (borderColor == vk::BorderColor::eFloatCustomEXT) {
|
||||
const auto borderColorIndex = sampler.border_color_ptr.Value();
|
||||
const auto borderColorBuffer = border_color_base.Address<std::array<float, 4>*>();
|
||||
const auto customBorderColorArray = borderColorBuffer[borderColorIndex];
|
||||
|
||||
const vk::SamplerCustomBorderColorCreateInfoEXT ret{
|
||||
.customBorderColor =
|
||||
vk::ClearColorValue{
|
||||
.float32 = customBorderColorArray,
|
||||
},
|
||||
.format = vk::Format::eR32G32B32A32Sfloat,
|
||||
};
|
||||
return ret;
|
||||
} else {
|
||||
return std::nullopt;
|
||||
}
|
||||
}();
|
||||
|
||||
const vk::SamplerCreateInfo sampler_ci = {
|
||||
.pNext = customColor ? &*customColor : nullptr,
|
||||
.magFilter = LiverpoolToVK::Filter(sampler.xy_mag_filter),
|
||||
.minFilter = LiverpoolToVK::Filter(sampler.xy_min_filter),
|
||||
.mipmapMode = LiverpoolToVK::MipFilter(sampler.mip_filter),
|
||||
|
@ -34,7 +61,7 @@ Sampler::Sampler(const Vulkan::Instance& instance, const AmdGpu::Sampler& sample
|
|||
.compareOp = LiverpoolToVK::DepthCompare(sampler.depth_compare_func),
|
||||
.minLod = sampler.MinLod(),
|
||||
.maxLod = sampler.MaxLod(),
|
||||
.borderColor = LiverpoolToVK::BorderColor(sampler.border_color_type),
|
||||
.borderColor = borderColor,
|
||||
.unnormalizedCoordinates = false, // Handled in shader due to Vulkan limitations.
|
||||
};
|
||||
auto [sampler_result, smplr] = instance.GetDevice().createSamplerUnique(sampler_ci);
|
||||
|
|
|
@ -14,7 +14,8 @@ namespace VideoCore {
|
|||
|
||||
class Sampler {
|
||||
public:
|
||||
explicit Sampler(const Vulkan::Instance& instance, const AmdGpu::Sampler& sampler);
|
||||
explicit Sampler(const Vulkan::Instance& instance, const AmdGpu::Sampler& sampler,
|
||||
const AmdGpu::Liverpool::BorderColorBufferBase& border_color_base);
|
||||
~Sampler();
|
||||
|
||||
Sampler(const Sampler&) = delete;
|
||||
|
|
|
@ -636,9 +636,11 @@ void TextureCache::RefreshImage(Image& image, Vulkan::Scheduler* custom_schedule
|
|||
image.flags &= ~ImageFlagBits::Dirty;
|
||||
}
|
||||
|
||||
vk::Sampler TextureCache::GetSampler(const AmdGpu::Sampler& sampler) {
|
||||
vk::Sampler TextureCache::GetSampler(
|
||||
const AmdGpu::Sampler& sampler,
|
||||
const AmdGpu::Liverpool::BorderColorBufferBase& border_color_base) {
|
||||
const u64 hash = XXH3_64bits(&sampler, sizeof(sampler));
|
||||
const auto [it, new_sampler] = samplers.try_emplace(hash, instance, sampler);
|
||||
const auto [it, new_sampler] = samplers.try_emplace(hash, instance, sampler, border_color_base);
|
||||
return it->second.Handle();
|
||||
}
|
||||
|
||||
|
|
|
@ -139,7 +139,9 @@ public:
|
|||
void RefreshImage(Image& image, Vulkan::Scheduler* custom_scheduler = nullptr);
|
||||
|
||||
/// Retrieves the sampler that matches the provided S# descriptor.
|
||||
[[nodiscard]] vk::Sampler GetSampler(const AmdGpu::Sampler& sampler);
|
||||
[[nodiscard]] vk::Sampler GetSampler(
|
||||
const AmdGpu::Sampler& sampler,
|
||||
const AmdGpu::Liverpool::BorderColorBufferBase& border_color_base);
|
||||
|
||||
/// Retrieves the image with the specified id.
|
||||
[[nodiscard]] Image& GetImage(ImageId id) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue