mirror of
				https://git.zaroz.cloud/nintendo-back-up/yuzu/yuzu-mainline.git
				synced 2025-03-21 01:53:15 +00:00 
			
		
		
		
	Merge pull request #1002 from bunnei/refactor-tex-fmt
textures: Refactor out for Texture/Depth FormatFromPixelFormat.
This commit is contained in:
		
						commit
						7e6a73963e
					
				@ -183,6 +183,21 @@ MathUtil::Rectangle<u32> SurfaceParams::GetRect() const {
 | 
				
			|||||||
    return {0, actual_height, width, 0};
 | 
					    return {0, actual_height, width, 0};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Returns true if the specified PixelFormat is a BCn format, e.g. DXT or DXN
 | 
				
			||||||
 | 
					static bool IsFormatBCn(PixelFormat format) {
 | 
				
			||||||
 | 
					    switch (format) {
 | 
				
			||||||
 | 
					    case PixelFormat::DXT1:
 | 
				
			||||||
 | 
					    case PixelFormat::DXT23:
 | 
				
			||||||
 | 
					    case PixelFormat::DXT45:
 | 
				
			||||||
 | 
					    case PixelFormat::DXN1:
 | 
				
			||||||
 | 
					    case PixelFormat::DXN2SNORM:
 | 
				
			||||||
 | 
					    case PixelFormat::DXN2UNORM:
 | 
				
			||||||
 | 
					    case PixelFormat::BC7U:
 | 
				
			||||||
 | 
					        return true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template <bool morton_to_gl, PixelFormat format>
 | 
					template <bool morton_to_gl, PixelFormat format>
 | 
				
			||||||
void MortonCopy(u32 stride, u32 block_height, u32 height, std::vector<u8>& gl_buffer,
 | 
					void MortonCopy(u32 stride, u32 block_height, u32 height, std::vector<u8>& gl_buffer,
 | 
				
			||||||
                Tegra::GPUVAddr addr) {
 | 
					                Tegra::GPUVAddr addr) {
 | 
				
			||||||
@ -191,16 +206,12 @@ void MortonCopy(u32 stride, u32 block_height, u32 height, std::vector<u8>& gl_bu
 | 
				
			|||||||
    const auto& gpu = Core::System::GetInstance().GPU();
 | 
					    const auto& gpu = Core::System::GetInstance().GPU();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (morton_to_gl) {
 | 
					    if (morton_to_gl) {
 | 
				
			||||||
        std::vector<u8> data;
 | 
					        // With the BCn formats (DXT and DXN), each 4x4 tile is swizzled instead of just individual
 | 
				
			||||||
        if (SurfaceParams::GetFormatType(format) == SurfaceType::ColorTexture) {
 | 
					        // pixel values.
 | 
				
			||||||
            data = Tegra::Texture::UnswizzleTexture(
 | 
					        const u32 tile_size{IsFormatBCn(format) ? 4U : 1U};
 | 
				
			||||||
                *gpu.memory_manager->GpuToCpuAddress(addr),
 | 
					        const std::vector<u8> data =
 | 
				
			||||||
                SurfaceParams::TextureFormatFromPixelFormat(format), stride, height, block_height);
 | 
					            Tegra::Texture::UnswizzleTexture(*gpu.memory_manager->GpuToCpuAddress(addr), tile_size,
 | 
				
			||||||
        } else {
 | 
					                                             bytes_per_pixel, stride, height, block_height);
 | 
				
			||||||
            data = Tegra::Texture::UnswizzleDepthTexture(
 | 
					 | 
				
			||||||
                *gpu.memory_manager->GpuToCpuAddress(addr),
 | 
					 | 
				
			||||||
                SurfaceParams::DepthFormatFromPixelFormat(format), stride, height, block_height);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        const size_t size_to_copy{std::min(gl_buffer.size(), data.size())};
 | 
					        const size_t size_to_copy{std::min(gl_buffer.size(), data.size())};
 | 
				
			||||||
        gl_buffer.assign(data.begin(), data.begin() + size_to_copy);
 | 
					        gl_buffer.assign(data.begin(), data.begin() + size_to_copy);
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
 | 
				
			|||||||
@ -348,92 +348,6 @@ struct SurfaceParams {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    static Tegra::Texture::TextureFormat TextureFormatFromPixelFormat(PixelFormat format) {
 | 
					 | 
				
			||||||
        // TODO(Subv): Properly implement this
 | 
					 | 
				
			||||||
        switch (format) {
 | 
					 | 
				
			||||||
        case PixelFormat::ABGR8:
 | 
					 | 
				
			||||||
        case PixelFormat::SRGBA8:
 | 
					 | 
				
			||||||
            return Tegra::Texture::TextureFormat::A8R8G8B8;
 | 
					 | 
				
			||||||
        case PixelFormat::B5G6R5:
 | 
					 | 
				
			||||||
            return Tegra::Texture::TextureFormat::B5G6R5;
 | 
					 | 
				
			||||||
        case PixelFormat::A2B10G10R10:
 | 
					 | 
				
			||||||
            return Tegra::Texture::TextureFormat::A2B10G10R10;
 | 
					 | 
				
			||||||
        case PixelFormat::A1B5G5R5:
 | 
					 | 
				
			||||||
            return Tegra::Texture::TextureFormat::A1B5G5R5;
 | 
					 | 
				
			||||||
        case PixelFormat::R8:
 | 
					 | 
				
			||||||
            return Tegra::Texture::TextureFormat::R8;
 | 
					 | 
				
			||||||
        case PixelFormat::G8R8:
 | 
					 | 
				
			||||||
            return Tegra::Texture::TextureFormat::G8R8;
 | 
					 | 
				
			||||||
        case PixelFormat::RGBA16F:
 | 
					 | 
				
			||||||
            return Tegra::Texture::TextureFormat::R16_G16_B16_A16;
 | 
					 | 
				
			||||||
        case PixelFormat::R11FG11FB10F:
 | 
					 | 
				
			||||||
            return Tegra::Texture::TextureFormat::BF10GF11RF11;
 | 
					 | 
				
			||||||
        case PixelFormat::RGBA32UI:
 | 
					 | 
				
			||||||
            return Tegra::Texture::TextureFormat::R32_G32_B32_A32;
 | 
					 | 
				
			||||||
        case PixelFormat::DXT1:
 | 
					 | 
				
			||||||
            return Tegra::Texture::TextureFormat::DXT1;
 | 
					 | 
				
			||||||
        case PixelFormat::DXT23:
 | 
					 | 
				
			||||||
            return Tegra::Texture::TextureFormat::DXT23;
 | 
					 | 
				
			||||||
        case PixelFormat::DXT45:
 | 
					 | 
				
			||||||
            return Tegra::Texture::TextureFormat::DXT45;
 | 
					 | 
				
			||||||
        case PixelFormat::DXN1:
 | 
					 | 
				
			||||||
            return Tegra::Texture::TextureFormat::DXN1;
 | 
					 | 
				
			||||||
        case PixelFormat::DXN2UNORM:
 | 
					 | 
				
			||||||
        case PixelFormat::DXN2SNORM:
 | 
					 | 
				
			||||||
            return Tegra::Texture::TextureFormat::DXN2;
 | 
					 | 
				
			||||||
        case PixelFormat::BC7U:
 | 
					 | 
				
			||||||
            return Tegra::Texture::TextureFormat::BC7U;
 | 
					 | 
				
			||||||
        case PixelFormat::ASTC_2D_4X4:
 | 
					 | 
				
			||||||
            return Tegra::Texture::TextureFormat::ASTC_2D_4X4;
 | 
					 | 
				
			||||||
        case PixelFormat::BGRA8:
 | 
					 | 
				
			||||||
            // TODO(bunnei): This is fine for unswizzling (since we just need the right component
 | 
					 | 
				
			||||||
            // sizes), but could be a bug if we used this function in different ways.
 | 
					 | 
				
			||||||
            return Tegra::Texture::TextureFormat::A8R8G8B8;
 | 
					 | 
				
			||||||
        case PixelFormat::RGBA32F:
 | 
					 | 
				
			||||||
            return Tegra::Texture::TextureFormat::R32_G32_B32_A32;
 | 
					 | 
				
			||||||
        case PixelFormat::RGB32F:
 | 
					 | 
				
			||||||
            return Tegra::Texture::TextureFormat::R32_G32_B32;
 | 
					 | 
				
			||||||
        case PixelFormat::RG32F:
 | 
					 | 
				
			||||||
            return Tegra::Texture::TextureFormat::R32_G32;
 | 
					 | 
				
			||||||
        case PixelFormat::R32F:
 | 
					 | 
				
			||||||
            return Tegra::Texture::TextureFormat::R32;
 | 
					 | 
				
			||||||
        case PixelFormat::R16F:
 | 
					 | 
				
			||||||
        case PixelFormat::R16UNORM:
 | 
					 | 
				
			||||||
            return Tegra::Texture::TextureFormat::R16;
 | 
					 | 
				
			||||||
        case PixelFormat::Z32F:
 | 
					 | 
				
			||||||
            return Tegra::Texture::TextureFormat::ZF32;
 | 
					 | 
				
			||||||
        case PixelFormat::Z24S8:
 | 
					 | 
				
			||||||
            return Tegra::Texture::TextureFormat::Z24S8;
 | 
					 | 
				
			||||||
        case PixelFormat::RG16F:
 | 
					 | 
				
			||||||
        case PixelFormat::RG16:
 | 
					 | 
				
			||||||
        case PixelFormat::RG16UI:
 | 
					 | 
				
			||||||
        case PixelFormat::RG16I:
 | 
					 | 
				
			||||||
        case PixelFormat::RG16S:
 | 
					 | 
				
			||||||
            return Tegra::Texture::TextureFormat::R16_G16;
 | 
					 | 
				
			||||||
        default:
 | 
					 | 
				
			||||||
            LOG_CRITICAL(HW_GPU, "Unimplemented format={}", static_cast<u32>(format));
 | 
					 | 
				
			||||||
            UNREACHABLE();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    static Tegra::DepthFormat DepthFormatFromPixelFormat(PixelFormat format) {
 | 
					 | 
				
			||||||
        switch (format) {
 | 
					 | 
				
			||||||
        case PixelFormat::S8Z24:
 | 
					 | 
				
			||||||
            return Tegra::DepthFormat::S8_Z24_UNORM;
 | 
					 | 
				
			||||||
        case PixelFormat::Z24S8:
 | 
					 | 
				
			||||||
            return Tegra::DepthFormat::Z24_S8_UNORM;
 | 
					 | 
				
			||||||
        case PixelFormat::Z32F:
 | 
					 | 
				
			||||||
            return Tegra::DepthFormat::Z32_FLOAT;
 | 
					 | 
				
			||||||
        case PixelFormat::Z16:
 | 
					 | 
				
			||||||
            return Tegra::DepthFormat::Z16_UNORM;
 | 
					 | 
				
			||||||
        case PixelFormat::Z32FS8:
 | 
					 | 
				
			||||||
            return Tegra::DepthFormat::Z32_S8_X24_FLOAT;
 | 
					 | 
				
			||||||
        default:
 | 
					 | 
				
			||||||
            LOG_CRITICAL(HW_GPU, "Unimplemented format={}", static_cast<u32>(format));
 | 
					 | 
				
			||||||
            UNREACHABLE();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    static ComponentType ComponentTypeFromTexture(Tegra::Texture::ComponentType type) {
 | 
					    static ComponentType ComponentTypeFromTexture(Tegra::Texture::ComponentType type) {
 | 
				
			||||||
        // TODO(Subv): Implement more component types
 | 
					        // TODO(Subv): Implement more component types
 | 
				
			||||||
        switch (type) {
 | 
					        switch (type) {
 | 
				
			||||||
 | 
				
			|||||||
@ -86,88 +86,11 @@ u32 BytesPerPixel(TextureFormat format) {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static u32 DepthBytesPerPixel(DepthFormat format) {
 | 
					std::vector<u8> UnswizzleTexture(VAddr address, u32 tile_size, u32 bytes_per_pixel, u32 width,
 | 
				
			||||||
    switch (format) {
 | 
					                                 u32 height, u32 block_height) {
 | 
				
			||||||
    case DepthFormat::Z16_UNORM:
 | 
					 | 
				
			||||||
        return 2;
 | 
					 | 
				
			||||||
    case DepthFormat::S8_Z24_UNORM:
 | 
					 | 
				
			||||||
    case DepthFormat::Z24_S8_UNORM:
 | 
					 | 
				
			||||||
    case DepthFormat::Z32_FLOAT:
 | 
					 | 
				
			||||||
        return 4;
 | 
					 | 
				
			||||||
    case DepthFormat::Z32_S8_X24_FLOAT:
 | 
					 | 
				
			||||||
        return 8;
 | 
					 | 
				
			||||||
    default:
 | 
					 | 
				
			||||||
        UNIMPLEMENTED_MSG("Format not implemented");
 | 
					 | 
				
			||||||
        break;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
std::vector<u8> UnswizzleTexture(VAddr address, TextureFormat format, u32 width, u32 height,
 | 
					 | 
				
			||||||
                                 u32 block_height) {
 | 
					 | 
				
			||||||
    u8* data = Memory::GetPointer(address);
 | 
					 | 
				
			||||||
    u32 bytes_per_pixel = BytesPerPixel(format);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    std::vector<u8> unswizzled_data(width * height * bytes_per_pixel);
 | 
					    std::vector<u8> unswizzled_data(width * height * bytes_per_pixel);
 | 
				
			||||||
 | 
					    CopySwizzledData(width / tile_size, height / tile_size, bytes_per_pixel, bytes_per_pixel,
 | 
				
			||||||
    switch (format) {
 | 
					                     Memory::GetPointer(address), unswizzled_data.data(), true, block_height);
 | 
				
			||||||
    case TextureFormat::DXT1:
 | 
					 | 
				
			||||||
    case TextureFormat::DXT23:
 | 
					 | 
				
			||||||
    case TextureFormat::DXT45:
 | 
					 | 
				
			||||||
    case TextureFormat::DXN1:
 | 
					 | 
				
			||||||
    case TextureFormat::DXN2:
 | 
					 | 
				
			||||||
    case TextureFormat::BC7U:
 | 
					 | 
				
			||||||
        // In the DXT and DXN formats, each 4x4 tile is swizzled instead of just individual pixel
 | 
					 | 
				
			||||||
        // values.
 | 
					 | 
				
			||||||
        CopySwizzledData(width / 4, height / 4, bytes_per_pixel, bytes_per_pixel, data,
 | 
					 | 
				
			||||||
                         unswizzled_data.data(), true, block_height);
 | 
					 | 
				
			||||||
        break;
 | 
					 | 
				
			||||||
    case TextureFormat::A8R8G8B8:
 | 
					 | 
				
			||||||
    case TextureFormat::A2B10G10R10:
 | 
					 | 
				
			||||||
    case TextureFormat::A1B5G5R5:
 | 
					 | 
				
			||||||
    case TextureFormat::B5G6R5:
 | 
					 | 
				
			||||||
    case TextureFormat::R8:
 | 
					 | 
				
			||||||
    case TextureFormat::G8R8:
 | 
					 | 
				
			||||||
    case TextureFormat::R16_G16_B16_A16:
 | 
					 | 
				
			||||||
    case TextureFormat::R32_G32_B32_A32:
 | 
					 | 
				
			||||||
    case TextureFormat::R32_G32:
 | 
					 | 
				
			||||||
    case TextureFormat::R32:
 | 
					 | 
				
			||||||
    case TextureFormat::R16:
 | 
					 | 
				
			||||||
    case TextureFormat::R16_G16:
 | 
					 | 
				
			||||||
    case TextureFormat::BF10GF11RF11:
 | 
					 | 
				
			||||||
    case TextureFormat::ASTC_2D_4X4:
 | 
					 | 
				
			||||||
    case TextureFormat::R32_G32_B32:
 | 
					 | 
				
			||||||
        CopySwizzledData(width, height, bytes_per_pixel, bytes_per_pixel, data,
 | 
					 | 
				
			||||||
                         unswizzled_data.data(), true, block_height);
 | 
					 | 
				
			||||||
        break;
 | 
					 | 
				
			||||||
    default:
 | 
					 | 
				
			||||||
        UNIMPLEMENTED_MSG("Format not implemented");
 | 
					 | 
				
			||||||
        break;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return unswizzled_data;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
std::vector<u8> UnswizzleDepthTexture(VAddr address, DepthFormat format, u32 width, u32 height,
 | 
					 | 
				
			||||||
                                      u32 block_height) {
 | 
					 | 
				
			||||||
    u8* data = Memory::GetPointer(address);
 | 
					 | 
				
			||||||
    u32 bytes_per_pixel = DepthBytesPerPixel(format);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    std::vector<u8> unswizzled_data(width * height * bytes_per_pixel);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    switch (format) {
 | 
					 | 
				
			||||||
    case DepthFormat::Z16_UNORM:
 | 
					 | 
				
			||||||
    case DepthFormat::S8_Z24_UNORM:
 | 
					 | 
				
			||||||
    case DepthFormat::Z24_S8_UNORM:
 | 
					 | 
				
			||||||
    case DepthFormat::Z32_FLOAT:
 | 
					 | 
				
			||||||
    case DepthFormat::Z32_S8_X24_FLOAT:
 | 
					 | 
				
			||||||
        CopySwizzledData(width, height, bytes_per_pixel, bytes_per_pixel, data,
 | 
					 | 
				
			||||||
                         unswizzled_data.data(), true, block_height);
 | 
					 | 
				
			||||||
        break;
 | 
					 | 
				
			||||||
    default:
 | 
					 | 
				
			||||||
        UNIMPLEMENTED_MSG("Format not implemented");
 | 
					 | 
				
			||||||
        break;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return unswizzled_data;
 | 
					    return unswizzled_data;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -13,8 +13,8 @@ namespace Tegra::Texture {
 | 
				
			|||||||
/**
 | 
					/**
 | 
				
			||||||
 * Unswizzles a swizzled texture without changing its format.
 | 
					 * Unswizzles a swizzled texture without changing its format.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
std::vector<u8> UnswizzleTexture(VAddr address, TextureFormat format, u32 width, u32 height,
 | 
					std::vector<u8> UnswizzleTexture(VAddr address, u32 tile_size, u32 bytes_per_pixel, u32 width,
 | 
				
			||||||
                                 u32 block_height = TICEntry::DefaultBlockHeight);
 | 
					                                 u32 height, u32 block_height = TICEntry::DefaultBlockHeight);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Unswizzles a swizzled depth texture without changing its format.
 | 
					 * Unswizzles a swizzled depth texture without changing its format.
 | 
				
			||||||
 | 
				
			|||||||
@ -383,8 +383,10 @@ void GraphicsSurfaceWidget::OnUpdate() {
 | 
				
			|||||||
    QImage decoded_image(surface_width, surface_height, QImage::Format_ARGB32);
 | 
					    QImage decoded_image(surface_width, surface_height, QImage::Format_ARGB32);
 | 
				
			||||||
    boost::optional<VAddr> address = gpu.memory_manager->GpuToCpuAddress(surface_address);
 | 
					    boost::optional<VAddr> address = gpu.memory_manager->GpuToCpuAddress(surface_address);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    auto unswizzled_data =
 | 
					    // TODO(bunnei): Will not work with BCn formats that swizzle 4x4 tiles.
 | 
				
			||||||
        Tegra::Texture::UnswizzleTexture(*address, surface_format, surface_width, surface_height);
 | 
					    // Needs to be fixed if we plan to use this feature more, otherwise we may remove it.
 | 
				
			||||||
 | 
					    auto unswizzled_data = Tegra::Texture::UnswizzleTexture(
 | 
				
			||||||
 | 
					        *address, 1, Tegra::Texture::BytesPerPixel(surface_format), surface_width, surface_height);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    auto texture_data = Tegra::Texture::DecodeTexture(unswizzled_data, surface_format,
 | 
					    auto texture_data = Tegra::Texture::DecodeTexture(unswizzled_data, surface_format,
 | 
				
			||||||
                                                      surface_width, surface_height);
 | 
					                                                      surface_width, surface_height);
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user