amdgpu: cross-platform descriptors layout

This commit is contained in:
DH 2025-12-25 19:56:12 +03:00
parent 95b458939b
commit 1b077dd6f4
3 changed files with 670 additions and 177 deletions

View file

@ -195,17 +195,18 @@ void Cache::ShaderResources::loadResources(
std::memcpy(reinterpret_cast<std::uint32_t *>(&buffer) + 3, &*word3,
sizeof(std::uint32_t));
if (auto it = bufferMemoryTable.queryArea(buffer.address());
if (auto it = bufferMemoryTable.queryArea(buffer.getAddress());
it != bufferMemoryTable.end() &&
it.beginAddress() == buffer.address() && it.size() == buffer.size()) {
it.beginAddress() == buffer.getAddress() &&
it.size() == buffer.size()) {
it.get() |= bufferRes.access;
} else {
bufferMemoryTable.map(
rx::AddressRange::fromBeginSize(buffer.address(), buffer.size()),
rx::AddressRange::fromBeginSize(buffer.getAddress(), buffer.size()),
bufferRes.access);
}
resourceSlotToAddress.emplace_back(slotOffset + bufferRes.resourceSlot,
buffer.address());
buffer.getAddress());
}
for (auto &imageBuffer : res.imageBuffers) {
@ -251,24 +252,24 @@ void Cache::ShaderResources::loadResources(
}
auto info = computeSurfaceInfo(
getDefaultTileModes()[tbuffer.tiling_idx], tbuffer.type, tbuffer.dfmt,
tbuffer.width + 1, tbuffer.height + 1, tbuffer.depth + 1,
tbuffer.pitch + 1, 0, tbuffer.last_array + 1, 0, tbuffer.last_level + 1,
tbuffer.pow2pad != 0);
getDefaultTileModes()[tbuffer.getTilingIndex()], tbuffer.getType(),
tbuffer.getDataFormat(), tbuffer.getWidth(), tbuffer.getHeight(),
tbuffer.getDepth(), tbuffer.getPitch(), 0, tbuffer.getTotalArrayCount(),
0, tbuffer.getTotalLevelCount(), tbuffer.isPow2Pad());
if (auto it = imageMemoryTable.queryArea(tbuffer.address());
if (auto it = imageMemoryTable.queryArea(tbuffer.getAddress());
it != imageMemoryTable.end() &&
it.beginAddress() == tbuffer.address() &&
it.beginAddress() == tbuffer.getAddress() &&
it.size() == info.totalTiledSize) {
it.get().second |= imageBuffer.access;
} else {
imageMemoryTable.map(
rx::AddressRange::fromBeginSize(tbuffer.address(),
rx::AddressRange::fromBeginSize(tbuffer.getAddress(),
info.totalTiledSize),
{ImageBufferKey::createFrom(tbuffer), imageBuffer.access});
}
resourceSlotToAddress.emplace_back(slotOffset + imageBuffer.resourceSlot,
tbuffer.address());
tbuffer.getAddress());
}
for (auto &texture : res.textures) {
@ -315,7 +316,7 @@ void Cache::ShaderResources::loadResources(
std::vector<amdgpu::Cache::ImageView> *resources = nullptr;
switch (tbuffer.type) {
switch (tbuffer.getType()) {
case gnm::TextureType::Array1D:
case gnm::TextureType::Dim1D:
resources = &imageResources[0];
@ -333,8 +334,7 @@ void Cache::ShaderResources::loadResources(
}
rx::dieIf(resources == nullptr,
"ShaderResources: unexpected texture type %u",
static_cast<unsigned>(tbuffer.type));
"ShaderResources: unexpected texture type {}", tbuffer.getType());
slotResources[slotOffset + texture.resourceSlot] = resources->size();
resources->push_back(cacheTag->getImageView(
@ -352,7 +352,7 @@ void Cache::ShaderResources::loadResources(
rx::die("failed to evaluate S#");
}
gnm::SSampler sSampler{};
gnm::Sampler sSampler{};
std::memcpy(reinterpret_cast<std::uint32_t *>(&sSampler), &*word0,
sizeof(std::uint32_t));
std::memcpy(reinterpret_cast<std::uint32_t *>(&sSampler) + 1, &*word1,
@ -363,7 +363,7 @@ void Cache::ShaderResources::loadResources(
sizeof(std::uint32_t));
if (sampler.unorm) {
sSampler.force_unorm_coords = true;
sSampler.setForceUnormCoords(true);
}
slotResources[slotOffset + sampler.resourceSlot] = samplerResources.size();
@ -1117,12 +1117,12 @@ struct CachedImageView : Cache::Entry {
};
ImageViewKey ImageViewKey::createFrom(const gnm::TBuffer &tbuffer) {
std::uint32_t width = tbuffer.width + 1u;
std::uint32_t height = tbuffer.height + 1u;
std::uint32_t depth = tbuffer.depth + 1u;
std::uint32_t arrayLayerCount = tbuffer.last_array - tbuffer.base_array + 1u;
std::uint32_t width = tbuffer.getWidth();
std::uint32_t height = tbuffer.getHeight();
std::uint32_t depth = tbuffer.getDepth();
std::uint32_t arrayLayerCount = tbuffer.getArrayCount();
switch (tbuffer.type) {
switch (tbuffer.getType()) {
case gnm::TextureType::Dim1D:
height = 1;
[[fallthrough]];
@ -1147,39 +1147,39 @@ ImageViewKey ImageViewKey::createFrom(const gnm::TBuffer &tbuffer) {
}
return {
.readAddress = tbuffer.address(),
.writeAddress = tbuffer.address(),
.type = tbuffer.type,
.dfmt = tbuffer.dfmt,
.nfmt = tbuffer.nfmt,
.tileMode = getDefaultTileModes()[tbuffer.tiling_idx],
.readAddress = tbuffer.getAddress(),
.writeAddress = tbuffer.getAddress(),
.type = tbuffer.getType(),
.dfmt = tbuffer.getDataFormat(),
.nfmt = tbuffer.getNumericFormat(),
.tileMode = getDefaultTileModes()[tbuffer.getTilingIndex()],
.extent =
{
.width = width,
.height = height,
.depth = depth,
},
.pitch = tbuffer.pitch + 1u,
.baseMipLevel = static_cast<std::uint32_t>(tbuffer.base_level),
.mipCount = tbuffer.last_level - tbuffer.base_level + 1u,
.baseArrayLayer = static_cast<std::uint32_t>(tbuffer.base_array),
.pitch = tbuffer.getPitch(),
.baseMipLevel = static_cast<std::uint32_t>(tbuffer.getBaseLevel()),
.mipCount = tbuffer.getTotalLevelCount(),
.baseArrayLayer = static_cast<std::uint32_t>(tbuffer.getBaseArray()),
.arrayLayerCount = arrayLayerCount,
.kind = ImageKind::Color,
.pow2pad = tbuffer.pow2pad != 0,
.r = tbuffer.dst_sel_x,
.g = tbuffer.dst_sel_y,
.b = tbuffer.dst_sel_z,
.a = tbuffer.dst_sel_w,
.pow2pad = tbuffer.isPow2Pad(),
.r = tbuffer.getDstSelX(),
.g = tbuffer.getDstSelY(),
.b = tbuffer.getDstSelZ(),
.a = tbuffer.getDstSelW(),
};
}
ImageKey ImageKey::createFrom(const gnm::TBuffer &tbuffer) {
std::uint32_t width = tbuffer.width + 1u;
std::uint32_t height = tbuffer.height + 1u;
std::uint32_t depth = tbuffer.depth + 1u;
std::uint32_t arrayLayerCount = tbuffer.last_array + 1u;
std::uint32_t width = tbuffer.getWidth();
std::uint32_t height = tbuffer.getHeight();
std::uint32_t depth = tbuffer.getDepth();
std::uint32_t arrayLayerCount = tbuffer.getTotalArrayCount();
switch (tbuffer.type) {
switch (tbuffer.getType()) {
case gnm::TextureType::Dim1D:
height = 1;
[[fallthrough]];
@ -1204,25 +1204,25 @@ ImageKey ImageKey::createFrom(const gnm::TBuffer &tbuffer) {
}
return {
.readAddress = tbuffer.address(),
.writeAddress = tbuffer.address(),
.type = tbuffer.type,
.dfmt = tbuffer.dfmt,
.nfmt = tbuffer.nfmt,
.tileMode = getDefaultTileModes()[tbuffer.tiling_idx],
.readAddress = tbuffer.getAddress(),
.writeAddress = tbuffer.getAddress(),
.type = tbuffer.getType(),
.dfmt = tbuffer.getDataFormat(),
.nfmt = tbuffer.getNumericFormat(),
.tileMode = getDefaultTileModes()[tbuffer.getTilingIndex()],
.extent =
{
.width = width,
.height = height,
.depth = depth,
},
.pitch = tbuffer.pitch + 1u,
.baseMipLevel = static_cast<std::uint32_t>(tbuffer.base_level),
.mipCount = tbuffer.last_level - tbuffer.base_level + 1u,
.pitch = tbuffer.getPitch(),
.baseMipLevel = static_cast<std::uint32_t>(tbuffer.getBaseLevel()),
.mipCount = tbuffer.getLevelCount(),
.baseArrayLayer = 0,
.arrayLayerCount = arrayLayerCount,
.kind = ImageKind::Color,
.pow2pad = tbuffer.pow2pad != 0,
.pow2pad = tbuffer.isPow2Pad(),
};
}
@ -1247,22 +1247,22 @@ ImageKey ImageKey::createFrom(const ImageViewKey &imageView) {
ImageBufferKey ImageBufferKey::createFrom(const gnm::TBuffer &tbuffer) {
return {
.address = tbuffer.address(),
.type = tbuffer.type,
.dfmt = tbuffer.dfmt,
.tileMode = getDefaultTileModes()[tbuffer.tiling_idx],
.address = tbuffer.getAddress(),
.type = tbuffer.getType(),
.dfmt = tbuffer.getDataFormat(),
.tileMode = getDefaultTileModes()[tbuffer.getTilingIndex()],
.extent =
{
.width = tbuffer.width + 1u,
.height = tbuffer.height + 1u,
.depth = tbuffer.depth + 1u,
.width = tbuffer.getWidth(),
.height = tbuffer.getHeight(),
.depth = tbuffer.getDepth(),
},
.pitch = tbuffer.pitch + 1u,
.baseMipLevel = static_cast<std::uint32_t>(tbuffer.base_level),
.mipCount = tbuffer.last_level - tbuffer.base_level + 1u,
.baseArrayLayer = static_cast<std::uint32_t>(tbuffer.base_array),
.arrayLayerCount = tbuffer.last_array - tbuffer.base_array + 1u,
.pow2pad = tbuffer.pow2pad != 0,
.pitch = tbuffer.getPitch(),
.baseMipLevel = static_cast<std::uint32_t>(tbuffer.getBaseLevel()),
.mipCount = tbuffer.getLevelCount(),
.baseArrayLayer = static_cast<std::uint32_t>(tbuffer.getBaseArray()),
.arrayLayerCount = tbuffer.getArrayCount(),
.pow2pad = tbuffer.isPow2Pad(),
};
}
@ -1282,26 +1282,26 @@ ImageBufferKey ImageBufferKey::createFrom(const ImageKey &imageKey) {
};
}
SamplerKey SamplerKey::createFrom(const gnm::SSampler &sampler) {
float lodBias = sampler.lod_bias / 256.f;
SamplerKey SamplerKey::createFrom(const gnm::Sampler &sampler) {
float lodBias = sampler.getLodBias() / 256.f;
// FIXME: lodBias can be scaled by gnm::TBuffer
return {
.magFilter = toVkFilter(sampler.xy_mag_filter),
.minFilter = toVkFilter(sampler.xy_min_filter),
.mipmapMode = toVkSamplerMipmapMode(sampler.mip_filter),
.addressModeU = toVkSamplerAddressMode(sampler.clamp_x),
.addressModeV = toVkSamplerAddressMode(sampler.clamp_y),
.addressModeW = toVkSamplerAddressMode(sampler.clamp_z),
.magFilter = toVkFilter(sampler.getXYMagFilter()),
.minFilter = toVkFilter(sampler.getXYMinFilter()),
.mipmapMode = toVkSamplerMipmapMode(sampler.getMipFilter()),
.addressModeU = toVkSamplerAddressMode(sampler.getClampX()),
.addressModeV = toVkSamplerAddressMode(sampler.getClampY()),
.addressModeW = toVkSamplerAddressMode(sampler.getClampZ()),
.mipLodBias = lodBias,
.maxAnisotropy = 0, // max_aniso_ratio
.compareOp = toVkCompareOp(sampler.depth_compare_func),
.minLod = sampler.min_lod / 256.f,
.maxLod = sampler.max_lod / 256.f,
.borderColor = toVkBorderColor(sampler.border_color_type),
.compareOp = toVkCompareOp(sampler.getDepthCompareFunc()),
.minLod = sampler.getMinLod() / 256.f,
.maxLod = sampler.getMaxLod() / 256.f,
.borderColor = toVkBorderColor(sampler.getBorderColor()),
.anisotropyEnable = false,
.compareEnable = sampler.depth_compare_func != gnm::CompareFunc::Never,
.unnormalizedCoordinates = sampler.force_unorm_coords != 0,
.compareEnable = sampler.getDepthCompareFunc() != gnm::CompareFunc::Never,
.unnormalizedCoordinates = sampler.isForceUnormCoords(),
};
}

View file

@ -107,7 +107,7 @@ struct SamplerKey {
bool compareEnable;
bool unnormalizedCoordinates;
static SamplerKey createFrom(const gnm::SSampler &sampler);
static SamplerKey createFrom(const gnm::Sampler &sampler);
auto operator<=>(const SamplerKey &other) const = default;
};

View file

@ -3,124 +3,617 @@
#include "constants.hpp"
#include <compare>
#include <cstdint>
#include <rx/bits.hpp>
namespace gnm {
#pragma pack(push, 1)
struct VBuffer {
std::uint64_t base : 44;
std::uint64_t mtype_L1s : 2;
std::uint64_t mtype_L2 : 2;
std::uint64_t stride : 14;
std::uint64_t cache_swizzle : 1;
std::uint64_t swizzle_en : 1;
std::uint32_t words[4];
std::uint32_t num_records;
[[nodiscard]] constexpr std::uint64_t getAddress() const {
return words[0] |
(static_cast<std::uint64_t>(rx::getBits(words[1], 11, 0)) << 32);
}
Swizzle dst_sel_x : 3;
Swizzle dst_sel_y : 3;
Swizzle dst_sel_z : 3;
Swizzle dst_sel_w : 3;
constexpr void setAddress(std::uint64_t address) {
words[0] = static_cast<std::uint32_t>(address);
words[1] = rx::setBits(words[1], 11, 0, static_cast<std::uint32_t>(address >> 32));
}
NumericFormat nfmt : 3;
DataFormat dfmt : 4;
std::uint32_t element_size : 2;
std::uint32_t index_stride : 2;
std::uint32_t addtid_en : 1;
std::uint32_t reserved0 : 1;
std::uint32_t hash_en : 1;
std::uint32_t reserved1 : 1;
std::uint32_t mtype : 3;
std::uint32_t type : 2;
[[nodiscard]] constexpr std::uint8_t getMTypeL1() const {
return static_cast<std::uint8_t>(rx::getBits(words[1], 13, 12));
}
std::uint64_t address() const { return base; }
std::uint64_t size() const {
return stride ? num_records * stride : num_records;
constexpr void setMTypeL1(std::uint8_t value) {
words[1] = rx::setBits(words[1], 13, 12, value);
}
[[nodiscard]] constexpr std::uint8_t getMTypeL2() const {
return static_cast<std::uint8_t>(rx::getBits(words[1], 15, 14));
}
constexpr void setMTypeL2(std::uint8_t value) {
words[1] = rx::setBits(words[1], 15, 14, value);
}
[[nodiscard]] constexpr std::uint16_t getStride() const {
return static_cast<std::uint16_t>(rx::getBits(words[1], 29, 16));
}
constexpr void setStride(std::uint16_t value) {
words[1] = rx::setBits(words[1], 29, 16, value);
}
[[nodiscard]] constexpr bool isCacheSwizzle() const {
return rx::getBit(words[1], 30);
}
constexpr void setCacheSwizzle(bool value) {
words[1] = rx::setBit(words[1], 30, value);
}
[[nodiscard]] constexpr bool isSwizzleEn() const {
return rx::getBit(words[1], 31);
}
constexpr void setSwizzleEn(bool value) {
words[1] = rx::setBit(words[1], 31, value);
}
[[nodiscard]] constexpr std::uint32_t getNumRecords() const {
return words[2];
}
constexpr void setNumRecords(std::uint32_t value) {
words[2] = value;
}
[[nodiscard]] constexpr Swizzle getDstSelX() const {
return static_cast<Swizzle>(rx::getBits(words[3], 2, 0));
}
constexpr void setDstSelX(Swizzle value) {
words[3] = rx::setBits(words[3], 2, 0, static_cast<std::uint32_t>(value));
}
[[nodiscard]] constexpr Swizzle getDstSelY() const {
return static_cast<Swizzle>(rx::getBits(words[3], 5, 3));
}
constexpr void setDstSelY(Swizzle value) {
words[3] = rx::setBits(words[3], 5, 3, static_cast<std::uint32_t>(value));
}
[[nodiscard]] constexpr Swizzle getDstSelZ() const {
return static_cast<Swizzle>(rx::getBits(words[3], 8, 6));
}
constexpr void setDstSelZ(Swizzle value) {
words[3] = rx::setBits(words[3], 8, 6, static_cast<std::uint32_t>(value));
}
[[nodiscard]] constexpr Swizzle getDstSelW() const {
return static_cast<Swizzle>(rx::getBits(words[3], 11, 9));
}
constexpr void setDstSelW(Swizzle value) {
words[3] = rx::setBits(words[3], 11, 9, static_cast<std::uint32_t>(value));
}
[[nodiscard]] constexpr NumericFormat getNumericFormat() const {
return static_cast<NumericFormat>(rx::getBits(words[3], 14, 12));
}
constexpr void setNumericFormat(NumericFormat value) {
words[3] = rx::setBits(words[3], 14, 12, static_cast<std::uint32_t>(value));
}
[[nodiscard]] constexpr DataFormat getDataFormat() const {
return static_cast<DataFormat>(rx::getBits(words[3], 18, 15));
}
constexpr void setDataFormat(DataFormat value) {
words[3] = rx::setBits(words[3], 18, 15, static_cast<std::uint32_t>(value));
}
[[nodiscard]] constexpr std::uint32_t getElementSize() const {
return rx::getBits(words[3], 20, 19);
}
constexpr void setElementSize(std::uint32_t value) {
words[3] = rx::setBits(words[3], 20, 19, value);
}
[[nodiscard]] constexpr std::uint32_t getIndexStride() const {
return rx::getBits(words[3], 22, 21);
}
constexpr void setIndexStride(std::uint32_t value) {
words[3] = rx::setBits(words[3], 22, 21, value);
}
[[nodiscard]] constexpr bool isAddTidEn() const {
return rx::getBit(words[3], 23);
}
constexpr void setAddTidEn(bool value) {
words[3] = rx::setBit(words[3], 23, value);
}
[[nodiscard]] constexpr bool isHashEn() const {
return rx::getBit(words[3], 25);
}
constexpr void setHashEn(bool value) {
words[3] = rx::setBit(words[3], 25, value);
}
[[nodiscard]] constexpr std::uint8_t getMType() const {
return rx::getBits(words[3], 29, 27);
}
constexpr void setMType(std::uint8_t value) {
words[3] = rx::setBits(words[3], 29, 27, value);
}
[[nodiscard]] constexpr std::uint8_t getType() const {
return rx::getBits(words[3], 31, 30);
}
constexpr void setType(std::uint8_t value) {
words[3] = rx::setBits(words[3], 31, 30, value);
}
[[nodiscard]] constexpr std::uint64_t size() const {
std::uint64_t result = getNumRecords();
if (auto stride = getStride()) {
result *= stride;
}
return result;
}
auto operator<=>(const VBuffer &) const = default;
};
static_assert(sizeof(VBuffer) == sizeof(std::uint64_t) * 2);
struct TBuffer {
uint64_t baseaddr256 : 38;
uint64_t mtype_L2 : 2;
uint64_t min_lod : 12;
DataFormat dfmt : 6;
NumericFormat nfmt : 4;
uint64_t mtype01 : 2;
std::uint32_t words[8];
uint64_t width : 14;
uint64_t height : 14;
uint64_t perfMod : 3;
uint64_t interlaced : 1;
Swizzle dst_sel_x : 3;
Swizzle dst_sel_y : 3;
Swizzle dst_sel_z : 3;
Swizzle dst_sel_w : 3;
uint64_t base_level : 4;
uint64_t last_level : 4;
uint64_t tiling_idx : 5;
uint64_t pow2pad : 1;
uint64_t mtype2 : 1;
uint64_t : 1; // reserved
TextureType type : 4;
uint64_t depth : 13;
uint64_t pitch : 14;
uint64_t : 5; // reserved
uint64_t base_array : 13;
uint64_t last_array : 13;
uint64_t : 6; // reserved
uint64_t min_lod_warn : 12; // fixed point 4.8
uint64_t counter_bank_id : 8;
uint64_t LOD_hdw_cnt_en : 1;
uint64_t : 42; // reserved
std::uint64_t address() const {
return static_cast<std::uint64_t>(static_cast<std::uint32_t>(baseaddr256))
[[nodiscard]] constexpr std::uint64_t getAddress() const {
return (words[0] |
(static_cast<std::uint64_t>(rx::getBits(words[1], 5, 0)) << 32))
<< 8;
}
constexpr void setAddress(std::uint64_t address) {
address >>= 8;
words[0] = static_cast<std::uint32_t>(address);
words[1] = rx::setBits(words[1], 5, 0, static_cast<std::uint32_t>(address >> 32));
}
[[nodiscard]] constexpr std::uint8_t getMTypeL2() const {
return static_cast<std::uint8_t>(rx::getBits(words[1], 7, 6));
}
constexpr void setMTypeL2(std::uint8_t value) {
words[1] = rx::setBits(words[1], 7, 6, value);
}
[[nodiscard]] constexpr std::uint16_t getMinLod() const {
return static_cast<std::uint16_t>(rx::getBits(words[1], 19, 8));
}
constexpr void setMinLod(std::uint16_t value) {
words[1] = rx::setBits(words[1], 19, 8, value);
}
[[nodiscard]] constexpr DataFormat getDataFormat() const {
return static_cast<DataFormat>(rx::getBits(words[1], 25, 20));
}
constexpr void setDataFormat(DataFormat value) {
words[1] = rx::setBits(words[1], 25, 20, static_cast<std::uint32_t>(value));
}
[[nodiscard]] constexpr NumericFormat getNumericFormat() const {
return static_cast<NumericFormat>(rx::getBits(words[1], 29, 26));
}
constexpr void setNumericFormat(NumericFormat value) {
words[1] = rx::setBits(words[1], 29, 26, static_cast<std::uint32_t>(value));
}
[[nodiscard]] constexpr std::uint8_t getMType() const {
return rx::getBits(words[1], 31, 30) | (rx::getBits(words[2], 27, 26) << 2);
}
constexpr void setMType(std::uint8_t value) {
words[1] = rx::setBits(words[1], 31, 30, value & 0x3);
words[2] = rx::setBits(words[2], 27, 26, (value >> 2) & 0x3);
}
[[nodiscard]] constexpr std::uint16_t getWidth() const {
return rx::getBits(words[2], 13, 0) + 1;
}
constexpr void setWidth(std::uint16_t value) {
words[2] = rx::setBits(words[2], 13, 0, value - 1);
}
[[nodiscard]] constexpr std::uint16_t getHeight() const {
return rx::getBits(words[2], 27, 14) + 1;
}
constexpr void setHeight(std::uint16_t value) {
words[2] = rx::setBits(words[2], 27, 14, value - 1);
}
[[nodiscard]] constexpr std::uint16_t getPerfMod() const {
return rx::getBits(words[2], 30, 28);
}
constexpr void setPerfMod(std::uint16_t value) {
words[2] = rx::setBits(words[2], 30, 28, value);
}
[[nodiscard]] constexpr bool isInterlaced() const {
return rx::getBit(words[2], 31);
}
constexpr void setInterlaced(bool value) {
words[2] = rx::setBit(words[2], 31, value);
}
[[nodiscard]] constexpr Swizzle getDstSelX() const {
return static_cast<Swizzle>(rx::getBits(words[3], 2, 0));
}
constexpr void setDstSelX(Swizzle value) {
words[3] = rx::setBits(words[3], 2, 0, static_cast<std::uint32_t>(value));
}
[[nodiscard]] constexpr Swizzle getDstSelY() const {
return static_cast<Swizzle>(rx::getBits(words[3], 5, 3));
}
constexpr void setDstSelY(Swizzle value) {
words[3] = rx::setBits(words[3], 5, 3, static_cast<std::uint32_t>(value));
}
[[nodiscard]] constexpr Swizzle getDstSelZ() const {
return static_cast<Swizzle>(rx::getBits(words[3], 8, 6));
}
constexpr void setDstSelZ(Swizzle value) {
words[3] = rx::setBits(words[3], 8, 6, static_cast<std::uint32_t>(value));
}
[[nodiscard]] constexpr Swizzle getDstSelW() const {
return static_cast<Swizzle>(rx::getBits(words[3], 11, 9));
}
constexpr void setDstSelW(Swizzle value) {
words[3] = rx::setBits(words[3], 11, 9, static_cast<std::uint32_t>(value));
}
[[nodiscard]] constexpr std::uint32_t getBaseLevel() const {
return rx::getBits(words[3], 15, 12);
}
constexpr void setBaseLevel(std::uint32_t value) {
words[3] = rx::setBits(words[3], 15, 12, value);
}
[[nodiscard]] constexpr std::uint32_t getLastLevel() const {
return rx::getBits(words[3], 19, 16);
}
constexpr void setLastLevel(std::uint32_t value) {
words[3] = rx::setBits(words[3], 19, 16, value);
}
[[nodiscard]] constexpr std::uint32_t getTilingIndex() const {
return rx::getBits(words[3], 24, 20);
}
constexpr void setTilingIndex(std::uint32_t value) {
words[3] = rx::setBits(words[3], 24, 20, value);
}
[[nodiscard]] constexpr bool isPow2Pad() const {
return rx::getBit(words[3], 25);
}
constexpr void setPow2Pad(bool value) {
words[3] = rx::setBit(words[3], 25, value);
}
[[nodiscard]] constexpr TextureType getType() const {
return static_cast<TextureType>(rx::getBits(words[3], 31, 28));
}
constexpr void setType(TextureType value) {
words[3] = rx::setBits(words[3], 31, 28, static_cast<std::uint32_t>(value));
}
[[nodiscard]] constexpr std::uint16_t getDepth() const {
return rx::getBits(words[4], 12, 0) + 1;
}
constexpr void setDepth(std::uint16_t value) {
words[4] = rx::setBits(words[4], 12, 0, value - 1);
}
[[nodiscard]] constexpr std::uint16_t getPitch() const {
return rx::getBits(words[4], 26, 13) + 1;
}
constexpr void setPitch(std::uint16_t value) {
words[4] = rx::setBits(words[4], 26, 13, value - 1);
}
[[nodiscard]] constexpr std::uint16_t getBaseArray() const {
return rx::getBits(words[5], 12, 0);
}
constexpr void setBaseArray(std::uint16_t value) {
words[5] = rx::setBits(words[5], 12, 0, value);
}
[[nodiscard]] constexpr std::uint16_t getLastArray() const {
return rx::getBits(words[5], 25, 13);
}
constexpr void setLastArray(std::uint16_t value) {
words[5] = rx::setBits(words[5], 25, 13, value);
}
[[nodiscard]] constexpr std::uint16_t getMinLodWarn() const {
return rx::getBits(words[6], 11, 0);
}
constexpr void setMinLodWarn(std::uint16_t value) {
words[6] = rx::setBits(words[6], 11, 0, value);
}
[[nodiscard]] constexpr std::uint16_t getCounterBankId() const {
return rx::getBits(words[6], 19, 12);
}
constexpr void setCounterBankId(std::uint16_t value) {
words[6] = rx::setBits(words[6], 19, 12, value);
}
[[nodiscard]] constexpr bool isLodHwCounterEn() const {
return rx::getBit(words[6], 20);
}
constexpr void setLodHwCounterEn(bool value) {
words[6] = rx::setBit(words[6], 20, value);
}
[[nodiscard]] constexpr std::uint32_t getTotalArrayCount() const {
return getLastArray() + 1;
}
[[nodiscard]] constexpr std::uint32_t getTotalLevelCount() const {
return getLastLevel() + 1;
}
[[nodiscard]] constexpr std::uint32_t getArrayCount() const {
return getTotalArrayCount() - getBaseArray();
}
[[nodiscard]] constexpr std::uint32_t getLevelCount() const {
return getTotalLevelCount() - getBaseLevel();
}
auto operator<=>(const TBuffer &) const = default;
};
static_assert(sizeof(TBuffer) == sizeof(std::uint64_t) * 4);
struct Sampler {
std::uint32_t words[4];
struct SSampler {
ClampMode clamp_x : 3;
ClampMode clamp_y : 3;
ClampMode clamp_z : 3;
AnisoRatio max_aniso_ratio : 3;
CompareFunc depth_compare_func : 3;
int32_t force_unorm_coords : 1;
int32_t aniso_threshold : 3;
int32_t mc_coord_trunc : 1;
int32_t force_degamma : 1;
int32_t aniso_bias : 6;
int32_t trunc_coord : 1;
int32_t disable_cube_wrap : 1;
FilterMode filter_mode : 2;
int32_t : 1;
uint32_t min_lod : 12;
uint32_t max_lod : 12;
int32_t perf_mip : 4;
int32_t perf_z : 4;
int32_t lod_bias : 14;
int32_t lod_bias_sec : 6;
Filter xy_mag_filter : 2;
Filter xy_min_filter : 2;
Filter z_filter : 2;
MipFilter mip_filter : 2;
int32_t : 4;
int32_t border_color_ptr : 12;
int32_t : 18;
BorderColor border_color_type : 2;
[[nodiscard]] constexpr ClampMode getClampX() const {
return static_cast<ClampMode>(rx::getBits(words[0], 2, 0));
}
auto operator<=>(const SSampler &) const = default;
constexpr void setClampX(ClampMode value) {
words[0] = rx::setBits(words[0], 2, 0, static_cast<std::uint32_t>(value));
}
[[nodiscard]] constexpr ClampMode getClampY() const {
return static_cast<ClampMode>(rx::getBits(words[0], 5, 3));
}
constexpr void setClampY(ClampMode value) {
words[0] = rx::setBits(words[0], 5, 3, static_cast<std::uint32_t>(value));
}
[[nodiscard]] constexpr ClampMode getClampZ() const {
return static_cast<ClampMode>(rx::getBits(words[0], 8, 6));
}
constexpr void setClampZ(ClampMode value) {
words[0] = rx::setBits(words[0], 8, 6, static_cast<std::uint32_t>(value));
}
[[nodiscard]] constexpr AnisoRatio getAnisoRatio() const {
return static_cast<AnisoRatio>(rx::getBits(words[0], 11, 9));
}
constexpr void setAnisoRatio(AnisoRatio value) {
words[0] = rx::setBits(words[0], 11, 9, static_cast<std::uint32_t>(value));
}
[[nodiscard]] constexpr CompareFunc getDepthCompareFunc() const {
return static_cast<CompareFunc>(rx::getBits(words[0], 14, 12));
}
constexpr void setDepthCompareFunc(CompareFunc value) {
words[0] = rx::setBits(words[0], 14, 12, static_cast<std::uint32_t>(value));
}
[[nodiscard]] constexpr bool isForceUnormCoords() const {
return rx::getBit(words[0], 15);
}
constexpr void setForceUnormCoords(bool value) {
words[0] = rx::setBit(words[0], 15, value);
}
[[nodiscard]] constexpr std::uint8_t getAnisoThreshold() const {
return rx::getBits(words[0], 18, 16);
}
constexpr void setAnisoThreshold(std::uint8_t value) {
words[0] = rx::setBits(words[0], 18, 16, value);
}
[[nodiscard]] constexpr bool isMcCoordTrunc() const {
return rx::getBit(words[0], 19);
}
constexpr void setMcCoordTrunc(bool value) {
words[0] = rx::setBit(words[0], 19, value);
}
[[nodiscard]] constexpr bool isForceDegamma() const {
return rx::getBit(words[0], 20);
}
constexpr void setForceDegamma(bool value) {
words[0] = rx::setBit(words[0], 20, value);
}
[[nodiscard]] constexpr std::uint8_t getAnisoBias() const {
return rx::getBits(words[0], 26, 21);
}
constexpr void setAnisoBias(std::uint8_t value) {
words[0] = rx::setBits(words[0], 26, 21, value);
}
[[nodiscard]] constexpr bool isTruncCoord() const {
return rx::getBit(words[0], 27);
}
constexpr void setTruncCoord(bool value) {
words[0] = rx::setBit(words[0], 27, value);
}
[[nodiscard]] constexpr bool isDisableCubeWarp() const {
return rx::getBit(words[0], 28);
}
constexpr void setDisableCubeWarp(bool value) {
words[0] = rx::setBit(words[0], 28, value);
}
[[nodiscard]] constexpr FilterMode getFiterMode() const {
return static_cast<FilterMode>(rx::getBits(words[0], 30, 29));
}
constexpr void setFiterMode(FilterMode value) {
words[0] = rx::setBits(words[0], 30, 29, static_cast<std::uint32_t>(value));
}
[[nodiscard]] constexpr std::uint16_t getMinLod() const {
return rx::getBits(words[1], 11, 0);
}
constexpr void setMinLod(std::uint16_t value) {
words[1] = rx::setBits(words[1], 11, 0, value);
}
[[nodiscard]] constexpr std::uint16_t getMaxLod() const {
return rx::getBits(words[1], 23, 12);
}
constexpr void setMaxLod(std::uint16_t value) {
words[1] = rx::setBits(words[1], 23, 12, value);
}
[[nodiscard]] constexpr std::uint8_t getPerfMip() const {
return rx::getBits(words[1], 27, 24);
}
constexpr void setPerfMip(std::uint8_t value) {
words[1] = rx::setBits(words[1], 27, 24, value);
}
[[nodiscard]] constexpr std::uint8_t getPerfZ() const {
return rx::getBits(words[1], 31, 28);
}
constexpr void setPerfZ(std::uint8_t value) {
words[1] = rx::setBits(words[1], 31, 28, value);
}
[[nodiscard]] constexpr std::uint16_t getLodBias() const {
return rx::getBits(words[2], 13, 0);
}
constexpr void setLodBias(std::uint16_t value) {
words[2] = rx::setBits(words[2], 13, 0, value);
}
[[nodiscard]] constexpr std::uint16_t getLodBiasSec() const {
return rx::getBits(words[2], 19, 14);
}
constexpr void setLodBiasSec(std::uint16_t value) {
words[2] = rx::setBits(words[2], 19, 14, value);
}
[[nodiscard]] constexpr Filter getXYMagFilter() const {
return static_cast<Filter>(rx::getBits(words[2], 21, 20));
}
constexpr void setXYMagFilter(Filter value) {
words[2] = rx::setBits(words[2], 21, 20, static_cast<std::uint32_t>(value));
}
[[nodiscard]] constexpr Filter getXYMinFilter() const {
return static_cast<Filter>(rx::getBits(words[2], 23, 22));
}
constexpr void setXYMinFilter(Filter value) {
words[2] = rx::setBits(words[2], 23, 22, static_cast<std::uint32_t>(value));
}
[[nodiscard]] constexpr Filter getZFilter() const {
return static_cast<Filter>(rx::getBits(words[2], 25, 24));
}
constexpr void setZFilter(Filter value) {
words[2] = rx::setBits(words[2], 25, 24, static_cast<std::uint32_t>(value));
}
[[nodiscard]] constexpr MipFilter getMipFilter() const {
return static_cast<MipFilter>(rx::getBits(words[2], 27, 26));
}
constexpr void setMipFilter(MipFilter value) {
words[2] = rx::setBits(words[2], 27, 26, static_cast<std::uint32_t>(value));
}
[[nodiscard]] constexpr std::uint16_t getBorderColorPtr() const {
return rx::getBits(words[3], 11, 0);
}
constexpr void setBorderColorPtr(std::uint16_t value) {
words[3] = rx::setBits(words[3], 11, 0, value);
}
[[nodiscard]] constexpr BorderColor getBorderColor() const {
return static_cast<BorderColor>(rx::getBits(words[2], 31, 30));
}
constexpr void setBorderColor(BorderColor value) {
words[2] = rx::setBits(words[2], 31, 30, static_cast<std::uint32_t>(value));
}
auto operator<=>(const Sampler &) const = default;
};
static_assert(sizeof(SSampler) == sizeof(std::uint32_t) * 4);
#pragma pack(pop)
} // namespace gnm