mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-28 05:46:56 +01:00
graphics: simplify render target format and color mapping resolution
This commit is contained in:
@@ -115,32 +115,52 @@ enum class ChannelOrder : uint32_t {
|
|||||||
kAltReversed = 3,
|
kAltReversed = 3,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Maps a shader's logical RGBA export to the host color-attachment components. Two bits per
|
// Selects the logical shader component written to each physical color-attachment component.
|
||||||
// component keep this cheap to carry in shader and pipeline keys.
|
// Two bits per component keep this cheap to carry in shader and pipeline keys.
|
||||||
struct ColorComponentMapping {
|
struct ColorComponentMapping {
|
||||||
uint8_t packed = 0xe4u; // RGBA: 0, 1, 2, 3
|
static constexpr uint8_t kIdentity = 0xe4u;
|
||||||
|
|
||||||
|
uint8_t packed = kIdentity;
|
||||||
|
|
||||||
[[nodiscard]] constexpr uint32_t Map(uint32_t component) const {
|
[[nodiscard]] constexpr uint32_t Map(uint32_t component) const {
|
||||||
return component < 4u ? (packed >> (component * 2u)) & 0x3u : component;
|
return component < 4u ? (packed >> (component * 2u)) & 0x3u : component;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] constexpr uint32_t ApplyMask(uint32_t mask) const {
|
[[nodiscard]] constexpr uint32_t ApplyMask(uint32_t logical_mask) const {
|
||||||
uint32_t mapped = 0;
|
uint32_t mapped = 0;
|
||||||
for (uint32_t component = 0; component < 4u; component++) {
|
for (uint32_t physical_component = 0; physical_component < 4u; physical_component++) {
|
||||||
mapped |= ((mask >> component) & 1u) << Map(component);
|
mapped |= ((logical_mask >> Map(physical_component)) & 1u) << physical_component;
|
||||||
}
|
}
|
||||||
return mapped;
|
return mapped;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] constexpr bool IsIdentity() const { return packed == 0xe4u; }
|
// This mapping selects an intermediate component; next selects the final logical component.
|
||||||
|
[[nodiscard]] constexpr ColorComponentMapping Then(ColorComponentMapping next) const {
|
||||||
|
ColorComponentMapping result {0u};
|
||||||
|
for (uint32_t physical_component = 0; physical_component < 4u; physical_component++) {
|
||||||
|
result.packed |= static_cast<uint8_t>(next.Map(Map(physical_component))
|
||||||
|
<< (physical_component * 2u));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] constexpr bool IsIdentity() const { return packed == kIdentity; }
|
||||||
|
|
||||||
bool operator==(const ColorComponentMapping&) const = default;
|
bool operator==(const ColorComponentMapping&) const = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
static_assert(sizeof(ColorComponentMapping) == sizeof(uint8_t));
|
static_assert(sizeof(ColorComponentMapping) == sizeof(uint8_t));
|
||||||
|
|
||||||
inline constexpr ColorComponentMapping ColorMappingAbgr {0x1bu}; // 3, 2, 1, 0
|
inline constexpr ColorComponentMapping ColorMappingRgba {ColorComponentMapping::kIdentity};
|
||||||
|
inline constexpr ColorComponentMapping ColorMappingGr {0xe1u}; // 1, 0, 2, 3
|
||||||
|
inline constexpr ColorComponentMapping ColorMappingRabg {0x6cu}; // 0, 3, 2, 1
|
||||||
|
inline constexpr ColorComponentMapping ColorMappingRgab {0xb4u}; // 0, 1, 3, 2
|
||||||
inline constexpr ColorComponentMapping ColorMappingBgra {0xc6u}; // 2, 1, 0, 3
|
inline constexpr ColorComponentMapping ColorMappingBgra {0xc6u}; // 2, 1, 0, 3
|
||||||
|
inline constexpr ColorComponentMapping ColorMappingAbgr {0x1bu}; // 3, 2, 1, 0
|
||||||
|
inline constexpr ColorComponentMapping ColorMappingAgba {0x27u}; // 3, 1, 2, 0
|
||||||
|
inline constexpr ColorComponentMapping ColorMappingArbg {0x63u}; // 3, 0, 2, 1
|
||||||
|
inline constexpr ColorComponentMapping ColorMappingAgbr {0x87u}; // 3, 1, 0, 2
|
||||||
|
inline constexpr ColorComponentMapping ColorMappingArgb {0x93u}; // 3, 0, 1, 2
|
||||||
|
|
||||||
enum class DepthFormat : uint32_t {
|
enum class DepthFormat : uint32_t {
|
||||||
kInvalid = 0,
|
kInvalid = 0,
|
||||||
@@ -388,9 +408,11 @@ enum class BufferFormat : uint32_t {
|
|||||||
k8Srgb = 128,
|
k8Srgb = 128,
|
||||||
k8_8Srgb = 129,
|
k8_8Srgb = 129,
|
||||||
k8_8_8_8Srgb = 130,
|
k8_8_8_8Srgb = 130,
|
||||||
|
k10_10_10_2Float = 131,
|
||||||
k9_9_9_5Float = 132,
|
k9_9_9_5Float = 132,
|
||||||
k5_6_5UNorm = 133,
|
k5_6_5UNorm = 133,
|
||||||
k5_5_5_1UNorm = 134,
|
k5_5_5_1UNorm = 134,
|
||||||
|
k1_5_5_5UNorm = 135,
|
||||||
k4_4_4_4UNorm = 136,
|
k4_4_4_4UNorm = 136,
|
||||||
kFmask8_S4_F4 = 161,
|
kFmask8_S4_F4 = 161,
|
||||||
kBc1UNorm = 169,
|
kBc1UNorm = 169,
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#include "graphics/guest_gpu/gpu_defs.h"
|
#include "graphics/guest_gpu/gpu_defs.h"
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
|
#include <bit>
|
||||||
|
|
||||||
namespace Libs::Graphics::Prospero {
|
namespace Libs::Graphics::Prospero {
|
||||||
namespace {
|
namespace {
|
||||||
@@ -64,6 +65,7 @@ constexpr FormatInfo kFormatInfo[] = {
|
|||||||
{GpuEnumValue(BufferFormat::k9_9_9_5Float), 4, 0, 0, true, false},
|
{GpuEnumValue(BufferFormat::k9_9_9_5Float), 4, 0, 0, true, false},
|
||||||
{GpuEnumValue(BufferFormat::k5_6_5UNorm), 2, 0, 2, true, false},
|
{GpuEnumValue(BufferFormat::k5_6_5UNorm), 2, 0, 2, true, false},
|
||||||
{GpuEnumValue(BufferFormat::k5_5_5_1UNorm), 2, 0, 2, true, false},
|
{GpuEnumValue(BufferFormat::k5_5_5_1UNorm), 2, 0, 2, true, false},
|
||||||
|
{GpuEnumValue(BufferFormat::k1_5_5_5UNorm), 0, 0, 2, false, false},
|
||||||
{GpuEnumValue(BufferFormat::k4_4_4_4UNorm), 2, 0, 2, true, false},
|
{GpuEnumValue(BufferFormat::k4_4_4_4UNorm), 2, 0, 2, true, false},
|
||||||
{GpuEnumValue(BufferFormat::kFmask8_S4_F4), 1, 0, 1, true, false},
|
{GpuEnumValue(BufferFormat::kFmask8_S4_F4), 1, 0, 1, true, false},
|
||||||
{GpuEnumValue(BufferFormat::kBc1UNorm), 0, 8, 0, true, false},
|
{GpuEnumValue(BufferFormat::kBc1UNorm), 0, 8, 0, true, false},
|
||||||
@@ -82,6 +84,68 @@ constexpr FormatInfo kFormatInfo[] = {
|
|||||||
{GpuEnumValue(BufferFormat::kBc7Srgb), 0, 16, 0, true, false},
|
{GpuEnumValue(BufferFormat::kBc7Srgb), 0, 16, 0, true, false},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
constexpr uint8_t RenderTargetTypeBit(ChannelType type) {
|
||||||
|
return static_cast<uint8_t>(1u << GpuEnumValue(type));
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr auto kUNormType = RenderTargetTypeBit(ChannelType::kUNorm);
|
||||||
|
constexpr auto kIntegerTypes =
|
||||||
|
RenderTargetTypeBit(ChannelType::kUInt) | RenderTargetTypeBit(ChannelType::kSInt);
|
||||||
|
constexpr auto kNormalizedIntegerTypes =
|
||||||
|
kUNormType | RenderTargetTypeBit(ChannelType::kSNorm) | kIntegerTypes;
|
||||||
|
|
||||||
|
struct RenderTargetLayoutInfo {
|
||||||
|
ChannelLayout layout;
|
||||||
|
BufferFormat first_linear_format;
|
||||||
|
uint8_t linear_type_mask;
|
||||||
|
uint8_t components;
|
||||||
|
BufferFormat extra_format = BufferFormat::kInvalid;
|
||||||
|
ChannelType extra_type = ChannelType::kUNorm;
|
||||||
|
ChannelOrderSupport order_support = ChannelOrderSupport::kAll;
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr RenderTargetLayoutInfo kRenderTargetLayouts[] = {
|
||||||
|
{ChannelLayout::k8, BufferFormat::k8UNorm, kNormalizedIntegerTypes, 1, BufferFormat::k8Srgb,
|
||||||
|
ChannelType::kSrgb},
|
||||||
|
{ChannelLayout::k16, BufferFormat::k16UNorm, kNormalizedIntegerTypes, 1, BufferFormat::k16Float,
|
||||||
|
ChannelType::kFloat},
|
||||||
|
{ChannelLayout::k8_8, BufferFormat::k8_8UNorm, kNormalizedIntegerTypes, 2,
|
||||||
|
BufferFormat::k8_8Srgb, ChannelType::kSrgb},
|
||||||
|
{ChannelLayout::k32, BufferFormat::k32UInt, kIntegerTypes, 1, BufferFormat::k32Float,
|
||||||
|
ChannelType::kFloat},
|
||||||
|
{ChannelLayout::k16_16, BufferFormat::k16_16UNorm, kNormalizedIntegerTypes, 2,
|
||||||
|
BufferFormat::k16_16Float, ChannelType::kFloat},
|
||||||
|
{ChannelLayout::k11_11_10, BufferFormat::k11_11_10UNorm, kNormalizedIntegerTypes, 3,
|
||||||
|
BufferFormat::k11_11_10Float, ChannelType::kFloat},
|
||||||
|
{ChannelLayout::k10_11_11, BufferFormat::k10_11_11UNorm, kNormalizedIntegerTypes, 3,
|
||||||
|
BufferFormat::k10_11_11Float, ChannelType::kFloat},
|
||||||
|
{ChannelLayout::k2_10_10_10, BufferFormat::k2_10_10_10UNorm, kNormalizedIntegerTypes, 4},
|
||||||
|
{ChannelLayout::k10_10_10_2, BufferFormat::k10_10_10_2UNorm, kNormalizedIntegerTypes, 4},
|
||||||
|
{ChannelLayout::k8_8_8_8, BufferFormat::k8_8_8_8UNorm, kNormalizedIntegerTypes, 4,
|
||||||
|
BufferFormat::k8_8_8_8Srgb, ChannelType::kSrgb},
|
||||||
|
{ChannelLayout::k32_32, BufferFormat::k32_32UInt, kIntegerTypes, 2, BufferFormat::k32_32Float,
|
||||||
|
ChannelType::kFloat},
|
||||||
|
{ChannelLayout::k16_16_16_16, BufferFormat::k16_16_16_16UNorm, kNormalizedIntegerTypes, 4,
|
||||||
|
BufferFormat::k16_16_16_16Float, ChannelType::kFloat},
|
||||||
|
{ChannelLayout::k32_32_32_32, BufferFormat::k32_32_32_32UInt, kIntegerTypes, 4,
|
||||||
|
BufferFormat::k32_32_32_32Float, ChannelType::kFloat},
|
||||||
|
{ChannelLayout::k5_6_5, BufferFormat::k5_6_5UNorm, kUNormType, 3},
|
||||||
|
{ChannelLayout::k5_5_5_1, BufferFormat::k5_5_5_1UNorm, kUNormType, 4},
|
||||||
|
{ChannelLayout::k1_5_5_5, BufferFormat::k1_5_5_5UNorm, kUNormType, 4},
|
||||||
|
{ChannelLayout::k4_4_4_4, BufferFormat::k4_4_4_4UNorm, kUNormType, 4},
|
||||||
|
{ChannelLayout::k10_10_10_2Float, BufferFormat::kInvalid, 0, 4, BufferFormat::k10_10_10_2Float,
|
||||||
|
ChannelType::kFloat, ChannelOrderSupport::kStandardOnly},
|
||||||
|
};
|
||||||
|
|
||||||
|
const RenderTargetLayoutInfo* FindRenderTargetLayout(uint32_t layout) {
|
||||||
|
for (const auto& info: kRenderTargetLayouts) {
|
||||||
|
if (GpuEnumValue(info.layout) == layout) {
|
||||||
|
return &info;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
constexpr auto MakeFormatInfoLookup() {
|
constexpr auto MakeFormatInfoLookup() {
|
||||||
constexpr uint32_t kMaxFormat = GpuEnumValue(BufferFormat::kBc7Srgb);
|
constexpr uint32_t kMaxFormat = GpuEnumValue(BufferFormat::kBc7Srgb);
|
||||||
std::array<const FormatInfo*, kMaxFormat + 1> lookup {};
|
std::array<const FormatInfo*, kMaxFormat + 1> lookup {};
|
||||||
@@ -99,6 +163,29 @@ const FormatInfo* FindFormatInfo(uint32_t format) {
|
|||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
RenderTargetFormatEncoding ResolveRenderTargetFormat(uint32_t layout, uint32_t type) {
|
||||||
|
const auto* layout_info = FindRenderTargetLayout(layout);
|
||||||
|
if (layout_info == nullptr || type >= 8u) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto channel_type = static_cast<ChannelType>(type);
|
||||||
|
auto format = BufferFormat::kInvalid;
|
||||||
|
if (layout_info->extra_format != BufferFormat::kInvalid &&
|
||||||
|
channel_type == layout_info->extra_type) {
|
||||||
|
format = layout_info->extra_format;
|
||||||
|
} else if ((layout_info->linear_type_mask & (1u << type)) != 0) {
|
||||||
|
const auto first_type =
|
||||||
|
std::countr_zero(static_cast<uint32_t>(layout_info->linear_type_mask));
|
||||||
|
format = static_cast<BufferFormat>(GpuEnumValue(layout_info->first_linear_format) + type -
|
||||||
|
first_type);
|
||||||
|
}
|
||||||
|
if (format == BufferFormat::kInvalid) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
return {format, layout_info->components, layout_info->order_support};
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t NumBytesPerElement(uint32_t format) {
|
uint32_t NumBytesPerElement(uint32_t format) {
|
||||||
const auto* info = FindFormatInfo(format);
|
const auto* info = FindFormatInfo(format);
|
||||||
return info != nullptr ? info->bytes_per_element : 0;
|
return info != nullptr ? info->bytes_per_element : 0;
|
||||||
|
|||||||
@@ -1,16 +1,44 @@
|
|||||||
#ifndef EMULATOR_INCLUDE_EMULATOR_GRAPHICS_GUEST_GPU_GPU_FORMAT_H_
|
#ifndef EMULATOR_INCLUDE_EMULATOR_GRAPHICS_GUEST_GPU_GPU_FORMAT_H_
|
||||||
#define EMULATOR_INCLUDE_EMULATOR_GRAPHICS_GUEST_GPU_GPU_FORMAT_H_
|
#define EMULATOR_INCLUDE_EMULATOR_GRAPHICS_GUEST_GPU_GPU_FORMAT_H_
|
||||||
|
|
||||||
#include "common/common.h"
|
#include "graphics/guest_gpu/gpu_defs.h"
|
||||||
|
|
||||||
namespace Libs::Graphics::Prospero {
|
namespace Libs::Graphics::Prospero {
|
||||||
|
|
||||||
uint32_t NumBytesPerElement(uint32_t format);
|
enum class ChannelOrderSupport : uint8_t {
|
||||||
uint32_t BlockCompressedBytesPerBlock(uint32_t format);
|
kNone,
|
||||||
uint32_t RenderTargetBytesPerElement(uint32_t format);
|
kStandardOnly,
|
||||||
bool IsSupportedTextureFormat(uint32_t format);
|
kAll,
|
||||||
bool IsUintTextureFormat(uint32_t format);
|
};
|
||||||
bool IsFmaskTextureFormat(uint32_t format);
|
|
||||||
|
struct RenderTargetFormatEncoding {
|
||||||
|
BufferFormat buffer_format = BufferFormat::kInvalid;
|
||||||
|
uint8_t components = 0;
|
||||||
|
ChannelOrderSupport order_support = ChannelOrderSupport::kNone;
|
||||||
|
|
||||||
|
[[nodiscard]] constexpr bool IsValid() const {
|
||||||
|
return buffer_format != BufferFormat::kInvalid && components >= 1u && components <= 4u &&
|
||||||
|
order_support != ChannelOrderSupport::kNone;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] constexpr bool SupportsOrder(uint32_t raw_order) const {
|
||||||
|
switch (order_support) {
|
||||||
|
case ChannelOrderSupport::kStandardOnly:
|
||||||
|
return raw_order == GpuEnumValue(ChannelOrder::kStandard);
|
||||||
|
case ChannelOrderSupport::kAll:
|
||||||
|
return raw_order <= GpuEnumValue(ChannelOrder::kAltReversed);
|
||||||
|
default: return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
RenderTargetFormatEncoding ResolveRenderTargetFormat(uint32_t layout, uint32_t type);
|
||||||
|
uint32_t NumBytesPerElement(uint32_t format);
|
||||||
|
uint32_t BlockCompressedBytesPerBlock(uint32_t format);
|
||||||
|
uint32_t RenderTargetBytesPerElement(uint32_t format);
|
||||||
|
bool IsSupportedTextureFormat(uint32_t format);
|
||||||
|
bool IsUintTextureFormat(uint32_t format);
|
||||||
|
bool IsFmaskTextureFormat(uint32_t format);
|
||||||
|
|
||||||
} // namespace Libs::Graphics::Prospero
|
} // namespace Libs::Graphics::Prospero
|
||||||
|
|
||||||
|
|||||||
@@ -14,152 +14,64 @@
|
|||||||
namespace Libs::Graphics {
|
namespace Libs::Graphics {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
struct RenderTargetFormatMapping {
|
// Rows are channel order; columns are the number of physical components minus one. Unused
|
||||||
Prospero::ChannelLayout layout;
|
// selectors complete each entry to a permutation so logical write masks can be inverted.
|
||||||
Prospero::ChannelType type;
|
constexpr Prospero::ColorComponentMapping kRenderTargetColorMappings[4][4] = {
|
||||||
Prospero::ChannelOrder order;
|
{Prospero::ColorMappingRgba, Prospero::ColorMappingRgba, Prospero::ColorMappingRgba,
|
||||||
RenderTargetFormatInfo info;
|
Prospero::ColorMappingRgba},
|
||||||
|
{Prospero::ColorMappingGr, Prospero::ColorMappingRabg, Prospero::ColorMappingRgab,
|
||||||
|
Prospero::ColorMappingBgra},
|
||||||
|
{Prospero::ColorMappingBgra, Prospero::ColorMappingGr, Prospero::ColorMappingBgra,
|
||||||
|
Prospero::ColorMappingAbgr},
|
||||||
|
{Prospero::ColorMappingAgba, Prospero::ColorMappingArbg, Prospero::ColorMappingAgbr,
|
||||||
|
Prospero::ColorMappingArgb},
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr RenderTargetFormatMapping kRenderTargetFormats[] = {
|
struct RenderTargetHostFormatInfo {
|
||||||
{Prospero::ChannelLayout::k8,
|
vk::Format format = vk::Format::eUndefined;
|
||||||
Prospero::ChannelType::kUInt,
|
Prospero::ColorComponentMapping host_to_storage;
|
||||||
Prospero::ChannelOrder::kStandard,
|
|
||||||
{vk::Format::eR8Uint, 1}},
|
|
||||||
{Prospero::ChannelLayout::k8_8,
|
|
||||||
Prospero::ChannelType::kUNorm,
|
|
||||||
Prospero::ChannelOrder::kStandard,
|
|
||||||
{vk::Format::eR8G8Unorm, 2}},
|
|
||||||
{Prospero::ChannelLayout::k8_8_8_8,
|
|
||||||
Prospero::ChannelType::kUNorm,
|
|
||||||
Prospero::ChannelOrder::kStandard,
|
|
||||||
{vk::Format::eR8G8B8A8Unorm, 4}},
|
|
||||||
{Prospero::ChannelLayout::k8_8_8_8,
|
|
||||||
Prospero::ChannelType::kSNorm,
|
|
||||||
Prospero::ChannelOrder::kStandard,
|
|
||||||
{vk::Format::eR8G8B8A8Snorm, 4}},
|
|
||||||
{Prospero::ChannelLayout::k8_8_8_8,
|
|
||||||
Prospero::ChannelType::kSrgb,
|
|
||||||
Prospero::ChannelOrder::kStandard,
|
|
||||||
{vk::Format::eR8G8B8A8Srgb, 4}},
|
|
||||||
{Prospero::ChannelLayout::k8_8_8_8,
|
|
||||||
Prospero::ChannelType::kUNorm,
|
|
||||||
Prospero::ChannelOrder::kAlt,
|
|
||||||
{vk::Format::eB8G8R8A8Unorm, 4}},
|
|
||||||
{Prospero::ChannelLayout::k8_8_8_8,
|
|
||||||
Prospero::ChannelType::kSNorm,
|
|
||||||
Prospero::ChannelOrder::kAlt,
|
|
||||||
{vk::Format::eB8G8R8A8Snorm, 4}},
|
|
||||||
{Prospero::ChannelLayout::k8_8_8_8,
|
|
||||||
Prospero::ChannelType::kSrgb,
|
|
||||||
Prospero::ChannelOrder::kAlt,
|
|
||||||
{vk::Format::eB8G8R8A8Srgb, 4}},
|
|
||||||
{Prospero::ChannelLayout::k5_5_5_1,
|
|
||||||
Prospero::ChannelType::kUNorm,
|
|
||||||
Prospero::ChannelOrder::kStandard,
|
|
||||||
{vk::Format::eR5G5B5A1UnormPack16, 2}},
|
|
||||||
{Prospero::ChannelLayout::k4_4_4_4,
|
|
||||||
Prospero::ChannelType::kUNorm,
|
|
||||||
Prospero::ChannelOrder::kReversed,
|
|
||||||
{vk::Format::eB4G4R4A4UnormPack16, 2}},
|
|
||||||
{Prospero::ChannelLayout::k10_10_10_2,
|
|
||||||
Prospero::ChannelType::kUNorm,
|
|
||||||
Prospero::ChannelOrder::kStandard,
|
|
||||||
{vk::Format::eA2B10G10R10UnormPack32, 4}},
|
|
||||||
{Prospero::ChannelLayout::k10_10_10_2,
|
|
||||||
Prospero::ChannelType::kUNorm,
|
|
||||||
Prospero::ChannelOrder::kAlt,
|
|
||||||
{vk::Format::eA2R10G10B10UnormPack32, 4}},
|
|
||||||
{Prospero::ChannelLayout::k11_11_10,
|
|
||||||
Prospero::ChannelType::kFloat,
|
|
||||||
Prospero::ChannelOrder::kStandard,
|
|
||||||
{vk::Format::eB10G11R11UfloatPack32, 4}},
|
|
||||||
{Prospero::ChannelLayout::k5_6_5,
|
|
||||||
Prospero::ChannelType::kUNorm,
|
|
||||||
Prospero::ChannelOrder::kStandard,
|
|
||||||
{vk::Format::eB5G6R5UnormPack16, 2}},
|
|
||||||
{Prospero::ChannelLayout::k16,
|
|
||||||
Prospero::ChannelType::kUNorm,
|
|
||||||
Prospero::ChannelOrder::kStandard,
|
|
||||||
{vk::Format::eR16Unorm, 2}},
|
|
||||||
{Prospero::ChannelLayout::k16,
|
|
||||||
Prospero::ChannelType::kUInt,
|
|
||||||
Prospero::ChannelOrder::kStandard,
|
|
||||||
{vk::Format::eR16Uint, 2}},
|
|
||||||
{Prospero::ChannelLayout::k16,
|
|
||||||
Prospero::ChannelType::kFloat,
|
|
||||||
Prospero::ChannelOrder::kStandard,
|
|
||||||
{vk::Format::eR16Sfloat, 2}},
|
|
||||||
{Prospero::ChannelLayout::k16_16,
|
|
||||||
Prospero::ChannelType::kUNorm,
|
|
||||||
Prospero::ChannelOrder::kStandard,
|
|
||||||
{vk::Format::eR16G16Unorm, 4}},
|
|
||||||
{Prospero::ChannelLayout::k16_16,
|
|
||||||
Prospero::ChannelType::kSNorm,
|
|
||||||
Prospero::ChannelOrder::kStandard,
|
|
||||||
{vk::Format::eR16G16Snorm, 4}},
|
|
||||||
{Prospero::ChannelLayout::k16_16,
|
|
||||||
Prospero::ChannelType::kUInt,
|
|
||||||
Prospero::ChannelOrder::kStandard,
|
|
||||||
{vk::Format::eR16G16Uint, 4}},
|
|
||||||
{Prospero::ChannelLayout::k16_16,
|
|
||||||
Prospero::ChannelType::kFloat,
|
|
||||||
Prospero::ChannelOrder::kStandard,
|
|
||||||
{vk::Format::eR16G16Sfloat, 4}},
|
|
||||||
{Prospero::ChannelLayout::k16_16_16_16,
|
|
||||||
Prospero::ChannelType::kUNorm,
|
|
||||||
Prospero::ChannelOrder::kStandard,
|
|
||||||
{vk::Format::eR16G16B16A16Unorm, 8}},
|
|
||||||
{Prospero::ChannelLayout::k16_16_16_16,
|
|
||||||
Prospero::ChannelType::kUInt,
|
|
||||||
Prospero::ChannelOrder::kStandard,
|
|
||||||
{vk::Format::eR16G16B16A16Uint, 8}},
|
|
||||||
{Prospero::ChannelLayout::k16_16_16_16,
|
|
||||||
Prospero::ChannelType::kFloat,
|
|
||||||
Prospero::ChannelOrder::kStandard,
|
|
||||||
{vk::Format::eR16G16B16A16Sfloat, 8}},
|
|
||||||
{Prospero::ChannelLayout::k16_16_16_16,
|
|
||||||
Prospero::ChannelType::kFloat,
|
|
||||||
Prospero::ChannelOrder::kAlt,
|
|
||||||
{vk::Format::eR16G16B16A16Sfloat, 8, Prospero::ColorMappingBgra}},
|
|
||||||
{Prospero::ChannelLayout::k16_16_16_16,
|
|
||||||
Prospero::ChannelType::kFloat,
|
|
||||||
Prospero::ChannelOrder::kReversed,
|
|
||||||
{vk::Format::eR16G16B16A16Sfloat, 8, Prospero::ColorMappingAbgr}},
|
|
||||||
{Prospero::ChannelLayout::k32,
|
|
||||||
Prospero::ChannelType::kFloat,
|
|
||||||
Prospero::ChannelOrder::kStandard,
|
|
||||||
{vk::Format::eR32Sfloat, 4}},
|
|
||||||
{Prospero::ChannelLayout::k32_32,
|
|
||||||
Prospero::ChannelType::kUInt,
|
|
||||||
Prospero::ChannelOrder::kStandard,
|
|
||||||
{vk::Format::eR32G32Uint, 8}},
|
|
||||||
{Prospero::ChannelLayout::k32_32,
|
|
||||||
Prospero::ChannelType::kFloat,
|
|
||||||
Prospero::ChannelOrder::kStandard,
|
|
||||||
{vk::Format::eR32G32Sfloat, 8}},
|
|
||||||
{Prospero::ChannelLayout::k32_32_32_32,
|
|
||||||
Prospero::ChannelType::kFloat,
|
|
||||||
Prospero::ChannelOrder::kStandard,
|
|
||||||
{vk::Format::eR32G32B32A32Sfloat, 16}},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
RenderTargetHostFormatInfo ResolveRenderTargetHostFormat(Prospero::BufferFormat guest_format,
|
||||||
|
Prospero::ChannelOrder order) {
|
||||||
|
if (order == Prospero::ChannelOrder::kAlt) {
|
||||||
|
switch (guest_format) {
|
||||||
|
case Prospero::BufferFormat::k8_8_8_8UNorm:
|
||||||
|
return {vk::Format::eB8G8R8A8Unorm, Prospero::ColorMappingBgra};
|
||||||
|
case Prospero::BufferFormat::k8_8_8_8SNorm:
|
||||||
|
return {vk::Format::eB8G8R8A8Snorm, Prospero::ColorMappingBgra};
|
||||||
|
case Prospero::BufferFormat::k8_8_8_8Srgb:
|
||||||
|
return {vk::Format::eB8G8R8A8Srgb, Prospero::ColorMappingBgra};
|
||||||
|
case Prospero::BufferFormat::k10_10_10_2UNorm:
|
||||||
|
return {vk::Format::eA2R10G10B10UnormPack32, Prospero::ColorMappingBgra};
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
switch (guest_format) {
|
||||||
|
case Prospero::BufferFormat::k5_5_5_1UNorm:
|
||||||
|
return {vk::Format::eA1R5G5B5UnormPack16, Prospero::ColorMappingBgra};
|
||||||
|
case Prospero::BufferFormat::k1_5_5_5UNorm:
|
||||||
|
return {vk::Format::eR5G5B5A1UnormPack16, Prospero::ColorMappingAbgr};
|
||||||
|
case Prospero::BufferFormat::k4_4_4_4UNorm:
|
||||||
|
return {vk::Format::eR4G4B4A4UnormPack16, Prospero::ColorMappingAbgr};
|
||||||
|
default: return {VulkanFormat(Prospero::GpuEnumValue(guest_format)), {}};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
// TODO: cleanup!
|
|
||||||
RenderTargetFormatInfo TextureGetRenderTargetFormat(uint32_t raw_layout, uint32_t raw_type,
|
RenderTargetFormatInfo TextureGetRenderTargetFormat(uint32_t raw_layout, uint32_t raw_type,
|
||||||
uint32_t raw_order) {
|
uint32_t raw_order) {
|
||||||
const auto layout = static_cast<Prospero::ChannelLayout>(raw_layout);
|
const auto encoding = Prospero::ResolveRenderTargetFormat(raw_layout, raw_type);
|
||||||
const auto type = static_cast<Prospero::ChannelType>(raw_type);
|
if (encoding.IsValid() && encoding.SupportsOrder(raw_order)) {
|
||||||
const auto order = static_cast<Prospero::ChannelOrder>(raw_order);
|
const auto order = static_cast<Prospero::ChannelOrder>(raw_order);
|
||||||
|
const auto host = ResolveRenderTargetHostFormat(encoding.buffer_format, order);
|
||||||
if (layout == Prospero::ChannelLayout::k8 && type == Prospero::ChannelType::kUNorm &&
|
const auto bytes =
|
||||||
raw_order <= Prospero::GpuEnumValue(Prospero::ChannelOrder::kAltReversed)) {
|
Prospero::RenderTargetBytesPerElement(Prospero::GpuEnumValue(encoding.buffer_format));
|
||||||
return {vk::Format::eR8Unorm, 1};
|
if (host.format != vk::Format::eUndefined && bytes != 0) {
|
||||||
}
|
const auto order_mapping =
|
||||||
for (const auto& mapping: kRenderTargetFormats) {
|
kRenderTargetColorMappings[raw_order][encoding.components - 1u];
|
||||||
if (mapping.layout == layout && mapping.type == type && mapping.order == order) {
|
return {host.format, bytes, host.host_to_storage.Then(order_mapping)};
|
||||||
return mapping.info;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
EXIT("unsupported render-target format combination: layout=%u type=%u order=%u\n", raw_layout,
|
EXIT("unsupported render-target format combination: layout=%u type=%u order=%u\n", raw_layout,
|
||||||
|
|||||||
@@ -15970,7 +15970,7 @@ void CheckEmbeddedFetchVertexOffset() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
[[noreturn]] void RunReverseRenderTargetDeathCase() {
|
[[noreturn]] void RunReverseRenderTargetDeathCase() {
|
||||||
(void)TextureGetRenderTargetFormat(12u, 7u, 3u);
|
(void)TextureGetRenderTargetFormat(12u, 6u, 0u);
|
||||||
std::_Exit(0x7f);
|
std::_Exit(0x7f);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -16010,6 +16010,26 @@ void CheckRenderTargetFormatContract() {
|
|||||||
format.export_mapping.ApplyMask(0xfu) == 0xfu,
|
format.export_mapping.ApplyMask(0xfu) == 0xfu,
|
||||||
"reverse RGBA16F component mask was not mapped exactly once");
|
"reverse RGBA16F component mask was not mapped exactly once");
|
||||||
|
|
||||||
|
const auto rg32 = TextureGetRenderTargetFormat(11u, 7u, 2u);
|
||||||
|
Require("ReverseRenderTarget", "GR32 float",
|
||||||
|
rg32.format == vk::Format::eR32G32Sfloat && rg32.bytes_per_element == 8u &&
|
||||||
|
rg32.export_mapping == Prospero::ColorMappingGr &&
|
||||||
|
rg32.export_mapping.ApplyMask(0x1u) == 0x2u &&
|
||||||
|
rg32.export_mapping.ApplyMask(0x2u) == 0x1u &&
|
||||||
|
rg32.export_mapping.ApplyMask(0x3u) == 0x3u &&
|
||||||
|
rg32.export_mapping.ApplyMask(0xfu) == 0xfu,
|
||||||
|
"reverse GR32F render-target export or write-mask mapping is incorrect");
|
||||||
|
|
||||||
|
const auto argb = TextureGetRenderTargetFormat(12u, 7u, 3u);
|
||||||
|
Require("ReverseRenderTarget", "ARGB float",
|
||||||
|
argb.format == vk::Format::eR16G16B16A16Sfloat &&
|
||||||
|
argb.export_mapping == Prospero::ColorMappingArgb &&
|
||||||
|
argb.export_mapping.ApplyMask(0x1u) == 0x2u &&
|
||||||
|
argb.export_mapping.ApplyMask(0x2u) == 0x4u &&
|
||||||
|
argb.export_mapping.ApplyMask(0x4u) == 0x8u &&
|
||||||
|
argb.export_mapping.ApplyMask(0x8u) == 0x1u,
|
||||||
|
"alternate-reversed render-target mapping did not invert its ARGB cycle");
|
||||||
|
|
||||||
char path[MAX_PATH] {};
|
char path[MAX_PATH] {};
|
||||||
Require("ReverseRenderTarget", "host", GetModuleFileNameA(nullptr, path, MAX_PATH) != 0,
|
Require("ReverseRenderTarget", "host", GetModuleFileNameA(nullptr, path, MAX_PATH) != 0,
|
||||||
"GetModuleFileName failed");
|
"GetModuleFileName failed");
|
||||||
@@ -16030,7 +16050,7 @@ void CheckRenderTargetFormatContract() {
|
|||||||
CloseHandle(process.hThread);
|
CloseHandle(process.hThread);
|
||||||
CloseHandle(process.hProcess);
|
CloseHandle(process.hProcess);
|
||||||
Require("ReverseRenderTarget", "hard failure", exited && exit_code == 321,
|
Require("ReverseRenderTarget", "hard failure", exited && exit_code == 321,
|
||||||
"adjacent unproven render-target tuple did not retain the fatal guard");
|
"invalid render-target tuple did not retain the fatal guard");
|
||||||
std::printf("[host] %-32s ok\n", "RenderTargetFormat");
|
std::printf("[host] %-32s ok\n", "RenderTargetFormat");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+131
-5
@@ -6484,7 +6484,7 @@ void TestNewShaderRecompilerExpPixelOutputs() {
|
|||||||
CheckSpirvBinaryValidates(uint16_result.spirv);
|
CheckSpirvBinaryValidates(uint16_result.spirv);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestRenderTargetReverseFloat16ExportMapping() {
|
void TestRenderTargetReverseExportMapping() {
|
||||||
const auto format =
|
const auto format =
|
||||||
TextureGetRenderTargetFormat(Prospero::GpuEnumValue(Prospero::ChannelLayout::k16_16_16_16),
|
TextureGetRenderTargetFormat(Prospero::GpuEnumValue(Prospero::ChannelLayout::k16_16_16_16),
|
||||||
Prospero::GpuEnumValue(Prospero::ChannelType::kFloat),
|
Prospero::GpuEnumValue(Prospero::ChannelType::kFloat),
|
||||||
@@ -6506,6 +6506,116 @@ void TestRenderTargetReverseFloat16ExportMapping() {
|
|||||||
Prospero::GpuEnumValue(Prospero::ChannelOrder::kAlt));
|
Prospero::GpuEnumValue(Prospero::ChannelOrder::kAlt));
|
||||||
Check(legacy_alt.format == vk::Format::eB8G8R8A8Unorm && legacy_alt.export_mapping.IsIdentity(),
|
Check(legacy_alt.format == vk::Format::eB8G8R8A8Unorm && legacy_alt.export_mapping.IsIdentity(),
|
||||||
"legacy BGRA render target acquired a duplicate shader export mapping");
|
"legacy BGRA render target acquired a duplicate shader export mapping");
|
||||||
|
const auto gr32 =
|
||||||
|
TextureGetRenderTargetFormat(Prospero::GpuEnumValue(Prospero::ChannelLayout::k32_32),
|
||||||
|
Prospero::GpuEnumValue(Prospero::ChannelType::kFloat),
|
||||||
|
Prospero::GpuEnumValue(Prospero::ChannelOrder::kReversed));
|
||||||
|
Check(gr32.format == vk::Format::eR32G32Sfloat && gr32.bytes_per_element == 8u &&
|
||||||
|
gr32.export_mapping == Prospero::ColorMappingGr,
|
||||||
|
"reverse GR32F render target did not retain its native host format, "
|
||||||
|
"size, and mapping");
|
||||||
|
|
||||||
|
struct MappingCase {
|
||||||
|
Prospero::ChannelLayout layout;
|
||||||
|
Prospero::ChannelType type;
|
||||||
|
vk::Format format;
|
||||||
|
uint32_t bytes;
|
||||||
|
std::array<Prospero::ColorComponentMapping, 4> mappings;
|
||||||
|
};
|
||||||
|
const MappingCase mapping_cases[] = {
|
||||||
|
{Prospero::ChannelLayout::k8,
|
||||||
|
Prospero::ChannelType::kUInt,
|
||||||
|
vk::Format::eR8Uint,
|
||||||
|
1,
|
||||||
|
{Prospero::ColorMappingRgba, Prospero::ColorMappingGr, Prospero::ColorMappingBgra,
|
||||||
|
Prospero::ColorMappingAgba}},
|
||||||
|
{Prospero::ChannelLayout::k32_32,
|
||||||
|
Prospero::ChannelType::kFloat,
|
||||||
|
vk::Format::eR32G32Sfloat,
|
||||||
|
8,
|
||||||
|
{Prospero::ColorMappingRgba, Prospero::ColorMappingRabg, Prospero::ColorMappingGr,
|
||||||
|
Prospero::ColorMappingArbg}},
|
||||||
|
{Prospero::ChannelLayout::k5_6_5,
|
||||||
|
Prospero::ChannelType::kUNorm,
|
||||||
|
vk::Format::eB5G6R5UnormPack16,
|
||||||
|
2,
|
||||||
|
{Prospero::ColorMappingRgba, Prospero::ColorMappingRgab, Prospero::ColorMappingBgra,
|
||||||
|
Prospero::ColorMappingAgbr}},
|
||||||
|
{Prospero::ChannelLayout::k16_16_16_16,
|
||||||
|
Prospero::ChannelType::kFloat,
|
||||||
|
vk::Format::eR16G16B16A16Sfloat,
|
||||||
|
8,
|
||||||
|
{Prospero::ColorMappingRgba, Prospero::ColorMappingBgra, Prospero::ColorMappingAbgr,
|
||||||
|
Prospero::ColorMappingArgb}},
|
||||||
|
};
|
||||||
|
for (const auto& mapping_case: mapping_cases) {
|
||||||
|
for (uint32_t order = 0; order < 4u; order++) {
|
||||||
|
const auto info =
|
||||||
|
TextureGetRenderTargetFormat(Prospero::GpuEnumValue(mapping_case.layout),
|
||||||
|
Prospero::GpuEnumValue(mapping_case.type), order);
|
||||||
|
Check(info.format == mapping_case.format &&
|
||||||
|
info.bytes_per_element == mapping_case.bytes &&
|
||||||
|
info.export_mapping == mapping_case.mappings[order],
|
||||||
|
"render-target channel order did not use the component-count "
|
||||||
|
"mapping");
|
||||||
|
for (uint32_t physical = 0; physical < 4u; physical++) {
|
||||||
|
const auto logical = info.export_mapping.Map(physical);
|
||||||
|
Check(info.export_mapping.ApplyMask(1u << logical) == (1u << physical),
|
||||||
|
"logical color write mask was not mapped to the inverse physical "
|
||||||
|
"component");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto alt_1010102 =
|
||||||
|
TextureGetRenderTargetFormat(Prospero::GpuEnumValue(Prospero::ChannelLayout::k10_10_10_2),
|
||||||
|
Prospero::GpuEnumValue(Prospero::ChannelType::kUNorm),
|
||||||
|
Prospero::GpuEnumValue(Prospero::ChannelOrder::kAlt));
|
||||||
|
Check(alt_1010102.format == vk::Format::eA2R10G10B10UnormPack32 &&
|
||||||
|
alt_1010102.export_mapping.IsIdentity(),
|
||||||
|
"native alternate 10:10:10:2 render target acquired a shader mapping");
|
||||||
|
const auto reversed_4444 =
|
||||||
|
TextureGetRenderTargetFormat(Prospero::GpuEnumValue(Prospero::ChannelLayout::k4_4_4_4),
|
||||||
|
Prospero::GpuEnumValue(Prospero::ChannelType::kUNorm),
|
||||||
|
Prospero::GpuEnumValue(Prospero::ChannelOrder::kReversed));
|
||||||
|
Check(reversed_4444.format == vk::Format::eR4G4B4A4UnormPack16 &&
|
||||||
|
reversed_4444.export_mapping.IsIdentity(),
|
||||||
|
"reversed 4:4:4:4 render target did not compose storage and channel "
|
||||||
|
"order");
|
||||||
|
const auto standard_4444 =
|
||||||
|
TextureGetRenderTargetFormat(Prospero::GpuEnumValue(Prospero::ChannelLayout::k4_4_4_4),
|
||||||
|
Prospero::GpuEnumValue(Prospero::ChannelType::kUNorm),
|
||||||
|
Prospero::GpuEnumValue(Prospero::ChannelOrder::kStandard));
|
||||||
|
Check(standard_4444.format == vk::Format::eR4G4B4A4UnormPack16 &&
|
||||||
|
standard_4444.export_mapping == Prospero::ColorMappingAbgr,
|
||||||
|
"standard 4:4:4:4 render target did not compensate host packed-bit "
|
||||||
|
"order");
|
||||||
|
const auto standard_5551 =
|
||||||
|
TextureGetRenderTargetFormat(Prospero::GpuEnumValue(Prospero::ChannelLayout::k5_5_5_1),
|
||||||
|
Prospero::GpuEnumValue(Prospero::ChannelType::kUNorm),
|
||||||
|
Prospero::GpuEnumValue(Prospero::ChannelOrder::kStandard));
|
||||||
|
Check(standard_5551.format == vk::Format::eA1R5G5B5UnormPack16 &&
|
||||||
|
standard_5551.export_mapping == Prospero::ColorMappingBgra,
|
||||||
|
"5:5:5:1 render target did not preserve its high one-bit component");
|
||||||
|
const auto standard_1555 =
|
||||||
|
TextureGetRenderTargetFormat(Prospero::GpuEnumValue(Prospero::ChannelLayout::k1_5_5_5),
|
||||||
|
Prospero::GpuEnumValue(Prospero::ChannelType::kUNorm),
|
||||||
|
Prospero::GpuEnumValue(Prospero::ChannelOrder::kStandard));
|
||||||
|
Check(standard_1555.format == vk::Format::eR5G5B5A1UnormPack16 &&
|
||||||
|
standard_1555.export_mapping == Prospero::ColorMappingAbgr,
|
||||||
|
"1:5:5:5 render target did not preserve its low one-bit component");
|
||||||
|
|
||||||
|
const auto argb =
|
||||||
|
TextureGetRenderTargetFormat(Prospero::GpuEnumValue(Prospero::ChannelLayout::k16_16_16_16),
|
||||||
|
Prospero::GpuEnumValue(Prospero::ChannelType::kFloat),
|
||||||
|
Prospero::GpuEnumValue(Prospero::ChannelOrder::kAltReversed));
|
||||||
|
Check(argb.export_mapping == Prospero::ColorMappingArgb &&
|
||||||
|
argb.export_mapping.ApplyMask(0x1u) == 0x2u &&
|
||||||
|
argb.export_mapping.ApplyMask(0x2u) == 0x4u &&
|
||||||
|
argb.export_mapping.ApplyMask(0x4u) == 0x8u &&
|
||||||
|
argb.export_mapping.ApplyMask(0x8u) == 0x1u,
|
||||||
|
"alternate-reversed render-target mapping did not invert its "
|
||||||
|
"non-involutive cycle");
|
||||||
|
|
||||||
const uint32_t shader[] = {
|
const uint32_t shader[] = {
|
||||||
EncodeExp0(0x00, 0xf),
|
EncodeExp0(0x00, 0xf),
|
||||||
@@ -6532,6 +6642,21 @@ void TestRenderTargetReverseFloat16ExportMapping() {
|
|||||||
"reverse MRT export did not emit a WZYX component shuffle");
|
"reverse MRT export did not emit a WZYX component shuffle");
|
||||||
CheckSpirvBinaryValidates(reversed_result.spirv);
|
CheckSpirvBinaryValidates(reversed_result.spirv);
|
||||||
|
|
||||||
|
reversed_info.target_export_mapping[0] = gr32.export_mapping;
|
||||||
|
ShaderRecompiler::CompileResult gr32_result;
|
||||||
|
Check(ShaderRecompiler::TryRecompile(shader, options, gr32_result, &error), error.c_str());
|
||||||
|
Check(SpirvContainsVectorShuffle(gr32_result.spirv, {1u, 0u, 2u, 3u}),
|
||||||
|
"reverse GR32F MRT export did not emit a YXZW component shuffle");
|
||||||
|
CheckSpirvBinaryValidates(gr32_result.spirv);
|
||||||
|
|
||||||
|
reversed_info.target_export_mapping[0] = argb.export_mapping;
|
||||||
|
ShaderRecompiler::CompileResult argb_result;
|
||||||
|
Check(ShaderRecompiler::TryRecompile(shader, options, argb_result, &error), error.c_str());
|
||||||
|
Check(SpirvContainsVectorShuffle(argb_result.spirv, {3u, 0u, 1u, 2u}),
|
||||||
|
"alternate-reversed MRT export did not emit an ARGB component shuffle");
|
||||||
|
CheckSpirvBinaryValidates(argb_result.spirv);
|
||||||
|
reversed_info.target_export_mapping[0] = gr32.export_mapping;
|
||||||
|
|
||||||
HW::PixelShaderInfo regs {};
|
HW::PixelShaderInfo regs {};
|
||||||
Check(ShaderGetIdPS(regs, identity_info, false) != ShaderGetIdPS(regs, reversed_info, false),
|
Check(ShaderGetIdPS(regs, identity_info, false) != ShaderGetIdPS(regs, reversed_info, false),
|
||||||
"pixel shader cache identity omitted the render-target export mapping");
|
"pixel shader cache identity omitted the render-target export mapping");
|
||||||
@@ -6545,17 +6670,18 @@ void TestRenderTargetReverseFloat16ExportMapping() {
|
|||||||
ShaderVertexInputInfo vs_info {};
|
ShaderVertexInputInfo vs_info {};
|
||||||
vs_info.stage.program = std::make_shared<ShaderRecompiler::IR::Program>();
|
vs_info.stage.program = std::make_shared<ShaderRecompiler::IR::Program>();
|
||||||
std::array<Prospero::ColorComponentMapping, 8> mappings {};
|
std::array<Prospero::ColorComponentMapping, 8> mappings {};
|
||||||
mappings[0] = format.export_mapping;
|
mappings[0] = gr32.export_mapping;
|
||||||
ShaderPixelInputInfo compiled_info {};
|
ShaderPixelInputInfo compiled_info {};
|
||||||
std::span<const uint32_t> compiled_spirv;
|
std::span<const uint32_t> compiled_spirv;
|
||||||
Check(ShaderCompileInfoPS(regs, sh, ShaderLaneMaskMode::NativeWave, vs_info, mappings,
|
Check(ShaderCompileInfoPS(regs, sh, ShaderLaneMaskMode::NativeWave, vs_info, mappings,
|
||||||
compiled_info, compiled_spirv) &&
|
compiled_info, compiled_spirv) &&
|
||||||
compiled_info.target_export_mapping[0].IsIdentity(),
|
compiled_info.target_export_mapping[0].IsIdentity(),
|
||||||
"inactive reverse MRT mapping was not normalized out of the shader cache key");
|
"inactive reverse MRT mapping was not normalized out of the shader "
|
||||||
|
"cache key");
|
||||||
sh.target_output_mode[0] = 4;
|
sh.target_output_mode[0] = 4;
|
||||||
Check(ShaderCompileInfoPS(regs, sh, ShaderLaneMaskMode::NativeWave, vs_info, mappings,
|
Check(ShaderCompileInfoPS(regs, sh, ShaderLaneMaskMode::NativeWave, vs_info, mappings,
|
||||||
compiled_info, compiled_spirv) &&
|
compiled_info, compiled_spirv) &&
|
||||||
compiled_info.target_export_mapping[0] == format.export_mapping,
|
compiled_info.target_export_mapping[0] == gr32.export_mapping,
|
||||||
"active reverse MRT mapping was lost before shader specialization");
|
"active reverse MRT mapping was lost before shader specialization");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -7625,7 +7751,7 @@ int main() {
|
|||||||
TestNewShaderRecompilerVertexExportUsesLaneExecMask();
|
TestNewShaderRecompilerVertexExportUsesLaneExecMask();
|
||||||
TestNewShaderRecompilerPerInvocationMasks();
|
TestNewShaderRecompilerPerInvocationMasks();
|
||||||
TestNewShaderRecompilerExpPixelOutputs();
|
TestNewShaderRecompilerExpPixelOutputs();
|
||||||
TestRenderTargetReverseFloat16ExportMapping();
|
TestRenderTargetReverseExportMapping();
|
||||||
TestNewShaderRecompilerEarlyZDisabledWhenPixelKillEnabled();
|
TestNewShaderRecompilerEarlyZDisabledWhenPixelKillEnabled();
|
||||||
TestScalarProvenanceRealWideMoveLowering();
|
TestScalarProvenanceRealWideMoveLowering();
|
||||||
TestScalarProvenanceRealCarryAndScalarLoads();
|
TestScalarProvenanceRealCarryAndScalarLoads();
|
||||||
|
|||||||
Reference in New Issue
Block a user