Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/Cafe/HW/Latte/Core/Latte.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ struct LatteGPUState_t
// temporary (replace with proper solution later)
bool tvBufferUsesSRGB;
bool drcBufferUsesSRGB;
float tvGamma = 0.0f;
float drcGamma = 0.0f;
// draw state
bool activeShaderHasError; // if try, at least one currently bound shader stage has an error and cannot be used for drawing
bool repeatTextureInitialization; // if set during rendertarget or texture initialization, repeat the process (textures likely have been invalidated)
Expand Down
10 changes: 0 additions & 10 deletions src/Cafe/HW/Latte/Core/LatteTextureLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -120,16 +120,6 @@ uint8* LatteTextureLoader_getInputLinearOptimized(LatteTextureLoaderCtx* texture

#define LatteTextureLoader_getInputLinearOptimized_(__textureLoader,__x,__y,__stepX,__stepY,__bpp,__sliceIndex,__numSlices,__sample,__pitch,__height) (textureLoader->inputData+((__x/__stepX) + __pitch * (__y/__stepY) + (__sliceIndex + __numSlices * __sample) * __height * __pitch)*(__bpp/8))

float SRGB_to_RGB(float cs)
{
float cl;
if (cs <= 0.04045f)
cl = cs / 12.92f;
else
cl = powf(((cs + 0.055f) / 1.055f), 2.4f);
return cl;
}

void decodeBC1Block(uint8* inputData, float* output4x4RGBA)
{
// read colors
Expand Down
8 changes: 3 additions & 5 deletions src/Cafe/HW/Latte/Renderer/OpenGL/OpenGLRenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -603,7 +603,7 @@ void OpenGLRenderer::DrawBackbufferQuad(LatteTextureView* texView, RendererOutpu
shader_unbind(RendererShader::ShaderType::kGeometry);
shader_bind(shader->GetVertexShader());
shader_bind(shader->GetFragmentShader());
shader->SetUniformParameters(*texView, {imageWidth, imageHeight});
shader->SetUniformParameters(*texView, {imageWidth, imageHeight}, padView);

// set viewport
glViewportIndexedf(0, imageX, imageY, imageWidth, imageHeight);
Expand All @@ -620,14 +620,12 @@ void OpenGLRenderer::DrawBackbufferQuad(LatteTextureView* texView, RendererOutpu
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, useLinearTexFilter ? GL_LINEAR : GL_NEAREST);
texViewGL->samplerState.filterMag = 0xFFFFFFFF;

if ((!padView && !LatteGPUState.tvBufferUsesSRGB) || (padView && !LatteGPUState.drcBufferUsesSRGB))
glDisable(GL_FRAMEBUFFER_SRGB);
glDisable(GL_FRAMEBUFFER_SRGB);

uint16 indexData[6] = { 0,1,2,3,4,5 };
glDrawRangeElements(GL_TRIANGLES, 0, 5, 6, GL_UNSIGNED_SHORT, indexData);

if ((!padView && !LatteGPUState.tvBufferUsesSRGB) || (padView && !LatteGPUState.drcBufferUsesSRGB))
glEnable(GL_FRAMEBUFFER_SRGB);
glEnable(GL_FRAMEBUFFER_SRGB);

// unbind texture
texture_bindAndActivate(nullptr, 0);
Expand Down
10 changes: 10 additions & 0 deletions src/Cafe/HW/Latte/Renderer/OpenGL/RendererShaderGL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,16 @@ sint32 RendererShaderGL::GetUniformLocation(const char* name)
return glGetUniformLocation(m_program, name);
}

void RendererShaderGL::SetUniform1i(sint32 location, sint32 value)
{
glProgramUniform1i(m_program, location, value);
}

void RendererShaderGL::SetUniform1f(sint32 location, float value)
{
glProgramUniform1f(m_program, location, value);
}

void RendererShaderGL::SetUniform2fv(sint32 location, void* data, sint32 count)
{
glProgramUniform2fv(m_program, location, count, (const GLfloat*)data);
Expand Down
3 changes: 3 additions & 0 deletions src/Cafe/HW/Latte/Renderer/OpenGL/RendererShaderGL.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ class RendererShaderGL : public RendererShader
GLuint GetShaderObject() const { cemu_assert_debug(m_isCompiled); return m_shader_object; }

sint32 GetUniformLocation(const char* name) override;

void SetUniform1i(sint32 location, sint32 value) override;
void SetUniform1f(sint32 location, float value) override;
void SetUniform2fv(sint32 location, void* data, sint32 count) override;
void SetUniform4iv(sint32 location, void* data, sint32 count) override;

Expand Down
67 changes: 63 additions & 4 deletions src/Cafe/HW/Latte/Renderer/RendererOuputShader.cpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
#include "Cafe/HW/Latte/Renderer/RendererOuputShader.h"
#include "Cafe/HW/Latte/Renderer/OpenGL/OpenGLRenderer.h"
#include "config/ActiveSettings.h"

const std::string RendererOutputShader::s_copy_shader_source =
R"(
void main()
void outputShader()
{
colorOut0 = vec4(texture(textureSrc, passUV).rgb,1.0);
}
Expand Down Expand Up @@ -49,7 +50,7 @@ vec4 bcFilter(vec2 uv, vec4 texelSize)
mix(sample1, sample0, sx), sy);
}

void main(){
void outputShader(){
vec4 texelSize = vec4( 1.0 / textureSrcResolution.xy, textureSrcResolution.xy);
colorOut0 = vec4(bcFilter(passUV, texelSize).rgb,1.0);
}
Expand Down Expand Up @@ -108,7 +109,7 @@ vec3 BicubicHermiteTexture(vec2 uv, vec4 texelSize)
return CubicHermite(CP0X, CP1X, CP2X, CP3X, frac.y);
}

void main(){
void outputShader(){
vec4 texelSize = vec4( 1.0 / textureSrcResolution.xy, textureSrcResolution.xy);
colorOut0 = vec4(BicubicHermiteTexture(passUV, texelSize), 1.0);
}
Expand All @@ -135,14 +136,20 @@ RendererOutputShader::RendererOutputShader(const std::string& vertex_source, con
m_uniformLocations[0].m_loc_textureSrcResolution = m_vertex_shader->GetUniformLocation("textureSrcResolution");
m_uniformLocations[0].m_loc_nativeResolution = m_vertex_shader->GetUniformLocation("nativeResolution");
m_uniformLocations[0].m_loc_outputResolution = m_vertex_shader->GetUniformLocation("outputResolution");
m_uniformLocations[0].m_loc_applySRGBEncoding = m_vertex_shader->GetUniformLocation("applySRGBEncoding");
m_uniformLocations[0].m_loc_targetGamma = m_fragment_shader->GetUniformLocation("targetGamma");
m_uniformLocations[0].m_loc_displayGamma = m_fragment_shader->GetUniformLocation("displayGamma");

m_uniformLocations[1].m_loc_textureSrcResolution = m_fragment_shader->GetUniformLocation("textureSrcResolution");
m_uniformLocations[1].m_loc_nativeResolution = m_fragment_shader->GetUniformLocation("nativeResolution");
m_uniformLocations[1].m_loc_outputResolution = m_fragment_shader->GetUniformLocation("outputResolution");
m_uniformLocations[1].m_loc_applySRGBEncoding = m_fragment_shader->GetUniformLocation("applySRGBEncoding");
m_uniformLocations[1].m_loc_targetGamma = m_fragment_shader->GetUniformLocation("targetGamma");
m_uniformLocations[1].m_loc_displayGamma = m_fragment_shader->GetUniformLocation("displayGamma");
}
}

void RendererOutputShader::SetUniformParameters(const LatteTextureView& texture_view, const Vector2i& output_res) const
void RendererOutputShader::SetUniformParameters(const LatteTextureView& texture_view, const Vector2i& output_res, const bool padView) const
{
sint32 effectiveWidth, effectiveHeight;
texture_view.baseTexture->GetEffectiveSize(effectiveWidth, effectiveHeight, 0);
Expand All @@ -168,6 +175,22 @@ void RendererOutputShader::SetUniformParameters(const LatteTextureView& texture_
res[1] = (float)output_res.y;
shader->SetUniform2fv(locations.m_loc_outputResolution, res, 1);
}

if (locations.m_loc_applySRGBEncoding != -1)
{
shader->SetUniform1i(locations.m_loc_applySRGBEncoding, padView ? LatteGPUState.drcBufferUsesSRGB : LatteGPUState.tvBufferUsesSRGB);
}

if (locations.m_loc_targetGamma != -1)
{
shader->SetUniform1f(locations.m_loc_targetGamma, padView ? ActiveSettings::GetDRCGamma() : ActiveSettings::GetTVGamma());
}

if (locations.m_loc_displayGamma != -1)
{
shader->SetUniform1f(locations.m_loc_displayGamma, GetConfig().userDisplayGamma);
}

};
setUniforms(m_vertex_shader.get(), m_uniformLocations[0]);
setUniforms(m_fragment_shader.get(), m_uniformLocations[1]);
Expand Down Expand Up @@ -290,16 +313,52 @@ layout(push_constant) uniform pc {
vec2 textureSrcResolution;
vec2 nativeResolution;
vec2 outputResolution;
bool applySRGBEncoding; // true = app requested sRGB encoding
float targetGamma;
float displayGamma;
};
#else
uniform vec2 textureSrcResolution;
uniform vec2 nativeResolution;
uniform vec2 outputResolution;
uniform bool applySRGBEncoding;
uniform float targetGamma;
uniform float displayGamma;
#endif

layout(location = 0) smooth in vec2 passUV;
layout(binding = 0) uniform sampler2D textureSrc;
layout(location = 0) out vec4 colorOut0;

float sRGBEncode(float linear)
{
if(linear <= 0.0031308)
return 12.92f * linear;
else
return 1.055f * pow(linear, 1.0f / 2.4f) - 0.055f;

}

vec3 sRGBEncode(vec3 linear)
{
return vec3(sRGBEncode(linear.r), sRGBEncode(linear.g), sRGBEncode(linear.b));
}

// fwd. declaration
void outputShader();
void main()
{
outputShader(); // sets colorOut0
if(applySRGBEncoding)
colorOut0 = vec4(sRGBEncode(colorOut0.rgb), 1.0f);

if (displayGamma > 0.0f)
colorOut0 = pow(colorOut0, vec4(targetGamma / displayGamma) );
else
colorOut0 = vec4( sRGBEncode( pow(colorOut0.rgb, vec3(targetGamma)) ), 1.0f);

}

)" + shaderSrc;
}
void RendererOutputShader::InitializeStatic()
Expand Down
5 changes: 4 additions & 1 deletion src/Cafe/HW/Latte/Renderer/RendererOuputShader.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class RendererOutputShader
RendererOutputShader(const std::string& vertex_source, const std::string& fragment_source);
virtual ~RendererOutputShader() = default;

void SetUniformParameters(const LatteTextureView& texture_view, const Vector2i& output_res) const;
void SetUniformParameters(const LatteTextureView& texture_view, const Vector2i& output_res, const bool padView) const;

RendererShader* GetVertexShader() const
{
Expand Down Expand Up @@ -55,6 +55,9 @@ class RendererOutputShader
sint32 m_loc_textureSrcResolution = -1;
sint32 m_loc_nativeResolution = -1;
sint32 m_loc_outputResolution = -1;
sint32 m_loc_applySRGBEncoding = -1;
sint32 m_loc_targetGamma = -1;
sint32 m_loc_displayGamma = -1;
} m_uniformLocations[2]{};

private:
Expand Down
2 changes: 2 additions & 0 deletions src/Cafe/HW/Latte/Renderer/RendererShader.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ class RendererShader

virtual sint32 GetUniformLocation(const char* name) = 0;

virtual void SetUniform1i(sint32 location, sint32 value) = 0;
virtual void SetUniform1f(sint32 location, float value) = 0;
virtual void SetUniform2fv(sint32 location, void* data, sint32 count) = 0;
virtual void SetUniform4iv(sint32 location, void* data, sint32 count) = 0;

Expand Down
10 changes: 10 additions & 0 deletions src/Cafe/HW/Latte/Renderer/Vulkan/RendererShaderVk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,16 @@ sint32 RendererShaderVk::GetUniformLocation(const char* name)
return 0;
}

void RendererShaderVk::SetUniform1i(sint32 location, sint32 value)
{
cemu_assert_suspicious();
}

void RendererShaderVk::SetUniform1f(sint32 location, float value)
{
cemu_assert_suspicious();
}

void RendererShaderVk::SetUniform2fv(sint32 location, void* data, sint32 count)
{
cemu_assert_suspicious();
Expand Down
2 changes: 2 additions & 0 deletions src/Cafe/HW/Latte/Renderer/Vulkan/RendererShaderVk.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ class RendererShaderVk : public RendererShader
static void Shutdown();

sint32 GetUniformLocation(const char* name) override;
void SetUniform1i(sint32 location, sint32 value) override;
void SetUniform1f(sint32 location, float value) override;
void SetUniform2fv(sint32 location, void* data, sint32 count) override;
void SetUniform4iv(sint32 location, void* data, sint32 count) override;
VkShaderModule& GetShaderModule() { return m_shader_module; }
Expand Down
14 changes: 2 additions & 12 deletions src/Cafe/HW/Latte/Renderer/Vulkan/SwapchainInfoVk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -319,18 +319,8 @@ VkSurfaceFormatKHR SwapchainInfoVk::ChooseSurfaceFormat(const std::vector<VkSurf

for (const auto& format : formats)
{
bool useSRGB = mainWindow ? LatteGPUState.tvBufferUsesSRGB : LatteGPUState.drcBufferUsesSRGB;

if (useSRGB)
{
if (format.format == VK_FORMAT_B8G8R8A8_SRGB && format.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR)
return format;
}
else
{
if (format.format == VK_FORMAT_B8G8R8A8_UNORM && format.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR)
return format;
}
if (format.format == VK_FORMAT_B8G8R8A8_UNORM && format.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR)
return format;
}

return formats[0];
Expand Down
29 changes: 19 additions & 10 deletions src/Cafe/HW/Latte/Renderer/Vulkan/VulkanRenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2660,6 +2660,8 @@ VkPipeline VulkanRenderer::backbufferBlit_createGraphicsPipeline(VkDescriptorSet
.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT,
.offset = 0,
.size = 3 * sizeof(float) * 2 // 3 vec2's
+ 4 // + 1 VkBool32
+ 4 * 2 // + 2 float
};

VkPipelineLayoutCreateInfo pipelineLayoutInfo{};
Expand Down Expand Up @@ -2771,10 +2773,6 @@ bool VulkanRenderer::UpdateSwapchainProperties(bool mainWindow)
if(chainInfo.m_vsyncState != configValue)
stateChanged = true;

const bool latteBufferUsesSRGB = mainWindow ? LatteGPUState.tvBufferUsesSRGB : LatteGPUState.drcBufferUsesSRGB;
if (chainInfo.m_usesSRGB != latteBufferUsesSRGB)
stateChanged = true;

int width, height;
if (mainWindow)
WindowSystem::GetWindowPhysSize(width, height);
Expand All @@ -2799,7 +2797,7 @@ bool VulkanRenderer::UpdateSwapchainProperties(bool mainWindow)

chainInfo.m_shouldRecreate = false;
chainInfo.m_vsyncState = configValue;
chainInfo.m_usesSRGB = latteBufferUsesSRGB;
chainInfo.m_usesSRGB = mainWindow ? LatteGPUState.tvBufferUsesSRGB : LatteGPUState.drcBufferUsesSRGB;
return true;
}

Expand Down Expand Up @@ -3046,24 +3044,35 @@ void VulkanRenderer::DrawBackbufferQuad(LatteTextureView* texView, RendererOutpu

vkCmdBindDescriptorSets(m_state.currentCommandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipelineLayout, 0, 1, &descriptSet, 0, nullptr);


// update push constants
Vector2f pushData[3];
struct
{
Vector2f vecs[3];
VkBool32 applySRGBEncoding;
float targetGamma;
float displayGamma;
} pushData;

// textureSrcResolution
sint32 effectiveWidth, effectiveHeight;
texView->baseTexture->GetEffectiveSize(effectiveWidth, effectiveHeight, 0);
pushData[0] = {(float)effectiveWidth, (float)effectiveHeight};
pushData.vecs[0] = {(float)effectiveWidth, (float)effectiveHeight};

// nativeResolution
pushData[1] = {
pushData.vecs[1] = {
(float)texViewVk->baseTexture->width,
(float)texViewVk->baseTexture->height,
};

// outputResolution
pushData[2] = {(float)imageWidth,(float)imageHeight};
pushData.vecs[2] = {(float)imageWidth,(float)imageHeight};

pushData.applySRGBEncoding = padView ? LatteGPUState.drcBufferUsesSRGB : LatteGPUState.tvBufferUsesSRGB;
pushData.targetGamma = padView ? ActiveSettings::GetDRCGamma() : ActiveSettings::GetTVGamma();
pushData.displayGamma = GetConfig().userDisplayGamma;

vkCmdPushConstants(m_state.currentCommandBuffer, m_pipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(float) * 2 * 3, &pushData);
vkCmdPushConstants(m_state.currentCommandBuffer, m_pipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(pushData), &pushData);

vkCmdDraw(m_state.currentCommandBuffer, 6, 1, 0, 0);

Expand Down
9 changes: 7 additions & 2 deletions src/Cafe/OS/libs/gx2/GX2_Misc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -206,8 +206,12 @@ namespace GX2

void GX2SetTVGamma(float gamma)
{
if (abs(gamma - 1.0f) > 0.01f)
cemuLog_logDebug(LogType::Force, "TV gamma set to {} which is not supported", gamma);
LatteGPUState.tvGamma = (1.0f - gamma);
}

void GX2SetDRCGamma(float gamma)
{
LatteGPUState.drcGamma = (1.0f - gamma);
}

bool GX2GetLastFrame(uint32 deviceId, GX2Texture* textureOut)
Expand Down Expand Up @@ -307,6 +311,7 @@ namespace GX2

cafeExportRegister("gx2", GX2SetTVBuffer, LogType::GX2);
cafeExportRegister("gx2", GX2SetTVGamma, LogType::GX2);
cafeExportRegister("gx2", GX2SetDRCGamma, LogType::GX2);

cafeExportRegister("gx2", GX2GetLastFrame, LogType::GX2);
cafeExportRegister("gx2", GX2GetLastFrameGammaA, LogType::GX2);
Expand Down
1 change: 1 addition & 0 deletions src/Common/GLInclude/glFunctions.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ GLFUNC(PFNGLPROGRAMUNIFORM1IPROC, glProgramUniform1i)
GLFUNC(PFNGLPROGRAMUNIFORM2IPROC, glProgramUniform2i)
GLFUNC(PFNGLPROGRAMUNIFORM1IVPROC, glProgramUniform1iv)
GLFUNC(PFNGLPROGRAMUNIFORM4IVPROC, glProgramUniform4iv)
GLFUNC(PFNGLPROGRAMUNIFORM1IPROC, glProgramUniform1f)
GLFUNC(PFNGLPROGRAMUNIFORM1FVPROC, glProgramUniform1fv)
GLFUNC(PFNGLPROGRAMUNIFORM2FVPROC, glProgramUniform2fv)

Expand Down
Loading
Loading