[vk] Fix F32/U32 missing conversions where the format is A8R8G8B8_UINT and vk requires the format to actually be inbdexed by an integer composite op (texel fetch)

Signed-off-by: lizzie <lizzie@eden-emu.dev>
This commit is contained in:
lizzie 2026-02-09 22:59:35 +00:00
parent f40e675aa2
commit 5cd6f7d6c0
9 changed files with 218 additions and 331 deletions

View File

@ -142,15 +142,20 @@ Id GetCbuf(EmitContext& ctx, Id result_type, Id UniformDefinitions::*member_ptr,
const auto is_float = UniformDefinitions::IsFloat(member_ptr);
const auto num_elements = UniformDefinitions::NumElements(member_ptr);
const std::array zero_vec{
is_float ? ctx.Const(0.0f) : ctx.Const(0u),
is_float ? ctx.Const(0.0f) : ctx.Const(0u),
is_float ? ctx.Const(0.0f) : ctx.Const(0u),
is_float ? ctx.Const(0.0f) : ctx.Const(0u),
};
const Id cond = ctx.OpULessThanEqual(ctx.TypeBool(), buffer_offset, ctx.Const(0xFFFFu));
const Id zero = ctx.OpCompositeConstruct(result_type, std::span(zero_vec.data(), num_elements));
return ctx.OpSelect(result_type, cond, val, zero);
if (num_elements > 1) {
const std::array zero_vec{
is_float ? ctx.Const(0.0f) : ctx.Const(0u),
is_float ? ctx.Const(0.0f) : ctx.Const(0u),
is_float ? ctx.Const(0.0f) : ctx.Const(0u),
is_float ? ctx.Const(0.0f) : ctx.Const(0u),
};
const Id zero = ctx.OpCompositeConstruct(result_type, std::span(zero_vec.data(), num_elements));
return ctx.OpSelect(result_type, cond, val, zero);
} else {
const Id zero = is_float ? ctx.Const(0.0f) : ctx.Const(0u);
return ctx.OpSelect(result_type, cond, val, zero);
}
}
Id GetCbufU32(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset) {

View File

@ -11,6 +11,7 @@
#include "shader_recompiler/backend/spirv/emit_spirv_instructions.h"
#include "shader_recompiler/backend/spirv/spirv_emit_context.h"
#include "shader_recompiler/frontend/ir/modifiers.h"
#include "shader_recompiler/shader_info.h"
namespace Shader::Backend::SPIRV {
namespace {
@ -70,8 +71,7 @@ public:
}
}
explicit ImageOperands(EmitContext& ctx, bool has_lod_clamp, Id derivatives,
u32 num_derivatives, const IR::Value& offset, Id lod_clamp) {
explicit ImageOperands(EmitContext& ctx, bool has_lod_clamp, Id derivatives, u32 num_derivatives, const IR::Value& offset, Id lod_clamp) {
if (!Sirit::ValidId(derivatives)) {
throw LogicError("Derivatives must be present");
}
@ -81,10 +81,8 @@ public:
deriv_x_accum.push_back(ctx.OpCompositeExtract(ctx.F32[1], derivatives, i * 2));
deriv_y_accum.push_back(ctx.OpCompositeExtract(ctx.F32[1], derivatives, i * 2 + 1));
}
const Id derivatives_X{ctx.OpCompositeConstruct(
ctx.F32[num_derivatives], std::span{deriv_x_accum.data(), deriv_x_accum.size()})};
const Id derivatives_Y{ctx.OpCompositeConstruct(
ctx.F32[num_derivatives], std::span{deriv_y_accum.data(), deriv_y_accum.size()})};
const Id derivatives_X{ctx.OpCompositeConstruct(ctx.F32[num_derivatives], std::span{deriv_x_accum.data(), deriv_x_accum.size()})};
const Id derivatives_Y{ctx.OpCompositeConstruct(ctx.F32[num_derivatives], std::span{deriv_y_accum.data(), deriv_y_accum.size()})};
Add(spv::ImageOperandsMask::Grad, derivatives_X, derivatives_Y);
AddOffset(ctx, offset, ImageGradientOffsetAllowed);
if (has_lod_clamp) {
@ -197,20 +195,14 @@ Id Texture(EmitContext& ctx, IR::TextureInstInfo info, [[maybe_unused]] const IR
}
Id TextureImage(EmitContext& ctx, IR::TextureInstInfo info, const IR::Value& index) {
if (!index.IsImmediate() || index.U32() != 0) {
throw NotImplementedException("Indirect image indexing");
}
UNIMPLEMENTED_IF_MSG(!index.IsImmediate() || index.U32() != 0, "Indirect image indexing");
if (info.type == TextureType::Buffer) {
const TextureBufferDefinition& def{ctx.texture_buffers.at(info.descriptor_index)};
if (def.count > 1) {
throw NotImplementedException("Indirect texture sample");
}
return ctx.OpLoad(ctx.image_buffer_type, def.id);
UNIMPLEMENTED_IF(def.count > 1);
return ctx.OpLoad(ctx.image_buffer_types[info.descriptor_index], def.id);
} else {
const TextureDefinition& def{ctx.textures.at(info.descriptor_index)};
if (def.count > 1) {
throw NotImplementedException("Indirect texture sample");
}
UNIMPLEMENTED_IF(def.count > 1);
return ctx.OpImage(def.image_type, ctx.OpLoad(def.sampled_type, def.id));
}
}
@ -533,13 +525,10 @@ Id EmitImageGatherDref(EmitContext& ctx, IR::Inst* inst, const IR::Value& index,
if (ctx.profile.need_gather_subpixel_offset) {
coords = ImageGatherSubpixelOffset(ctx, info, TextureImage(ctx, info, index), coords);
}
return Emit(&EmitContext::OpImageSparseDrefGather, &EmitContext::OpImageDrefGather, ctx, inst,
ctx.F32[4], Texture(ctx, info, index), coords, dref, operands.MaskOptional(),
operands.Span());
return Emit(&EmitContext::OpImageSparseDrefGather, &EmitContext::OpImageDrefGather, ctx, inst, ctx.F32[4], Texture(ctx, info, index), coords, dref, operands.MaskOptional(), operands.Span());
}
Id EmitImageFetch(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, Id offset,
Id lod, Id ms) {
Id EmitImageFetch(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, Id offset, Id lod, Id ms) {
const auto info{inst->Flags<IR::TextureInstInfo>()};
AddOffsetToCoordinates(ctx, info, coords, offset);
if (info.type == TextureType::Buffer) {
@ -549,9 +538,14 @@ Id EmitImageFetch(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id c
// This image is multisampled, lod must be implicit
lod = Id{};
}
const auto is_integer = info.type == TextureType::Buffer
? ctx.texture_buffers.at(info.descriptor_index).is_integer
: ctx.textures.at(info.descriptor_index).is_integer;
const ImageOperands operands(lod, ms);
return Emit(&EmitContext::OpImageSparseFetch, &EmitContext::OpImageFetch, ctx, inst, ctx.F32[4],
TextureImage(ctx, info, index), coords, operands.MaskOptional(), operands.Span());
auto const result = Emit(&EmitContext::OpImageSparseFetch, &EmitContext::OpImageFetch, ctx, inst,
is_integer ? ctx.U32[4] : ctx.F32[4], TextureImage(ctx, info, index), coords, operands.MaskOptional(), operands.Span());
// TODO: Is this even correct?????
return is_integer ? ctx.OpConvertUToF(ctx.F32[4], result) : result;
}
Id EmitImageQueryDimensions(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id lod,
@ -593,14 +587,11 @@ Id EmitImageQueryLod(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, I
zero, zero);
}
Id EmitImageGradient(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords,
Id derivatives, const IR::Value& offset, Id lod_clamp) {
Id EmitImageGradient(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, Id derivatives, const IR::Value& offset, Id lod_clamp) {
const auto info{inst->Flags<IR::TextureInstInfo>()};
const auto operands = info.num_derivatives == 3
? ImageOperands(ctx, info.has_lod_clamp != 0, derivatives,
ctx.Def(offset), {}, lod_clamp)
: ImageOperands(ctx, info.has_lod_clamp != 0, derivatives,
info.num_derivatives, offset, lod_clamp);
? ImageOperands(ctx, info.has_lod_clamp != 0, derivatives, ctx.Def(offset), {}, lod_clamp)
: ImageOperands(ctx, info.has_lod_clamp != 0, derivatives, info.num_derivatives, offset, lod_clamp);
return Emit(&EmitContext::OpImageSparseSampleExplicitLod,
&EmitContext::OpImageSampleExplicitLod, ctx, inst, ctx.F32[4],
Texture(ctx, info, index), coords, operands.Mask(), operands.Span());

View File

@ -30,9 +30,9 @@ enum class Operation {
Id ImageType(EmitContext& ctx, const TextureDescriptor& desc) {
const spv::ImageFormat format{spv::ImageFormat::Unknown};
const Id type{ctx.F32[1]};
const bool depth{desc.is_depth};
const bool ms{desc.is_multisample};
const Id type = desc.is_integer ? ctx.U32[1] : ctx.F32[1];
const bool depth = desc.is_depth;
const bool ms = desc.is_multisample;
switch (desc.type) {
case TextureType::Color1D:
return ctx.TypeImage(type, spv::Dim::Dim1D, depth, false, false, 1, format);
@ -1304,22 +1304,23 @@ void EmitContext::DefineTextureBuffers(const Info& info, u32& binding) {
if (info.texture_buffer_descriptors.empty()) {
return;
}
const spv::ImageFormat format{spv::ImageFormat::Unknown};
image_buffer_type = TypeImage(F32[1], spv::Dim::Buffer, 0U, false, false, 1, format);
const Id type{TypePointer(spv::StorageClass::UniformConstant, image_buffer_type)};
const spv::ImageFormat format = spv::ImageFormat::Unknown;
texture_buffers.reserve(info.texture_buffer_descriptors.size());
for (const TextureBufferDescriptor& desc : info.texture_buffer_descriptors) {
if (desc.count != 1) {
throw NotImplementedException("Array of texture buffers");
}
const Id id{AddGlobalVariable(type, spv::StorageClass::UniformConstant)};
for (size_t i = 0; i < info.texture_buffer_descriptors.size(); ++i) {
auto const& desc = info.texture_buffer_descriptors[i];
UNIMPLEMENTED_IF(desc.count != 1);
image_buffer_types[i] = TypeImage(desc.is_integer ? U32[1] : F32[1], spv::Dim::Buffer, 0U, false, false, 1, format);
const Id type = TypePointer(spv::StorageClass::UniformConstant, image_buffer_types[i]);
const Id id = AddGlobalVariable(type, spv::StorageClass::UniformConstant);
Decorate(id, spv::Decoration::Binding, binding);
Decorate(id, spv::Decoration::DescriptorSet, 0U);
Name(id, NameOf(stage, desc, "texbuf"));
texture_buffers.push_back({
.id = id,
.count = desc.count,
.is_integer = desc.is_integer
});
if (profile.supported_spirv >= 0x00010400) {
interfaces.push_back(id);
@ -1374,6 +1375,7 @@ void EmitContext::DefineTextures(const Info& info, u32& binding, u32& scaling_in
.image_type = image_type,
.count = desc.count,
.is_multisample = desc.is_multisample,
.is_integer = desc.is_integer
});
if (profile.supported_spirv >= 0x00010400) {
interfaces.push_back(id);

View File

@ -41,11 +41,13 @@ struct TextureDefinition {
Id image_type;
u32 count;
bool is_multisample;
bool is_integer;
};
struct TextureBufferDefinition {
Id id;
u32 count;
bool is_integer;
};
struct ImageBufferDefinition {
@ -248,7 +250,8 @@ public:
Id output_f32{};
Id output_u32{};
Id image_buffer_type{};
// Max TextureBuffers?
std::array<Id, Info::MAX_CBUFS> image_buffer_types{};
Id image_u32{};
std::array<UniformDefinitions, Info::MAX_CBUFS> cbufs{};

View File

@ -429,7 +429,7 @@ public:
texture_descriptors{texture_descriptors_}, image_descriptors{image_descriptors_} {}
u32 Add(const TextureBufferDescriptor& desc) {
return Add(texture_buffer_descriptors, desc, [&desc](const auto& existing) {
const u32 index = Add(texture_buffer_descriptors, desc, [&desc](const auto& existing) {
return desc.cbuf_index == existing.cbuf_index &&
desc.cbuf_offset == existing.cbuf_offset &&
desc.shift_left == existing.shift_left &&
@ -439,6 +439,8 @@ public:
desc.count == existing.count && desc.size_shift == existing.size_shift &&
desc.has_secondary == existing.has_secondary;
});
texture_buffer_descriptors[index].is_integer |= desc.is_integer;
return index;
}
u32 Add(const ImageBufferDescriptor& desc) {
@ -465,7 +467,8 @@ public:
desc.secondary_shift_left == existing.secondary_shift_left &&
desc.count == existing.count && desc.size_shift == existing.size_shift;
})};
// TODO: Read this from TIC
texture_descriptors[index].is_integer |= desc.is_integer;
// TODO: Read this from TIC (the MSAA whatever)
texture_descriptors[index].is_multisample |= desc.is_multisample;
return index;
}
@ -632,6 +635,7 @@ void TexturePass(Environment& env, IR::Program& program, const HostTranslateInfo
break;
}
u32 index;
const bool is_integer = IsTexturePixelFormatIntegerCached(env, cbuf);
switch (inst->GetOpcode()) {
case IR::Opcode::ImageRead:
case IR::Opcode::ImageAtomicIAdd32:
@ -649,9 +653,8 @@ void TexturePass(Environment& env, IR::Program& program, const HostTranslateInfo
if (cbuf.has_secondary) {
throw NotImplementedException("Unexpected separate sampler");
}
const bool is_written{inst->GetOpcode() != IR::Opcode::ImageRead};
const bool is_read{inst->GetOpcode() != IR::Opcode::ImageWrite};
const bool is_integer{IsTexturePixelFormatIntegerCached(env, cbuf)};
const bool is_written = inst->GetOpcode() != IR::Opcode::ImageRead;
const bool is_read = inst->GetOpcode() != IR::Opcode::ImageWrite;
if (flags.type == TextureType::Buffer) {
index = descriptors.Add(ImageBufferDescriptor{
.format = flags.image_format,
@ -682,6 +685,7 @@ void TexturePass(Environment& env, IR::Program& program, const HostTranslateInfo
if (flags.type == TextureType::Buffer) {
index = descriptors.Add(TextureBufferDescriptor{
.has_secondary = cbuf.has_secondary,
.is_integer = is_integer,
.cbuf_index = cbuf.index,
.cbuf_offset = cbuf.offset,
.shift_left = cbuf.shift_left,
@ -696,6 +700,7 @@ void TexturePass(Environment& env, IR::Program& program, const HostTranslateInfo
.type = flags.type,
.is_depth = flags.is_depth != 0,
.is_multisample = is_multisample,
.is_integer = is_integer,
.has_secondary = cbuf.has_secondary,
.cbuf_index = cbuf.index,
.cbuf_offset = cbuf.offset,

View File

@ -178,6 +178,7 @@ struct StorageBufferDescriptor {
struct TextureBufferDescriptor {
bool has_secondary;
bool is_integer;
u32 cbuf_index;
u32 cbuf_offset;
u32 shift_left;
@ -209,6 +210,7 @@ struct TextureDescriptor {
TextureType type;
bool is_depth;
bool is_multisample;
bool is_integer;
bool has_secondary;
u32 cbuf_index;
u32 cbuf_offset;

View File

@ -65,9 +65,7 @@ static Shader::TextureType ConvertTextureType(const Tegra::Texture::TICEntry& en
}
static Shader::TexturePixelFormat ConvertTexturePixelFormat(const Tegra::Texture::TICEntry& entry) {
return static_cast<Shader::TexturePixelFormat>(
PixelFormatFromTextureInfo(entry.format, entry.r_type, entry.g_type, entry.b_type,
entry.a_type, entry.srgb_conversion));
return Shader::TexturePixelFormat(PixelFormatFromTextureInfo(entry.format, entry.r_type, entry.g_type, entry.b_type, entry.a_type, entry.srgb_conversion));
}
static std::string_view StageToPrefix(Shader::Stage stage) {
@ -388,8 +386,7 @@ Shader::TexturePixelFormat GraphicsEnvironment::ReadTexturePixelFormat(u32 handl
}
bool GraphicsEnvironment::IsTexturePixelFormatInteger(u32 handle) {
return VideoCore::Surface::IsPixelFormatInteger(
static_cast<VideoCore::Surface::PixelFormat>(ReadTexturePixelFormat(handle)));
return VideoCore::Surface::IsPixelFormatInteger(VideoCore::Surface::PixelFormat(ReadTexturePixelFormat(handle)));
}
u32 GraphicsEnvironment::ReadViewportTransformState() {
@ -443,8 +440,7 @@ Shader::TexturePixelFormat ComputeEnvironment::ReadTexturePixelFormat(u32 handle
}
bool ComputeEnvironment::IsTexturePixelFormatInteger(u32 handle) {
return VideoCore::Surface::IsPixelFormatInteger(
static_cast<VideoCore::Surface::PixelFormat>(ReadTexturePixelFormat(handle)));
return VideoCore::Surface::IsPixelFormatInteger(VideoCore::Surface::PixelFormat(ReadTexturePixelFormat(handle)));
}
u32 ComputeEnvironment::ReadViewportTransformState() {
@ -551,8 +547,7 @@ Shader::TexturePixelFormat FileEnvironment::ReadTexturePixelFormat(u32 handle) {
}
bool FileEnvironment::IsTexturePixelFormatInteger(u32 handle) {
return VideoCore::Surface::IsPixelFormatInteger(
static_cast<VideoCore::Surface::PixelFormat>(ReadTexturePixelFormat(handle)));
return VideoCore::Surface::IsPixelFormatInteger(VideoCore::Surface::PixelFormat(ReadTexturePixelFormat(handle)));
}
u32 FileEnvironment::ReadViewportTransformState() {

View File

@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: 2014 Citra Emulator Project
@ -242,39 +242,39 @@ SurfaceType GetFormatType(PixelFormat pixel_format) {
bool HasAlpha(PixelFormat pixel_format) {
switch (pixel_format) {
case PixelFormat::A8B8G8R8_UNORM:
case PixelFormat::A8B8G8R8_SNORM:
case PixelFormat::A8B8G8R8_SINT:
case PixelFormat::A8B8G8R8_UINT:
case PixelFormat::A1R5G5B5_UNORM:
case PixelFormat::A2B10G10R10_UNORM:
case PixelFormat::A2B10G10R10_UINT:
case PixelFormat::A2R10G10B10_UNORM:
case PixelFormat::A1B5G5R5_UNORM:
case PixelFormat::A5B5G5R1_UNORM:
case PixelFormat::R16G16B16A16_FLOAT:
case PixelFormat::R16G16B16A16_UNORM:
case PixelFormat::R16G16B16A16_SNORM:
case PixelFormat::R16G16B16A16_SINT:
case PixelFormat::R16G16B16A16_UINT:
case PixelFormat::R32G32B32A32_UINT:
case PixelFormat::BC1_RGBA_UNORM:
case PixelFormat::B8G8R8A8_UNORM:
case PixelFormat::R32G32B32A32_FLOAT:
case PixelFormat::R32G32B32A32_SINT:
case PixelFormat::A8B8G8R8_SRGB:
case PixelFormat::B8G8R8A8_SRGB:
case PixelFormat::BC1_RGBA_SRGB:
case PixelFormat::A4B4G4R4_UNORM:
case PixelFormat::BC2_SRGB:
case PixelFormat::BC2_UNORM:
case PixelFormat::BC3_SRGB:
case PixelFormat::BC3_UNORM:
case PixelFormat::BC7_SRGB:
case PixelFormat::BC7_UNORM:
return true;
default:
return false;
case PixelFormat::A8B8G8R8_UNORM:
case PixelFormat::A8B8G8R8_SNORM:
case PixelFormat::A8B8G8R8_SINT:
case PixelFormat::A8B8G8R8_UINT:
case PixelFormat::A1R5G5B5_UNORM:
case PixelFormat::A2B10G10R10_UNORM:
case PixelFormat::A2B10G10R10_UINT:
case PixelFormat::A2R10G10B10_UNORM:
case PixelFormat::A1B5G5R5_UNORM:
case PixelFormat::A5B5G5R1_UNORM:
case PixelFormat::R16G16B16A16_FLOAT:
case PixelFormat::R16G16B16A16_UNORM:
case PixelFormat::R16G16B16A16_SNORM:
case PixelFormat::R16G16B16A16_SINT:
case PixelFormat::R16G16B16A16_UINT:
case PixelFormat::R32G32B32A32_UINT:
case PixelFormat::BC1_RGBA_UNORM:
case PixelFormat::B8G8R8A8_UNORM:
case PixelFormat::R32G32B32A32_FLOAT:
case PixelFormat::R32G32B32A32_SINT:
case PixelFormat::A8B8G8R8_SRGB:
case PixelFormat::B8G8R8A8_SRGB:
case PixelFormat::BC1_RGBA_SRGB:
case PixelFormat::A4B4G4R4_UNORM:
case PixelFormat::BC2_SRGB:
case PixelFormat::BC2_UNORM:
case PixelFormat::BC3_SRGB:
case PixelFormat::BC3_UNORM:
case PixelFormat::BC7_SRGB:
case PixelFormat::BC7_UNORM:
return true;
default:
return false;
}
}

View File

@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@ -11,243 +14,124 @@ using Tegra::Texture::ComponentType;
using Tegra::Texture::TextureFormat;
using VideoCore::Surface::PixelFormat;
namespace {
constexpr auto SNORM = ComponentType::SNORM;
constexpr auto UNORM = ComponentType::UNORM;
constexpr auto SINT = ComponentType::SINT;
constexpr auto UINT = ComponentType::UINT;
constexpr auto FLOAT = ComponentType::FLOAT;
constexpr bool LINEAR = false;
constexpr bool SRGB = true;
constexpr u32 Hash(TextureFormat format, ComponentType red_component, ComponentType green_component,
ComponentType blue_component, ComponentType alpha_component, bool is_srgb) {
u32 hash = is_srgb ? 1 : 0;
hash |= static_cast<u32>(red_component) << 1;
hash |= static_cast<u32>(green_component) << 4;
hash |= static_cast<u32>(blue_component) << 7;
hash |= static_cast<u32>(alpha_component) << 10;
hash |= static_cast<u32>(format) << 13;
return hash;
}
// (TF2PF_ELEM[A-Z_0-9(]+, )([A-Z]+)(, LINEAR|. SRGB)
// $1$2, $2, $2, $2$3
#define TF2PF_LIST \
TF2PF_ELEM(A8B8G8R8, UNORM, UNORM, UNORM, UNORM, LINEAR, A8B8G8R8_UNORM) \
TF2PF_ELEM(A8B8G8R8, UNORM, UNORM, UNORM, UNORM, SRGB, A8B8G8R8_SRGB) \
TF2PF_ELEM(A8B8G8R8, SNORM, SNORM, SNORM, SNORM, LINEAR, A8B8G8R8_SNORM) \
TF2PF_ELEM(A8B8G8R8, UINT, UINT, UINT, UINT, LINEAR, A8B8G8R8_UINT) \
TF2PF_ELEM(A8B8G8R8, SINT, SINT, SINT, SINT, LINEAR, A8B8G8R8_SINT) \
TF2PF_ELEM(B5G6R5, UNORM, UNORM, UNORM, UNORM, LINEAR, B5G6R5_UNORM) \
TF2PF_ELEM(A2B10G10R10, UNORM, UNORM, UNORM, UNORM, LINEAR, A2B10G10R10_UNORM) \
TF2PF_ELEM(A2B10G10R10, UINT, UINT, UINT, UINT, LINEAR, A2B10G10R10_UINT) \
TF2PF_ELEM(A1B5G5R5, UNORM, UNORM, UNORM, UNORM, LINEAR, A1B5G5R5_UNORM) \
TF2PF_ELEM(A4B4G4R4, UNORM, UNORM, UNORM, UNORM, LINEAR, A4B4G4R4_UNORM) \
TF2PF_ELEM(G4R4, UNORM, UNORM, UNORM, UNORM, LINEAR, G4R4_UNORM) \
TF2PF_ELEM(A5B5G5R1, UNORM, UNORM, UNORM, UNORM, LINEAR, A5B5G5R1_UNORM) \
TF2PF_ELEM(R8, UNORM, UNORM, UNORM, UNORM, LINEAR, R8_UNORM) \
TF2PF_ELEM(R8, SNORM, SNORM, SNORM, SNORM, LINEAR, R8_SNORM) \
TF2PF_ELEM(R8, UINT, UINT, UINT, UINT, LINEAR, R8_UINT) \
TF2PF_ELEM(R8, SINT, SINT, SINT, SINT, LINEAR, R8_SINT) \
TF2PF_ELEM(G8R8, UNORM, UNORM, UNORM, UNORM, LINEAR, R8G8_UNORM) \
TF2PF_ELEM(G8R8, SNORM, SNORM, SNORM, SNORM, LINEAR, R8G8_SNORM) \
TF2PF_ELEM(G8R8, UINT, UINT, UINT, UINT, LINEAR, R8G8_UINT) \
TF2PF_ELEM(G8R8, SINT, SINT, SINT, SINT, LINEAR, R8G8_SINT) \
TF2PF_ELEM(R16G16B16A16, FLOAT, FLOAT, FLOAT, FLOAT, LINEAR, R16G16B16A16_FLOAT) \
TF2PF_ELEM(R16G16B16A16, UNORM, UNORM, UNORM, UNORM, LINEAR, R16G16B16A16_UNORM) \
TF2PF_ELEM(R16G16B16A16, SNORM, SNORM, SNORM, SNORM, LINEAR, R16G16B16A16_SNORM) \
TF2PF_ELEM(R16G16B16A16, UINT, UINT, UINT, UINT, LINEAR, R16G16B16A16_UINT) \
TF2PF_ELEM(R16G16B16A16, SINT, SINT, SINT, SINT, LINEAR, R16G16B16A16_SINT) \
TF2PF_ELEM(R16G16, FLOAT, FLOAT, FLOAT, FLOAT, LINEAR, R16G16_FLOAT) \
TF2PF_ELEM(R16G16, UNORM, UNORM, UNORM, UNORM, LINEAR, R16G16_UNORM) \
TF2PF_ELEM(R16G16, SNORM, SNORM, SNORM, SNORM, LINEAR, R16G16_SNORM) \
TF2PF_ELEM(R16G16, UINT, UINT, UINT, UINT, LINEAR, R16G16_UINT) \
TF2PF_ELEM(R16G16, SINT, SINT, SINT, SINT, LINEAR, R16G16_SINT) \
TF2PF_ELEM(R16, FLOAT, FLOAT, FLOAT, FLOAT, LINEAR, R16_FLOAT) \
TF2PF_ELEM(R16, UNORM, UNORM, UNORM, UNORM, LINEAR, R16_UNORM) \
TF2PF_ELEM(R16, SNORM, SNORM, SNORM, SNORM, LINEAR, R16_SNORM) \
TF2PF_ELEM(R16, UINT, UINT, UINT, UINT, LINEAR, R16_UINT) \
TF2PF_ELEM(R16, SINT, SINT, SINT, SINT, LINEAR, R16_SINT) \
TF2PF_ELEM(B10G11R11, FLOAT, FLOAT, FLOAT, FLOAT, LINEAR, B10G11R11_FLOAT) \
TF2PF_ELEM(R32G32B32A32, FLOAT, FLOAT, FLOAT, FLOAT, LINEAR, R32G32B32A32_FLOAT) \
TF2PF_ELEM(R32G32B32A32, UINT, UINT, UINT, UINT, LINEAR, R32G32B32A32_UINT) \
TF2PF_ELEM(R32G32B32A32, SINT, SINT, SINT, SINT, LINEAR, R32G32B32A32_SINT) \
TF2PF_ELEM(R32G32B32, FLOAT, FLOAT, FLOAT, FLOAT, LINEAR, R32G32B32_FLOAT) \
TF2PF_ELEM(R32G32, FLOAT, FLOAT, FLOAT, FLOAT, LINEAR, R32G32_FLOAT) \
TF2PF_ELEM(R32G32, UINT, UINT, UINT, UINT, LINEAR, R32G32_UINT) \
TF2PF_ELEM(R32G32, SINT, SINT, SINT, SINT, LINEAR, R32G32_SINT) \
TF2PF_ELEM(R32, FLOAT, FLOAT, FLOAT, FLOAT, LINEAR, R32_FLOAT) \
TF2PF_ELEM(R32, UINT, UINT, UINT, UINT, LINEAR, R32_UINT) \
TF2PF_ELEM(R32, SINT, SINT, SINT, SINT, LINEAR, R32_SINT) \
TF2PF_ELEM(E5B9G9R9, FLOAT, FLOAT, FLOAT, FLOAT, LINEAR, E5B9G9R9_FLOAT) \
TF2PF_ELEM(Z32, FLOAT, FLOAT, FLOAT, FLOAT, LINEAR, D32_FLOAT) \
TF2PF_ELEM(Z32, FLOAT, UINT, UINT, UINT, LINEAR, D32_FLOAT) \
TF2PF_ELEM(Z16, UNORM, UNORM, UNORM, UNORM, LINEAR, D16_UNORM) \
TF2PF_ELEM(Z16, UNORM, UINT, UINT, UINT, LINEAR, D16_UNORM) \
TF2PF_ELEM(X8Z24, UNORM, UNORM, UNORM, UNORM, LINEAR, X8_D24_UNORM) \
TF2PF_ELEM(X8Z24, UNORM, UINT, UINT, UINT, LINEAR, X8_D24_UNORM) \
TF2PF_ELEM(Z24S8, UINT, UNORM, UNORM, UNORM, LINEAR, S8_UINT_D24_UNORM) \
TF2PF_ELEM(Z24S8, UINT, UNORM, UINT, UINT, LINEAR, S8_UINT_D24_UNORM) \
TF2PF_ELEM(G24R8, UINT, UNORM, UNORM, UNORM, LINEAR, S8_UINT_D24_UNORM) \
TF2PF_ELEM(S8Z24, UNORM, UINT, UINT, UINT, LINEAR, D24_UNORM_S8_UINT) \
TF2PF_ELEM(Z32_X24S8, FLOAT, UINT, UNORM, UNORM, LINEAR, D32_FLOAT_S8_UINT) \
TF2PF_ELEM(R32B24G8, FLOAT, UINT, UNORM, UNORM, LINEAR, D32_FLOAT_S8_UINT) \
TF2PF_ELEM(DXT1, UNORM, UNORM, UNORM, UNORM, LINEAR, BC1_RGBA_UNORM) \
TF2PF_ELEM(DXT1, UNORM, UNORM, UNORM, UNORM, SRGB, BC1_RGBA_SRGB) \
TF2PF_ELEM(DXT23, UNORM, UNORM, UNORM, UNORM, LINEAR, BC2_UNORM) \
TF2PF_ELEM(DXT23, UNORM, UNORM, UNORM, UNORM, SRGB, BC2_SRGB) \
TF2PF_ELEM(DXT45, UNORM, UNORM, UNORM, UNORM, LINEAR, BC3_UNORM) \
TF2PF_ELEM(DXT45, UNORM, UNORM, UNORM, UNORM, SRGB, BC3_SRGB) \
TF2PF_ELEM(DXN1, UNORM, UNORM, UNORM, UNORM, LINEAR, BC4_UNORM) \
TF2PF_ELEM(DXN1, SNORM, SNORM, SNORM, SNORM, LINEAR, BC4_SNORM) \
TF2PF_ELEM(DXN2, UNORM, UNORM, UNORM, UNORM, LINEAR, BC5_UNORM) \
TF2PF_ELEM(DXN2, SNORM, SNORM, SNORM, SNORM, LINEAR, BC5_SNORM) \
TF2PF_ELEM(BC7U, UNORM, UNORM, UNORM, UNORM, LINEAR, BC7_UNORM) \
TF2PF_ELEM(BC7U, UNORM, UNORM, UNORM, UNORM, SRGB, BC7_SRGB) \
TF2PF_ELEM(BC6H_S16, FLOAT, FLOAT, FLOAT, FLOAT, LINEAR, BC6H_SFLOAT) \
TF2PF_ELEM(BC6H_U16, FLOAT, FLOAT, FLOAT, FLOAT, LINEAR, BC6H_UFLOAT) \
TF2PF_ELEM(ASTC_2D_4X4, UNORM, UNORM, UNORM, UNORM, LINEAR, ASTC_2D_4X4_UNORM) \
TF2PF_ELEM(ASTC_2D_4X4, UNORM, UNORM, UNORM, UNORM, SRGB, ASTC_2D_4X4_SRGB) \
TF2PF_ELEM(ASTC_2D_5X4, UNORM, UNORM, UNORM, UNORM, LINEAR, ASTC_2D_5X4_UNORM) \
TF2PF_ELEM(ASTC_2D_5X4, UNORM, UNORM, UNORM, UNORM, SRGB, ASTC_2D_5X4_SRGB) \
TF2PF_ELEM(ASTC_2D_5X5, UNORM, UNORM, UNORM, UNORM, LINEAR, ASTC_2D_5X5_UNORM) \
TF2PF_ELEM(ASTC_2D_5X5, UNORM, UNORM, UNORM, UNORM, SRGB, ASTC_2D_5X5_SRGB) \
TF2PF_ELEM(ASTC_2D_8X8, UNORM, UNORM, UNORM, UNORM, LINEAR, ASTC_2D_8X8_UNORM) \
TF2PF_ELEM(ASTC_2D_8X8, UNORM, UNORM, UNORM, UNORM, SRGB, ASTC_2D_8X8_SRGB) \
TF2PF_ELEM(ASTC_2D_8X5, UNORM, UNORM, UNORM, UNORM, LINEAR, ASTC_2D_8X5_UNORM) \
TF2PF_ELEM(ASTC_2D_8X5, UNORM, UNORM, UNORM, UNORM, SRGB, ASTC_2D_8X5_SRGB) \
TF2PF_ELEM(ASTC_2D_10X8, UNORM, UNORM, UNORM, UNORM, LINEAR, ASTC_2D_10X8_UNORM) \
TF2PF_ELEM(ASTC_2D_10X8, UNORM, UNORM, UNORM, UNORM, SRGB, ASTC_2D_10X8_SRGB) \
TF2PF_ELEM(ASTC_2D_6X6, UNORM, UNORM, UNORM, UNORM, LINEAR, ASTC_2D_6X6_UNORM) \
TF2PF_ELEM(ASTC_2D_6X6, UNORM, UNORM, UNORM, UNORM, SRGB, ASTC_2D_6X6_SRGB) \
TF2PF_ELEM(ASTC_2D_10X6, UNORM, UNORM, UNORM, UNORM, LINEAR, ASTC_2D_10X6_UNORM) \
TF2PF_ELEM(ASTC_2D_10X6, UNORM, UNORM, UNORM, UNORM, SRGB, ASTC_2D_10X6_SRGB) \
TF2PF_ELEM(ASTC_2D_10X5, UNORM, UNORM, UNORM, UNORM, LINEAR, ASTC_2D_10X5_UNORM) \
TF2PF_ELEM(ASTC_2D_10X5, UNORM, UNORM, UNORM, UNORM, SRGB, ASTC_2D_10X5_SRGB) \
TF2PF_ELEM(ASTC_2D_10X10, UNORM, UNORM, UNORM, UNORM, LINEAR, ASTC_2D_10X10_UNORM) \
TF2PF_ELEM(ASTC_2D_10X10, UNORM, UNORM, UNORM, UNORM, SRGB, ASTC_2D_10X10_SRGB) \
TF2PF_ELEM(ASTC_2D_12X10, UNORM, UNORM, UNORM, UNORM, LINEAR, ASTC_2D_12X10_UNORM) \
TF2PF_ELEM(ASTC_2D_12X10, UNORM, UNORM, UNORM, UNORM, SRGB, ASTC_2D_12X10_SRGB) \
TF2PF_ELEM(ASTC_2D_12X12, UNORM, UNORM, UNORM, UNORM, LINEAR, ASTC_2D_12X12_UNORM) \
TF2PF_ELEM(ASTC_2D_12X12, UNORM, UNORM, UNORM, UNORM, SRGB, ASTC_2D_12X12_SRGB) \
TF2PF_ELEM(ASTC_2D_8X6, UNORM, UNORM, UNORM, UNORM, LINEAR, ASTC_2D_8X6_UNORM) \
TF2PF_ELEM(ASTC_2D_8X6, UNORM, UNORM, UNORM, UNORM, SRGB, ASTC_2D_8X6_SRGB) \
TF2PF_ELEM(ASTC_2D_6X5, UNORM, UNORM, UNORM, UNORM, LINEAR, ASTC_2D_6X5_UNORM) \
TF2PF_ELEM(ASTC_2D_6X5, UNORM, UNORM, UNORM, UNORM, SRGB, ASTC_2D_6X5_SRGB) \
constexpr u32 Hash(TextureFormat format, ComponentType component, bool is_srgb = LINEAR) {
return Hash(format, component, component, component, component, is_srgb);
}
} // Anonymous namespace
PixelFormat PixelFormatFromTextureInfo(TextureFormat format, ComponentType red, ComponentType green,
ComponentType blue, ComponentType alpha,
bool is_srgb) noexcept {
switch (Hash(format, red, green, blue, alpha, is_srgb)) {
case Hash(TextureFormat::A8B8G8R8, UNORM):
return PixelFormat::A8B8G8R8_UNORM;
case Hash(TextureFormat::A8B8G8R8, SNORM):
return PixelFormat::A8B8G8R8_SNORM;
case Hash(TextureFormat::A8B8G8R8, UINT):
return PixelFormat::A8B8G8R8_UINT;
case Hash(TextureFormat::A8B8G8R8, SINT):
return PixelFormat::A8B8G8R8_SINT;
case Hash(TextureFormat::A8B8G8R8, UNORM, SRGB):
return PixelFormat::A8B8G8R8_SRGB;
case Hash(TextureFormat::B5G6R5, UNORM):
return PixelFormat::B5G6R5_UNORM;
case Hash(TextureFormat::A2B10G10R10, UNORM):
return PixelFormat::A2B10G10R10_UNORM;
case Hash(TextureFormat::A2B10G10R10, UINT):
return PixelFormat::A2B10G10R10_UINT;
case Hash(TextureFormat::A1B5G5R5, UNORM):
return PixelFormat::A1B5G5R5_UNORM;
case Hash(TextureFormat::A4B4G4R4, UNORM):
return PixelFormat::A4B4G4R4_UNORM;
case Hash(TextureFormat::G4R4, UNORM):
return PixelFormat::G4R4_UNORM;
case Hash(TextureFormat::A5B5G5R1, UNORM):
return PixelFormat::A5B5G5R1_UNORM;
case Hash(TextureFormat::R8, UNORM):
return PixelFormat::R8_UNORM;
case Hash(TextureFormat::R8, SNORM):
return PixelFormat::R8_SNORM;
case Hash(TextureFormat::R8, UINT):
return PixelFormat::R8_UINT;
case Hash(TextureFormat::R8, SINT):
return PixelFormat::R8_SINT;
case Hash(TextureFormat::G8R8, UNORM):
return PixelFormat::R8G8_UNORM;
case Hash(TextureFormat::G8R8, SNORM):
return PixelFormat::R8G8_SNORM;
case Hash(TextureFormat::G8R8, UINT):
return PixelFormat::R8G8_UINT;
case Hash(TextureFormat::G8R8, SINT):
return PixelFormat::R8G8_SINT;
case Hash(TextureFormat::R16G16B16A16, FLOAT):
return PixelFormat::R16G16B16A16_FLOAT;
case Hash(TextureFormat::R16G16B16A16, UNORM):
return PixelFormat::R16G16B16A16_UNORM;
case Hash(TextureFormat::R16G16B16A16, SNORM):
return PixelFormat::R16G16B16A16_SNORM;
case Hash(TextureFormat::R16G16B16A16, UINT):
return PixelFormat::R16G16B16A16_UINT;
case Hash(TextureFormat::R16G16B16A16, SINT):
return PixelFormat::R16G16B16A16_SINT;
case Hash(TextureFormat::R16G16, FLOAT):
return PixelFormat::R16G16_FLOAT;
case Hash(TextureFormat::R16G16, UNORM):
return PixelFormat::R16G16_UNORM;
case Hash(TextureFormat::R16G16, SNORM):
return PixelFormat::R16G16_SNORM;
case Hash(TextureFormat::R16G16, UINT):
return PixelFormat::R16G16_UINT;
case Hash(TextureFormat::R16G16, SINT):
return PixelFormat::R16G16_SINT;
case Hash(TextureFormat::R16, FLOAT):
return PixelFormat::R16_FLOAT;
case Hash(TextureFormat::R16, UNORM):
return PixelFormat::R16_UNORM;
case Hash(TextureFormat::R16, SNORM):
return PixelFormat::R16_SNORM;
case Hash(TextureFormat::R16, UINT):
return PixelFormat::R16_UINT;
case Hash(TextureFormat::R16, SINT):
return PixelFormat::R16_SINT;
case Hash(TextureFormat::B10G11R11, FLOAT):
return PixelFormat::B10G11R11_FLOAT;
case Hash(TextureFormat::R32G32B32A32, FLOAT):
return PixelFormat::R32G32B32A32_FLOAT;
case Hash(TextureFormat::R32G32B32A32, UINT):
return PixelFormat::R32G32B32A32_UINT;
case Hash(TextureFormat::R32G32B32A32, SINT):
return PixelFormat::R32G32B32A32_SINT;
case Hash(TextureFormat::R32G32B32, FLOAT):
return PixelFormat::R32G32B32_FLOAT;
case Hash(TextureFormat::R32G32, FLOAT):
return PixelFormat::R32G32_FLOAT;
case Hash(TextureFormat::R32G32, UINT):
return PixelFormat::R32G32_UINT;
case Hash(TextureFormat::R32G32, SINT):
return PixelFormat::R32G32_SINT;
case Hash(TextureFormat::R32, FLOAT):
return PixelFormat::R32_FLOAT;
case Hash(TextureFormat::R32, UINT):
return PixelFormat::R32_UINT;
case Hash(TextureFormat::R32, SINT):
return PixelFormat::R32_SINT;
case Hash(TextureFormat::E5B9G9R9, FLOAT):
return PixelFormat::E5B9G9R9_FLOAT;
case Hash(TextureFormat::Z32, FLOAT):
return PixelFormat::D32_FLOAT;
case Hash(TextureFormat::Z32, FLOAT, UINT, UINT, UINT, LINEAR):
return PixelFormat::D32_FLOAT;
case Hash(TextureFormat::Z16, UNORM):
return PixelFormat::D16_UNORM;
case Hash(TextureFormat::Z16, UNORM, UINT, UINT, UINT, LINEAR):
return PixelFormat::D16_UNORM;
case Hash(TextureFormat::X8Z24, UNORM):
return PixelFormat::X8_D24_UNORM;
case Hash(TextureFormat::X8Z24, UNORM, UINT, UINT, UINT, LINEAR):
return PixelFormat::X8_D24_UNORM;
case Hash(TextureFormat::Z24S8, UINT, UNORM, UNORM, UNORM, LINEAR):
return PixelFormat::S8_UINT_D24_UNORM;
case Hash(TextureFormat::Z24S8, UINT, UNORM, UINT, UINT, LINEAR):
return PixelFormat::S8_UINT_D24_UNORM;
case Hash(TextureFormat::G24R8, UINT, UNORM, UNORM, UNORM, LINEAR):
return PixelFormat::S8_UINT_D24_UNORM;
case Hash(TextureFormat::S8Z24, UNORM, UINT, UINT, UINT, LINEAR):
return PixelFormat::D24_UNORM_S8_UINT;
case Hash(TextureFormat::Z32_X24S8, FLOAT, UINT, UNORM, UNORM, LINEAR):
return PixelFormat::D32_FLOAT_S8_UINT;
case Hash(TextureFormat::R32B24G8, FLOAT, UINT, UNORM, UNORM, LINEAR):
return PixelFormat::D32_FLOAT_S8_UINT;
case Hash(TextureFormat::DXT1, UNORM, LINEAR):
return PixelFormat::BC1_RGBA_UNORM;
case Hash(TextureFormat::DXT1, UNORM, SRGB):
return PixelFormat::BC1_RGBA_SRGB;
case Hash(TextureFormat::DXT23, UNORM, LINEAR):
return PixelFormat::BC2_UNORM;
case Hash(TextureFormat::DXT23, UNORM, SRGB):
return PixelFormat::BC2_SRGB;
case Hash(TextureFormat::DXT45, UNORM, LINEAR):
return PixelFormat::BC3_UNORM;
case Hash(TextureFormat::DXT45, UNORM, SRGB):
return PixelFormat::BC3_SRGB;
case Hash(TextureFormat::DXN1, UNORM):
return PixelFormat::BC4_UNORM;
case Hash(TextureFormat::DXN1, SNORM):
return PixelFormat::BC4_SNORM;
case Hash(TextureFormat::DXN2, UNORM):
return PixelFormat::BC5_UNORM;
case Hash(TextureFormat::DXN2, SNORM):
return PixelFormat::BC5_SNORM;
case Hash(TextureFormat::BC7U, UNORM, LINEAR):
return PixelFormat::BC7_UNORM;
case Hash(TextureFormat::BC7U, UNORM, SRGB):
return PixelFormat::BC7_SRGB;
case Hash(TextureFormat::BC6H_S16, FLOAT):
return PixelFormat::BC6H_SFLOAT;
case Hash(TextureFormat::BC6H_U16, FLOAT):
return PixelFormat::BC6H_UFLOAT;
case Hash(TextureFormat::ASTC_2D_4X4, UNORM, LINEAR):
return PixelFormat::ASTC_2D_4X4_UNORM;
case Hash(TextureFormat::ASTC_2D_4X4, UNORM, SRGB):
return PixelFormat::ASTC_2D_4X4_SRGB;
case Hash(TextureFormat::ASTC_2D_5X4, UNORM, LINEAR):
return PixelFormat::ASTC_2D_5X4_UNORM;
case Hash(TextureFormat::ASTC_2D_5X4, UNORM, SRGB):
return PixelFormat::ASTC_2D_5X4_SRGB;
case Hash(TextureFormat::ASTC_2D_5X5, UNORM, LINEAR):
return PixelFormat::ASTC_2D_5X5_UNORM;
case Hash(TextureFormat::ASTC_2D_5X5, UNORM, SRGB):
return PixelFormat::ASTC_2D_5X5_SRGB;
case Hash(TextureFormat::ASTC_2D_8X8, UNORM, LINEAR):
return PixelFormat::ASTC_2D_8X8_UNORM;
case Hash(TextureFormat::ASTC_2D_8X8, UNORM, SRGB):
return PixelFormat::ASTC_2D_8X8_SRGB;
case Hash(TextureFormat::ASTC_2D_8X5, UNORM, LINEAR):
return PixelFormat::ASTC_2D_8X5_UNORM;
case Hash(TextureFormat::ASTC_2D_8X5, UNORM, SRGB):
return PixelFormat::ASTC_2D_8X5_SRGB;
case Hash(TextureFormat::ASTC_2D_10X8, UNORM, LINEAR):
return PixelFormat::ASTC_2D_10X8_UNORM;
case Hash(TextureFormat::ASTC_2D_10X8, UNORM, SRGB):
return PixelFormat::ASTC_2D_10X8_SRGB;
case Hash(TextureFormat::ASTC_2D_6X6, UNORM, LINEAR):
return PixelFormat::ASTC_2D_6X6_UNORM;
case Hash(TextureFormat::ASTC_2D_6X6, UNORM, SRGB):
return PixelFormat::ASTC_2D_6X6_SRGB;
case Hash(TextureFormat::ASTC_2D_10X6, UNORM, LINEAR):
return PixelFormat::ASTC_2D_10X6_UNORM;
case Hash(TextureFormat::ASTC_2D_10X6, UNORM, SRGB):
return PixelFormat::ASTC_2D_10X6_SRGB;
case Hash(TextureFormat::ASTC_2D_10X5, UNORM, LINEAR):
return PixelFormat::ASTC_2D_10X5_UNORM;
case Hash(TextureFormat::ASTC_2D_10X5, UNORM, SRGB):
return PixelFormat::ASTC_2D_10X5_SRGB;
case Hash(TextureFormat::ASTC_2D_10X10, UNORM, LINEAR):
return PixelFormat::ASTC_2D_10X10_UNORM;
case Hash(TextureFormat::ASTC_2D_10X10, UNORM, SRGB):
return PixelFormat::ASTC_2D_10X10_SRGB;
case Hash(TextureFormat::ASTC_2D_12X10, UNORM, LINEAR):
return PixelFormat::ASTC_2D_12X10_UNORM;
case Hash(TextureFormat::ASTC_2D_12X10, UNORM, SRGB):
return PixelFormat::ASTC_2D_12X10_SRGB;
case Hash(TextureFormat::ASTC_2D_12X12, UNORM, LINEAR):
return PixelFormat::ASTC_2D_12X12_UNORM;
case Hash(TextureFormat::ASTC_2D_12X12, UNORM, SRGB):
return PixelFormat::ASTC_2D_12X12_SRGB;
case Hash(TextureFormat::ASTC_2D_8X6, UNORM, LINEAR):
return PixelFormat::ASTC_2D_8X6_UNORM;
case Hash(TextureFormat::ASTC_2D_8X6, UNORM, SRGB):
return PixelFormat::ASTC_2D_8X6_SRGB;
case Hash(TextureFormat::ASTC_2D_6X5, UNORM, LINEAR):
return PixelFormat::ASTC_2D_6X5_UNORM;
case Hash(TextureFormat::ASTC_2D_6X5, UNORM, SRGB):
return PixelFormat::ASTC_2D_6X5_SRGB;
}
UNIMPLEMENTED_MSG("texture format={} srgb={} components={{{} {} {} {}}}",
static_cast<int>(format), is_srgb, static_cast<int>(red),
static_cast<int>(green), static_cast<int>(blue), static_cast<int>(alpha));
PixelFormat PixelFormatFromTextureInfo(TextureFormat format, ComponentType red, ComponentType green, ComponentType blue, ComponentType alpha, bool is_srgb) noexcept {
if (false) { /* no op */ }
#define TF2PF_ELEM(FMT, CR, CG, CB, CA, SRGB, RES) \
else if (format == TextureFormat::FMT \
&& red == ComponentType::CR && green == ComponentType::CG \
&& blue == ComponentType::CB && alpha == ComponentType::CA \
&& is_srgb == SRGB) return PixelFormat::RES;
TF2PF_LIST
#undef TF2PF_ELEM
UNIMPLEMENTED_MSG("texture format={} srgb={} components={{{} {} {} {}}}", int(format), is_srgb, int(red), int(green), int(blue), int(alpha));
return PixelFormat::A8B8G8R8_UNORM;
}