ReXGlue SDK
Loading...
Searching...
No Matches
texture.h
Go to the documentation of this file.
1
16
17#pragma once
18
19#include <memory>
20#include <algorithm>
21#include <cstring>
22#include <functional>
23
24#include <rex/platform.h>
25#include <rex/assert.h>
26#include <rex/types.h>
27#include <rex/xenos/fetch.h>
28#include <rex/xenos/format.h>
29#include <rex/bit.h>
30
31namespace rex::xenos {
32
44void GetSubresourcesFromFetchConstant(const xenos::TextureFetch& fetch, u32* width_minus_1_out,
45 u32* height_minus_1_out, u32* depth_or_array_size_minus_1_out,
46 u32* base_page_out, u32* mip_page_out, u32* mip_min_level_out,
47 u32* mip_max_level_out);
48
50inline u32 GetPackedMipLevel(u32 width, u32 height) {
51 u32 log2_size = rex::log2_ceil(std::min(width, height));
52 return log2_size > 4 ? log2_size - 4 : 0;
53}
54
64bool GetPackedMipOffset(u32 width, u32 height, u32 depth, xenos::TextureFormat format, u32 mip,
65 u32& x_blocks, u32& y_blocks, u32& z_blocks);
66
84
85 Level base;
87 Level mips[xenos::kTextureMaxMips];
88 u32 mip_offsets_bytes[xenos::kTextureMaxMips];
89 u32 mips_total_extent_bytes;
93};
94
105 u32 base_pitch_texels_div_32, u32 width_texels,
106 u32 height_texels, u32 depth_or_array_size, bool is_tiled,
107 xenos::TextureFormat format, bool has_packed_levels,
108 bool has_base, u32 max_level);
109
116i32 GetTiledOffset2D(i32 x, i32 y, u32 pitch, u32 bytes_per_block_log2);
117
126i32 GetTiledOffset3D(i32 x, i32 y, i32 z, u32 pitch, u32 height, u32 bytes_per_block_log2);
127
137inline u32 GetTiledAddressLowerBound2D(u32 left, u32 top, u32 pitch, u32 bytes_per_block_log2) {
138 return static_cast<u32>(GetTiledOffset2D(
139 static_cast<i32>(left & ~(xenos::kTextureTileWidthHeight - 1)),
140 static_cast<i32>(top & ~(xenos::kTextureTileWidthHeight - 1)), pitch, bytes_per_block_log2));
141}
142
153inline u32 GetTiledAddressLowerBound3D(u32 left, u32 top, u32 front, u32 pitch, u32 height,
154 u32 bytes_per_block_log2) {
155 return static_cast<u32>(
156 GetTiledOffset3D(static_cast<i32>(left & ~(xenos::kTextureTileWidthHeight - 1)),
157 static_cast<i32>(top & ~(xenos::kTextureTileWidthHeight - 1)),
158 static_cast<i32>(front & ~(xenos::kTextureTileDepth - 1)), pitch, height,
159 bytes_per_block_log2));
160}
161
171u32 GetTiledAddressUpperBound2D(u32 right, u32 bottom, u32 pitch, u32 bytes_per_block_log2);
172
184u32 GetTiledAddressUpperBound3D(u32 right, u32 bottom, u32 back, u32 pitch, u32 height,
185 u32 bytes_per_block_log2);
186
194
200constexpr bool HasNonSignedComponent(u8 packed_signs) {
201 return packed_signs != std::to_underlying(xenos::TextureSign::kSigned) * 0b01010101;
202}
203
209constexpr bool HasSignedComponent(u8 packed_signs) {
210 u32 xor_signed = packed_signs ^ (std::to_underlying(xenos::TextureSign::kSigned) * 0b01010101);
211 return ((xor_signed | (xor_signed >> 1)) & 0b01010101) != 0b01010101;
212}
213
223 xenos::ClampMode& clamp_y_out, xenos::ClampMode& clamp_z_out);
224
225} // namespace rex::xenos
226
227namespace rex::xenos {
228
235 switch (texture_format) {
236 case xenos::TextureFormat::k_16_EXPAND:
237 return xenos::TextureFormat::k_16_FLOAT;
238 case xenos::TextureFormat::k_16_16_EXPAND:
239 return xenos::TextureFormat::k_16_16_FLOAT;
240 case xenos::TextureFormat::k_16_16_16_16_EXPAND:
241 return xenos::TextureFormat::k_16_16_16_16_FLOAT;
242 case xenos::TextureFormat::k_8_8_8_8_AS_16_16_16_16:
243 return xenos::TextureFormat::k_8_8_8_8;
244 case xenos::TextureFormat::k_DXT1_AS_16_16_16_16:
245 return xenos::TextureFormat::k_DXT1;
246 case xenos::TextureFormat::k_DXT2_3_AS_16_16_16_16:
247 return xenos::TextureFormat::k_DXT2_3;
248 case xenos::TextureFormat::k_DXT4_5_AS_16_16_16_16:
249 return xenos::TextureFormat::k_DXT4_5;
250 case xenos::TextureFormat::k_2_10_10_10_AS_16_16_16_16:
251 return xenos::TextureFormat::k_2_10_10_10;
252 case xenos::TextureFormat::k_10_11_11_AS_16_16_16_16:
253 return xenos::TextureFormat::k_10_11_11;
254 case xenos::TextureFormat::k_11_11_10_AS_16_16_16_16:
255 return xenos::TextureFormat::k_11_11_10;
256 case xenos::TextureFormat::k_8_8_8_8_GAMMA_EDRAM:
257 return xenos::TextureFormat::k_8_8_8_8;
258 default:
259 break;
260 }
261
262 return texture_format;
263}
264
268inline size_t GetTexelSize(xenos::TextureFormat format) {
269 switch (format) {
270 case xenos::TextureFormat::k_8:
271 return 1;
272 case xenos::TextureFormat::k_1_5_5_5:
273 case xenos::TextureFormat::k_4_4_4_4:
274 case xenos::TextureFormat::k_5_6_5:
275 case xenos::TextureFormat::k_8_8:
276 return 2;
277 case xenos::TextureFormat::k_2_10_10_10:
278 case xenos::TextureFormat::k_8_8_8_8:
279 case xenos::TextureFormat::k_16:
280 case xenos::TextureFormat::k_16_FLOAT:
281 case xenos::TextureFormat::k_16_16:
282 case xenos::TextureFormat::k_16_16_FLOAT:
283 case xenos::TextureFormat::k_32_FLOAT:
284 case xenos::TextureFormat::k_10_11_11:
285 case xenos::TextureFormat::k_11_11_10:
286 return 4;
287 case xenos::TextureFormat::k_16_16_16_16:
288 case xenos::TextureFormat::k_16_16_16_16_FLOAT:
289 case xenos::TextureFormat::k_32_32_FLOAT:
290 return 8;
291 case xenos::TextureFormat::k_32_32_32_32_FLOAT:
292 return 16;
293 default:
294 REX_UNHANDLED_CASE(format);
295 return 0;
296 }
297}
298
301 return static_cast<xenos::TextureFormat>(color_format);
302}
303
309 xenos::DepthRenderTargetFormat depth_format) {
310 switch (depth_format) {
315 default:
316 REX_UNHANDLED_CASE(depth_format);
317 return static_cast<xenos::TextureFormat>(~0);
318 }
319}
320
321enum class FormatType : u8 {
324 kCompressed,
325};
326
329 const char* name;
330 FormatType type;
331 u32 block_width;
332 u32 block_height;
333 u32 bits_per_pixel;
334
335 u32 GetBytesPerBlock() const { return block_width * block_height * bits_per_pixel / 8; }
336
342 static const FormatInfo* Get(u32 gpu_format);
343
344 static const FormatInfo* Get(xenos::TextureFormat format) {
345 return Get(static_cast<u32>(format));
346 }
347};
348
349struct TextureInfo;
350
352 u32 pitch;
353 u32 height;
358 u32 depth;
359
361 u32 GetAllBlocks() const { return block_pitch_h * block_pitch_v * depth; }
362
364 u32 GetVisibleBlocks() const { return block_pitch_h * block_height * depth; }
365
372 static TextureExtent Calculate(const FormatInfo* format_info, u32 pitch, u32 height, u32 depth,
373 bool is_tiled, bool is_guest);
374
381 static TextureExtent Calculate(const TextureInfo* texture_info, bool is_guest);
382
383 bool operator==(const TextureExtent& other) const = default;
384};
385
388 u32 base_size;
390 u32 mip_size;
391
392 bool operator==(const TextureMemoryRanges& other) const = default;
393};
394
398 xenos::Endian endianness;
399
401 u32 width_minus_1;
402 u32 height_minus_1;
403 u32 depth_or_array_size_minus_1;
404 u32 pitch;
405 u32 mip_min_level;
406 u32 mip_max_level;
408 bool is_tiled;
410
411 TextureMemoryRanges memory;
413
414 const FormatInfo* GetFormatInfo() const { return FormatInfo::Get(static_cast<u32>(format)); }
415
416 bool IsCompressed() const { return GetFormatInfo()->type == FormatType::kCompressed; }
417
418 u32 GetMipLevels() const { return 1 + (mip_max_level - mip_min_level); }
419
425 static bool FromFetchConstant(const xenos::TextureFetch& fetch, TextureInfo* out_info);
426
435 static bool FromResolve(u32 physical_address, xenos::TextureFormat texture_format,
436 xenos::Endian endian, u32 pitch, u32 width, u32 height, u32 depth,
437 TextureInfo* out_info);
438
440 u32 GetMaxMipLevels() const;
441
447 const TextureExtent GetMipExtent(u32 mip, bool is_guest) const;
448
455 void GetMipSize(u32 mip, u32* width, u32* height) const;
456
465 u32 GetMipLocation(u32 mip, u32* offset_x, u32* offset_y, bool is_guest) const;
466
477 static bool GetPackedMipOffset(u32 width, u32 height, const FormatInfo* format_info,
478 u32 packed_tile, u32* offset_x, u32* offset_y);
479
488 bool GetPackedMipOffset(u32 packed_tile, u32* offset_x, u32* offset_y) const;
489
491 u64 Hash() const;
492
493 bool operator==(const TextureInfo& other) const = default;
494
495 private:
496 void SetupMemoryRanges(u32 base_address, u32 mip_address);
497};
498
499} // namespace rex::xenos
500
501namespace rex::xenos {
502
504using CopyBlockCallback = std::function<void(xenos::Endian, void*, const void*, size_t)>;
505
507void CopySwapBlock(xenos::Endian endian, void* output, const void* input, size_t length);
508
517void ConvertTexelCTX1ToR8G8(xenos::Endian endian, void* output, const void* input,
518 size_t output_pitch);
519
528void ConvertTexelDXT3AToDXT3(xenos::Endian endian, void* output, const void* input, size_t length);
529
530using UntileCopyBlockCallback = std::function<void(void*, const void*, size_t)>;
531
535 u32 width;
536 u32 height;
539 const FormatInfo* input_format_info;
540 const FormatInfo* output_format_info;
541 UntileCopyBlockCallback copy_callback;
542};
543
551void Untile(u8* output_buffer, const u8* input_buffer, const UntileRegion* untile_info);
552
553} // namespace rex::xenos
#define REX_UNHANDLED_CASE(var)
Definition assert.h:119
Fetch constant layouts, texture sampling enums and limits.
ClampMode
Definition fetch.h:35
@ kSigned
Definition fetch.h:59
DataDimension
Definition fetch.h:27
Data, texture, vertex and render target formats and conversions.
DepthRenderTargetFormat
Definition format.h:135
@ kD24S8
Definition format.h:136
@ kD24FS8
Definition format.h:137
Endian
Definition format.h:27
TextureFormat
Definition format.h:198
@ k_24_8_FLOAT
Definition format.h:222
@ k_24_8
Definition format.h:221
ColorFormat
Definition format.h:267
T log2_ceil(T v)
Definition bit.h:263
Platform flags, packing macros and export markers.
Definition texture.h:327
const char * name
Definition texture.h:329
static const FormatInfo * Get(u32 gpu_format)
u32 z_extent
Definition texture.h:80
u32 x_extent_blocks
Definition texture.h:78
u32 y_extent_blocks
Definition texture.h:79
u32 level_data_extent_bytes
Definition texture.h:82
u32 array_layer_data_extent_bytes
Definition texture.h:81
u32 row_pitch_bytes
Definition texture.h:75
u32 array_layer_stride_bytes
Definition texture.h:77
Definition texture.h:73
u32 packed_level
Definition texture.h:91
Level mips[xenos::kTextureMaxMips]
Definition texture.h:87
u32 max_level
Definition texture.h:90
u32 mip_offsets_bytes[xenos::kTextureMaxMips]
Definition texture.h:88
u32 array_size
Definition texture.h:92
Definition texture.h:351
u32 height
Definition texture.h:353
u32 GetAllBlocks() const
Definition texture.h:361
u32 block_width
Definition texture.h:354
u32 GetVisibleBlocks() const
Definition texture.h:364
static TextureExtent Calculate(const TextureInfo *texture_info, bool is_guest)
static TextureExtent Calculate(const FormatInfo *format_info, u32 pitch, u32 height, u32 depth, bool is_tiled, bool is_guest)
u32 block_height
Definition texture.h:355
u32 block_pitch_h
Definition texture.h:356
u32 block_pitch_v
Definition texture.h:357
Definition texture.h:396
xenos::DataDimension dimension
Definition texture.h:400
static bool FromFetchConstant(const xenos::TextureFetch &fetch, TextureInfo *out_info)
static bool FromResolve(u32 physical_address, xenos::TextureFormat texture_format, xenos::Endian endian, u32 pitch, u32 width, u32 height, u32 depth, TextureInfo *out_info)
TextureExtent extent
Definition texture.h:412
u32 GetMipLocation(u32 mip, u32 *offset_x, u32 *offset_y, bool is_guest) const
void GetMipSize(u32 mip, u32 *width, u32 *height) const
bool has_packed_mips
Definition texture.h:409
bool is_stacked
Definition texture.h:407
bool GetPackedMipOffset(u32 packed_tile, u32 *offset_x, u32 *offset_y) const
static bool GetPackedMipOffset(u32 width, u32 height, const FormatInfo *format_info, u32 packed_tile, u32 *offset_x, u32 *offset_y)
u32 GetMaxMipLevels() const
const TextureExtent GetMipExtent(u32 mip, bool is_guest) const
Definition texture.h:386
u32 mip_address
Definition texture.h:389
u32 base_address
Definition texture.h:387
Definition texture.h:532
u32 offset_x
Definition texture.h:533
u32 output_pitch
Definition texture.h:538
u32 input_pitch
Definition texture.h:537
u32 width
Definition texture.h:535
u32 offset_y
Definition texture.h:534
u32 height
Definition texture.h:536
void GetSubresourcesFromFetchConstant(const xenos::TextureFetch &fetch, u32 *width_minus_1_out, u32 *height_minus_1_out, u32 *depth_or_array_size_minus_1_out, u32 *base_page_out, u32 *mip_page_out, u32 *mip_min_level_out, u32 *mip_max_level_out)
void GetClampModesForDimension(const xenos::TextureFetch &fetch, xenos::ClampMode &clamp_x_out, xenos::ClampMode &clamp_y_out, xenos::ClampMode &clamp_z_out)
i32 GetTiledOffset3D(i32 x, i32 y, i32 z, u32 pitch, u32 height, u32 bytes_per_block_log2)
size_t GetTexelSize(xenos::TextureFormat format)
Definition texture.h:268
std::function< void(xenos::Endian, void *, const void *, size_t)> CopyBlockCallback
Definition texture.h:504
void ConvertTexelCTX1ToR8G8(xenos::Endian endian, void *output, const void *input, size_t output_pitch)
xenos::TextureFormat DepthRenderTargetToTextureFormat(xenos::DepthRenderTargetFormat depth_format)
Definition texture.h:308
GuestTextureLayout GetGuestTextureLayout(xenos::DataDimension dimension, u32 base_pitch_texels_div_32, u32 width_texels, u32 height_texels, u32 depth_or_array_size, bool is_tiled, xenos::TextureFormat format, bool has_packed_levels, bool has_base, u32 max_level)
xenos::TextureFormat GetBaseFormat(xenos::TextureFormat texture_format)
Definition texture.h:234
u32 GetTiledAddressLowerBound2D(u32 left, u32 top, u32 pitch, u32 bytes_per_block_log2)
Definition texture.h:137
constexpr bool HasNonSignedComponent(u8 packed_signs)
Definition texture.h:200
i32 GetTiledOffset2D(i32 x, i32 y, u32 pitch, u32 bytes_per_block_log2)
FormatType
Definition texture.h:321
@ kUncompressed
Definition texture.h:323
@ kResolvable
Definition texture.h:322
xenos::TextureFormat ColorFormatToTextureFormat(xenos::ColorFormat color_format)
Definition texture.h:300
u32 GetTiledAddressUpperBound3D(u32 right, u32 bottom, u32 back, u32 pitch, u32 height, u32 bytes_per_block_log2)
void CopySwapBlock(xenos::Endian endian, void *output, const void *input, size_t length)
void ConvertTexelDXT3AToDXT3(xenos::Endian endian, void *output, const void *input, size_t length)
u32 GetPackedMipLevel(u32 width, u32 height)
Definition texture.h:50
bool GetPackedMipOffset(u32 width, u32 height, u32 depth, xenos::TextureFormat format, u32 mip, u32 &x_blocks, u32 &y_blocks, u32 &z_blocks)
u32 GetTiledAddressLowerBound3D(u32 left, u32 top, u32 front, u32 pitch, u32 height, u32 bytes_per_block_log2)
Definition texture.h:153
u8 SwizzleSigns(const xenos::TextureFetch &fetch)
u32 GetTiledAddressUpperBound2D(u32 right, u32 bottom, u32 pitch, u32 bytes_per_block_log2)
void Untile(u8 *output_buffer, const u8 *input_buffer, const UntileRegion *untile_info)
constexpr bool HasSignedComponent(u8 packed_signs)
Definition texture.h:209
Integer types, byte order wrappers and size literals.
Definition fetch.h:237