early-access version 1452
This commit is contained in:
@@ -198,8 +198,8 @@ bool IsASTCSupported() {
|
||||
} // Anonymous namespace
|
||||
|
||||
Device::Device() {
|
||||
if (!GLAD_GL_VERSION_4_3) {
|
||||
LOG_ERROR(Render_OpenGL, "OpenGL 4.3 is not available");
|
||||
if (!GLAD_GL_VERSION_4_6) {
|
||||
LOG_ERROR(Render_OpenGL, "OpenGL 4.6 is not available");
|
||||
throw std::runtime_error{"Insufficient version"};
|
||||
}
|
||||
const std::string_view vendor = reinterpret_cast<const char*>(glGetString(GL_VENDOR));
|
||||
|
@@ -38,6 +38,7 @@
|
||||
namespace OpenGL {
|
||||
|
||||
using Maxwell = Tegra::Engines::Maxwell3D::Regs;
|
||||
using GLvec4 = std::array<GLfloat, 4>;
|
||||
|
||||
using Tegra::Engines::ShaderType;
|
||||
using VideoCore::Surface::PixelFormat;
|
||||
@@ -51,14 +52,7 @@ MICROPROFILE_DEFINE(OpenGL_CacheManagement, "OpenGL", "Cache Management", MP_RGB
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr size_t NUM_CONST_BUFFERS_PER_STAGE = 18;
|
||||
constexpr size_t NUM_CONST_BUFFERS_BYTES_PER_STAGE =
|
||||
NUM_CONST_BUFFERS_PER_STAGE * Maxwell::MaxConstBufferSize;
|
||||
constexpr size_t TOTAL_CONST_BUFFER_BYTES =
|
||||
NUM_CONST_BUFFERS_BYTES_PER_STAGE * Maxwell::MaxShaderStage;
|
||||
|
||||
constexpr size_t NUM_SUPPORTED_VERTEX_ATTRIBUTES = 16;
|
||||
constexpr size_t NUM_SUPPORTED_VERTEX_BINDINGS = 16;
|
||||
|
||||
struct TextureHandle {
|
||||
constexpr TextureHandle(u32 data, bool via_header_index) {
|
||||
|
@@ -398,7 +398,9 @@ void AttachTexture(GLuint fbo, GLenum attachment, const ImageView* image_view) {
|
||||
|
||||
[[nodiscard]] bool IsPixelFormatBGR(PixelFormat format) {
|
||||
switch (format) {
|
||||
case PixelFormat::B5G6R5_UNORM:
|
||||
// TODO: B5G6R5 is currently not rendering after the compute copy.
|
||||
// uncomment when this is resolved.
|
||||
// case PixelFormat::B5G6R5_UNORM:
|
||||
case PixelFormat::B8G8R8A8_UNORM:
|
||||
case PixelFormat::B8G8R8A8_SRGB:
|
||||
return true;
|
||||
@@ -407,6 +409,16 @@ void AttachTexture(GLuint fbo, GLenum attachment, const ImageView* image_view) {
|
||||
}
|
||||
}
|
||||
|
||||
[[nodiscard]] GLenum GetStorageInternalFormat(PixelFormat format) {
|
||||
switch (format) {
|
||||
case PixelFormat::R5G6B5_UNORM:
|
||||
case PixelFormat::B5G6R5_UNORM:
|
||||
return GL_RGB565;
|
||||
default:
|
||||
return GL_RGBA8;
|
||||
}
|
||||
}
|
||||
|
||||
} // Anonymous namespace
|
||||
|
||||
ImageBufferMap::~ImageBufferMap() {
|
||||
@@ -523,6 +535,9 @@ bool TextureCacheRuntime::CanImageBeCopied(const Image& dst, const Image& src) {
|
||||
if (dst.info.type == ImageType::e3D && dst.info.format == PixelFormat::BC4_UNORM) {
|
||||
return false;
|
||||
}
|
||||
if (IsPixelFormatBGR(dst.info.format) || IsPixelFormatBGR(src.info.format)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -531,6 +546,8 @@ void TextureCacheRuntime::EmulateCopyImage(Image& dst, Image& src,
|
||||
if (dst.info.type == ImageType::e3D && dst.info.format == PixelFormat::BC4_UNORM) {
|
||||
ASSERT(src.info.type == ImageType::e3D);
|
||||
util_shaders.CopyBC4(dst, src, copies);
|
||||
} else if (IsPixelFormatBGR(dst.info.format) || IsPixelFormatBGR(src.info.format)) {
|
||||
util_shaders.CopyBGR(dst, src, copies);
|
||||
} else {
|
||||
UNREACHABLE();
|
||||
}
|
||||
@@ -774,6 +791,39 @@ void Image::DownloadMemory(ImageBufferMap& map,
|
||||
}
|
||||
}
|
||||
|
||||
GLuint Image::StorageHandle() noexcept {
|
||||
switch (info.format) {
|
||||
case PixelFormat::A8B8G8R8_SRGB:
|
||||
case PixelFormat::B8G8R8A8_SRGB:
|
||||
case PixelFormat::R5G6B5_UNORM:
|
||||
case PixelFormat::B5G6R5_UNORM:
|
||||
case PixelFormat::BC1_RGBA_SRGB:
|
||||
case PixelFormat::BC2_SRGB:
|
||||
case PixelFormat::BC3_SRGB:
|
||||
case PixelFormat::BC7_SRGB:
|
||||
case PixelFormat::ASTC_2D_4X4_SRGB:
|
||||
case PixelFormat::ASTC_2D_8X8_SRGB:
|
||||
case PixelFormat::ASTC_2D_8X5_SRGB:
|
||||
case PixelFormat::ASTC_2D_5X4_SRGB:
|
||||
case PixelFormat::ASTC_2D_5X5_SRGB:
|
||||
case PixelFormat::ASTC_2D_10X8_SRGB:
|
||||
case PixelFormat::ASTC_2D_6X6_SRGB:
|
||||
case PixelFormat::ASTC_2D_10X10_SRGB:
|
||||
case PixelFormat::ASTC_2D_12X12_SRGB:
|
||||
case PixelFormat::ASTC_2D_8X6_SRGB:
|
||||
case PixelFormat::ASTC_2D_6X5_SRGB:
|
||||
if (store_view.handle != 0) {
|
||||
return store_view.handle;
|
||||
}
|
||||
store_view.Create();
|
||||
glTextureView(store_view.handle, ImageTarget(info), texture.handle,
|
||||
GetStorageInternalFormat(info.format), 0, info.resources.levels, 0,
|
||||
info.resources.layers);
|
||||
return store_view.handle;
|
||||
default:
|
||||
return texture.handle;
|
||||
}
|
||||
}
|
||||
void Image::CopyBufferToImage(const VideoCommon::BufferImageCopy& copy, size_t buffer_offset) {
|
||||
// Compressed formats don't have a pixel format or type
|
||||
const bool is_compressed = gl_format == GL_NONE;
|
||||
@@ -955,13 +1005,7 @@ void ImageView::SetupView(const Device& device, Image& image, ImageViewType view
|
||||
glTextureView(handle, target, parent, internal_format, view_range.base.level,
|
||||
view_range.extent.levels, view_range.base.layer, view_range.extent.layers);
|
||||
if (!info.IsRenderTarget()) {
|
||||
auto swizzle = info.Swizzle();
|
||||
if (IsPixelFormatBGR(image.info.format) || IsPixelFormatBGR(info.format)) {
|
||||
// Explicitly swap the R and B channels of the swizzle.
|
||||
swizzle[0] = SwizzleSource::R;
|
||||
swizzle[2] = SwizzleSource::B;
|
||||
}
|
||||
ApplySwizzle(handle, format, swizzle);
|
||||
ApplySwizzle(handle, format, info.Swizzle());
|
||||
}
|
||||
}
|
||||
if (device.HasDebuggingToolAttached()) {
|
||||
|
@@ -145,6 +145,8 @@ public:
|
||||
|
||||
void DownloadMemory(ImageBufferMap& map, std::span<const VideoCommon::BufferImageCopy> copies);
|
||||
|
||||
GLuint StorageHandle() noexcept;
|
||||
|
||||
GLuint Handle() const noexcept {
|
||||
return texture.handle;
|
||||
}
|
||||
@@ -155,8 +157,8 @@ private:
|
||||
void CopyImageToBuffer(const VideoCommon::BufferImageCopy& copy, size_t buffer_offset);
|
||||
|
||||
OGLTexture texture;
|
||||
OGLTextureView store_view;
|
||||
OGLBuffer buffer;
|
||||
OGLTextureView store_view;
|
||||
GLenum gl_internal_format = GL_NONE;
|
||||
GLenum gl_format = GL_NONE;
|
||||
GLenum gl_type = GL_NONE;
|
||||
|
@@ -4,23 +4,10 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <glad/glad.h>
|
||||
#include "common/common_types.h"
|
||||
#include "common/logging/log.h"
|
||||
#include "video_core/engines/maxwell_3d.h"
|
||||
|
||||
namespace OpenGL {
|
||||
|
||||
using GLvec2 = std::array<GLfloat, 2>;
|
||||
using GLvec3 = std::array<GLfloat, 3>;
|
||||
using GLvec4 = std::array<GLfloat, 4>;
|
||||
|
||||
using GLuvec2 = std::array<GLuint, 2>;
|
||||
using GLuvec3 = std::array<GLuint, 3>;
|
||||
using GLuvec4 = std::array<GLuint, 4>;
|
||||
|
||||
namespace MaxwellToGL {
|
||||
namespace OpenGL::MaxwellToGL {
|
||||
|
||||
using Maxwell = Tegra::Engines::Maxwell3D::Regs;
|
||||
|
||||
@@ -317,26 +304,6 @@ inline GLenum BlendFunc(Maxwell::Blend::Factor factor) {
|
||||
return GL_ZERO;
|
||||
}
|
||||
|
||||
inline GLenum SwizzleSource(Tegra::Texture::SwizzleSource source) {
|
||||
switch (source) {
|
||||
case Tegra::Texture::SwizzleSource::Zero:
|
||||
return GL_ZERO;
|
||||
case Tegra::Texture::SwizzleSource::R:
|
||||
return GL_RED;
|
||||
case Tegra::Texture::SwizzleSource::G:
|
||||
return GL_GREEN;
|
||||
case Tegra::Texture::SwizzleSource::B:
|
||||
return GL_BLUE;
|
||||
case Tegra::Texture::SwizzleSource::A:
|
||||
return GL_ALPHA;
|
||||
case Tegra::Texture::SwizzleSource::OneInt:
|
||||
case Tegra::Texture::SwizzleSource::OneFloat:
|
||||
return GL_ONE;
|
||||
}
|
||||
UNIMPLEMENTED_MSG("Unimplemented swizzle source={}", source);
|
||||
return GL_ZERO;
|
||||
}
|
||||
|
||||
inline GLenum ComparisonOp(Maxwell::ComparisonOp comparison) {
|
||||
switch (comparison) {
|
||||
case Maxwell::ComparisonOp::Never:
|
||||
@@ -493,5 +460,4 @@ inline GLenum ViewportSwizzle(Maxwell::ViewportSwizzle swizzle) {
|
||||
return GL_VIEWPORT_SWIZZLE_POSITIVE_X_NV + static_cast<GLenum>(swizzle);
|
||||
}
|
||||
|
||||
} // namespace MaxwellToGL
|
||||
} // namespace OpenGL
|
||||
} // namespace OpenGL::MaxwellToGL
|
||||
|
@@ -14,6 +14,8 @@
|
||||
#include "video_core/host_shaders/block_linear_unswizzle_2d_comp.h"
|
||||
#include "video_core/host_shaders/block_linear_unswizzle_3d_comp.h"
|
||||
#include "video_core/host_shaders/opengl_copy_bc4_comp.h"
|
||||
#include "video_core/host_shaders/opengl_copy_bgr16_comp.h"
|
||||
#include "video_core/host_shaders/opengl_copy_bgra_comp.h"
|
||||
#include "video_core/host_shaders/pitch_unswizzle_comp.h"
|
||||
#include "video_core/renderer_opengl/gl_resource_manager.h"
|
||||
#include "video_core/renderer_opengl/gl_shader_manager.h"
|
||||
@@ -36,6 +38,7 @@ using VideoCommon::SwizzleParameters;
|
||||
using VideoCommon::Accelerated::MakeBlockLinearSwizzle2DParams;
|
||||
using VideoCommon::Accelerated::MakeBlockLinearSwizzle3DParams;
|
||||
using VideoCore::Surface::BytesPerBlock;
|
||||
using VideoCore::Surface::PixelFormat;
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -55,7 +58,9 @@ UtilShaders::UtilShaders(ProgramManager& program_manager_)
|
||||
block_linear_unswizzle_2d_program(MakeProgram(BLOCK_LINEAR_UNSWIZZLE_2D_COMP)),
|
||||
block_linear_unswizzle_3d_program(MakeProgram(BLOCK_LINEAR_UNSWIZZLE_3D_COMP)),
|
||||
pitch_unswizzle_program(MakeProgram(PITCH_UNSWIZZLE_COMP)),
|
||||
copy_bc4_program(MakeProgram(OPENGL_COPY_BC4_COMP)) {
|
||||
copy_bc4_program(MakeProgram(OPENGL_COPY_BC4_COMP)),
|
||||
copy_bgr16_program(MakeProgram(OPENGL_COPY_BGR16_COMP)),
|
||||
copy_bgra_program(MakeProgram(OPENGL_COPY_BGRA_COMP)) {
|
||||
const auto swizzle_table = Tegra::Texture::MakeSwizzleTable();
|
||||
swizzle_table_buffer.Create();
|
||||
glNamedBufferStorage(swizzle_table_buffer.handle, sizeof(swizzle_table), &swizzle_table, 0);
|
||||
@@ -93,7 +98,7 @@ void UtilShaders::BlockLinearUpload2D(Image& image, const ImageBufferMap& map,
|
||||
glUniform1ui(7, params.block_height_mask);
|
||||
glBindBufferRange(GL_SHADER_STORAGE_BUFFER, BINDING_INPUT_BUFFER, map.buffer, input_offset,
|
||||
image.guest_size_bytes - swizzle.buffer_offset);
|
||||
glBindImageTexture(BINDING_OUTPUT_IMAGE, image.Handle(), swizzle.level, GL_TRUE, 0,
|
||||
glBindImageTexture(BINDING_OUTPUT_IMAGE, image.StorageHandle(), swizzle.level, GL_TRUE, 0,
|
||||
GL_WRITE_ONLY, store_format);
|
||||
glDispatchCompute(num_dispatches_x, num_dispatches_y, image.info.resources.layers);
|
||||
}
|
||||
@@ -134,7 +139,7 @@ void UtilShaders::BlockLinearUpload3D(Image& image, const ImageBufferMap& map,
|
||||
glUniform1ui(9, params.block_depth_mask);
|
||||
glBindBufferRange(GL_SHADER_STORAGE_BUFFER, BINDING_INPUT_BUFFER, map.buffer, input_offset,
|
||||
image.guest_size_bytes - swizzle.buffer_offset);
|
||||
glBindImageTexture(BINDING_OUTPUT_IMAGE, image.Handle(), swizzle.level, GL_TRUE, 0,
|
||||
glBindImageTexture(BINDING_OUTPUT_IMAGE, image.StorageHandle(), swizzle.level, GL_TRUE, 0,
|
||||
GL_WRITE_ONLY, store_format);
|
||||
glDispatchCompute(num_dispatches_x, num_dispatches_y, num_dispatches_z);
|
||||
}
|
||||
@@ -164,7 +169,8 @@ void UtilShaders::PitchUpload(Image& image, const ImageBufferMap& map,
|
||||
glUniform2i(LOC_DESTINATION, 0, 0);
|
||||
glUniform1ui(LOC_BYTES_PER_BLOCK, bytes_per_block);
|
||||
glUniform1ui(LOC_PITCH, pitch);
|
||||
glBindImageTexture(BINDING_OUTPUT_IMAGE, image.Handle(), 0, GL_FALSE, 0, GL_WRITE_ONLY, format);
|
||||
glBindImageTexture(BINDING_OUTPUT_IMAGE, image.StorageHandle(), 0, GL_FALSE, 0, GL_WRITE_ONLY,
|
||||
format);
|
||||
for (const SwizzleParameters& swizzle : swizzles) {
|
||||
const Extent3D num_tiles = swizzle.num_tiles;
|
||||
const size_t input_offset = swizzle.buffer_offset + map.offset;
|
||||
@@ -195,15 +201,41 @@ void UtilShaders::CopyBC4(Image& dst_image, Image& src_image, std::span<const Im
|
||||
|
||||
glUniform3ui(LOC_SRC_OFFSET, copy.src_offset.x, copy.src_offset.y, copy.src_offset.z);
|
||||
glUniform3ui(LOC_DST_OFFSET, copy.dst_offset.x, copy.dst_offset.y, copy.dst_offset.z);
|
||||
glBindImageTexture(BINDING_INPUT_IMAGE, src_image.Handle(), copy.src_subresource.base_level,
|
||||
GL_FALSE, 0, GL_READ_ONLY, GL_RG32UI);
|
||||
glBindImageTexture(BINDING_OUTPUT_IMAGE, dst_image.Handle(),
|
||||
glBindImageTexture(BINDING_INPUT_IMAGE, src_image.StorageHandle(),
|
||||
copy.src_subresource.base_level, GL_FALSE, 0, GL_READ_ONLY, GL_RG32UI);
|
||||
glBindImageTexture(BINDING_OUTPUT_IMAGE, dst_image.StorageHandle(),
|
||||
copy.dst_subresource.base_level, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA8UI);
|
||||
glDispatchCompute(copy.extent.width, copy.extent.height, copy.extent.depth);
|
||||
}
|
||||
program_manager.RestoreGuestCompute();
|
||||
}
|
||||
|
||||
void UtilShaders::CopyBGR(Image& dst_image, Image& src_image,
|
||||
std::span<const VideoCommon::ImageCopy> copies) {
|
||||
static constexpr GLuint BINDING_INPUT_IMAGE = 0;
|
||||
static constexpr GLuint BINDING_OUTPUT_IMAGE = 1;
|
||||
|
||||
GLenum format{};
|
||||
const u32 bytes_per_block = BytesPerBlock(dst_image.info.format);
|
||||
if (bytes_per_block == 2) {
|
||||
// BGR565 Copy
|
||||
program_manager.BindHostCompute(copy_bgr16_program.handle);
|
||||
format = GL_R16UI;
|
||||
} else if (bytes_per_block == 4) {
|
||||
// BGRA8 Copy
|
||||
program_manager.BindHostCompute(copy_bgra_program.handle);
|
||||
format = GL_RGBA8;
|
||||
}
|
||||
for (const ImageCopy& copy : copies) {
|
||||
glBindImageTexture(BINDING_INPUT_IMAGE, src_image.StorageHandle(),
|
||||
copy.src_subresource.base_level, GL_FALSE, 0, GL_READ_ONLY, format);
|
||||
glBindImageTexture(BINDING_OUTPUT_IMAGE, dst_image.StorageHandle(),
|
||||
copy.dst_subresource.base_level, GL_FALSE, 0, GL_WRITE_ONLY, format);
|
||||
glDispatchCompute(copy.extent.width, copy.extent.height, copy.extent.depth);
|
||||
}
|
||||
program_manager.RestoreGuestCompute();
|
||||
}
|
||||
|
||||
GLenum StoreFormat(u32 bytes_per_block) {
|
||||
switch (bytes_per_block) {
|
||||
case 1:
|
||||
|
@@ -36,6 +36,9 @@ public:
|
||||
void CopyBC4(Image& dst_image, Image& src_image,
|
||||
std::span<const VideoCommon::ImageCopy> copies);
|
||||
|
||||
void CopyBGR(Image& dst_image, Image& src_image,
|
||||
std::span<const VideoCommon::ImageCopy> copies);
|
||||
|
||||
private:
|
||||
ProgramManager& program_manager;
|
||||
|
||||
@@ -45,6 +48,8 @@ private:
|
||||
OGLProgram block_linear_unswizzle_3d_program;
|
||||
OGLProgram pitch_unswizzle_program;
|
||||
OGLProgram copy_bc4_program;
|
||||
OGLProgram copy_bgr16_program;
|
||||
OGLProgram copy_bgra_program;
|
||||
};
|
||||
|
||||
GLenum StoreFormat(u32 bytes_per_block);
|
||||
|
Reference in New Issue
Block a user