TextureInfo: Store the texture format, not a pointer to texture format info.
This commit is contained in:
parent
59f9a19d30
commit
b40d75aa3d
|
@ -714,8 +714,7 @@ bool TextureCache::UploadTexture1D(GLuint texture,
|
||||||
const auto host_address =
|
const auto host_address =
|
||||||
memory_->TranslatePhysical(texture_info.guest_address);
|
memory_->TranslatePhysical(texture_info.guest_address);
|
||||||
|
|
||||||
const auto& config =
|
const auto& config = texture_configs[uint32_t(texture_info.texture_format)];
|
||||||
texture_configs[uint32_t(texture_info.format_info->format)];
|
|
||||||
if (config.format == GL_INVALID_ENUM) {
|
if (config.format == GL_INVALID_ENUM) {
|
||||||
assert_always("Unhandled texture format");
|
assert_always("Unhandled texture format");
|
||||||
return false;
|
return false;
|
||||||
|
@ -771,7 +770,7 @@ bool TextureCache::UploadTexture2D(GLuint texture,
|
||||||
memory_->TranslatePhysical(texture_info.guest_address);
|
memory_->TranslatePhysical(texture_info.guest_address);
|
||||||
|
|
||||||
const auto& config =
|
const auto& config =
|
||||||
texture_configs[uint32_t(texture_info.format_info->format)];
|
texture_configs[uint32_t(texture_info.format_info()->format)];
|
||||||
if (config.format == GL_INVALID_ENUM) {
|
if (config.format == GL_INVALID_ENUM) {
|
||||||
assert_always("Unhandled texture format");
|
assert_always("Unhandled texture format");
|
||||||
return false;
|
return false;
|
||||||
|
@ -788,9 +787,9 @@ bool TextureCache::UploadTexture2D(GLuint texture,
|
||||||
uint32_t offset_x, offset_y;
|
uint32_t offset_x, offset_y;
|
||||||
if (texture_info.has_packed_mips &&
|
if (texture_info.has_packed_mips &&
|
||||||
TextureInfo::GetPackedTileOffset(texture_info, &offset_x, &offset_y)) {
|
TextureInfo::GetPackedTileOffset(texture_info, &offset_x, &offset_y)) {
|
||||||
uint32_t bytes_per_block = texture_info.format_info->block_width *
|
uint32_t bytes_per_block = texture_info.format_info()->block_width *
|
||||||
texture_info.format_info->block_height *
|
texture_info.format_info()->block_height *
|
||||||
texture_info.format_info->bits_per_pixel / 8;
|
texture_info.format_info()->bits_per_pixel / 8;
|
||||||
const uint8_t* src = host_address;
|
const uint8_t* src = host_address;
|
||||||
// TODO(gibbed): this needs checking
|
// TODO(gibbed): this needs checking
|
||||||
src += offset_y * texture_info.size_2d.input_pitch;
|
src += offset_y * texture_info.size_2d.input_pitch;
|
||||||
|
@ -833,9 +832,9 @@ bool TextureCache::UploadTexture2D(GLuint texture,
|
||||||
// TODO(benvanik): optimize this inner loop (or work by tiles).
|
// TODO(benvanik): optimize this inner loop (or work by tiles).
|
||||||
const uint8_t* src = host_address;
|
const uint8_t* src = host_address;
|
||||||
uint8_t* dest = reinterpret_cast<uint8_t*>(allocation.host_ptr);
|
uint8_t* dest = reinterpret_cast<uint8_t*>(allocation.host_ptr);
|
||||||
uint32_t bytes_per_block = texture_info.format_info->block_width *
|
uint32_t bytes_per_block = texture_info.format_info()->block_width *
|
||||||
texture_info.format_info->block_height *
|
texture_info.format_info()->block_height *
|
||||||
texture_info.format_info->bits_per_pixel / 8;
|
texture_info.format_info()->bits_per_pixel / 8;
|
||||||
|
|
||||||
// Tiled textures can be packed; get the offset into the packed texture.
|
// Tiled textures can be packed; get the offset into the packed texture.
|
||||||
uint32_t offset_x;
|
uint32_t offset_x;
|
||||||
|
@ -849,8 +848,9 @@ bool TextureCache::UploadTexture2D(GLuint texture,
|
||||||
texture_info.size_2d.logical_height);
|
texture_info.size_2d.logical_height);
|
||||||
y++, output_base_offset += texture_info.size_2d.output_pitch) {
|
y++, output_base_offset += texture_info.size_2d.output_pitch) {
|
||||||
auto input_base_offset = TextureInfo::TiledOffset2DOuter(
|
auto input_base_offset = TextureInfo::TiledOffset2DOuter(
|
||||||
offset_y + y, (texture_info.size_2d.input_width /
|
offset_y + y,
|
||||||
texture_info.format_info->block_width),
|
(texture_info.size_2d.input_width /
|
||||||
|
texture_info.format_info()->block_width),
|
||||||
bpp);
|
bpp);
|
||||||
for (uint32_t x = 0, output_offset = output_base_offset;
|
for (uint32_t x = 0, output_offset = output_base_offset;
|
||||||
x < texture_info.size_2d.block_width;
|
x < texture_info.size_2d.block_width;
|
||||||
|
@ -899,7 +899,7 @@ bool TextureCache::UploadTextureCube(GLuint texture,
|
||||||
memory_->TranslatePhysical(texture_info.guest_address);
|
memory_->TranslatePhysical(texture_info.guest_address);
|
||||||
|
|
||||||
const auto& config =
|
const auto& config =
|
||||||
texture_configs[uint32_t(texture_info.format_info->format)];
|
texture_configs[uint32_t(texture_info.format_info()->format)];
|
||||||
if (config.format == GL_INVALID_ENUM) {
|
if (config.format == GL_INVALID_ENUM) {
|
||||||
assert_always("Unhandled texture format");
|
assert_always("Unhandled texture format");
|
||||||
return false;
|
return false;
|
||||||
|
@ -937,9 +937,9 @@ bool TextureCache::UploadTextureCube(GLuint texture,
|
||||||
// TODO(benvanik): optimize this inner loop (or work by tiles).
|
// TODO(benvanik): optimize this inner loop (or work by tiles).
|
||||||
const uint8_t* src = host_address;
|
const uint8_t* src = host_address;
|
||||||
uint8_t* dest = reinterpret_cast<uint8_t*>(allocation.host_ptr);
|
uint8_t* dest = reinterpret_cast<uint8_t*>(allocation.host_ptr);
|
||||||
uint32_t bytes_per_block = texture_info.format_info->block_width *
|
uint32_t bytes_per_block = texture_info.format_info()->block_width *
|
||||||
texture_info.format_info->block_height *
|
texture_info.format_info()->block_height *
|
||||||
texture_info.format_info->bits_per_pixel / 8;
|
texture_info.format_info()->bits_per_pixel / 8;
|
||||||
// Tiled textures can be packed; get the offset into the packed texture.
|
// Tiled textures can be packed; get the offset into the packed texture.
|
||||||
uint32_t offset_x;
|
uint32_t offset_x;
|
||||||
uint32_t offset_y;
|
uint32_t offset_y;
|
||||||
|
@ -951,8 +951,9 @@ bool TextureCache::UploadTextureCube(GLuint texture,
|
||||||
y < texture_info.size_cube.block_height;
|
y < texture_info.size_cube.block_height;
|
||||||
y++, output_base_offset += texture_info.size_cube.output_pitch) {
|
y++, output_base_offset += texture_info.size_cube.output_pitch) {
|
||||||
auto input_base_offset = TextureInfo::TiledOffset2DOuter(
|
auto input_base_offset = TextureInfo::TiledOffset2DOuter(
|
||||||
offset_y + y, (texture_info.size_cube.input_width /
|
offset_y + y,
|
||||||
texture_info.format_info->block_width),
|
(texture_info.size_cube.input_width /
|
||||||
|
texture_info.format_info()->block_width),
|
||||||
bpp);
|
bpp);
|
||||||
for (uint32_t x = 0, output_offset = output_base_offset;
|
for (uint32_t x = 0, output_offset = output_base_offset;
|
||||||
x < texture_info.size_cube.block_width;
|
x < texture_info.size_cube.block_width;
|
||||||
|
|
|
@ -132,14 +132,14 @@ bool TextureInfo::Prepare(const xe_gpu_texture_fetch_t& fetch,
|
||||||
info.depth = fetch.size_stack.depth;
|
info.depth = fetch.size_stack.depth;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
info.format_info = FormatInfo::Get(fetch.format);
|
info.texture_format = static_cast<TextureFormat>(fetch.format);
|
||||||
info.endianness = static_cast<Endian>(fetch.endianness);
|
info.endianness = static_cast<Endian>(fetch.endianness);
|
||||||
info.is_tiled = fetch.tiled;
|
info.is_tiled = fetch.tiled;
|
||||||
info.has_packed_mips = fetch.packed_mips;
|
info.has_packed_mips = fetch.packed_mips;
|
||||||
info.input_length = 0; // Populated below.
|
info.input_length = 0; // Populated below.
|
||||||
info.output_length = 0;
|
info.output_length = 0;
|
||||||
|
|
||||||
if (info.format_info->format == TextureFormat::kUnknown) {
|
if (info.format_info()->format == TextureFormat::kUnknown) {
|
||||||
assert_true("Unsupported texture format");
|
assert_true("Unsupported texture format");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -154,13 +154,13 @@ bool TextureInfo::Prepare(const xe_gpu_texture_fetch_t& fetch,
|
||||||
fetch.size_2d.height + 1);
|
fetch.size_2d.height + 1);
|
||||||
|
|
||||||
// DEBUG: Make sure our calculated pitch is equal to the fetch pitch.
|
// DEBUG: Make sure our calculated pitch is equal to the fetch pitch.
|
||||||
uint32_t bytes_per_block = info.format_info->block_width *
|
uint32_t bytes_per_block = info.format_info()->block_width *
|
||||||
info.format_info->block_height *
|
info.format_info()->block_height *
|
||||||
info.format_info->bits_per_pixel / 8;
|
info.format_info()->bits_per_pixel / 8;
|
||||||
|
|
||||||
assert_true(info.size_2d.input_pitch ==
|
assert_true(info.size_2d.input_pitch ==
|
||||||
(bytes_per_block * fetch.pitch << 5) /
|
(bytes_per_block * fetch.pitch << 5) /
|
||||||
info.format_info->block_width);
|
info.format_info()->block_width);
|
||||||
} break;
|
} break;
|
||||||
case Dimension::k3D: {
|
case Dimension::k3D: {
|
||||||
// TODO(benvanik): calculate size.
|
// TODO(benvanik): calculate size.
|
||||||
|
@ -186,14 +186,14 @@ bool TextureInfo::PrepareResolve(uint32_t physical_address,
|
||||||
info.dimension = Dimension::k2D;
|
info.dimension = Dimension::k2D;
|
||||||
info.width = width - 1;
|
info.width = width - 1;
|
||||||
info.height = height - 1;
|
info.height = height - 1;
|
||||||
info.format_info = FormatInfo::Get(static_cast<uint32_t>(texture_format));
|
info.texture_format = texture_format;
|
||||||
info.endianness = endian;
|
info.endianness = endian;
|
||||||
info.is_tiled = true;
|
info.is_tiled = true;
|
||||||
info.has_packed_mips = false;
|
info.has_packed_mips = false;
|
||||||
info.input_length = 0;
|
info.input_length = 0;
|
||||||
info.output_length = 0;
|
info.output_length = 0;
|
||||||
|
|
||||||
if (info.format_info->format == TextureFormat::kUnknown) {
|
if (info.format_info()->format == TextureFormat::kUnknown) {
|
||||||
assert_true("Unsupported texture format");
|
assert_true("Unsupported texture format");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -206,15 +206,16 @@ void TextureInfo::CalculateTextureSizes1D(uint32_t width) {
|
||||||
// ?
|
// ?
|
||||||
size_1d.logical_width = width;
|
size_1d.logical_width = width;
|
||||||
|
|
||||||
|
auto format = format_info();
|
||||||
|
|
||||||
uint32_t block_width =
|
uint32_t block_width =
|
||||||
xe::round_up(size_1d.logical_width, format_info->block_width) /
|
xe::round_up(size_1d.logical_width, format->block_width) /
|
||||||
format_info->block_width;
|
format->block_width;
|
||||||
|
|
||||||
uint32_t tile_width = xe::round_up(block_width, 32) / 32;
|
uint32_t tile_width = xe::round_up(block_width, 32) / 32;
|
||||||
size_1d.block_width = tile_width * 32;
|
size_1d.block_width = tile_width * 32;
|
||||||
|
|
||||||
uint32_t bytes_per_block =
|
uint32_t bytes_per_block = format->block_width * format->bits_per_pixel / 8;
|
||||||
format_info->block_width * format_info->bits_per_pixel / 8;
|
|
||||||
|
|
||||||
uint32_t byte_pitch = tile_width * 32 * bytes_per_block;
|
uint32_t byte_pitch = tile_width * 32 * bytes_per_block;
|
||||||
if (!is_tiled) {
|
if (!is_tiled) {
|
||||||
|
@ -222,12 +223,12 @@ void TextureInfo::CalculateTextureSizes1D(uint32_t width) {
|
||||||
byte_pitch = xe::round_up(byte_pitch, 256);
|
byte_pitch = xe::round_up(byte_pitch, 256);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_1d.input_width = tile_width * 32 * format_info->block_width;
|
size_1d.input_width = tile_width * 32 * format->block_width;
|
||||||
size_1d.input_pitch = byte_pitch;
|
size_1d.input_pitch = byte_pitch;
|
||||||
input_length = size_1d.input_pitch;
|
input_length = size_1d.input_pitch;
|
||||||
|
|
||||||
// TODO(DrChat): Remove this, leave it up to the backend.
|
// TODO(DrChat): Remove this, leave it up to the backend.
|
||||||
size_1d.output_width = block_width * format_info->block_width;
|
size_1d.output_width = block_width * format->block_width;
|
||||||
size_1d.output_pitch = block_width * bytes_per_block;
|
size_1d.output_pitch = block_width * bytes_per_block;
|
||||||
output_length = size_1d.output_pitch;
|
output_length = size_1d.output_pitch;
|
||||||
}
|
}
|
||||||
|
@ -240,13 +241,15 @@ void TextureInfo::CalculateTextureSizes2D(uint32_t width, uint32_t height) {
|
||||||
// images and create GL textures. Changes here will impact that code.
|
// images and create GL textures. Changes here will impact that code.
|
||||||
// TODO(benvanik): generic texture copying utility.
|
// TODO(benvanik): generic texture copying utility.
|
||||||
|
|
||||||
|
auto format = format_info();
|
||||||
|
|
||||||
// w/h in blocks.
|
// w/h in blocks.
|
||||||
uint32_t block_width =
|
uint32_t block_width =
|
||||||
xe::round_up(size_2d.logical_width, format_info->block_width) /
|
xe::round_up(size_2d.logical_width, format->block_width) /
|
||||||
format_info->block_width;
|
format->block_width;
|
||||||
uint32_t block_height =
|
uint32_t block_height =
|
||||||
xe::round_up(size_2d.logical_height, format_info->block_height) /
|
xe::round_up(size_2d.logical_height, format->block_height) /
|
||||||
format_info->block_height;
|
format->block_height;
|
||||||
|
|
||||||
// Tiles are 32x32 blocks. The pitch of all textures must a multiple of tile
|
// Tiles are 32x32 blocks. The pitch of all textures must a multiple of tile
|
||||||
// dimensions.
|
// dimensions.
|
||||||
|
@ -254,9 +257,8 @@ void TextureInfo::CalculateTextureSizes2D(uint32_t width, uint32_t height) {
|
||||||
size_2d.block_width = tile_width * 32;
|
size_2d.block_width = tile_width * 32;
|
||||||
size_2d.block_height = block_height;
|
size_2d.block_height = block_height;
|
||||||
|
|
||||||
uint32_t bytes_per_block = format_info->block_width *
|
uint32_t bytes_per_block =
|
||||||
format_info->block_height *
|
format->block_width * format->block_height * format->bits_per_pixel / 8;
|
||||||
format_info->bits_per_pixel / 8;
|
|
||||||
uint32_t byte_pitch = size_2d.block_width * bytes_per_block;
|
uint32_t byte_pitch = size_2d.block_width * bytes_per_block;
|
||||||
|
|
||||||
if (!is_tiled) {
|
if (!is_tiled) {
|
||||||
|
@ -264,15 +266,15 @@ void TextureInfo::CalculateTextureSizes2D(uint32_t width, uint32_t height) {
|
||||||
byte_pitch = xe::round_up(byte_pitch, 256);
|
byte_pitch = xe::round_up(byte_pitch, 256);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_2d.input_width = size_2d.block_width * format_info->block_width;
|
size_2d.input_width = size_2d.block_width * format->block_width;
|
||||||
size_2d.input_height = size_2d.block_height * format_info->block_height;
|
size_2d.input_height = size_2d.block_height * format->block_height;
|
||||||
size_2d.input_pitch = byte_pitch;
|
size_2d.input_pitch = byte_pitch;
|
||||||
|
|
||||||
input_length = size_2d.input_pitch * size_2d.block_height;
|
input_length = size_2d.input_pitch * size_2d.block_height;
|
||||||
|
|
||||||
// TODO(DrChat): Remove this, leave it up to the backend.
|
// TODO(DrChat): Remove this, leave it up to the backend.
|
||||||
size_2d.output_width = block_width * format_info->block_width;
|
size_2d.output_width = block_width * format->block_width;
|
||||||
size_2d.output_height = block_height * format_info->block_height;
|
size_2d.output_height = block_height * format->block_height;
|
||||||
size_2d.output_pitch = block_width * bytes_per_block;
|
size_2d.output_pitch = block_width * bytes_per_block;
|
||||||
|
|
||||||
output_length = size_2d.output_pitch * block_height;
|
output_length = size_2d.output_pitch * block_height;
|
||||||
|
@ -284,13 +286,15 @@ void TextureInfo::CalculateTextureSizesCube(uint32_t width, uint32_t height,
|
||||||
size_cube.logical_width = width;
|
size_cube.logical_width = width;
|
||||||
size_cube.logical_height = height;
|
size_cube.logical_height = height;
|
||||||
|
|
||||||
|
auto format = format_info();
|
||||||
|
|
||||||
// w/h in blocks must be a multiple of block size.
|
// w/h in blocks must be a multiple of block size.
|
||||||
uint32_t block_width =
|
uint32_t block_width =
|
||||||
xe::round_up(size_cube.logical_width, format_info->block_width) /
|
xe::round_up(size_cube.logical_width, format->block_width) /
|
||||||
format_info->block_width;
|
format->block_width;
|
||||||
uint32_t block_height =
|
uint32_t block_height =
|
||||||
xe::round_up(size_cube.logical_height, format_info->block_height) /
|
xe::round_up(size_cube.logical_height, format->block_height) /
|
||||||
format_info->block_height;
|
format->block_height;
|
||||||
|
|
||||||
// Tiles are 32x32 blocks. All textures must be multiples of tile dimensions.
|
// Tiles are 32x32 blocks. All textures must be multiples of tile dimensions.
|
||||||
uint32_t tile_width = xe::round_up(block_width, 32) / 32;
|
uint32_t tile_width = xe::round_up(block_width, 32) / 32;
|
||||||
|
@ -298,25 +302,24 @@ void TextureInfo::CalculateTextureSizesCube(uint32_t width, uint32_t height,
|
||||||
size_cube.block_width = tile_width * 32;
|
size_cube.block_width = tile_width * 32;
|
||||||
size_cube.block_height = tile_height * 32;
|
size_cube.block_height = tile_height * 32;
|
||||||
|
|
||||||
uint32_t bytes_per_block = format_info->block_width *
|
uint32_t bytes_per_block =
|
||||||
format_info->block_height *
|
format->block_width * format->block_height * format->bits_per_pixel / 8;
|
||||||
format_info->bits_per_pixel / 8;
|
|
||||||
uint32_t byte_pitch = size_cube.block_width * bytes_per_block;
|
uint32_t byte_pitch = size_cube.block_width * bytes_per_block;
|
||||||
if (!is_tiled) {
|
if (!is_tiled) {
|
||||||
// Each row must be a multiple of 256 in linear textures.
|
// Each row must be a multiple of 256 in linear textures.
|
||||||
byte_pitch = xe::round_up(byte_pitch, 256);
|
byte_pitch = xe::round_up(byte_pitch, 256);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_cube.input_width = size_cube.block_width * format_info->block_width;
|
size_cube.input_width = size_cube.block_width * format->block_width;
|
||||||
size_cube.input_height = size_cube.block_height * format_info->block_height;
|
size_cube.input_height = size_cube.block_height * format->block_height;
|
||||||
size_cube.input_pitch = byte_pitch;
|
size_cube.input_pitch = byte_pitch;
|
||||||
|
|
||||||
size_cube.input_face_length = size_cube.input_pitch * size_cube.block_height;
|
size_cube.input_face_length = size_cube.input_pitch * size_cube.block_height;
|
||||||
input_length = size_cube.input_face_length * 6;
|
input_length = size_cube.input_face_length * 6;
|
||||||
|
|
||||||
// TODO(DrChat): Remove this, leave it up to the backend.
|
// TODO(DrChat): Remove this, leave it up to the backend.
|
||||||
size_cube.output_width = block_width * format_info->block_width;
|
size_cube.output_width = block_width * format->block_width;
|
||||||
size_cube.output_height = block_height * format_info->block_height;
|
size_cube.output_height = block_height * format->block_height;
|
||||||
size_cube.output_pitch = block_width * bytes_per_block;
|
size_cube.output_pitch = block_width * bytes_per_block;
|
||||||
|
|
||||||
size_cube.output_face_length = size_cube.output_pitch * block_height;
|
size_cube.output_face_length = size_cube.output_pitch * block_height;
|
||||||
|
@ -375,8 +378,8 @@ bool TextureInfo::GetPackedTileOffset(const TextureInfo& texture_info,
|
||||||
*out_offset_x = 16;
|
*out_offset_x = 16;
|
||||||
*out_offset_y = 0;
|
*out_offset_y = 0;
|
||||||
}
|
}
|
||||||
*out_offset_x /= texture_info.format_info->block_width;
|
*out_offset_x /= texture_info.format_info()->block_width;
|
||||||
*out_offset_y /= texture_info.format_info->block_height;
|
*out_offset_y /= texture_info.format_info()->block_height;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -88,6 +88,38 @@ enum class TextureFormat : uint32_t {
|
||||||
kUnknown = 0xFFFFFFFFu,
|
kUnknown = 0xFFFFFFFFu,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline TextureFormat GetBaseFormat(TextureFormat texture_format) {
|
||||||
|
// These formats are used for resampling textures / gamma control.
|
||||||
|
switch (texture_format) {
|
||||||
|
case TextureFormat::k_16_EXPAND:
|
||||||
|
return TextureFormat::k_16;
|
||||||
|
case TextureFormat::k_16_16_EXPAND:
|
||||||
|
return TextureFormat::k_16_16;
|
||||||
|
case TextureFormat::k_16_16_16_16_EXPAND:
|
||||||
|
return TextureFormat::k_16_16_16_16;
|
||||||
|
case TextureFormat::k_8_8_8_8_AS_16_16_16_16:
|
||||||
|
return TextureFormat::k_8_8_8_8;
|
||||||
|
case TextureFormat::k_DXT1_AS_16_16_16_16:
|
||||||
|
return TextureFormat::k_DXT1;
|
||||||
|
case TextureFormat::k_DXT2_3_AS_16_16_16_16:
|
||||||
|
return TextureFormat::k_DXT2_3;
|
||||||
|
case TextureFormat::k_DXT4_5_AS_16_16_16_16:
|
||||||
|
return TextureFormat::k_DXT4_5;
|
||||||
|
case TextureFormat::k_2_10_10_10_AS_16_16_16_16:
|
||||||
|
return TextureFormat::k_2_10_10_10;
|
||||||
|
case TextureFormat::k_10_11_11_AS_16_16_16_16:
|
||||||
|
return TextureFormat::k_10_11_11;
|
||||||
|
case TextureFormat::k_11_11_10_AS_16_16_16_16:
|
||||||
|
return TextureFormat::k_11_11_10;
|
||||||
|
case TextureFormat::k_DXT3A_AS_1_1_1_1:
|
||||||
|
return TextureFormat::k_DXT3A;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return texture_format;
|
||||||
|
}
|
||||||
|
|
||||||
inline size_t GetTexelSize(TextureFormat format) {
|
inline size_t GetTexelSize(TextureFormat format) {
|
||||||
switch (format) {
|
switch (format) {
|
||||||
case TextureFormat::k_1_5_5_5:
|
case TextureFormat::k_1_5_5_5:
|
||||||
|
@ -215,19 +247,23 @@ struct FormatInfo {
|
||||||
|
|
||||||
struct TextureInfo {
|
struct TextureInfo {
|
||||||
uint32_t guest_address;
|
uint32_t guest_address;
|
||||||
|
TextureFormat texture_format;
|
||||||
Dimension dimension;
|
Dimension dimension;
|
||||||
uint32_t width;
|
uint32_t width;
|
||||||
uint32_t height;
|
uint32_t height;
|
||||||
uint32_t depth;
|
uint32_t depth;
|
||||||
const FormatInfo* format_info;
|
|
||||||
Endian endianness;
|
Endian endianness;
|
||||||
bool is_tiled;
|
bool is_tiled;
|
||||||
bool has_packed_mips;
|
bool has_packed_mips;
|
||||||
uint32_t input_length;
|
uint32_t input_length;
|
||||||
uint32_t output_length;
|
uint32_t output_length;
|
||||||
|
|
||||||
|
const FormatInfo* format_info() const {
|
||||||
|
return FormatInfo::Get(static_cast<uint32_t>(texture_format));
|
||||||
|
}
|
||||||
|
|
||||||
bool is_compressed() const {
|
bool is_compressed() const {
|
||||||
return format_info->type == FormatType::kCompressed;
|
return format_info()->type == FormatType::kCompressed;
|
||||||
}
|
}
|
||||||
|
|
||||||
union {
|
union {
|
||||||
|
|
|
@ -334,8 +334,8 @@ TextureCache::Texture* TextureCache::AllocateTexture(
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert_not_null(texture_info.format_info);
|
assert_not_null(texture_info.format_info());
|
||||||
auto& config = texture_configs[int(texture_info.format_info->format)];
|
auto& config = texture_configs[int(texture_info.format_info()->format)];
|
||||||
VkFormat format = config.host_format != VK_FORMAT_UNDEFINED
|
VkFormat format = config.host_format != VK_FORMAT_UNDEFINED
|
||||||
? config.host_format
|
? config.host_format
|
||||||
: VK_FORMAT_R8G8B8A8_UNORM;
|
: VK_FORMAT_R8G8B8A8_UNORM;
|
||||||
|
@ -517,6 +517,18 @@ TextureCache::Texture* TextureCache::Demand(const TextureInfo& texture_info,
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Though we didn't find an exact match, that doesn't mean we're out of the
|
||||||
|
// woods yet. This texture could either be a portion of another texture or
|
||||||
|
// vice versa. Copy any overlapping textures into this texture.
|
||||||
|
// TODO: Byte count -> pixel count (on x and y axes)
|
||||||
|
VkOffset2D offset;
|
||||||
|
auto collide_tex = LookupAddress(
|
||||||
|
texture_info.guest_address, texture_info.width + 1,
|
||||||
|
texture_info.height + 1, texture_info.format_info()->format, &offset);
|
||||||
|
if (collide_tex != nullptr) {
|
||||||
|
// assert_always();
|
||||||
|
}
|
||||||
|
|
||||||
trace_writer_->WriteMemoryRead(texture_info.guest_address,
|
trace_writer_->WriteMemoryRead(texture_info.guest_address,
|
||||||
texture_info.input_length);
|
texture_info.input_length);
|
||||||
|
|
||||||
|
@ -555,16 +567,6 @@ TextureCache::Texture* TextureCache::Demand(const TextureInfo& texture_info,
|
||||||
"0x%.8X - 0x%.8X", texture_info.guest_address,
|
"0x%.8X - 0x%.8X", texture_info.guest_address,
|
||||||
texture_info.guest_address + texture_info.output_length));
|
texture_info.guest_address + texture_info.output_length));
|
||||||
|
|
||||||
// Though we didn't find an exact match, that doesn't mean we're out of the
|
|
||||||
// woods yet. This texture could either be a portion of another texture or
|
|
||||||
// vice versa. Copy any overlapping textures into this texture.
|
|
||||||
// TODO: Byte count -> pixel count (on x and y axes)
|
|
||||||
/*
|
|
||||||
for (auto it = textures_.begin(); it != textures_.end(); ++it) {
|
|
||||||
// TODO(DrChat)
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Okay. Now that the texture is uploaded from system memory, put a writewatch
|
// Okay. Now that the texture is uploaded from system memory, put a writewatch
|
||||||
// on it to tell us if it's been modified from the guest.
|
// on it to tell us if it's been modified from the guest.
|
||||||
texture->access_watch_handle = memory_->AddPhysicalAccessWatch(
|
texture->access_watch_handle = memory_->AddPhysicalAccessWatch(
|
||||||
|
@ -915,9 +917,9 @@ void TextureCache::ConvertTexture2D(uint8_t* dest, const TextureInfo& src) {
|
||||||
uint32_t offset_x, offset_y;
|
uint32_t offset_x, offset_y;
|
||||||
if (src.has_packed_mips &&
|
if (src.has_packed_mips &&
|
||||||
TextureInfo::GetPackedTileOffset(src, &offset_x, &offset_y)) {
|
TextureInfo::GetPackedTileOffset(src, &offset_x, &offset_y)) {
|
||||||
uint32_t bytes_per_block = src.format_info->block_width *
|
uint32_t bytes_per_block = src.format_info()->block_width *
|
||||||
src.format_info->block_height *
|
src.format_info()->block_height *
|
||||||
src.format_info->bits_per_pixel / 8;
|
src.format_info()->bits_per_pixel / 8;
|
||||||
|
|
||||||
const uint8_t* src_mem = reinterpret_cast<const uint8_t*>(host_address);
|
const uint8_t* src_mem = reinterpret_cast<const uint8_t*>(host_address);
|
||||||
src_mem += offset_y * src.size_2d.input_pitch;
|
src_mem += offset_y * src.size_2d.input_pitch;
|
||||||
|
@ -955,9 +957,9 @@ void TextureCache::ConvertTexture2D(uint8_t* dest, const TextureInfo& src) {
|
||||||
|
|
||||||
// TODO(benvanik): optimize this inner loop (or work by tiles).
|
// TODO(benvanik): optimize this inner loop (or work by tiles).
|
||||||
const uint8_t* src_mem = reinterpret_cast<const uint8_t*>(host_address);
|
const uint8_t* src_mem = reinterpret_cast<const uint8_t*>(host_address);
|
||||||
uint32_t bytes_per_block = src.format_info->block_width *
|
uint32_t bytes_per_block = src.format_info()->block_width *
|
||||||
src.format_info->block_height *
|
src.format_info()->block_height *
|
||||||
src.format_info->bits_per_pixel / 8;
|
src.format_info()->bits_per_pixel / 8;
|
||||||
|
|
||||||
// Tiled textures can be packed; get the offset into the packed texture.
|
// Tiled textures can be packed; get the offset into the packed texture.
|
||||||
uint32_t offset_x;
|
uint32_t offset_x;
|
||||||
|
@ -970,7 +972,7 @@ void TextureCache::ConvertTexture2D(uint8_t* dest, const TextureInfo& src) {
|
||||||
y++, output_base_offset += src.size_2d.output_pitch) {
|
y++, output_base_offset += src.size_2d.output_pitch) {
|
||||||
auto input_base_offset = TextureInfo::TiledOffset2DOuter(
|
auto input_base_offset = TextureInfo::TiledOffset2DOuter(
|
||||||
offset_y + y,
|
offset_y + y,
|
||||||
(src.size_2d.input_width / src.format_info->block_width), bpp);
|
(src.size_2d.input_width / src.format_info()->block_width), bpp);
|
||||||
for (uint32_t x = 0, output_offset = output_base_offset;
|
for (uint32_t x = 0, output_offset = output_base_offset;
|
||||||
x < src.size_2d.block_width; x++, output_offset += bytes_per_block) {
|
x < src.size_2d.block_width; x++, output_offset += bytes_per_block) {
|
||||||
auto input_offset =
|
auto input_offset =
|
||||||
|
@ -1008,9 +1010,9 @@ void TextureCache::ConvertTextureCube(uint8_t* dest, const TextureInfo& src) {
|
||||||
} else {
|
} else {
|
||||||
// TODO(benvanik): optimize this inner loop (or work by tiles).
|
// TODO(benvanik): optimize this inner loop (or work by tiles).
|
||||||
const uint8_t* src_mem = reinterpret_cast<const uint8_t*>(host_address);
|
const uint8_t* src_mem = reinterpret_cast<const uint8_t*>(host_address);
|
||||||
uint32_t bytes_per_block = src.format_info->block_width *
|
uint32_t bytes_per_block = src.format_info()->block_width *
|
||||||
src.format_info->block_height *
|
src.format_info()->block_height *
|
||||||
src.format_info->bits_per_pixel / 8;
|
src.format_info()->bits_per_pixel / 8;
|
||||||
// Tiled textures can be packed; get the offset into the packed texture.
|
// Tiled textures can be packed; get the offset into the packed texture.
|
||||||
uint32_t offset_x;
|
uint32_t offset_x;
|
||||||
uint32_t offset_y;
|
uint32_t offset_y;
|
||||||
|
@ -1023,7 +1025,7 @@ void TextureCache::ConvertTextureCube(uint8_t* dest, const TextureInfo& src) {
|
||||||
y++, output_base_offset += src.size_cube.output_pitch) {
|
y++, output_base_offset += src.size_cube.output_pitch) {
|
||||||
auto input_base_offset = TextureInfo::TiledOffset2DOuter(
|
auto input_base_offset = TextureInfo::TiledOffset2DOuter(
|
||||||
offset_y + y,
|
offset_y + y,
|
||||||
(src.size_cube.input_width / src.format_info->block_width), bpp);
|
(src.size_cube.input_width / src.format_info()->block_width), bpp);
|
||||||
for (uint32_t x = 0, output_offset = output_base_offset;
|
for (uint32_t x = 0, output_offset = output_base_offset;
|
||||||
x < src.size_cube.block_width;
|
x < src.size_cube.block_width;
|
||||||
x++, output_offset += bytes_per_block) {
|
x++, output_offset += bytes_per_block) {
|
||||||
|
|
Loading…
Reference in New Issue