Vulkan Rasterizer: Fix clears on integer textures.
This commit is contained in:
parent
150bc45401
commit
826a350e2b
3 changed files with 84 additions and 1 deletions
|
@ -211,6 +211,8 @@ void RasterizerVulkan::Draw(bool is_indexed, bool is_instanced) {
|
||||||
EndTransformFeedback();
|
EndTransformFeedback();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pragma optimize("", off)
|
||||||
|
|
||||||
void RasterizerVulkan::Clear() {
|
void RasterizerVulkan::Clear() {
|
||||||
MICROPROFILE_SCOPE(Vulkan_Clearing);
|
MICROPROFILE_SCOPE(Vulkan_Clearing);
|
||||||
|
|
||||||
|
@ -260,7 +262,37 @@ void RasterizerVulkan::Clear() {
|
||||||
const u32 color_attachment = regs.clear_buffers.RT;
|
const u32 color_attachment = regs.clear_buffers.RT;
|
||||||
if (use_color && framebuffer->HasAspectColorBit(color_attachment)) {
|
if (use_color && framebuffer->HasAspectColorBit(color_attachment)) {
|
||||||
VkClearValue clear_value;
|
VkClearValue clear_value;
|
||||||
|
bool is_integer = false;
|
||||||
|
bool is_signed = false;
|
||||||
|
size_t int_size = 8;
|
||||||
|
for (std::size_t i = 0; i < Tegra::Engines::Maxwell3D::Regs::NumRenderTargets; ++i) {
|
||||||
|
const auto& this_rt = regs.rt[i];
|
||||||
|
if (this_rt.Address() == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (this_rt.format == Tegra::RenderTargetFormat::NONE) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const auto format =
|
||||||
|
VideoCore::Surface::PixelFormatFromRenderTargetFormat(this_rt.format);
|
||||||
|
is_integer = IsPixelFormatInteger(format);
|
||||||
|
is_signed = IsPixelFormatSignedInteger(format);
|
||||||
|
int_size = PixelComponentSizeBitsInteger(format);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!is_integer) {
|
||||||
std::memcpy(clear_value.color.float32, regs.clear_color, sizeof(regs.clear_color));
|
std::memcpy(clear_value.color.float32, regs.clear_color, sizeof(regs.clear_color));
|
||||||
|
} else if (!is_signed) {
|
||||||
|
for (size_t i = 0; i < 4; i++) {
|
||||||
|
clear_value.color.uint32[i] =
|
||||||
|
static_cast<u32>(static_cast<u64>(int_size << 1U) * regs.clear_color[i]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (size_t i = 0; i < 4; i++) {
|
||||||
|
clear_value.color.int32[i] = static_cast<s32>(
|
||||||
|
(static_cast<s32>(int_size - 1) << 1) * (regs.clear_color[i] - 0.5f));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
scheduler.Record([color_attachment, clear_value, clear_rect](vk::CommandBuffer cmdbuf) {
|
scheduler.Record([color_attachment, clear_value, clear_rect](vk::CommandBuffer cmdbuf) {
|
||||||
const VkClearAttachment attachment{
|
const VkClearAttachment attachment{
|
||||||
|
|
|
@ -306,6 +306,53 @@ bool IsPixelFormatInteger(PixelFormat format) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IsPixelFormatSignedInteger(PixelFormat format) {
|
||||||
|
switch (format) {
|
||||||
|
case PixelFormat::A8B8G8R8_SINT:
|
||||||
|
case PixelFormat::R8_SINT:
|
||||||
|
case PixelFormat::R16G16B16A16_SINT:
|
||||||
|
case PixelFormat::R32G32B32A32_SINT:
|
||||||
|
case PixelFormat::R32G32_SINT:
|
||||||
|
case PixelFormat::R16_SINT:
|
||||||
|
case PixelFormat::R16G16_SINT:
|
||||||
|
case PixelFormat::R8G8_SINT:
|
||||||
|
case PixelFormat::R32_SINT:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t PixelComponentSizeBitsInteger(PixelFormat format) {
|
||||||
|
switch (format) {
|
||||||
|
case PixelFormat::A8B8G8R8_SINT:
|
||||||
|
case PixelFormat::A8B8G8R8_UINT:
|
||||||
|
case PixelFormat::R8_SINT:
|
||||||
|
case PixelFormat::R8_UINT:
|
||||||
|
case PixelFormat::R8G8_SINT:
|
||||||
|
case PixelFormat::R8G8_UINT:
|
||||||
|
return 8;
|
||||||
|
case PixelFormat::A2B10G10R10_UINT:
|
||||||
|
return 10;
|
||||||
|
case PixelFormat::R16G16B16A16_SINT:
|
||||||
|
case PixelFormat::R16G16B16A16_UINT:
|
||||||
|
case PixelFormat::R16_UINT:
|
||||||
|
case PixelFormat::R16_SINT:
|
||||||
|
case PixelFormat::R16G16_UINT:
|
||||||
|
case PixelFormat::R16G16_SINT:
|
||||||
|
return 16;
|
||||||
|
case PixelFormat::R32G32B32A32_UINT:
|
||||||
|
case PixelFormat::R32G32B32A32_SINT:
|
||||||
|
case PixelFormat::R32G32_SINT:
|
||||||
|
case PixelFormat::R32G32_UINT:
|
||||||
|
case PixelFormat::R32_UINT:
|
||||||
|
case PixelFormat::R32_SINT:
|
||||||
|
return 32;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::pair<u32, u32> GetASTCBlockSize(PixelFormat format) {
|
std::pair<u32, u32> GetASTCBlockSize(PixelFormat format) {
|
||||||
return {DefaultBlockWidth(format), DefaultBlockHeight(format)};
|
return {DefaultBlockWidth(format), DefaultBlockHeight(format)};
|
||||||
}
|
}
|
||||||
|
|
|
@ -462,6 +462,10 @@ bool IsPixelFormatSRGB(PixelFormat format);
|
||||||
|
|
||||||
bool IsPixelFormatInteger(PixelFormat format);
|
bool IsPixelFormatInteger(PixelFormat format);
|
||||||
|
|
||||||
|
bool IsPixelFormatSignedInteger(PixelFormat format);
|
||||||
|
|
||||||
|
size_t PixelComponentSizeBitsInteger(PixelFormat format);
|
||||||
|
|
||||||
std::pair<u32, u32> GetASTCBlockSize(PixelFormat format);
|
std::pair<u32, u32> GetASTCBlockSize(PixelFormat format);
|
||||||
|
|
||||||
u64 EstimatedDecompressedSize(u64 base_size, PixelFormat format);
|
u64 EstimatedDecompressedSize(u64 base_size, PixelFormat format);
|
||||||
|
|
Loading…
Reference in a new issue