Skip to content

Commit

Permalink
Merge pull request #99 from Swordfish90/add-cut2-upscaling-shader
Browse files Browse the repository at this point in the history
Add CUT2 upscaling shader
  • Loading branch information
Swordfish90 authored Mar 9, 2023
2 parents 45f4e88 + eab75f4 commit 3b054fc
Show file tree
Hide file tree
Showing 18 changed files with 1,185 additions and 394 deletions.
2 changes: 2 additions & 0 deletions libretrodroid/src/main/cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ add_library(libretrodroid SHARED
video.cpp
renderers/renderer.h
renderers/renderer.cpp
renderers/es3/es3utils.h
renderers/es3/es3utils.cpp
renderers/es3/framebufferrenderer.h
renderers/es3/framebufferrenderer.cpp
renderers/es2/imagerendereres2.h
Expand Down
28 changes: 10 additions & 18 deletions libretrodroid/src/main/cpp/libretrodroid.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -187,32 +187,24 @@ void LibretroDroid::onSurfaceCreated() {

video = nullptr;

Renderer *renderer;
if (Environment::getInstance().isUseHwAcceleration()) {
renderer = new FramebufferRenderer(
system_av_info.geometry.base_width,
system_av_info.geometry.base_height,
Environment::getInstance().isUseDepth(),
Environment::getInstance().isUseStencil()
);
} else {
if (openglESVersion >= 3) {
renderer = new ImageRendererES3();
} else {
renderer = new ImageRendererES2();
}
}
Video::RenderingOptions renderingOptions {
Environment::getInstance().isUseHwAcceleration(),
system_av_info.geometry.base_width,
system_av_info.geometry.base_height,
Environment::getInstance().isUseDepth(),
Environment::getInstance().isUseStencil(),
openglESVersion,
Environment::getInstance().getPixelFormat()
};

auto newVideo = new Video(
renderer,
renderingOptions,
fragmentShaderConfig,
Environment::getInstance().isBottomLeftOrigin(),
Environment::getInstance().getScreenRotation(),
skipDuplicateFrames
);

renderer->setPixelFormat(Environment::getInstance().getPixelFormat());

video = std::unique_ptr<Video>(newVideo);

if (Environment::getInstance().getHwContextReset() != nullptr) {
Expand Down
9 changes: 7 additions & 2 deletions libretrodroid/src/main/cpp/renderers/es2/imagerendereres2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,13 @@ bool ImageRendererES2::rendersInVideoCallback() {
return false;
}

void ImageRendererES2::setLinear(bool linear) {
this->linear = linear;
void ImageRendererES2::setShaders(ShaderManager::Chain shaders) {
this->linear = shaders.linearTexture;
}

// ES2 Renderer doesn't currently support multiple passes.
Renderer::PassData ImageRendererES2::getPassData(unsigned int layer) {
return { };
}

} //namespace libretrodroid
5 changes: 4 additions & 1 deletion libretrodroid/src/main/cpp/renderers/es2/imagerendereres2.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,10 @@ class ImageRendererES2: public Renderer {
void setPixelFormat(int pixelFormat) override;
void updateRenderedResolution(unsigned int width, unsigned int height) override;
bool rendersInVideoCallback() override;
void setLinear(bool linear) override;

void setShaders(ShaderManager::Chain shaders) override;

PassData getPassData(unsigned int layer) override;

private:
void convertDataFromRGB8888(const void* pixelData, size_t size);
Expand Down
121 changes: 121 additions & 0 deletions libretrodroid/src/main/cpp/renderers/es3/es3utils.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
/*
* Copyright (C) 2022 Filippo Scognamiglio
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

#include "es3utils.h"

#include "../../log.h"

namespace libretrodroid {

std::unique_ptr<ES3Utils::Framebuffer> ES3Utils::createFramebuffer(
unsigned int width,
unsigned int height,
bool linear,
bool includeDepth,
bool includeStencil
) {
auto result = std::make_unique<Framebuffer>();
result->width = width;
result->height = height;

glGenFramebuffers(1, &result->framebuffer);
glGenTextures(1, &result->texture);

if (includeDepth) {
unsigned int depthBuffer;
glGenRenderbuffers(1, &depthBuffer);
result->depth = depthBuffer;
}

glBindFramebuffer(GL_FRAMEBUFFER, result->framebuffer);

glBindTexture(GL_TEXTURE_2D, result->texture);
glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, width, height);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, linear ? GL_LINEAR : GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, linear ? GL_LINEAR : GL_NEAREST);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, result->texture, 0);

if (includeDepth) {
glBindRenderbuffer(GL_RENDERBUFFER, result->depth.value());
glRenderbufferStorage(
GL_RENDERBUFFER,
includeStencil ? GL_DEPTH24_STENCIL8 : GL_DEPTH_COMPONENT16,
width,
height
);
glFramebufferRenderbuffer(
GL_FRAMEBUFFER,
includeStencil ? GL_DEPTH_STENCIL_ATTACHMENT : GL_DEPTH_ATTACHMENT,
GL_RENDERBUFFER,
result->depth.value()
);
}

if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
LOGE("Error while creating framebuffer. Leaving!");
throw std::runtime_error("Cannot create framebuffer");
}

glBindTexture(GL_TEXTURE_2D, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBindRenderbuffer(GL_RENDERBUFFER, 0);

return result;
}

void ES3Utils::deleteFramebuffer(std::unique_ptr<ES3Utils::Framebuffer> data) {
if (data == nullptr) {
return;
}

glDeleteFramebuffers(1, &data->framebuffer);
glDeleteTextures(1, &data->texture);

if (data->depth.has_value()) {
glDeleteRenderbuffers(1, &data->depth.value());
}
}

std::unique_ptr<ES3Utils::Framebuffers> ES3Utils::buildShaderPasses(
unsigned int width,
unsigned int height,
const libretrodroid::ShaderManager::Chain &shaders
) {
auto result = std::make_unique<std::vector<std::unique_ptr<ES3Utils::Framebuffer>>>();
auto passes = shaders.passes;

for (int i = 0; i < passes.size() - 1; ++i) {
auto pass = passes[i];
unsigned int passWidth = std::lround(width * pass.scale);
unsigned int passHeight = std::lround(height * pass.scale);

std::unique_ptr<ES3Utils::Framebuffer> data = ES3Utils::createFramebuffer(
passWidth,
passHeight,
pass.linear,
false,
false
);
result->push_back(std::move(data));
}

return result;
}

} //namespace libretrodroid
64 changes: 64 additions & 0 deletions libretrodroid/src/main/cpp/renderers/es3/es3utils.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*
* Copyright (C) 2022 Filippo Scognamiglio
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

#ifndef LIBRETRODROID_ES3UTILS_H
#define LIBRETRODROID_ES3UTILS_H

#include <optional>
#include <memory>

#include "GLES3/gl3.h"
#include "GLES3/gl3ext.h"

#include "../../shadermanager.h"

namespace libretrodroid {

class ES3Utils {

public:
struct Framebuffer {
unsigned int framebuffer = 0;
unsigned int texture = 0;
std::optional<unsigned int> depth = std::nullopt;
unsigned int width = 0;
unsigned int height = 0;
};

public:
using Framebuffers = std::vector<std::unique_ptr<ES3Utils::Framebuffer>>;

static std::unique_ptr<Framebuffers> buildShaderPasses(
unsigned int width,
unsigned int height,
const ShaderManager::Chain &shaders
);

static std::unique_ptr<ES3Utils::Framebuffer> createFramebuffer(
unsigned int width,
unsigned int height,
bool linear,
bool includeDepth,
bool includeStencil
);

static void deleteFramebuffer(std::unique_ptr<Framebuffer> data);
};

}

#endif //LIBRETRODROID_ES3UTILS_H
Loading

0 comments on commit 3b054fc

Please sign in to comment.