[GPU] Unified function for mip level bounds, BaseMap mip filter, small refactoring
This commit is contained in:
parent
0437488853
commit
47eee5e1c3
|
@ -1587,17 +1587,10 @@ TextureCache::SamplerParameters TextureCache::GetSamplerParameters(
|
||||||
parameters.clamp_z = fetch.clamp_z;
|
parameters.clamp_z = fetch.clamp_z;
|
||||||
parameters.border_color = fetch.border_color;
|
parameters.border_color = fetch.border_color;
|
||||||
|
|
||||||
uint32_t mip_min_level = fetch.mip_min_level;
|
uint32_t mip_min_level, mip_max_level;
|
||||||
uint32_t mip_max_level = fetch.mip_max_level;
|
texture_util::GetSubresourcesFromFetchConstant(
|
||||||
uint32_t base_page = fetch.base_address & 0x1FFFF;
|
fetch, nullptr, nullptr, nullptr, nullptr, nullptr, &mip_min_level,
|
||||||
uint32_t mip_page = fetch.mip_address & 0x1FFFF;
|
&mip_max_level, binding.mip_filter);
|
||||||
if (base_page == 0 || base_page == mip_page) {
|
|
||||||
// Games should clamp mip level in this case anyway, but just for safety.
|
|
||||||
mip_min_level = std::max(mip_min_level, 1u);
|
|
||||||
}
|
|
||||||
if (mip_page == 0) {
|
|
||||||
mip_max_level = 0;
|
|
||||||
}
|
|
||||||
parameters.mip_min_level = mip_min_level;
|
parameters.mip_min_level = mip_min_level;
|
||||||
parameters.mip_max_level = std::max(mip_max_level, mip_min_level);
|
parameters.mip_max_level = std::max(mip_max_level, mip_min_level);
|
||||||
parameters.lod_bias = fetch.lod_bias;
|
parameters.lod_bias = fetch.lod_bias;
|
||||||
|
@ -1627,7 +1620,6 @@ TextureCache::SamplerParameters TextureCache::GetSamplerParameters(
|
||||||
? fetch.mip_filter
|
? fetch.mip_filter
|
||||||
: binding.mip_filter;
|
: binding.mip_filter;
|
||||||
parameters.mip_linear = mip_filter == TextureFilter::kLinear;
|
parameters.mip_linear = mip_filter == TextureFilter::kLinear;
|
||||||
// TODO(Triang3l): Investigate mip_filter TextureFilter::kBaseMap.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return parameters;
|
return parameters;
|
||||||
|
@ -1649,7 +1641,6 @@ void TextureCache::WriteSampler(SamplerParameters parameters,
|
||||||
D3D12_FILTER_TYPE d3d_filter_mip = parameters.mip_linear
|
D3D12_FILTER_TYPE d3d_filter_mip = parameters.mip_linear
|
||||||
? D3D12_FILTER_TYPE_LINEAR
|
? D3D12_FILTER_TYPE_LINEAR
|
||||||
: D3D12_FILTER_TYPE_POINT;
|
: D3D12_FILTER_TYPE_POINT;
|
||||||
// TODO(Triang3l): Investigate mip_filter TextureFilter::kBaseMap.
|
|
||||||
desc.Filter = D3D12_ENCODE_BASIC_FILTER(
|
desc.Filter = D3D12_ENCODE_BASIC_FILTER(
|
||||||
d3d_filter_min, d3d_filter_mag, d3d_filter_mip,
|
d3d_filter_min, d3d_filter_mag, d3d_filter_mip,
|
||||||
D3D12_FILTER_REDUCTION_TYPE_STANDARD);
|
D3D12_FILTER_REDUCTION_TYPE_STANDARD);
|
||||||
|
@ -2119,76 +2110,31 @@ void TextureCache::BindingInfoFromFetchConstant(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate the dimensions, get the size and clamp the maximum mip level.
|
uint32_t width, height, depth_or_faces;
|
||||||
Dimension dimension = Dimension(fetch.dimension);
|
uint32_t base_page, mip_page, mip_max_level;
|
||||||
uint32_t width, height, depth;
|
texture_util::GetSubresourcesFromFetchConstant(
|
||||||
switch (dimension) {
|
fetch, &width, &height, &depth_or_faces, &base_page, &mip_page, nullptr,
|
||||||
case Dimension::k1D:
|
&mip_max_level);
|
||||||
if (fetch.tiled || fetch.stacked || fetch.packed_mips) {
|
|
||||||
assert_always();
|
|
||||||
XELOGGPU(
|
|
||||||
"1D texture has unsupported properties - ignoring! "
|
|
||||||
"Report the game to Xenia developers");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
width = fetch.size_1d.width + 1;
|
|
||||||
if (width > 8192) {
|
|
||||||
assert_always();
|
|
||||||
XELOGGPU(
|
|
||||||
"1D texture is too wide (%u) - ignoring! "
|
|
||||||
"Report the game to Xenia developers",
|
|
||||||
width);
|
|
||||||
}
|
|
||||||
height = 1;
|
|
||||||
depth = 1;
|
|
||||||
break;
|
|
||||||
case Dimension::k2D:
|
|
||||||
width = fetch.size_stack.width + 1;
|
|
||||||
height = fetch.size_stack.height + 1;
|
|
||||||
depth = fetch.stacked ? fetch.size_stack.depth + 1 : 1;
|
|
||||||
break;
|
|
||||||
case Dimension::k3D:
|
|
||||||
width = fetch.size_3d.width + 1;
|
|
||||||
height = fetch.size_3d.height + 1;
|
|
||||||
depth = fetch.size_3d.depth + 1;
|
|
||||||
break;
|
|
||||||
case Dimension::kCube:
|
|
||||||
width = fetch.size_2d.width + 1;
|
|
||||||
height = fetch.size_2d.height + 1;
|
|
||||||
depth = 6;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
uint32_t mip_max_level = texture_util::GetSmallestMipLevel(
|
|
||||||
width, height, dimension == Dimension::k3D ? depth : 1, false);
|
|
||||||
mip_max_level = std::min(mip_max_level, fetch.mip_max_level);
|
|
||||||
|
|
||||||
// Normalize and check the addresses.
|
|
||||||
uint32_t base_page = fetch.base_address & 0x1FFFF;
|
|
||||||
uint32_t mip_page = mip_max_level != 0 ? fetch.mip_address & 0x1FFFF : 0;
|
|
||||||
// Special case for streaming. Games such as Banjo-Kazooie: Nuts & Bolts
|
|
||||||
// specify the same address for both the base level and the mips and set
|
|
||||||
// mip_min_index to 1 until the texture is actually loaded - this is the way
|
|
||||||
// recommended by a GPU hang error message found in game executables. In this
|
|
||||||
// case we assume that the base level is not loaded yet.
|
|
||||||
// TODO(Triang3l): Ignore the base level completely if min_mip_level is not 0
|
|
||||||
// once we start reusing textures with zero base address to reduce memory
|
|
||||||
// usage.
|
|
||||||
if (base_page == mip_page) {
|
|
||||||
base_page = 0;
|
|
||||||
}
|
|
||||||
if (base_page == 0 && mip_page == 0) {
|
if (base_page == 0 && mip_page == 0) {
|
||||||
// No texture data at all.
|
// No texture data at all.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (fetch.dimension == Dimension::k1D && width > 8192) {
|
||||||
|
XELOGE(
|
||||||
|
"1D texture is too wide (%u) - ignoring! "
|
||||||
|
"Report the game to Xenia developers",
|
||||||
|
width);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
TextureFormat format = GetBaseFormat(fetch.format);
|
TextureFormat format = GetBaseFormat(fetch.format);
|
||||||
|
|
||||||
key_out.base_page = base_page;
|
key_out.base_page = base_page;
|
||||||
key_out.mip_page = mip_page;
|
key_out.mip_page = mip_page;
|
||||||
key_out.dimension = dimension;
|
key_out.dimension = fetch.dimension;
|
||||||
key_out.width = width;
|
key_out.width = width;
|
||||||
key_out.height = height;
|
key_out.height = height;
|
||||||
key_out.depth = depth;
|
key_out.depth = depth_or_faces;
|
||||||
key_out.mip_max_level = mip_max_level;
|
key_out.mip_max_level = mip_max_level;
|
||||||
key_out.tiled = fetch.tiled;
|
key_out.tiled = fetch.tiled;
|
||||||
key_out.packed_mips = fetch.packed_mips;
|
key_out.packed_mips = fetch.packed_mips;
|
||||||
|
@ -2278,6 +2224,8 @@ TextureCache::Texture* TextureCache::FindOrCreateTexture(TextureKey key) {
|
||||||
uint64_t map_key = key.GetMapKey();
|
uint64_t map_key = key.GetMapKey();
|
||||||
|
|
||||||
// Try to find an existing texture.
|
// Try to find an existing texture.
|
||||||
|
// TODO(Triang3l): Reuse a texture with mip_page unchanged, but base_page
|
||||||
|
// previously 0, now not 0, to save memory - common case in streaming.
|
||||||
auto found_range = textures_.equal_range(map_key);
|
auto found_range = textures_.equal_range(map_key);
|
||||||
for (auto iter = found_range.first; iter != found_range.second; ++iter) {
|
for (auto iter = found_range.first; iter != found_range.second; ++iter) {
|
||||||
Texture* found_texture = iter->second;
|
Texture* found_texture = iter->second;
|
||||||
|
|
|
@ -36,7 +36,7 @@ bool TextureInfo::Prepare(const xe_gpu_texture_fetch_t& fetch,
|
||||||
info.format = fetch.format;
|
info.format = fetch.format;
|
||||||
info.endianness = fetch.endianness;
|
info.endianness = fetch.endianness;
|
||||||
|
|
||||||
info.dimension = static_cast<Dimension>(fetch.dimension);
|
info.dimension = fetch.dimension;
|
||||||
info.width = info.height = info.depth = 0;
|
info.width = info.height = info.depth = 0;
|
||||||
info.is_stacked = false;
|
info.is_stacked = false;
|
||||||
switch (info.dimension) {
|
switch (info.dimension) {
|
||||||
|
@ -46,13 +46,10 @@ bool TextureInfo::Prepare(const xe_gpu_texture_fetch_t& fetch,
|
||||||
assert_true(!fetch.stacked);
|
assert_true(!fetch.stacked);
|
||||||
break;
|
break;
|
||||||
case Dimension::k2D:
|
case Dimension::k2D:
|
||||||
if (!fetch.stacked) {
|
info.width = fetch.size_2d.width;
|
||||||
info.width = fetch.size_2d.width;
|
info.height = fetch.size_2d.height;
|
||||||
info.height = fetch.size_2d.height;
|
if (fetch.stacked) {
|
||||||
} else {
|
info.depth = fetch.size_2d.stack_depth;
|
||||||
info.width = fetch.size_stack.width;
|
|
||||||
info.height = fetch.size_stack.height;
|
|
||||||
info.depth = fetch.size_stack.depth;
|
|
||||||
info.is_stacked = true;
|
info.is_stacked = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -63,9 +60,10 @@ bool TextureInfo::Prepare(const xe_gpu_texture_fetch_t& fetch,
|
||||||
assert_true(!fetch.stacked);
|
assert_true(!fetch.stacked);
|
||||||
break;
|
break;
|
||||||
case Dimension::kCube:
|
case Dimension::kCube:
|
||||||
info.width = fetch.size_stack.width;
|
info.width = fetch.size_2d.width;
|
||||||
info.height = fetch.size_stack.height;
|
info.height = fetch.size_2d.height;
|
||||||
info.depth = fetch.size_stack.depth;
|
assert_true(fetch.size_2d.stack_depth == 5);
|
||||||
|
info.depth = fetch.size_2d.stack_depth;
|
||||||
assert_true(!fetch.stacked);
|
assert_true(!fetch.stacked);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -18,12 +18,108 @@ namespace xe {
|
||||||
namespace gpu {
|
namespace gpu {
|
||||||
namespace texture_util {
|
namespace texture_util {
|
||||||
|
|
||||||
|
void GetSubresourcesFromFetchConstant(
|
||||||
|
const xenos::xe_gpu_texture_fetch_t& fetch, uint32_t* width_out,
|
||||||
|
uint32_t* height_out, uint32_t* depth_or_faces_out, uint32_t* base_page_out,
|
||||||
|
uint32_t* mip_page_out, uint32_t* mip_min_level_out,
|
||||||
|
uint32_t* mip_max_level_out, TextureFilter sampler_mip_filter) {
|
||||||
|
uint32_t width = 0, height = 0, depth_or_faces = 0;
|
||||||
|
switch (fetch.dimension) {
|
||||||
|
case Dimension::k1D:
|
||||||
|
assert_false(fetch.stacked);
|
||||||
|
assert_false(fetch.tiled);
|
||||||
|
assert_false(fetch.packed_mips);
|
||||||
|
width = fetch.size_1d.width;
|
||||||
|
break;
|
||||||
|
case Dimension::k2D:
|
||||||
|
width = fetch.size_2d.width;
|
||||||
|
height = fetch.size_2d.height;
|
||||||
|
depth_or_faces = fetch.stacked ? fetch.size_2d.stack_depth : 0;
|
||||||
|
break;
|
||||||
|
case Dimension::k3D:
|
||||||
|
assert_false(fetch.stacked);
|
||||||
|
width = fetch.size_3d.width;
|
||||||
|
height = fetch.size_3d.height;
|
||||||
|
depth_or_faces = fetch.size_3d.depth;
|
||||||
|
break;
|
||||||
|
case Dimension::kCube:
|
||||||
|
assert_false(fetch.stacked);
|
||||||
|
assert_true(fetch.size_2d.stack_depth == 5);
|
||||||
|
width = fetch.size_2d.width;
|
||||||
|
height = fetch.size_2d.height;
|
||||||
|
depth_or_faces = 5;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
++width;
|
||||||
|
++height;
|
||||||
|
++depth_or_faces;
|
||||||
|
if (width_out) {
|
||||||
|
*width_out = width;
|
||||||
|
}
|
||||||
|
if (height_out) {
|
||||||
|
*height_out = height;
|
||||||
|
}
|
||||||
|
if (depth_or_faces_out) {
|
||||||
|
*depth_or_faces_out = depth_or_faces;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t size_mip_max_level = GetSmallestMipLevel(
|
||||||
|
width, height, fetch.dimension == Dimension::k3D ? depth_or_faces : 1,
|
||||||
|
false);
|
||||||
|
TextureFilter mip_filter = sampler_mip_filter == TextureFilter::kUseFetchConst
|
||||||
|
? fetch.mip_filter
|
||||||
|
: sampler_mip_filter;
|
||||||
|
|
||||||
|
uint32_t base_page = fetch.base_address & 0x1FFFF;
|
||||||
|
uint32_t mip_page = fetch.mip_address & 0x1FFFF;
|
||||||
|
|
||||||
|
uint32_t mip_min_level, mip_max_level;
|
||||||
|
if (mip_filter == TextureFilter::kBaseMap || mip_page == 0) {
|
||||||
|
mip_min_level = 0;
|
||||||
|
mip_max_level = 0;
|
||||||
|
} else {
|
||||||
|
mip_min_level = std::min(fetch.mip_min_level, size_mip_max_level);
|
||||||
|
mip_max_level = std::max(std::min(fetch.mip_max_level, size_mip_max_level),
|
||||||
|
mip_min_level);
|
||||||
|
}
|
||||||
|
if (mip_max_level != 0) {
|
||||||
|
// Special case for streaming. Games such as Banjo-Kazooie: Nuts & Bolts
|
||||||
|
// specify the same address for both the base level and the mips and set
|
||||||
|
// mip_min_index to 1 until the texture is actually loaded - this is the way
|
||||||
|
// recommended by a GPU hang error message found in game executables. In
|
||||||
|
// this case we assume that the base level is not loaded yet.
|
||||||
|
if (base_page == mip_page) {
|
||||||
|
base_page = 0;
|
||||||
|
}
|
||||||
|
if (base_page == 0) {
|
||||||
|
mip_min_level = std::max(mip_min_level, uint32_t(1));
|
||||||
|
}
|
||||||
|
if (mip_min_level != 0) {
|
||||||
|
base_page = 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
mip_page = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (base_page_out) {
|
||||||
|
*base_page_out = base_page;
|
||||||
|
}
|
||||||
|
if (mip_page_out) {
|
||||||
|
*mip_page_out = mip_page;
|
||||||
|
}
|
||||||
|
if (mip_min_level_out) {
|
||||||
|
*mip_min_level_out = mip_min_level;
|
||||||
|
}
|
||||||
|
if (mip_max_level_out) {
|
||||||
|
*mip_max_level_out = mip_max_level;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void GetGuestMipBlocks(Dimension dimension, uint32_t width, uint32_t height,
|
void GetGuestMipBlocks(Dimension dimension, uint32_t width, uint32_t height,
|
||||||
uint32_t depth, TextureFormat format, uint32_t mip,
|
uint32_t depth, TextureFormat format, uint32_t mip,
|
||||||
uint32_t& width_blocks_out, uint32_t& height_blocks_out,
|
uint32_t& width_blocks_out, uint32_t& height_blocks_out,
|
||||||
uint32_t& depth_blocks_out) {
|
uint32_t& depth_blocks_out) {
|
||||||
// Get mipmap size.
|
// Get mipmap size.
|
||||||
// TODO(Triang3l): Verify if mipmap storage actually needs to be power of two.
|
|
||||||
if (mip != 0) {
|
if (mip != 0) {
|
||||||
width = std::max(xe::next_pow2(width) >> mip, 1u);
|
width = std::max(xe::next_pow2(width) >> mip, 1u);
|
||||||
if (dimension != Dimension::k1D) {
|
if (dimension != Dimension::k1D) {
|
||||||
|
@ -171,10 +267,10 @@ bool GetPackedMipOffset(uint32_t width, uint32_t height, uint32_t depth,
|
||||||
void GetTextureTotalSize(Dimension dimension, uint32_t width, uint32_t height,
|
void GetTextureTotalSize(Dimension dimension, uint32_t width, uint32_t height,
|
||||||
uint32_t depth, TextureFormat format, bool is_tiled,
|
uint32_t depth, TextureFormat format, bool is_tiled,
|
||||||
bool packed_mips, uint32_t mip_max_level,
|
bool packed_mips, uint32_t mip_max_level,
|
||||||
uint32_t* base_size, uint32_t* mip_size) {
|
uint32_t* base_size_out, uint32_t* mip_size_out) {
|
||||||
bool is_3d = dimension == Dimension::k3D;
|
bool is_3d = dimension == Dimension::k3D;
|
||||||
uint32_t width_blocks, height_blocks, depth_blocks;
|
uint32_t width_blocks, height_blocks, depth_blocks;
|
||||||
if (base_size != nullptr) {
|
if (base_size_out) {
|
||||||
GetGuestMipBlocks(dimension, width, height, depth, format, 0, width_blocks,
|
GetGuestMipBlocks(dimension, width, height, depth, format, 0, width_blocks,
|
||||||
height_blocks, depth_blocks);
|
height_blocks, depth_blocks);
|
||||||
uint32_t size = GetGuestMipSliceStorageSize(
|
uint32_t size = GetGuestMipSliceStorageSize(
|
||||||
|
@ -182,9 +278,9 @@ void GetTextureTotalSize(Dimension dimension, uint32_t width, uint32_t height,
|
||||||
if (!is_3d) {
|
if (!is_3d) {
|
||||||
size *= depth;
|
size *= depth;
|
||||||
}
|
}
|
||||||
*base_size = size;
|
*base_size_out = size;
|
||||||
}
|
}
|
||||||
if (mip_size != nullptr) {
|
if (mip_size_out) {
|
||||||
mip_max_level = std::min(
|
mip_max_level = std::min(
|
||||||
mip_max_level,
|
mip_max_level,
|
||||||
GetSmallestMipLevel(width, height, is_3d ? depth : 1, packed_mips));
|
GetSmallestMipLevel(width, height, is_3d ? depth : 1, packed_mips));
|
||||||
|
@ -199,7 +295,7 @@ void GetTextureTotalSize(Dimension dimension, uint32_t width, uint32_t height,
|
||||||
}
|
}
|
||||||
size += level_size;
|
size += level_size;
|
||||||
}
|
}
|
||||||
*mip_size = size;
|
*mip_size_out = size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,16 @@ namespace texture_util {
|
||||||
// This namespace replaces texture_extent and most of texture_info for
|
// This namespace replaces texture_extent and most of texture_info for
|
||||||
// simplicity.
|
// simplicity.
|
||||||
|
|
||||||
|
// Extracts the size from the fetch constant, and also cleans up addresses and
|
||||||
|
// mip range based on real presence of the base level and mips. Returns 6 faces
|
||||||
|
// for cube textures.
|
||||||
|
void GetSubresourcesFromFetchConstant(
|
||||||
|
const xenos::xe_gpu_texture_fetch_t& fetch, uint32_t* width_out,
|
||||||
|
uint32_t* height_out, uint32_t* depth_or_faces_out, uint32_t* base_page_out,
|
||||||
|
uint32_t* mip_page_out, uint32_t* mip_min_level_out,
|
||||||
|
uint32_t* mip_max_level_out,
|
||||||
|
TextureFilter sampler_mip_filter = TextureFilter::kUseFetchConst);
|
||||||
|
|
||||||
// Calculates width, height and depth of the image backing the guest mipmap (or
|
// Calculates width, height and depth of the image backing the guest mipmap (or
|
||||||
// the base level if mip is 0).
|
// the base level if mip is 0).
|
||||||
void GetGuestMipBlocks(Dimension dimension, uint32_t width, uint32_t height,
|
void GetGuestMipBlocks(Dimension dimension, uint32_t width, uint32_t height,
|
||||||
|
@ -71,7 +81,7 @@ inline uint32_t GetSmallestMipLevel(uint32_t width, uint32_t height,
|
||||||
void GetTextureTotalSize(Dimension dimension, uint32_t width, uint32_t height,
|
void GetTextureTotalSize(Dimension dimension, uint32_t width, uint32_t height,
|
||||||
uint32_t depth, TextureFormat format, bool is_tiled,
|
uint32_t depth, TextureFormat format, bool is_tiled,
|
||||||
bool packed_mips, uint32_t mip_max_level,
|
bool packed_mips, uint32_t mip_max_level,
|
||||||
uint32_t* base_size, uint32_t* mip_size);
|
uint32_t* base_size_out, uint32_t* mip_size_out);
|
||||||
|
|
||||||
int32_t GetTiledOffset2D(int32_t x, int32_t y, uint32_t width,
|
int32_t GetTiledOffset2D(int32_t x, int32_t y, uint32_t width,
|
||||||
uint32_t bpb_log2);
|
uint32_t bpb_log2);
|
||||||
|
|
|
@ -112,7 +112,7 @@ enum class TextureSign : uint32_t {
|
||||||
enum class TextureFilter : uint32_t {
|
enum class TextureFilter : uint32_t {
|
||||||
kPoint = 0,
|
kPoint = 0,
|
||||||
kLinear = 1,
|
kLinear = 1,
|
||||||
kBaseMap = 2, // Only applicable for mip-filter.
|
kBaseMap = 2, // Only applicable for mip-filter - always fetch from level 0.
|
||||||
kUseFetchConst = 3,
|
kUseFetchConst = 3,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -133,6 +133,8 @@ enum class BorderColor : uint32_t {
|
||||||
k_ACBCRY_BLACK = 3,
|
k_ACBCRY_BLACK = 3,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// For the tfetch instruction, not the fetch constant - slightly different
|
||||||
|
// meaning, as stacked textures are stored as 2D, but fetched using tfetch3D.
|
||||||
enum class TextureDimension : uint32_t {
|
enum class TextureDimension : uint32_t {
|
||||||
k1D = 0,
|
k1D = 0,
|
||||||
k2D = 1,
|
k2D = 1,
|
||||||
|
@ -661,13 +663,11 @@ XEPACKEDUNION(xe_gpu_texture_fetch_t, {
|
||||||
struct {
|
struct {
|
||||||
uint32_t width : 13;
|
uint32_t width : 13;
|
||||||
uint32_t height : 13;
|
uint32_t height : 13;
|
||||||
uint32_t : 6;
|
// Should be 0 for k2D and 5 for kCube if not stacked, but not very
|
||||||
|
// meaningful in this case, preferably should be ignored for
|
||||||
|
// non-stacked.
|
||||||
|
uint32_t stack_depth : 6;
|
||||||
} size_2d;
|
} size_2d;
|
||||||
struct {
|
|
||||||
uint32_t width : 13;
|
|
||||||
uint32_t height : 13;
|
|
||||||
uint32_t depth : 6;
|
|
||||||
} size_stack;
|
|
||||||
struct {
|
struct {
|
||||||
uint32_t width : 11;
|
uint32_t width : 11;
|
||||||
uint32_t height : 11;
|
uint32_t height : 11;
|
||||||
|
@ -700,7 +700,7 @@ XEPACKEDUNION(xe_gpu_texture_fetch_t, {
|
||||||
uint32_t force_bc_w_to_max : 1; // +2
|
uint32_t force_bc_w_to_max : 1; // +2
|
||||||
uint32_t tri_clamp : 2; // +3
|
uint32_t tri_clamp : 2; // +3
|
||||||
int32_t aniso_bias : 4; // +5
|
int32_t aniso_bias : 4; // +5
|
||||||
uint32_t dimension : 2; // +9
|
Dimension dimension : 2; // +9
|
||||||
uint32_t packed_mips : 1; // +11
|
uint32_t packed_mips : 1; // +11
|
||||||
uint32_t mip_address : 20; // +12 mip address >> 12
|
uint32_t mip_address : 20; // +12 mip address >> 12
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue