summaryrefslogtreecommitdiffstats
path: root/src/video_core/renderer_opengl
diff options
context:
space:
mode:
Diffstat (limited to 'src/video_core/renderer_opengl')
-rw-r--r--src/video_core/renderer_opengl/gl_texture_cache.cpp10
-rw-r--r--src/video_core/renderer_opengl/gl_texture_cache.h2
-rw-r--r--src/video_core/renderer_opengl/util_shaders.cpp99
-rw-r--r--src/video_core/renderer_opengl/util_shaders.h11
4 files changed, 120 insertions, 2 deletions
diff --git a/src/video_core/renderer_opengl/gl_texture_cache.cpp b/src/video_core/renderer_opengl/gl_texture_cache.cpp
index e028677e9..29105ecad 100644
--- a/src/video_core/renderer_opengl/gl_texture_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_texture_cache.cpp
@@ -307,7 +307,8 @@ void ApplySwizzle(GLuint handle, PixelFormat format, std::array<SwizzleSource, 4
[[nodiscard]] bool CanBeAccelerated(const TextureCacheRuntime& runtime,
const VideoCommon::ImageInfo& info) {
- // Disable accelerated uploads for now as they don't implement swizzled uploads
+ return (!runtime.HasNativeASTC() && IsPixelFormatASTC(info.format));
+ // Disable other accelerated uploads for now as they don't implement swizzled uploads
return false;
switch (info.type) {
case ImageType::e2D:
@@ -567,6 +568,9 @@ void TextureCacheRuntime::BlitFramebuffer(Framebuffer* dst, Framebuffer* src,
void TextureCacheRuntime::AccelerateImageUpload(Image& image, const ImageBufferMap& map,
std::span<const SwizzleParameters> swizzles) {
+ if (IsPixelFormatASTC(image.info.format)) {
+ return util_shaders.ASTCDecode(image, map, swizzles);
+ }
switch (image.info.type) {
case ImageType::e2D:
return util_shaders.BlockLinearUpload2D(image, map, swizzles);
@@ -599,6 +603,10 @@ FormatProperties TextureCacheRuntime::FormatInfo(ImageType type, GLenum internal
}
}
+bool TextureCacheRuntime::HasNativeASTC() const noexcept {
+ return device.HasASTC();
+}
+
TextureCacheRuntime::StagingBuffers::StagingBuffers(GLenum storage_flags_, GLenum map_flags_)
: storage_flags{storage_flags_}, map_flags{map_flags_} {}
diff --git a/src/video_core/renderer_opengl/gl_texture_cache.h b/src/video_core/renderer_opengl/gl_texture_cache.h
index 3fbaa102f..3c871541b 100644
--- a/src/video_core/renderer_opengl/gl_texture_cache.h
+++ b/src/video_core/renderer_opengl/gl_texture_cache.h
@@ -95,6 +95,8 @@ public:
return has_broken_texture_view_formats;
}
+ bool HasNativeASTC() const noexcept;
+
private:
struct StagingBuffers {
explicit StagingBuffers(GLenum storage_flags_, GLenum map_flags_);
diff --git a/src/video_core/renderer_opengl/util_shaders.cpp b/src/video_core/renderer_opengl/util_shaders.cpp
index 2fe4799bc..2a4220661 100644
--- a/src/video_core/renderer_opengl/util_shaders.cpp
+++ b/src/video_core/renderer_opengl/util_shaders.cpp
@@ -3,7 +3,10 @@
// Refer to the license.txt file included.
#include <bit>
+#include <fstream>
#include <span>
+#include <streambuf>
+#include <string>
#include <string_view>
#include <glad/glad.h>
@@ -24,11 +27,13 @@
#include "video_core/texture_cache/accelerated_swizzle.h"
#include "video_core/texture_cache/types.h"
#include "video_core/texture_cache/util.h"
+#include "video_core/textures/astc.h"
#include "video_core/textures/decoders.h"
namespace OpenGL {
using namespace HostShaders;
+using namespace Tegra::Texture::ASTC;
using VideoCommon::Extent3D;
using VideoCommon::ImageCopy;
@@ -63,12 +68,104 @@ UtilShaders::UtilShaders(ProgramManager& program_manager_)
pitch_unswizzle_program(MakeProgram(PITCH_UNSWIZZLE_COMP)),
copy_bgra_program(MakeProgram(OPENGL_COPY_BGRA_COMP)),
copy_bc4_program(MakeProgram(OPENGL_COPY_BC4_COMP)) {
+ // TODO: Load shader string as a header
+ std::string astc_path = "astc_decoder.comp";
+ std::ifstream t(astc_path);
+ std::string str((std::istreambuf_iterator<char>(t)), std::istreambuf_iterator<char>());
+ astc_decoder_program = MakeProgram(str);
+ MakeBuffers();
+}
+
+UtilShaders::~UtilShaders() = default;
+
+void UtilShaders::MakeBuffers() {
const auto swizzle_table = Tegra::Texture::MakeSwizzleTable();
swizzle_table_buffer.Create();
glNamedBufferStorage(swizzle_table_buffer.handle, sizeof(swizzle_table), &swizzle_table, 0);
+
+ astc_encodings_buffer.Create();
+ glNamedBufferStorage(astc_encodings_buffer.handle, sizeof(EncodingsValues), &EncodingsValues,
+ 0);
+ replicate_6_to_8_buffer.Create();
+ glNamedBufferStorage(replicate_6_to_8_buffer.handle, sizeof(REPLICATE_6_BIT_TO_8_TABLE),
+ &REPLICATE_6_BIT_TO_8_TABLE, 0);
+ replicate_7_to_8_buffer.Create();
+ glNamedBufferStorage(replicate_7_to_8_buffer.handle, sizeof(REPLICATE_7_BIT_TO_8_TABLE),
+ &REPLICATE_7_BIT_TO_8_TABLE, 0);
+ replicate_8_to_8_buffer.Create();
+ glNamedBufferStorage(replicate_8_to_8_buffer.handle, sizeof(REPLICATE_8_BIT_TO_8_TABLE),
+ &REPLICATE_8_BIT_TO_8_TABLE, 0);
+ replicate_byte_to_16_buffer.Create();
+ glNamedBufferStorage(replicate_byte_to_16_buffer.handle, sizeof(REPLICATE_BYTE_TO_16_TABLE),
+ &REPLICATE_BYTE_TO_16_TABLE, 0);
}
-UtilShaders::~UtilShaders() = default;
+void UtilShaders::ASTCDecode(Image& image, const ImageBufferMap& map,
+ std::span<const VideoCommon::SwizzleParameters> swizzles) {
+ static constexpr GLuint BINDING_SWIZZLE_BUFFER = 0;
+ static constexpr GLuint BINDING_INPUT_BUFFER = 1;
+ static constexpr GLuint BINDING_ENC_BUFFER = 2;
+
+ static constexpr GLuint BINDING_6_TO_8_BUFFER = 3;
+ static constexpr GLuint BINDING_7_TO_8_BUFFER = 4;
+ static constexpr GLuint BINDING_8_TO_8_BUFFER = 5;
+ static constexpr GLuint BINDING_BYTE_TO_16_BUFFER = 6;
+
+ static constexpr GLuint BINDING_OUTPUT_IMAGE = 0;
+ static constexpr GLuint LOC_NUM_IMAGE_BLOCKS = 0;
+ static constexpr GLuint LOC_BLOCK_DIMS = 1;
+ static constexpr GLuint LOC_LAYER = 2;
+
+ const Extent3D tile_size = {
+ VideoCore::Surface::DefaultBlockWidth(image.info.format),
+ VideoCore::Surface::DefaultBlockHeight(image.info.format),
+ };
+ program_manager.BindHostCompute(astc_decoder_program.handle);
+ glBindBufferBase(GL_SHADER_STORAGE_BUFFER, BINDING_SWIZZLE_BUFFER, swizzle_table_buffer.handle);
+ glBindBufferBase(GL_SHADER_STORAGE_BUFFER, BINDING_ENC_BUFFER, astc_encodings_buffer.handle);
+ glBindBufferBase(GL_SHADER_STORAGE_BUFFER, BINDING_6_TO_8_BUFFER,
+ replicate_6_to_8_buffer.handle);
+ glBindBufferBase(GL_SHADER_STORAGE_BUFFER, BINDING_7_TO_8_BUFFER,
+ replicate_7_to_8_buffer.handle);
+ glBindBufferBase(GL_SHADER_STORAGE_BUFFER, BINDING_8_TO_8_BUFFER,
+ replicate_8_to_8_buffer.handle);
+ glBindBufferBase(GL_SHADER_STORAGE_BUFFER, BINDING_BYTE_TO_16_BUFFER,
+ replicate_byte_to_16_buffer.handle);
+
+ glFlushMappedNamedBufferRange(map.buffer, map.offset, image.guest_size_bytes);
+ glUniform2ui(LOC_BLOCK_DIMS, tile_size.width, tile_size.height);
+
+ for (u32 layer = 0; layer < image.info.resources.layers; layer++) {
+ for (const SwizzleParameters& swizzle : swizzles) {
+ glBindImageTexture(BINDING_OUTPUT_IMAGE, image.StorageHandle(), swizzle.level, GL_FALSE,
+ layer, GL_WRITE_ONLY, GL_RGBA8);
+ const size_t input_offset = swizzle.buffer_offset + map.offset;
+ const auto num_dispatches_x = Common::DivCeil(swizzle.num_tiles.width, 32U);
+ const auto num_dispatches_y = Common::DivCeil(swizzle.num_tiles.height, 32U);
+
+ glUniform2ui(LOC_NUM_IMAGE_BLOCKS, swizzle.num_tiles.width, swizzle.num_tiles.height);
+ glUniform1ui(LOC_LAYER, layer);
+
+ // To unswizzle the ASTC data
+ const auto params = MakeBlockLinearSwizzle2DParams(swizzle, image.info);
+ glUniform3uiv(3, 1, params.origin.data());
+ glUniform3iv(4, 1, params.destination.data());
+ glUniform1ui(5, params.bytes_per_block_log2);
+ glUniform1ui(6, params.layer_stride);
+ glUniform1ui(7, params.block_size);
+ glUniform1ui(8, params.x_shift);
+ glUniform1ui(9, params.block_height);
+ glUniform1ui(10, params.block_height_mask);
+
+ // ASTC texture data
+ glBindBufferRange(GL_SHADER_STORAGE_BUFFER, BINDING_INPUT_BUFFER, map.buffer,
+ input_offset, image.guest_size_bytes - swizzle.buffer_offset);
+
+ glDispatchCompute(num_dispatches_x, num_dispatches_y, 1);
+ }
+ }
+ program_manager.RestoreGuestCompute();
+}
void UtilShaders::BlockLinearUpload2D(Image& image, const ImageBufferMap& map,
std::span<const SwizzleParameters> swizzles) {
diff --git a/src/video_core/renderer_opengl/util_shaders.h b/src/video_core/renderer_opengl/util_shaders.h
index 93b009743..08a1cb9b2 100644
--- a/src/video_core/renderer_opengl/util_shaders.h
+++ b/src/video_core/renderer_opengl/util_shaders.h
@@ -40,6 +40,11 @@ public:
explicit UtilShaders(ProgramManager& program_manager);
~UtilShaders();
+ void MakeBuffers();
+
+ void ASTCDecode(Image& image, const ImageBufferMap& map,
+ std::span<const VideoCommon::SwizzleParameters> swizzles);
+
void BlockLinearUpload2D(Image& image, const ImageBufferMap& map,
std::span<const VideoCommon::SwizzleParameters> swizzles);
@@ -59,7 +64,13 @@ private:
ProgramManager& program_manager;
OGLBuffer swizzle_table_buffer;
+ OGLBuffer astc_encodings_buffer;
+ OGLBuffer replicate_6_to_8_buffer;
+ OGLBuffer replicate_7_to_8_buffer;
+ OGLBuffer replicate_8_to_8_buffer;
+ OGLBuffer replicate_byte_to_16_buffer;
+ OGLProgram astc_decoder_program;
OGLProgram block_linear_unswizzle_2d_program;
OGLProgram block_linear_unswizzle_3d_program;
OGLProgram pitch_unswizzle_program;