mirror of
https://github.com/RPCSX/rpcsx.git
synced 2026-01-08 17:50:31 +01:00
amdgpu: cross-platform descriptors layout
This commit is contained in:
parent
95b458939b
commit
1b077dd6f4
|
|
@ -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(),
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in a new issue