Merge pull request #3513 from ReinUsesLisp/native-astc
video_core: Use native ASTC when available
This commit is contained in:
commit
588a20be3f
|
@ -131,6 +131,31 @@ std::array<Device::BaseBindings, Tegra::Engines::MaxShaderTypes> BuildBaseBindin
|
|||
return bindings;
|
||||
}
|
||||
|
||||
bool IsASTCSupported() {
|
||||
static constexpr std::array formats = {
|
||||
GL_COMPRESSED_RGBA_ASTC_4x4_KHR, GL_COMPRESSED_RGBA_ASTC_5x4_KHR,
|
||||
GL_COMPRESSED_RGBA_ASTC_5x5_KHR, GL_COMPRESSED_RGBA_ASTC_6x5_KHR,
|
||||
GL_COMPRESSED_RGBA_ASTC_6x6_KHR, GL_COMPRESSED_RGBA_ASTC_8x5_KHR,
|
||||
GL_COMPRESSED_RGBA_ASTC_8x6_KHR, GL_COMPRESSED_RGBA_ASTC_8x8_KHR,
|
||||
GL_COMPRESSED_RGBA_ASTC_10x5_KHR, GL_COMPRESSED_RGBA_ASTC_10x6_KHR,
|
||||
GL_COMPRESSED_RGBA_ASTC_10x8_KHR, GL_COMPRESSED_RGBA_ASTC_10x10_KHR,
|
||||
GL_COMPRESSED_RGBA_ASTC_12x10_KHR, GL_COMPRESSED_RGBA_ASTC_12x12_KHR,
|
||||
GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR,
|
||||
GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR,
|
||||
GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR,
|
||||
GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR,
|
||||
GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR,
|
||||
GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR,
|
||||
GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR,
|
||||
};
|
||||
return std::find_if_not(formats.begin(), formats.end(), [](GLenum format) {
|
||||
GLint supported;
|
||||
glGetInternalformativ(GL_TEXTURE_2D, format, GL_INTERNALFORMAT_SUPPORTED, 1,
|
||||
&supported);
|
||||
return supported == GL_TRUE;
|
||||
}) == formats.end();
|
||||
}
|
||||
|
||||
} // Anonymous namespace
|
||||
|
||||
Device::Device() : base_bindings{BuildBaseBindings()} {
|
||||
|
@ -152,6 +177,7 @@ Device::Device() : base_bindings{BuildBaseBindings()} {
|
|||
has_shader_ballot = GLAD_GL_ARB_shader_ballot;
|
||||
has_vertex_viewport_layer = GLAD_GL_ARB_shader_viewport_layer_array;
|
||||
has_image_load_formatted = HasExtension(extensions, "GL_EXT_shader_image_load_formatted");
|
||||
has_astc = IsASTCSupported();
|
||||
has_variable_aoffi = TestVariableAoffi();
|
||||
has_component_indexing_bug = is_amd;
|
||||
has_precise_bug = TestPreciseBug();
|
||||
|
|
|
@ -64,6 +64,10 @@ public:
|
|||
return has_image_load_formatted;
|
||||
}
|
||||
|
||||
bool HasASTC() const {
|
||||
return has_astc;
|
||||
}
|
||||
|
||||
bool HasVariableAoffi() const {
|
||||
return has_variable_aoffi;
|
||||
}
|
||||
|
@ -97,6 +101,7 @@ private:
|
|||
bool has_shader_ballot{};
|
||||
bool has_vertex_viewport_layer{};
|
||||
bool has_image_load_formatted{};
|
||||
bool has_astc{};
|
||||
bool has_variable_aoffi{};
|
||||
bool has_component_indexing_bug{};
|
||||
bool has_precise_bug{};
|
||||
|
|
|
@ -24,7 +24,6 @@ using Tegra::Texture::SwizzleSource;
|
|||
using VideoCore::MortonSwizzleMode;
|
||||
|
||||
using VideoCore::Surface::PixelFormat;
|
||||
using VideoCore::Surface::SurfaceCompression;
|
||||
using VideoCore::Surface::SurfaceTarget;
|
||||
using VideoCore::Surface::SurfaceType;
|
||||
|
||||
|
@ -37,102 +36,100 @@ namespace {
|
|||
|
||||
struct FormatTuple {
|
||||
GLint internal_format;
|
||||
GLenum format;
|
||||
GLenum type;
|
||||
bool compressed;
|
||||
GLenum format = GL_NONE;
|
||||
GLenum type = GL_NONE;
|
||||
};
|
||||
|
||||
constexpr std::array<FormatTuple, VideoCore::Surface::MaxPixelFormat> tex_format_tuples = {{
|
||||
{GL_RGBA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, false}, // ABGR8U
|
||||
{GL_RGBA8_SNORM, GL_RGBA, GL_BYTE, false}, // ABGR8S
|
||||
{GL_RGBA8UI, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, false}, // ABGR8UI
|
||||
{GL_RGB565, GL_RGB, GL_UNSIGNED_SHORT_5_6_5_REV, false}, // B5G6R5U
|
||||
{GL_RGB10_A2, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, false}, // A2B10G10R10U
|
||||
{GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, false}, // A1B5G5R5U
|
||||
{GL_R8, GL_RED, GL_UNSIGNED_BYTE, false}, // R8U
|
||||
{GL_R8UI, GL_RED_INTEGER, GL_UNSIGNED_BYTE, false}, // R8UI
|
||||
{GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT, false}, // RGBA16F
|
||||
{GL_RGBA16, GL_RGBA, GL_UNSIGNED_SHORT, false}, // RGBA16U
|
||||
{GL_RGBA16_SNORM, GL_RGBA, GL_SHORT, false}, // RGBA16S
|
||||
{GL_RGBA16UI, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT, false}, // RGBA16UI
|
||||
{GL_R11F_G11F_B10F, GL_RGB, GL_UNSIGNED_INT_10F_11F_11F_REV, false}, // R11FG11FB10F
|
||||
{GL_RGBA32UI, GL_RGBA_INTEGER, GL_UNSIGNED_INT, false}, // RGBA32UI
|
||||
{GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, true}, // DXT1
|
||||
{GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, true}, // DXT23
|
||||
{GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, true}, // DXT45
|
||||
{GL_COMPRESSED_RED_RGTC1, GL_RED, GL_UNSIGNED_INT_8_8_8_8, true}, // DXN1
|
||||
{GL_COMPRESSED_RG_RGTC2, GL_RG, GL_UNSIGNED_INT_8_8_8_8, true}, // DXN2UNORM
|
||||
{GL_COMPRESSED_SIGNED_RG_RGTC2, GL_RG, GL_INT, true}, // DXN2SNORM
|
||||
{GL_COMPRESSED_RGBA_BPTC_UNORM, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, true}, // BC7U
|
||||
{GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT, GL_RGB, GL_UNSIGNED_INT_8_8_8_8, true}, // BC6H_UF16
|
||||
{GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT, GL_RGB, GL_UNSIGNED_INT_8_8_8_8, true}, // BC6H_SF16
|
||||
{GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, false}, // ASTC_2D_4X4
|
||||
{GL_RGBA8, GL_BGRA, GL_UNSIGNED_BYTE, false}, // BGRA8
|
||||
{GL_RGBA32F, GL_RGBA, GL_FLOAT, false}, // RGBA32F
|
||||
{GL_RG32F, GL_RG, GL_FLOAT, false}, // RG32F
|
||||
{GL_R32F, GL_RED, GL_FLOAT, false}, // R32F
|
||||
{GL_R16F, GL_RED, GL_HALF_FLOAT, false}, // R16F
|
||||
{GL_R16, GL_RED, GL_UNSIGNED_SHORT, false}, // R16U
|
||||
{GL_R16_SNORM, GL_RED, GL_SHORT, false}, // R16S
|
||||
{GL_R16UI, GL_RED_INTEGER, GL_UNSIGNED_SHORT, false}, // R16UI
|
||||
{GL_R16I, GL_RED_INTEGER, GL_SHORT, false}, // R16I
|
||||
{GL_RG16, GL_RG, GL_UNSIGNED_SHORT, false}, // RG16
|
||||
{GL_RG16F, GL_RG, GL_HALF_FLOAT, false}, // RG16F
|
||||
{GL_RG16UI, GL_RG_INTEGER, GL_UNSIGNED_SHORT, false}, // RG16UI
|
||||
{GL_RG16I, GL_RG_INTEGER, GL_SHORT, false}, // RG16I
|
||||
{GL_RG16_SNORM, GL_RG, GL_SHORT, false}, // RG16S
|
||||
{GL_RGB32F, GL_RGB, GL_FLOAT, false}, // RGB32F
|
||||
{GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, false}, // RGBA8_SRGB
|
||||
{GL_RG8, GL_RG, GL_UNSIGNED_BYTE, false}, // RG8U
|
||||
{GL_RG8_SNORM, GL_RG, GL_BYTE, false}, // RG8S
|
||||
{GL_RG32UI, GL_RG_INTEGER, GL_UNSIGNED_INT, false}, // RG32UI
|
||||
{GL_RGB16F, GL_RGBA, GL_HALF_FLOAT, false}, // RGBX16F
|
||||
{GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT, false}, // R32UI
|
||||
{GL_R32I, GL_RED_INTEGER, GL_INT, false}, // R32I
|
||||
{GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, false}, // ASTC_2D_8X8
|
||||
{GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, false}, // ASTC_2D_8X5
|
||||
{GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, false}, // ASTC_2D_5X4
|
||||
{GL_SRGB8_ALPHA8, GL_BGRA, GL_UNSIGNED_BYTE, false}, // BGRA8
|
||||
{GL_RGBA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV}, // ABGR8U
|
||||
{GL_RGBA8_SNORM, GL_RGBA, GL_BYTE}, // ABGR8S
|
||||
{GL_RGBA8UI, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE}, // ABGR8UI
|
||||
{GL_RGB565, GL_RGB, GL_UNSIGNED_SHORT_5_6_5_REV}, // B5G6R5U
|
||||
{GL_RGB10_A2, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV}, // A2B10G10R10U
|
||||
{GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV}, // A1B5G5R5U
|
||||
{GL_R8, GL_RED, GL_UNSIGNED_BYTE}, // R8U
|
||||
{GL_R8UI, GL_RED_INTEGER, GL_UNSIGNED_BYTE}, // R8UI
|
||||
{GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT}, // RGBA16F
|
||||
{GL_RGBA16, GL_RGBA, GL_UNSIGNED_SHORT}, // RGBA16U
|
||||
{GL_RGBA16_SNORM, GL_RGBA, GL_SHORT}, // RGBA16S
|
||||
{GL_RGBA16UI, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT}, // RGBA16UI
|
||||
{GL_R11F_G11F_B10F, GL_RGB, GL_UNSIGNED_INT_10F_11F_11F_REV}, // R11FG11FB10F
|
||||
{GL_RGBA32UI, GL_RGBA_INTEGER, GL_UNSIGNED_INT}, // RGBA32UI
|
||||
{GL_COMPRESSED_RGBA_S3TC_DXT1_EXT}, // DXT1
|
||||
{GL_COMPRESSED_RGBA_S3TC_DXT3_EXT}, // DXT23
|
||||
{GL_COMPRESSED_RGBA_S3TC_DXT5_EXT}, // DXT45
|
||||
{GL_COMPRESSED_RED_RGTC1}, // DXN1
|
||||
{GL_COMPRESSED_RG_RGTC2}, // DXN2UNORM
|
||||
{GL_COMPRESSED_SIGNED_RG_RGTC2}, // DXN2SNORM
|
||||
{GL_COMPRESSED_RGBA_BPTC_UNORM}, // BC7U
|
||||
{GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT}, // BC6H_UF16
|
||||
{GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT}, // BC6H_SF16
|
||||
{GL_COMPRESSED_RGBA_ASTC_4x4_KHR}, // ASTC_2D_4X4
|
||||
{GL_RGBA8, GL_BGRA, GL_UNSIGNED_BYTE}, // BGRA8
|
||||
{GL_RGBA32F, GL_RGBA, GL_FLOAT}, // RGBA32F
|
||||
{GL_RG32F, GL_RG, GL_FLOAT}, // RG32F
|
||||
{GL_R32F, GL_RED, GL_FLOAT}, // R32F
|
||||
{GL_R16F, GL_RED, GL_HALF_FLOAT}, // R16F
|
||||
{GL_R16, GL_RED, GL_UNSIGNED_SHORT}, // R16U
|
||||
{GL_R16_SNORM, GL_RED, GL_SHORT}, // R16S
|
||||
{GL_R16UI, GL_RED_INTEGER, GL_UNSIGNED_SHORT}, // R16UI
|
||||
{GL_R16I, GL_RED_INTEGER, GL_SHORT}, // R16I
|
||||
{GL_RG16, GL_RG, GL_UNSIGNED_SHORT}, // RG16
|
||||
{GL_RG16F, GL_RG, GL_HALF_FLOAT}, // RG16F
|
||||
{GL_RG16UI, GL_RG_INTEGER, GL_UNSIGNED_SHORT}, // RG16UI
|
||||
{GL_RG16I, GL_RG_INTEGER, GL_SHORT}, // RG16I
|
||||
{GL_RG16_SNORM, GL_RG, GL_SHORT}, // RG16S
|
||||
{GL_RGB32F, GL_RGB, GL_FLOAT}, // RGB32F
|
||||
{GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV}, // RGBA8_SRGB
|
||||
{GL_RG8, GL_RG, GL_UNSIGNED_BYTE}, // RG8U
|
||||
{GL_RG8_SNORM, GL_RG, GL_BYTE}, // RG8S
|
||||
{GL_RG32UI, GL_RG_INTEGER, GL_UNSIGNED_INT}, // RG32UI
|
||||
{GL_RGB16F, GL_RGBA, GL_HALF_FLOAT}, // RGBX16F
|
||||
{GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT}, // R32UI
|
||||
{GL_R32I, GL_RED_INTEGER, GL_INT}, // R32I
|
||||
{GL_COMPRESSED_RGBA_ASTC_8x8_KHR}, // ASTC_2D_8X8
|
||||
{GL_COMPRESSED_RGBA_ASTC_8x5_KHR}, // ASTC_2D_8X5
|
||||
{GL_COMPRESSED_RGBA_ASTC_5x4_KHR}, // ASTC_2D_5X4
|
||||
{GL_SRGB8_ALPHA8, GL_BGRA, GL_UNSIGNED_BYTE}, // BGRA8
|
||||
// Compressed sRGB formats
|
||||
{GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, true}, // DXT1_SRGB
|
||||
{GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, true}, // DXT23_SRGB
|
||||
{GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, true}, // DXT45_SRGB
|
||||
{GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, true}, // BC7U_SRGB
|
||||
{GL_RGBA4, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4_REV, false}, // R4G4B4A4U
|
||||
{GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_BYTE, false}, // ASTC_2D_4X4_SRGB
|
||||
{GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_BYTE, false}, // ASTC_2D_8X8_SRGB
|
||||
{GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_BYTE, false}, // ASTC_2D_8X5_SRGB
|
||||
{GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_BYTE, false}, // ASTC_2D_5X4_SRGB
|
||||
{GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, false}, // ASTC_2D_5X5
|
||||
{GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_BYTE, false}, // ASTC_2D_5X5_SRGB
|
||||
{GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, false}, // ASTC_2D_10X8
|
||||
{GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_BYTE, false}, // ASTC_2D_10X8_SRGB
|
||||
{GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, false}, // ASTC_2D_6X6
|
||||
{GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_BYTE, false}, // ASTC_2D_6X6_SRGB
|
||||
{GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, false}, // ASTC_2D_10X10
|
||||
{GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_BYTE, false}, // ASTC_2D_10X10_SRGB
|
||||
{GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, false}, // ASTC_2D_12X12
|
||||
{GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_BYTE, false}, // ASTC_2D_12X12_SRGB
|
||||
{GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, false}, // ASTC_2D_8X6
|
||||
{GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_BYTE, false}, // ASTC_2D_8X6_SRGB
|
||||
{GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, false}, // ASTC_2D_6X5
|
||||
{GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_BYTE, false}, // ASTC_2D_6X5_SRGB
|
||||
{GL_RGB9_E5, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV, false}, // E5B9G9R9F
|
||||
{GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT}, // DXT1_SRGB
|
||||
{GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT}, // DXT23_SRGB
|
||||
{GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT}, // DXT45_SRGB
|
||||
{GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM}, // BC7U_SRGB
|
||||
{GL_RGBA4, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4_REV}, // R4G4B4A4U
|
||||
{GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR}, // ASTC_2D_4X4_SRGB
|
||||
{GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR}, // ASTC_2D_8X8_SRGB
|
||||
{GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR}, // ASTC_2D_8X5_SRGB
|
||||
{GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR}, // ASTC_2D_5X4_SRGB
|
||||
{GL_COMPRESSED_RGBA_ASTC_5x5_KHR}, // ASTC_2D_5X5
|
||||
{GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR}, // ASTC_2D_5X5_SRGB
|
||||
{GL_COMPRESSED_RGBA_ASTC_10x8_KHR}, // ASTC_2D_10X8
|
||||
{GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR}, // ASTC_2D_10X8_SRGB
|
||||
{GL_COMPRESSED_RGBA_ASTC_6x6_KHR}, // ASTC_2D_6X6
|
||||
{GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR}, // ASTC_2D_6X6_SRGB
|
||||
{GL_COMPRESSED_RGBA_ASTC_10x10_KHR}, // ASTC_2D_10X10
|
||||
{GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR}, // ASTC_2D_10X10_SRGB
|
||||
{GL_COMPRESSED_RGBA_ASTC_12x12_KHR}, // ASTC_2D_12X12
|
||||
{GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR}, // ASTC_2D_12X12_SRGB
|
||||
{GL_COMPRESSED_RGBA_ASTC_8x6_KHR}, // ASTC_2D_8X6
|
||||
{GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR}, // ASTC_2D_8X6_SRGB
|
||||
{GL_COMPRESSED_RGBA_ASTC_6x5_KHR}, // ASTC_2D_6X5
|
||||
{GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR}, // ASTC_2D_6X5_SRGB
|
||||
{GL_RGB9_E5, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV}, // E5B9G9R9F
|
||||
|
||||
// Depth formats
|
||||
{GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT, false}, // Z32F
|
||||
{GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, false}, // Z16
|
||||
{GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT}, // Z32F
|
||||
{GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT}, // Z16
|
||||
|
||||
// DepthStencil formats
|
||||
{GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, false}, // Z24S8
|
||||
{GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, false}, // S8Z24
|
||||
{GL_DEPTH32F_STENCIL8, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, false}, // Z32FS8
|
||||
{GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8}, // Z24S8
|
||||
{GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8}, // S8Z24
|
||||
{GL_DEPTH32F_STENCIL8, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV}, // Z32FS8
|
||||
}};
|
||||
|
||||
const FormatTuple& GetFormatTuple(PixelFormat pixel_format) {
|
||||
ASSERT(static_cast<std::size_t>(pixel_format) < tex_format_tuples.size());
|
||||
const auto& format{tex_format_tuples[static_cast<std::size_t>(pixel_format)]};
|
||||
return format;
|
||||
return tex_format_tuples[static_cast<std::size_t>(pixel_format)];
|
||||
}
|
||||
|
||||
GLenum GetTextureTarget(const SurfaceTarget& target) {
|
||||
|
@ -242,13 +239,20 @@ OGLTexture CreateTexture(const SurfaceParams& params, GLenum target, GLenum inte
|
|||
|
||||
} // Anonymous namespace
|
||||
|
||||
CachedSurface::CachedSurface(const GPUVAddr gpu_addr, const SurfaceParams& params)
|
||||
: VideoCommon::SurfaceBase<View>(gpu_addr, params) {
|
||||
const auto& tuple{GetFormatTuple(params.pixel_format)};
|
||||
internal_format = tuple.internal_format;
|
||||
format = tuple.format;
|
||||
type = tuple.type;
|
||||
is_compressed = tuple.compressed;
|
||||
CachedSurface::CachedSurface(const GPUVAddr gpu_addr, const SurfaceParams& params,
|
||||
bool is_astc_supported)
|
||||
: VideoCommon::SurfaceBase<View>(gpu_addr, params, is_astc_supported) {
|
||||
if (is_converted) {
|
||||
internal_format = params.srgb_conversion ? GL_SRGB8_ALPHA8 : GL_RGBA8;
|
||||
format = GL_RGBA;
|
||||
type = GL_UNSIGNED_BYTE;
|
||||
} else {
|
||||
const auto& tuple{GetFormatTuple(params.pixel_format)};
|
||||
internal_format = tuple.internal_format;
|
||||
format = tuple.format;
|
||||
type = tuple.type;
|
||||
is_compressed = params.IsCompressed();
|
||||
}
|
||||
target = GetTextureTarget(params.target);
|
||||
texture = CreateTexture(params, target, internal_format, texture_buffer);
|
||||
DecorateSurfaceName();
|
||||
|
@ -264,7 +268,7 @@ void CachedSurface::DownloadTexture(std::vector<u8>& staging_buffer) {
|
|||
|
||||
if (params.IsBuffer()) {
|
||||
glGetNamedBufferSubData(texture_buffer.handle, 0,
|
||||
static_cast<GLsizeiptr>(params.GetHostSizeInBytes()),
|
||||
static_cast<GLsizeiptr>(params.GetHostSizeInBytes(false)),
|
||||
staging_buffer.data());
|
||||
return;
|
||||
}
|
||||
|
@ -272,9 +276,10 @@ void CachedSurface::DownloadTexture(std::vector<u8>& staging_buffer) {
|
|||
SCOPE_EXIT({ glPixelStorei(GL_PACK_ROW_LENGTH, 0); });
|
||||
|
||||
for (u32 level = 0; level < params.emulated_levels; ++level) {
|
||||
glPixelStorei(GL_PACK_ALIGNMENT, std::min(8U, params.GetRowAlignment(level)));
|
||||
glPixelStorei(GL_PACK_ALIGNMENT, std::min(8U, params.GetRowAlignment(level, is_converted)));
|
||||
glPixelStorei(GL_PACK_ROW_LENGTH, static_cast<GLint>(params.GetMipWidth(level)));
|
||||
const std::size_t mip_offset = params.GetHostMipmapLevelOffset(level);
|
||||
const std::size_t mip_offset = params.GetHostMipmapLevelOffset(level, is_converted);
|
||||
|
||||
u8* const mip_data = staging_buffer.data() + mip_offset;
|
||||
const GLsizei size = static_cast<GLsizei>(params.GetHostMipmapSize(level));
|
||||
if (is_compressed) {
|
||||
|
@ -294,14 +299,10 @@ void CachedSurface::UploadTexture(const std::vector<u8>& staging_buffer) {
|
|||
}
|
||||
|
||||
void CachedSurface::UploadTextureMipmap(u32 level, const std::vector<u8>& staging_buffer) {
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, std::min(8U, params.GetRowAlignment(level)));
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, std::min(8U, params.GetRowAlignment(level, is_converted)));
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, static_cast<GLint>(params.GetMipWidth(level)));
|
||||
|
||||
auto compression_type = params.GetCompressionType();
|
||||
|
||||
const std::size_t mip_offset = compression_type == SurfaceCompression::Converted
|
||||
? params.GetConvertedMipmapOffset(level)
|
||||
: params.GetHostMipmapLevelOffset(level);
|
||||
const std::size_t mip_offset = params.GetHostMipmapLevelOffset(level, is_converted);
|
||||
const u8* buffer{staging_buffer.data() + mip_offset};
|
||||
if (is_compressed) {
|
||||
const auto image_size{static_cast<GLsizei>(params.GetHostMipmapSize(level))};
|
||||
|
@ -482,7 +483,7 @@ OGLTextureView CachedSurfaceView::CreateTextureView() const {
|
|||
TextureCacheOpenGL::TextureCacheOpenGL(Core::System& system,
|
||||
VideoCore::RasterizerInterface& rasterizer,
|
||||
const Device& device, StateTracker& state_tracker)
|
||||
: TextureCacheBase{system, rasterizer}, state_tracker{state_tracker} {
|
||||
: TextureCacheBase{system, rasterizer, device.HasASTC()}, state_tracker{state_tracker} {
|
||||
src_framebuffer.Create();
|
||||
dst_framebuffer.Create();
|
||||
}
|
||||
|
@ -490,7 +491,7 @@ TextureCacheOpenGL::TextureCacheOpenGL(Core::System& system,
|
|||
TextureCacheOpenGL::~TextureCacheOpenGL() = default;
|
||||
|
||||
Surface TextureCacheOpenGL::CreateSurface(GPUVAddr gpu_addr, const SurfaceParams& params) {
|
||||
return std::make_shared<CachedSurface>(gpu_addr, params);
|
||||
return std::make_shared<CachedSurface>(gpu_addr, params, is_astc_supported);
|
||||
}
|
||||
|
||||
void TextureCacheOpenGL::ImageCopy(Surface& src_surface, Surface& dst_surface,
|
||||
|
@ -596,7 +597,7 @@ void TextureCacheOpenGL::BufferCopy(Surface& src_surface, Surface& dst_surface)
|
|||
|
||||
glBindBuffer(GL_PIXEL_PACK_BUFFER, copy_pbo_handle);
|
||||
|
||||
if (source_format.compressed) {
|
||||
if (src_surface->IsCompressed()) {
|
||||
glGetCompressedTextureImage(src_surface->GetTexture(), 0, static_cast<GLsizei>(source_size),
|
||||
nullptr);
|
||||
} else {
|
||||
|
@ -610,7 +611,7 @@ void TextureCacheOpenGL::BufferCopy(Surface& src_surface, Surface& dst_surface)
|
|||
const GLsizei width = static_cast<GLsizei>(dst_params.width);
|
||||
const GLsizei height = static_cast<GLsizei>(dst_params.height);
|
||||
const GLsizei depth = static_cast<GLsizei>(dst_params.depth);
|
||||
if (dest_format.compressed) {
|
||||
if (dst_surface->IsCompressed()) {
|
||||
LOG_CRITICAL(HW_GPU, "Compressed buffer copy is unimplemented!");
|
||||
UNREACHABLE();
|
||||
} else {
|
||||
|
|
|
@ -37,7 +37,7 @@ class CachedSurface final : public VideoCommon::SurfaceBase<View> {
|
|||
friend CachedSurfaceView;
|
||||
|
||||
public:
|
||||
explicit CachedSurface(GPUVAddr gpu_addr, const SurfaceParams& params);
|
||||
explicit CachedSurface(GPUVAddr gpu_addr, const SurfaceParams& params, bool is_astc_supported);
|
||||
~CachedSurface();
|
||||
|
||||
void UploadTexture(const std::vector<u8>& staging_buffer) override;
|
||||
|
@ -51,6 +51,10 @@ public:
|
|||
return texture.handle;
|
||||
}
|
||||
|
||||
bool IsCompressed() const {
|
||||
return is_compressed;
|
||||
}
|
||||
|
||||
protected:
|
||||
void DecorateSurfaceName() override;
|
||||
|
||||
|
|
|
@ -237,18 +237,21 @@ void VKDevice::ReportLoss() const {
|
|||
|
||||
bool VKDevice::IsOptimalAstcSupported(const vk::PhysicalDeviceFeatures& features,
|
||||
const vk::DispatchLoaderDynamic& dldi) const {
|
||||
// Disable for now to avoid converting ASTC twice.
|
||||
return false;
|
||||
static constexpr std::array astc_formats = {
|
||||
vk::Format::eAstc4x4SrgbBlock, vk::Format::eAstc8x8SrgbBlock,
|
||||
vk::Format::eAstc8x5SrgbBlock, vk::Format::eAstc5x4SrgbBlock,
|
||||
vk::Format::eAstc4x4UnormBlock, vk::Format::eAstc4x4SrgbBlock,
|
||||
vk::Format::eAstc5x4UnormBlock, vk::Format::eAstc5x4SrgbBlock,
|
||||
vk::Format::eAstc5x5UnormBlock, vk::Format::eAstc5x5SrgbBlock,
|
||||
vk::Format::eAstc10x8UnormBlock, vk::Format::eAstc10x8SrgbBlock,
|
||||
vk::Format::eAstc6x5UnormBlock, vk::Format::eAstc6x5SrgbBlock,
|
||||
vk::Format::eAstc6x6UnormBlock, vk::Format::eAstc6x6SrgbBlock,
|
||||
vk::Format::eAstc10x10UnormBlock, vk::Format::eAstc10x10SrgbBlock,
|
||||
vk::Format::eAstc12x12UnormBlock, vk::Format::eAstc12x12SrgbBlock,
|
||||
vk::Format::eAstc8x5UnormBlock, vk::Format::eAstc8x5SrgbBlock,
|
||||
vk::Format::eAstc8x6UnormBlock, vk::Format::eAstc8x6SrgbBlock,
|
||||
vk::Format::eAstc6x5UnormBlock, vk::Format::eAstc6x5SrgbBlock};
|
||||
vk::Format::eAstc8x8UnormBlock, vk::Format::eAstc8x8SrgbBlock,
|
||||
vk::Format::eAstc10x5UnormBlock, vk::Format::eAstc10x5SrgbBlock,
|
||||
vk::Format::eAstc10x6UnormBlock, vk::Format::eAstc10x6SrgbBlock,
|
||||
vk::Format::eAstc10x8UnormBlock, vk::Format::eAstc10x8SrgbBlock,
|
||||
vk::Format::eAstc10x10UnormBlock, vk::Format::eAstc10x10SrgbBlock,
|
||||
vk::Format::eAstc12x10UnormBlock, vk::Format::eAstc12x10SrgbBlock,
|
||||
vk::Format::eAstc12x12UnormBlock, vk::Format::eAstc12x12SrgbBlock};
|
||||
if (!features.textureCompressionASTC_LDR) {
|
||||
return false;
|
||||
}
|
||||
|
@ -572,24 +575,34 @@ std::unordered_map<vk::Format, vk::FormatProperties> VKDevice::GetFormatProperti
|
|||
vk::Format::eBc2SrgbBlock,
|
||||
vk::Format::eBc3SrgbBlock,
|
||||
vk::Format::eBc7SrgbBlock,
|
||||
vk::Format::eAstc4x4UnormBlock,
|
||||
vk::Format::eAstc4x4SrgbBlock,
|
||||
vk::Format::eAstc8x8SrgbBlock,
|
||||
vk::Format::eAstc8x5SrgbBlock,
|
||||
vk::Format::eAstc5x4UnormBlock,
|
||||
vk::Format::eAstc5x4SrgbBlock,
|
||||
vk::Format::eAstc5x5UnormBlock,
|
||||
vk::Format::eAstc5x5SrgbBlock,
|
||||
vk::Format::eAstc10x8UnormBlock,
|
||||
vk::Format::eAstc10x8SrgbBlock,
|
||||
vk::Format::eAstc6x6UnormBlock,
|
||||
vk::Format::eAstc6x6SrgbBlock,
|
||||
vk::Format::eAstc10x10UnormBlock,
|
||||
vk::Format::eAstc10x10SrgbBlock,
|
||||
vk::Format::eAstc12x12UnormBlock,
|
||||
vk::Format::eAstc12x12SrgbBlock,
|
||||
vk::Format::eAstc8x6UnormBlock,
|
||||
vk::Format::eAstc8x6SrgbBlock,
|
||||
vk::Format::eAstc6x5UnormBlock,
|
||||
vk::Format::eAstc6x5SrgbBlock,
|
||||
vk::Format::eAstc6x6UnormBlock,
|
||||
vk::Format::eAstc6x6SrgbBlock,
|
||||
vk::Format::eAstc8x5UnormBlock,
|
||||
vk::Format::eAstc8x5SrgbBlock,
|
||||
vk::Format::eAstc8x6UnormBlock,
|
||||
vk::Format::eAstc8x6SrgbBlock,
|
||||
vk::Format::eAstc8x8UnormBlock,
|
||||
vk::Format::eAstc8x8SrgbBlock,
|
||||
vk::Format::eAstc10x5UnormBlock,
|
||||
vk::Format::eAstc10x5SrgbBlock,
|
||||
vk::Format::eAstc10x6UnormBlock,
|
||||
vk::Format::eAstc10x6SrgbBlock,
|
||||
vk::Format::eAstc10x8UnormBlock,
|
||||
vk::Format::eAstc10x8SrgbBlock,
|
||||
vk::Format::eAstc10x10UnormBlock,
|
||||
vk::Format::eAstc10x10SrgbBlock,
|
||||
vk::Format::eAstc12x10UnormBlock,
|
||||
vk::Format::eAstc12x10SrgbBlock,
|
||||
vk::Format::eAstc12x12UnormBlock,
|
||||
vk::Format::eAstc12x12SrgbBlock,
|
||||
vk::Format::eE5B9G9R9UfloatPack32};
|
||||
std::unordered_map<vk::Format, vk::FormatProperties> format_properties;
|
||||
for (const auto format : formats) {
|
||||
|
|
|
@ -35,7 +35,6 @@ using VideoCore::MortonSwizzleMode;
|
|||
|
||||
using Tegra::Texture::SwizzleSource;
|
||||
using VideoCore::Surface::PixelFormat;
|
||||
using VideoCore::Surface::SurfaceCompression;
|
||||
using VideoCore::Surface::SurfaceTarget;
|
||||
|
||||
namespace {
|
||||
|
@ -96,9 +95,10 @@ vk::ImageViewType GetImageViewType(SurfaceTarget target) {
|
|||
return {};
|
||||
}
|
||||
|
||||
UniqueBuffer CreateBuffer(const VKDevice& device, const SurfaceParams& params) {
|
||||
UniqueBuffer CreateBuffer(const VKDevice& device, const SurfaceParams& params,
|
||||
std::size_t host_memory_size) {
|
||||
// TODO(Rodrigo): Move texture buffer creation to the buffer cache
|
||||
const vk::BufferCreateInfo buffer_ci({}, params.GetHostSizeInBytes(),
|
||||
const vk::BufferCreateInfo buffer_ci({}, host_memory_size,
|
||||
vk::BufferUsageFlagBits::eUniformTexelBuffer |
|
||||
vk::BufferUsageFlagBits::eTransferSrc |
|
||||
vk::BufferUsageFlagBits::eTransferDst,
|
||||
|
@ -110,12 +110,13 @@ UniqueBuffer CreateBuffer(const VKDevice& device, const SurfaceParams& params) {
|
|||
|
||||
vk::BufferViewCreateInfo GenerateBufferViewCreateInfo(const VKDevice& device,
|
||||
const SurfaceParams& params,
|
||||
vk::Buffer buffer) {
|
||||
vk::Buffer buffer,
|
||||
std::size_t host_memory_size) {
|
||||
ASSERT(params.IsBuffer());
|
||||
|
||||
const auto format =
|
||||
MaxwellToVK::SurfaceFormat(device, FormatType::Buffer, params.pixel_format).format;
|
||||
return vk::BufferViewCreateInfo({}, buffer, format, 0, params.GetHostSizeInBytes());
|
||||
return vk::BufferViewCreateInfo({}, buffer, format, 0, host_memory_size);
|
||||
}
|
||||
|
||||
vk::ImageCreateInfo GenerateImageCreateInfo(const VKDevice& device, const SurfaceParams& params) {
|
||||
|
@ -169,14 +170,15 @@ CachedSurface::CachedSurface(Core::System& system, const VKDevice& device,
|
|||
VKResourceManager& resource_manager, VKMemoryManager& memory_manager,
|
||||
VKScheduler& scheduler, VKStagingBufferPool& staging_pool,
|
||||
GPUVAddr gpu_addr, const SurfaceParams& params)
|
||||
: SurfaceBase<View>{gpu_addr, params}, system{system}, device{device},
|
||||
resource_manager{resource_manager}, memory_manager{memory_manager}, scheduler{scheduler},
|
||||
staging_pool{staging_pool} {
|
||||
: SurfaceBase<View>{gpu_addr, params, device.IsOptimalAstcSupported()}, system{system},
|
||||
device{device}, resource_manager{resource_manager},
|
||||
memory_manager{memory_manager}, scheduler{scheduler}, staging_pool{staging_pool} {
|
||||
if (params.IsBuffer()) {
|
||||
buffer = CreateBuffer(device, params);
|
||||
buffer = CreateBuffer(device, params, host_memory_size);
|
||||
commit = memory_manager.Commit(*buffer, false);
|
||||
|
||||
const auto buffer_view_ci = GenerateBufferViewCreateInfo(device, params, *buffer);
|
||||
const auto buffer_view_ci =
|
||||
GenerateBufferViewCreateInfo(device, params, *buffer, host_memory_size);
|
||||
format = buffer_view_ci.format;
|
||||
|
||||
const auto dev = device.GetLogical();
|
||||
|
@ -255,7 +257,7 @@ void CachedSurface::UploadBuffer(const std::vector<u8>& staging_buffer) {
|
|||
std::memcpy(src_buffer.commit->Map(host_memory_size), staging_buffer.data(), host_memory_size);
|
||||
|
||||
scheduler.Record([src_buffer = *src_buffer.handle, dst_buffer = *buffer,
|
||||
size = params.GetHostSizeInBytes()](auto cmdbuf, auto& dld) {
|
||||
size = host_memory_size](auto cmdbuf, auto& dld) {
|
||||
const vk::BufferCopy copy(0, 0, size);
|
||||
cmdbuf.copyBuffer(src_buffer, dst_buffer, {copy}, dld);
|
||||
|
||||
|
@ -299,10 +301,7 @@ void CachedSurface::UploadImage(const std::vector<u8>& staging_buffer) {
|
|||
|
||||
vk::BufferImageCopy CachedSurface::GetBufferImageCopy(u32 level) const {
|
||||
const u32 vk_depth = params.target == SurfaceTarget::Texture3D ? params.GetMipDepth(level) : 1;
|
||||
const auto compression_type = params.GetCompressionType();
|
||||
const std::size_t mip_offset = compression_type == SurfaceCompression::Converted
|
||||
? params.GetConvertedMipmapOffset(level)
|
||||
: params.GetHostMipmapLevelOffset(level);
|
||||
const std::size_t mip_offset = params.GetHostMipmapLevelOffset(level, is_converted);
|
||||
|
||||
return vk::BufferImageCopy(
|
||||
mip_offset, 0, 0,
|
||||
|
@ -390,8 +389,9 @@ VKTextureCache::VKTextureCache(Core::System& system, VideoCore::RasterizerInterf
|
|||
const VKDevice& device, VKResourceManager& resource_manager,
|
||||
VKMemoryManager& memory_manager, VKScheduler& scheduler,
|
||||
VKStagingBufferPool& staging_pool)
|
||||
: TextureCache(system, rasterizer), device{device}, resource_manager{resource_manager},
|
||||
memory_manager{memory_manager}, scheduler{scheduler}, staging_pool{staging_pool} {}
|
||||
: TextureCache(system, rasterizer, device.IsOptimalAstcSupported()), device{device},
|
||||
resource_manager{resource_manager}, memory_manager{memory_manager}, scheduler{scheduler},
|
||||
staging_pool{staging_pool} {}
|
||||
|
||||
VKTextureCache::~VKTextureCache() = default;
|
||||
|
||||
|
|
|
@ -504,103 +504,6 @@ static constexpr u32 GetBytesPerPixel(PixelFormat pixel_format) {
|
|||
return GetFormatBpp(pixel_format) / CHAR_BIT;
|
||||
}
|
||||
|
||||
enum class SurfaceCompression {
|
||||
None, // Not compressed
|
||||
Compressed, // Texture is compressed
|
||||
Converted, // Texture is converted before upload or after download
|
||||
Rearranged, // Texture is swizzled before upload or after download
|
||||
};
|
||||
|
||||
constexpr std::array<SurfaceCompression, MaxPixelFormat> compression_type_table = {{
|
||||
SurfaceCompression::None, // ABGR8U
|
||||
SurfaceCompression::None, // ABGR8S
|
||||
SurfaceCompression::None, // ABGR8UI
|
||||
SurfaceCompression::None, // B5G6R5U
|
||||
SurfaceCompression::None, // A2B10G10R10U
|
||||
SurfaceCompression::None, // A1B5G5R5U
|
||||
SurfaceCompression::None, // R8U
|
||||
SurfaceCompression::None, // R8UI
|
||||
SurfaceCompression::None, // RGBA16F
|
||||
SurfaceCompression::None, // RGBA16U
|
||||
SurfaceCompression::None, // RGBA16S
|
||||
SurfaceCompression::None, // RGBA16UI
|
||||
SurfaceCompression::None, // R11FG11FB10F
|
||||
SurfaceCompression::None, // RGBA32UI
|
||||
SurfaceCompression::Compressed, // DXT1
|
||||
SurfaceCompression::Compressed, // DXT23
|
||||
SurfaceCompression::Compressed, // DXT45
|
||||
SurfaceCompression::Compressed, // DXN1
|
||||
SurfaceCompression::Compressed, // DXN2UNORM
|
||||
SurfaceCompression::Compressed, // DXN2SNORM
|
||||
SurfaceCompression::Compressed, // BC7U
|
||||
SurfaceCompression::Compressed, // BC6H_UF16
|
||||
SurfaceCompression::Compressed, // BC6H_SF16
|
||||
SurfaceCompression::Converted, // ASTC_2D_4X4
|
||||
SurfaceCompression::None, // BGRA8
|
||||
SurfaceCompression::None, // RGBA32F
|
||||
SurfaceCompression::None, // RG32F
|
||||
SurfaceCompression::None, // R32F
|
||||
SurfaceCompression::None, // R16F
|
||||
SurfaceCompression::None, // R16U
|
||||
SurfaceCompression::None, // R16S
|
||||
SurfaceCompression::None, // R16UI
|
||||
SurfaceCompression::None, // R16I
|
||||
SurfaceCompression::None, // RG16
|
||||
SurfaceCompression::None, // RG16F
|
||||
SurfaceCompression::None, // RG16UI
|
||||
SurfaceCompression::None, // RG16I
|
||||
SurfaceCompression::None, // RG16S
|
||||
SurfaceCompression::None, // RGB32F
|
||||
SurfaceCompression::None, // RGBA8_SRGB
|
||||
SurfaceCompression::None, // RG8U
|
||||
SurfaceCompression::None, // RG8S
|
||||
SurfaceCompression::None, // RG32UI
|
||||
SurfaceCompression::None, // RGBX16F
|
||||
SurfaceCompression::None, // R32UI
|
||||
SurfaceCompression::None, // R32I
|
||||
SurfaceCompression::Converted, // ASTC_2D_8X8
|
||||
SurfaceCompression::Converted, // ASTC_2D_8X5
|
||||
SurfaceCompression::Converted, // ASTC_2D_5X4
|
||||
SurfaceCompression::None, // BGRA8_SRGB
|
||||
SurfaceCompression::Compressed, // DXT1_SRGB
|
||||
SurfaceCompression::Compressed, // DXT23_SRGB
|
||||
SurfaceCompression::Compressed, // DXT45_SRGB
|
||||
SurfaceCompression::Compressed, // BC7U_SRGB
|
||||
SurfaceCompression::None, // R4G4B4A4U
|
||||
SurfaceCompression::Converted, // ASTC_2D_4X4_SRGB
|
||||
SurfaceCompression::Converted, // ASTC_2D_8X8_SRGB
|
||||
SurfaceCompression::Converted, // ASTC_2D_8X5_SRGB
|
||||
SurfaceCompression::Converted, // ASTC_2D_5X4_SRGB
|
||||
SurfaceCompression::Converted, // ASTC_2D_5X5
|
||||
SurfaceCompression::Converted, // ASTC_2D_5X5_SRGB
|
||||
SurfaceCompression::Converted, // ASTC_2D_10X8
|
||||
SurfaceCompression::Converted, // ASTC_2D_10X8_SRGB
|
||||
SurfaceCompression::Converted, // ASTC_2D_6X6
|
||||
SurfaceCompression::Converted, // ASTC_2D_6X6_SRGB
|
||||
SurfaceCompression::Converted, // ASTC_2D_10X10
|
||||
SurfaceCompression::Converted, // ASTC_2D_10X10_SRGB
|
||||
SurfaceCompression::Converted, // ASTC_2D_12X12
|
||||
SurfaceCompression::Converted, // ASTC_2D_12X12_SRGB
|
||||
SurfaceCompression::Converted, // ASTC_2D_8X6
|
||||
SurfaceCompression::Converted, // ASTC_2D_8X6_SRGB
|
||||
SurfaceCompression::Converted, // ASTC_2D_6X5
|
||||
SurfaceCompression::Converted, // ASTC_2D_6X5_SRGB
|
||||
SurfaceCompression::None, // E5B9G9R9F
|
||||
SurfaceCompression::None, // Z32F
|
||||
SurfaceCompression::None, // Z16
|
||||
SurfaceCompression::None, // Z24S8
|
||||
SurfaceCompression::Rearranged, // S8Z24
|
||||
SurfaceCompression::None, // Z32FS8
|
||||
}};
|
||||
|
||||
constexpr SurfaceCompression GetFormatCompressionType(PixelFormat format) {
|
||||
if (format == PixelFormat::Invalid) {
|
||||
return SurfaceCompression::None;
|
||||
}
|
||||
DEBUG_ASSERT(static_cast<std::size_t>(format) < compression_type_table.size());
|
||||
return compression_type_table[static_cast<std::size_t>(format)];
|
||||
}
|
||||
|
||||
SurfaceTarget SurfaceTargetFromTextureType(Tegra::Texture::TextureType texture_type);
|
||||
|
||||
bool SurfaceTargetIsLayered(SurfaceTarget target);
|
||||
|
|
|
@ -18,15 +18,20 @@ MICROPROFILE_DEFINE(GPU_Flush_Texture, "GPU", "Texture Flush", MP_RGB(128, 192,
|
|||
|
||||
using Tegra::Texture::ConvertFromGuestToHost;
|
||||
using VideoCore::MortonSwizzleMode;
|
||||
using VideoCore::Surface::SurfaceCompression;
|
||||
using VideoCore::Surface::IsPixelFormatASTC;
|
||||
using VideoCore::Surface::PixelFormat;
|
||||
|
||||
StagingCache::StagingCache() = default;
|
||||
|
||||
StagingCache::~StagingCache() = default;
|
||||
|
||||
SurfaceBaseImpl::SurfaceBaseImpl(GPUVAddr gpu_addr, const SurfaceParams& params)
|
||||
: params{params}, host_memory_size{params.GetHostSizeInBytes()}, gpu_addr{gpu_addr},
|
||||
mipmap_sizes(params.num_levels), mipmap_offsets(params.num_levels) {
|
||||
SurfaceBaseImpl::SurfaceBaseImpl(GPUVAddr gpu_addr, const SurfaceParams& params,
|
||||
bool is_astc_supported)
|
||||
: params{params}, gpu_addr{gpu_addr}, mipmap_sizes(params.num_levels),
|
||||
mipmap_offsets(params.num_levels) {
|
||||
is_converted = IsPixelFormatASTC(params.pixel_format) && !is_astc_supported;
|
||||
host_memory_size = params.GetHostSizeInBytes(is_converted);
|
||||
|
||||
std::size_t offset = 0;
|
||||
for (u32 level = 0; level < params.num_levels; ++level) {
|
||||
const std::size_t mipmap_size{params.GetGuestMipmapSize(level)};
|
||||
|
@ -164,7 +169,7 @@ void SurfaceBaseImpl::SwizzleFunc(MortonSwizzleMode mode, u8* memory, const Surf
|
|||
|
||||
std::size_t guest_offset{mipmap_offsets[level]};
|
||||
if (params.is_layered) {
|
||||
std::size_t host_offset{0};
|
||||
std::size_t host_offset = 0;
|
||||
const std::size_t guest_stride = layer_size;
|
||||
const std::size_t host_stride = params.GetHostLayerSize(level);
|
||||
for (u32 layer = 0; layer < params.depth; ++layer) {
|
||||
|
@ -206,7 +211,7 @@ void SurfaceBaseImpl::LoadBuffer(Tegra::MemoryManager& memory_manager,
|
|||
ASSERT_MSG(params.block_width == 0, "Block width is defined as {} on texture target {}",
|
||||
params.block_width, static_cast<u32>(params.target));
|
||||
for (u32 level = 0; level < params.num_levels; ++level) {
|
||||
const std::size_t host_offset{params.GetHostMipmapLevelOffset(level)};
|
||||
const std::size_t host_offset{params.GetHostMipmapLevelOffset(level, false)};
|
||||
SwizzleFunc(MortonSwizzleMode::MortonToLinear, host_ptr, params,
|
||||
staging_buffer.data() + host_offset, level);
|
||||
}
|
||||
|
@ -219,7 +224,7 @@ void SurfaceBaseImpl::LoadBuffer(Tegra::MemoryManager& memory_manager,
|
|||
const u32 height{(params.height + block_height - 1) / block_height};
|
||||
const u32 copy_size{width * bpp};
|
||||
if (params.pitch == copy_size) {
|
||||
std::memcpy(staging_buffer.data(), host_ptr, params.GetHostSizeInBytes());
|
||||
std::memcpy(staging_buffer.data(), host_ptr, params.GetHostSizeInBytes(false));
|
||||
} else {
|
||||
const u8* start{host_ptr};
|
||||
u8* write_to{staging_buffer.data()};
|
||||
|
@ -231,19 +236,15 @@ void SurfaceBaseImpl::LoadBuffer(Tegra::MemoryManager& memory_manager,
|
|||
}
|
||||
}
|
||||
|
||||
auto compression_type = params.GetCompressionType();
|
||||
if (compression_type == SurfaceCompression::None ||
|
||||
compression_type == SurfaceCompression::Compressed)
|
||||
if (!is_converted && params.pixel_format != PixelFormat::S8Z24) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (u32 level_up = params.num_levels; level_up > 0; --level_up) {
|
||||
const u32 level = level_up - 1;
|
||||
const std::size_t in_host_offset{params.GetHostMipmapLevelOffset(level)};
|
||||
const std::size_t out_host_offset = compression_type == SurfaceCompression::Rearranged
|
||||
? in_host_offset
|
||||
: params.GetConvertedMipmapOffset(level);
|
||||
u8* in_buffer = staging_buffer.data() + in_host_offset;
|
||||
u8* out_buffer = staging_buffer.data() + out_host_offset;
|
||||
for (u32 level = params.num_levels; level--;) {
|
||||
const std::size_t in_host_offset{params.GetHostMipmapLevelOffset(level, false)};
|
||||
const std::size_t out_host_offset{params.GetHostMipmapLevelOffset(level, is_converted)};
|
||||
u8* const in_buffer = staging_buffer.data() + in_host_offset;
|
||||
u8* const out_buffer = staging_buffer.data() + out_host_offset;
|
||||
ConvertFromGuestToHost(in_buffer, out_buffer, params.pixel_format,
|
||||
params.GetMipWidth(level), params.GetMipHeight(level),
|
||||
params.GetMipDepth(level), true, true);
|
||||
|
@ -273,7 +274,7 @@ void SurfaceBaseImpl::FlushBuffer(Tegra::MemoryManager& memory_manager,
|
|||
if (params.is_tiled) {
|
||||
ASSERT_MSG(params.block_width == 0, "Block width is defined as {}", params.block_width);
|
||||
for (u32 level = 0; level < params.num_levels; ++level) {
|
||||
const std::size_t host_offset{params.GetHostMipmapLevelOffset(level)};
|
||||
const std::size_t host_offset{params.GetHostMipmapLevelOffset(level, false)};
|
||||
SwizzleFunc(MortonSwizzleMode::LinearToMorton, host_ptr, params,
|
||||
staging_buffer.data() + host_offset, level);
|
||||
}
|
||||
|
|
|
@ -131,6 +131,10 @@ public:
|
|||
return !params.is_tiled;
|
||||
}
|
||||
|
||||
bool IsConverted() const {
|
||||
return is_converted;
|
||||
}
|
||||
|
||||
bool MatchFormat(VideoCore::Surface::PixelFormat pixel_format) const {
|
||||
return params.pixel_format == pixel_format;
|
||||
}
|
||||
|
@ -160,7 +164,8 @@ public:
|
|||
}
|
||||
|
||||
protected:
|
||||
explicit SurfaceBaseImpl(GPUVAddr gpu_addr, const SurfaceParams& params);
|
||||
explicit SurfaceBaseImpl(GPUVAddr gpu_addr, const SurfaceParams& params,
|
||||
bool is_astc_supported);
|
||||
~SurfaceBaseImpl() = default;
|
||||
|
||||
virtual void DecorateSurfaceName() = 0;
|
||||
|
@ -168,12 +173,13 @@ protected:
|
|||
const SurfaceParams params;
|
||||
std::size_t layer_size;
|
||||
std::size_t guest_memory_size;
|
||||
const std::size_t host_memory_size;
|
||||
std::size_t host_memory_size;
|
||||
GPUVAddr gpu_addr{};
|
||||
CacheAddr cache_addr{};
|
||||
CacheAddr cache_addr_end{};
|
||||
VAddr cpu_addr{};
|
||||
bool is_continuous{};
|
||||
bool is_converted{};
|
||||
|
||||
std::vector<std::size_t> mipmap_sizes;
|
||||
std::vector<std::size_t> mipmap_offsets;
|
||||
|
@ -288,8 +294,9 @@ public:
|
|||
}
|
||||
|
||||
protected:
|
||||
explicit SurfaceBase(const GPUVAddr gpu_addr, const SurfaceParams& params)
|
||||
: SurfaceBaseImpl(gpu_addr, params) {}
|
||||
explicit SurfaceBase(const GPUVAddr gpu_addr, const SurfaceParams& params,
|
||||
bool is_astc_supported)
|
||||
: SurfaceBaseImpl(gpu_addr, params, is_astc_supported) {}
|
||||
|
||||
~SurfaceBase() = default;
|
||||
|
||||
|
|
|
@ -309,28 +309,26 @@ std::size_t SurfaceParams::GetGuestMipmapLevelOffset(u32 level) const {
|
|||
return offset;
|
||||
}
|
||||
|
||||
std::size_t SurfaceParams::GetHostMipmapLevelOffset(u32 level) const {
|
||||
std::size_t SurfaceParams::GetHostMipmapLevelOffset(u32 level, bool is_converted) const {
|
||||
std::size_t offset = 0;
|
||||
for (u32 i = 0; i < level; i++) {
|
||||
offset += GetInnerMipmapMemorySize(i, true, false) * GetNumLayers();
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
|
||||
std::size_t SurfaceParams::GetConvertedMipmapOffset(u32 level) const {
|
||||
std::size_t offset = 0;
|
||||
for (u32 i = 0; i < level; i++) {
|
||||
offset += GetConvertedMipmapSize(i);
|
||||
if (is_converted) {
|
||||
for (u32 i = 0; i < level; ++i) {
|
||||
offset += GetConvertedMipmapSize(i) * GetNumLayers();
|
||||
}
|
||||
} else {
|
||||
for (u32 i = 0; i < level; ++i) {
|
||||
offset += GetInnerMipmapMemorySize(i, true, false) * GetNumLayers();
|
||||
}
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
|
||||
std::size_t SurfaceParams::GetConvertedMipmapSize(u32 level) const {
|
||||
constexpr std::size_t rgba8_bpp = 4ULL;
|
||||
const std::size_t width_t = GetMipWidth(level);
|
||||
const std::size_t height_t = GetMipHeight(level);
|
||||
const std::size_t depth_t = is_layered ? depth : GetMipDepth(level);
|
||||
return width_t * height_t * depth_t * rgba8_bpp;
|
||||
const std::size_t mip_width = GetMipWidth(level);
|
||||
const std::size_t mip_height = GetMipHeight(level);
|
||||
const std::size_t mip_depth = is_layered ? 1 : GetMipDepth(level);
|
||||
return mip_width * mip_height * mip_depth * rgba8_bpp;
|
||||
}
|
||||
|
||||
std::size_t SurfaceParams::GetLayerSize(bool as_host_size, bool uncompressed) const {
|
||||
|
|
|
@ -20,8 +20,6 @@ namespace VideoCommon {
|
|||
|
||||
class FormatLookupTable;
|
||||
|
||||
using VideoCore::Surface::SurfaceCompression;
|
||||
|
||||
class SurfaceParams {
|
||||
public:
|
||||
/// Creates SurfaceCachedParams from a texture configuration.
|
||||
|
@ -67,16 +65,14 @@ public:
|
|||
return GetInnerMemorySize(false, false, false);
|
||||
}
|
||||
|
||||
std::size_t GetHostSizeInBytes() const {
|
||||
std::size_t host_size_in_bytes;
|
||||
if (GetCompressionType() == SurfaceCompression::Converted) {
|
||||
// ASTC is uncompressed in software, in emulated as RGBA8
|
||||
host_size_in_bytes = 0;
|
||||
for (u32 level = 0; level < num_levels; ++level) {
|
||||
host_size_in_bytes += GetConvertedMipmapSize(level);
|
||||
}
|
||||
} else {
|
||||
host_size_in_bytes = GetInnerMemorySize(true, false, false);
|
||||
std::size_t GetHostSizeInBytes(bool is_converted) const {
|
||||
if (!is_converted) {
|
||||
return GetInnerMemorySize(true, false, false);
|
||||
}
|
||||
// ASTC is uncompressed in software, in emulated as RGBA8
|
||||
std::size_t host_size_in_bytes = 0;
|
||||
for (u32 level = 0; level < num_levels; ++level) {
|
||||
host_size_in_bytes += GetConvertedMipmapSize(level) * GetNumLayers();
|
||||
}
|
||||
return host_size_in_bytes;
|
||||
}
|
||||
|
@ -107,9 +103,8 @@ public:
|
|||
u32 GetMipBlockDepth(u32 level) const;
|
||||
|
||||
/// Returns the best possible row/pitch alignment for the surface.
|
||||
u32 GetRowAlignment(u32 level) const {
|
||||
const u32 bpp =
|
||||
GetCompressionType() == SurfaceCompression::Converted ? 4 : GetBytesPerPixel();
|
||||
u32 GetRowAlignment(u32 level, bool is_converted) const {
|
||||
const u32 bpp = is_converted ? 4 : GetBytesPerPixel();
|
||||
return 1U << Common::CountTrailingZeroes32(GetMipWidth(level) * bpp);
|
||||
}
|
||||
|
||||
|
@ -117,11 +112,7 @@ public:
|
|||
std::size_t GetGuestMipmapLevelOffset(u32 level) const;
|
||||
|
||||
/// Returns the offset in bytes in host memory (linear) of a given mipmap level.
|
||||
std::size_t GetHostMipmapLevelOffset(u32 level) const;
|
||||
|
||||
/// Returns the offset in bytes in host memory (linear) of a given mipmap level
|
||||
/// for a texture that is converted in host gpu.
|
||||
std::size_t GetConvertedMipmapOffset(u32 level) const;
|
||||
std::size_t GetHostMipmapLevelOffset(u32 level, bool is_converted) const;
|
||||
|
||||
/// Returns the size in bytes in guest memory of a given mipmap level.
|
||||
std::size_t GetGuestMipmapSize(u32 level) const {
|
||||
|
@ -196,11 +187,6 @@ public:
|
|||
pixel_format < VideoCore::Surface::PixelFormat::MaxDepthStencilFormat;
|
||||
}
|
||||
|
||||
/// Returns how the compression should be handled for this texture.
|
||||
SurfaceCompression GetCompressionType() const {
|
||||
return VideoCore::Surface::GetFormatCompressionType(pixel_format);
|
||||
}
|
||||
|
||||
/// Returns is the surface is a TextureBuffer type of surface.
|
||||
bool IsBuffer() const {
|
||||
return target == VideoCore::Surface::SurfaceTarget::TextureBuffer;
|
||||
|
|
|
@ -289,8 +289,9 @@ public:
|
|||
}
|
||||
|
||||
protected:
|
||||
TextureCache(Core::System& system, VideoCore::RasterizerInterface& rasterizer)
|
||||
: system{system}, rasterizer{rasterizer} {
|
||||
explicit TextureCache(Core::System& system, VideoCore::RasterizerInterface& rasterizer,
|
||||
bool is_astc_supported)
|
||||
: system{system}, is_astc_supported{is_astc_supported}, rasterizer{rasterizer} {
|
||||
for (std::size_t i = 0; i < Tegra::Engines::Maxwell3D::Regs::NumRenderTargets; i++) {
|
||||
SetEmptyColorBuffer(i);
|
||||
}
|
||||
|
@ -381,6 +382,7 @@ protected:
|
|||
}
|
||||
|
||||
Core::System& system;
|
||||
const bool is_astc_supported;
|
||||
|
||||
private:
|
||||
enum class RecycleStrategy : u32 {
|
||||
|
|
Reference in New Issue