Maybe fix texture uploads where mipmaps are packed in linear textures.
This commit is contained in:
parent
284aa14a67
commit
69b92c6c31
|
@ -785,7 +785,29 @@ bool TextureCache::UploadTexture2D(GLuint texture,
|
||||||
auto allocation = scratch_buffer_->Acquire(unpack_length);
|
auto allocation = scratch_buffer_->Acquire(unpack_length);
|
||||||
|
|
||||||
if (!texture_info.is_tiled) {
|
if (!texture_info.is_tiled) {
|
||||||
if (texture_info.size_2d.input_pitch == texture_info.size_2d.output_pitch) {
|
if (texture_info.has_packed_mips) {
|
||||||
|
uint32_t bytes_per_block = texture_info.format_info->block_width *
|
||||||
|
texture_info.format_info->block_height *
|
||||||
|
texture_info.format_info->bits_per_pixel / 8;
|
||||||
|
uint32_t offset_x;
|
||||||
|
uint32_t offset_y;
|
||||||
|
TextureInfo::GetPackedTileOffset(texture_info, &offset_x, &offset_y);
|
||||||
|
const uint8_t* src = host_address;
|
||||||
|
// TODO(gibbed): this needs checking
|
||||||
|
src += offset_y * texture_info.size_2d.input_pitch;
|
||||||
|
src += offset_x * bytes_per_block;
|
||||||
|
uint8_t* dest = reinterpret_cast<uint8_t*>(allocation.host_ptr);
|
||||||
|
uint32_t pitch = std::min(texture_info.size_2d.input_pitch,
|
||||||
|
texture_info.size_2d.output_pitch);
|
||||||
|
for (uint32_t y = 0; y < std::min(texture_info.size_2d.block_height,
|
||||||
|
texture_info.size_2d.logical_height);
|
||||||
|
y++) {
|
||||||
|
TextureSwap(texture_info.endianness, dest, src, pitch);
|
||||||
|
src += texture_info.size_2d.input_pitch;
|
||||||
|
dest += texture_info.size_2d.output_pitch;
|
||||||
|
}
|
||||||
|
} else if (texture_info.size_2d.input_pitch ==
|
||||||
|
texture_info.size_2d.output_pitch) {
|
||||||
// Fast path copy entire image.
|
// Fast path copy entire image.
|
||||||
TextureSwap(texture_info.endianness, allocation.host_ptr, host_address,
|
TextureSwap(texture_info.endianness, allocation.host_ptr, host_address,
|
||||||
unpack_length);
|
unpack_length);
|
||||||
|
|
|
@ -135,6 +135,7 @@ bool TextureInfo::Prepare(const xe_gpu_texture_fetch_t& fetch,
|
||||||
info.format_info = FormatInfo::Get(fetch.format);
|
info.format_info = FormatInfo::Get(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.input_length = 0; // Populated below.
|
info.input_length = 0; // Populated below.
|
||||||
info.output_length = 0;
|
info.output_length = 0;
|
||||||
|
|
||||||
|
|
|
@ -222,6 +222,7 @@ struct TextureInfo {
|
||||||
const FormatInfo* format_info;
|
const FormatInfo* format_info;
|
||||||
Endian endianness;
|
Endian endianness;
|
||||||
bool is_tiled;
|
bool is_tiled;
|
||||||
|
bool has_packed_mips;
|
||||||
uint32_t input_length;
|
uint32_t input_length;
|
||||||
uint32_t output_length;
|
uint32_t output_length;
|
||||||
|
|
||||||
|
|
|
@ -986,7 +986,26 @@ void TextureCache::ConvertTexture1D(uint8_t* dest, const TextureInfo& src) {
|
||||||
void TextureCache::ConvertTexture2D(uint8_t* dest, const TextureInfo& src) {
|
void TextureCache::ConvertTexture2D(uint8_t* dest, const TextureInfo& src) {
|
||||||
void* host_address = memory_->TranslatePhysical(src.guest_address);
|
void* host_address = memory_->TranslatePhysical(src.guest_address);
|
||||||
if (!src.is_tiled) {
|
if (!src.is_tiled) {
|
||||||
if (src.size_2d.input_pitch == src.size_2d.output_pitch) {
|
if (src.has_packed_mips) {
|
||||||
|
uint32_t bytes_per_block = src.format_info->block_width *
|
||||||
|
src.format_info->block_height *
|
||||||
|
src.format_info->bits_per_pixel / 8;
|
||||||
|
uint32_t offset_x;
|
||||||
|
uint32_t offset_y;
|
||||||
|
TextureInfo::GetPackedTileOffset(src, &offset_x, &offset_y);
|
||||||
|
const uint8_t* src_mem = reinterpret_cast<const uint8_t*>(host_address);
|
||||||
|
src_mem += offset_y * src.size_2d.input_pitch;
|
||||||
|
src_mem += offset_x * bytes_per_block;
|
||||||
|
uint32_t pitch =
|
||||||
|
std::min(src.size_2d.input_pitch, src.size_2d.output_pitch);
|
||||||
|
for (uint32_t y = 0;
|
||||||
|
y < std::min(src.size_2d.block_height, src.size_2d.logical_height);
|
||||||
|
y++) {
|
||||||
|
TextureSwap(src.endianness, dest, src_mem, pitch);
|
||||||
|
src_mem += src.size_2d.input_pitch;
|
||||||
|
dest += src.size_2d.output_pitch;
|
||||||
|
}
|
||||||
|
} else if (src.size_2d.input_pitch == src.size_2d.output_pitch) {
|
||||||
// Fast path copy entire image.
|
// Fast path copy entire image.
|
||||||
TextureSwap(src.endianness, dest, host_address, src.output_length);
|
TextureSwap(src.endianness, dest, host_address, src.output_length);
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Reference in New Issue