renderer_opengl: Port scaled upload/download code from vulkan
This commit is contained in:
@ -80,7 +80,7 @@ Driver::Driver(bool gles, bool enable_debug) : is_gles{gles} {
|
||||
* https://developer.qualcomm.com/comment/11845
|
||||
*/
|
||||
if (!gles) {
|
||||
glEnable(GL_DEBUG_OUTPUT);
|
||||
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
|
||||
glDebugMessageCallback(DebugHandler, nullptr);
|
||||
}
|
||||
#endif
|
||||
|
@ -385,7 +385,7 @@ void Surface::Upload(const VideoCore::BufferTextureCopy& upload, const StagingBu
|
||||
|
||||
const bool is_scaled = res_scale != 1;
|
||||
if (is_scaled) {
|
||||
ScaledUpload(upload);
|
||||
ScaledUpload(upload, staging);
|
||||
} else {
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, texture.handle);
|
||||
@ -434,24 +434,66 @@ void Surface::Download(const VideoCore::BufferTextureCopy& download, const Stagi
|
||||
glPixelStorei(GL_PACK_ROW_LENGTH, 0);
|
||||
}
|
||||
|
||||
void Surface::ScaledUpload(const VideoCore::BufferTextureCopy& upload,
|
||||
const StagingBuffer& staging) {
|
||||
const u32 rect_width = upload.texture_rect.GetWidth();
|
||||
const u32 rect_height = upload.texture_rect.GetHeight();
|
||||
const auto scaled_rect = upload.texture_rect * res_scale;
|
||||
const auto unscaled_rect = VideoCore::Rect2D{0, rect_height, rect_width, 0};
|
||||
|
||||
SurfaceParams unscaled_params = *this;
|
||||
unscaled_params.width = rect_width;
|
||||
unscaled_params.stride = rect_width;
|
||||
unscaled_params.height = rect_height;
|
||||
unscaled_params.res_scale = 1;
|
||||
Surface unscaled_surface{unscaled_params, runtime};
|
||||
|
||||
const VideoCore::BufferTextureCopy unscaled_upload = {.buffer_offset = upload.buffer_offset,
|
||||
.buffer_size = upload.buffer_size,
|
||||
.texture_rect = unscaled_rect};
|
||||
|
||||
unscaled_surface.Upload(unscaled_upload, staging);
|
||||
|
||||
const auto& filterer = runtime.GetFilterer();
|
||||
if (!filterer.Filter(unscaled_surface.texture, unscaled_rect, texture, scaled_rect, type)) {
|
||||
const VideoCore::TextureBlit blit = {.src_level = 0,
|
||||
.dst_level = upload.texture_level,
|
||||
.src_layer = 0,
|
||||
.dst_layer = 0,
|
||||
.src_rect = unscaled_rect,
|
||||
.dst_rect = scaled_rect};
|
||||
|
||||
// If filtering fails, resort to normal blitting
|
||||
runtime.BlitTextures(unscaled_surface, *this, blit);
|
||||
}
|
||||
}
|
||||
|
||||
void Surface::ScaledDownload(const VideoCore::BufferTextureCopy& download) {
|
||||
const u32 rect_width = download.texture_rect.GetWidth();
|
||||
const u32 rect_height = download.texture_rect.GetHeight();
|
||||
const VideoCore::Rect2D scaled_rect = download.texture_rect * res_scale;
|
||||
const VideoCore::Rect2D unscaled_rect = VideoCore::Rect2D{0, rect_height, rect_width, 0};
|
||||
|
||||
// Allocate an unscaled texture that fits the download rectangle to use as a blit destination
|
||||
OGLTexture unscaled_tex =
|
||||
runtime.Allocate(rect_width, rect_height, pixel_format, VideoCore::TextureType::Texture2D);
|
||||
runtime.BindFramebuffer(GL_DRAW_FRAMEBUFFER, 0, GL_TEXTURE_2D, type, unscaled_tex);
|
||||
runtime.BindFramebuffer(GL_READ_FRAMEBUFFER, download.texture_level, GL_TEXTURE_2D, type,
|
||||
texture);
|
||||
SurfaceParams unscaled_params = *this;
|
||||
unscaled_params.width = rect_width;
|
||||
unscaled_params.stride = rect_width;
|
||||
unscaled_params.height = rect_height;
|
||||
unscaled_params.res_scale = 1;
|
||||
Surface unscaled_surface{unscaled_params, runtime};
|
||||
|
||||
const VideoCore::TextureBlit blit = {.src_level = download.texture_level,
|
||||
.dst_level = 0,
|
||||
.src_layer = 0,
|
||||
.dst_layer = 0,
|
||||
.src_rect = scaled_rect,
|
||||
.dst_rect = unscaled_rect};
|
||||
|
||||
// Blit the scaled rectangle to the unscaled texture
|
||||
const VideoCore::Rect2D scaled_rect = download.texture_rect * res_scale;
|
||||
glBlitFramebuffer(scaled_rect.left, scaled_rect.bottom, scaled_rect.right, scaled_rect.top, 0,
|
||||
0, rect_width, rect_height, MakeBufferMask(type), GL_LINEAR);
|
||||
runtime.BlitTextures(*this, unscaled_surface, blit);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, unscaled_tex.handle);
|
||||
glBindTexture(GL_TEXTURE_2D, unscaled_surface.texture.handle);
|
||||
|
||||
const auto& tuple = runtime.GetFormatTuple(pixel_format);
|
||||
if (driver.IsOpenGLES()) {
|
||||
@ -463,32 +505,4 @@ void Surface::ScaledDownload(const VideoCore::BufferTextureCopy& download) {
|
||||
}
|
||||
}
|
||||
|
||||
void Surface::ScaledUpload(const VideoCore::BufferTextureCopy& upload) {
|
||||
const u32 rect_width = upload.texture_rect.GetWidth();
|
||||
const u32 rect_height = upload.texture_rect.GetHeight();
|
||||
|
||||
OGLTexture unscaled_tex =
|
||||
runtime.Allocate(rect_width, rect_height, pixel_format, VideoCore::TextureType::Texture2D);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, unscaled_tex.handle);
|
||||
|
||||
const auto& tuple = runtime.GetFormatTuple(pixel_format);
|
||||
glTexSubImage2D(GL_TEXTURE_2D, upload.texture_level, 0, 0, rect_width, rect_height,
|
||||
tuple.format, tuple.type, 0);
|
||||
|
||||
const auto scaled_rect = upload.texture_rect * res_scale;
|
||||
const auto unscaled_rect = VideoCore::Rect2D{0, rect_height, rect_width, 0};
|
||||
const auto& filterer = runtime.GetFilterer();
|
||||
if (!filterer.Filter(unscaled_tex, unscaled_rect, texture, scaled_rect, type)) {
|
||||
runtime.BindFramebuffer(GL_READ_FRAMEBUFFER, 0, GL_TEXTURE_2D, type, unscaled_tex);
|
||||
runtime.BindFramebuffer(GL_DRAW_FRAMEBUFFER, upload.texture_level, GL_TEXTURE_2D, type,
|
||||
texture);
|
||||
|
||||
// If filtering fails, resort to normal blitting
|
||||
glBlitFramebuffer(0, 0, rect_width, rect_height, upload.texture_rect.left,
|
||||
upload.texture_rect.bottom, upload.texture_rect.right,
|
||||
upload.texture_rect.top, MakeBufferMask(type), GL_LINEAR);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace OpenGL
|
||||
|
@ -152,12 +152,12 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
/// Uploads pixel data to scaled texture
|
||||
void ScaledUpload(const VideoCore::BufferTextureCopy& upload, const StagingBuffer& staging);
|
||||
|
||||
/// Downloads scaled image by downscaling the requested rectangle
|
||||
void ScaledDownload(const VideoCore::BufferTextureCopy& download);
|
||||
|
||||
/// Uploads pixel data to scaled texture
|
||||
void ScaledUpload(const VideoCore::BufferTextureCopy& upload);
|
||||
|
||||
private:
|
||||
TextureRuntime& runtime;
|
||||
const Driver& driver;
|
||||
|
Reference in New Issue
Block a user