mirror of
https://github.com/cemu-project/Cemu.git
synced 2024-11-21 16:49:19 +01:00
Vulkan: Make scaling shaders compatible + fixes (#1392)
This commit is contained in:
parent
6f9f3d52ea
commit
269d5b9aab
@ -960,7 +960,7 @@ bool GraphicPack2::Activate()
|
|||||||
auto option_upscale = rules.FindOption("upscaleMagFilter");
|
auto option_upscale = rules.FindOption("upscaleMagFilter");
|
||||||
if(option_upscale && boost::iequals(*option_upscale, "NearestNeighbor"))
|
if(option_upscale && boost::iequals(*option_upscale, "NearestNeighbor"))
|
||||||
m_output_settings.upscale_filter = LatteTextureView::MagFilter::kNearestNeighbor;
|
m_output_settings.upscale_filter = LatteTextureView::MagFilter::kNearestNeighbor;
|
||||||
auto option_downscale = rules.FindOption("NearestNeighbor");
|
auto option_downscale = rules.FindOption("downscaleMinFilter");
|
||||||
if (option_downscale && boost::iequals(*option_downscale, "NearestNeighbor"))
|
if (option_downscale && boost::iequals(*option_downscale, "NearestNeighbor"))
|
||||||
m_output_settings.downscale_filter = LatteTextureView::MagFilter::kNearestNeighbor;
|
m_output_settings.downscale_filter = LatteTextureView::MagFilter::kNearestNeighbor;
|
||||||
}
|
}
|
||||||
|
@ -933,13 +933,6 @@ void LatteRenderTarget_copyToBackbuffer(LatteTextureView* textureView, bool isPa
|
|||||||
if (shader == nullptr)
|
if (shader == nullptr)
|
||||||
{
|
{
|
||||||
sint32 scaling_filter = downscaling ? GetConfig().downscale_filter : GetConfig().upscale_filter;
|
sint32 scaling_filter = downscaling ? GetConfig().downscale_filter : GetConfig().upscale_filter;
|
||||||
|
|
||||||
if (g_renderer->GetType() == RendererAPI::Vulkan)
|
|
||||||
{
|
|
||||||
// force linear or nearest neighbor filter
|
|
||||||
if(scaling_filter != kLinearFilter && scaling_filter != kNearestNeighborFilter)
|
|
||||||
scaling_filter = kLinearFilter;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (scaling_filter == kLinearFilter)
|
if (scaling_filter == kLinearFilter)
|
||||||
{
|
{
|
||||||
@ -957,7 +950,7 @@ void LatteRenderTarget_copyToBackbuffer(LatteTextureView* textureView, bool isPa
|
|||||||
else
|
else
|
||||||
shader = RendererOutputShader::s_bicubic_shader;
|
shader = RendererOutputShader::s_bicubic_shader;
|
||||||
|
|
||||||
filter = LatteTextureView::MagFilter::kNearestNeighbor;
|
filter = LatteTextureView::MagFilter::kLinear;
|
||||||
}
|
}
|
||||||
else if (scaling_filter == kBicubicHermiteFilter)
|
else if (scaling_filter == kBicubicHermiteFilter)
|
||||||
{
|
{
|
||||||
|
@ -570,13 +570,10 @@ void OpenGLRenderer::DrawBackbufferQuad(LatteTextureView* texView, RendererOutpu
|
|||||||
g_renderer->ClearColorbuffer(padView);
|
g_renderer->ClearColorbuffer(padView);
|
||||||
}
|
}
|
||||||
|
|
||||||
sint32 effectiveWidth, effectiveHeight;
|
|
||||||
texView->baseTexture->GetEffectiveSize(effectiveWidth, effectiveHeight, 0);
|
|
||||||
|
|
||||||
shader_unbind(RendererShader::ShaderType::kGeometry);
|
shader_unbind(RendererShader::ShaderType::kGeometry);
|
||||||
shader_bind(shader->GetVertexShader());
|
shader_bind(shader->GetVertexShader());
|
||||||
shader_bind(shader->GetFragmentShader());
|
shader_bind(shader->GetFragmentShader());
|
||||||
shader->SetUniformParameters(*texView, { effectiveWidth, effectiveHeight }, { imageWidth, imageHeight });
|
shader->SetUniformParameters(*texView, {imageWidth, imageHeight});
|
||||||
|
|
||||||
// set viewport
|
// set viewport
|
||||||
glViewportIndexedf(0, imageX, imageY, imageWidth, imageHeight);
|
glViewportIndexedf(0, imageX, imageY, imageWidth, imageHeight);
|
||||||
@ -584,6 +581,12 @@ void OpenGLRenderer::DrawBackbufferQuad(LatteTextureView* texView, RendererOutpu
|
|||||||
LatteTextureViewGL* texViewGL = (LatteTextureViewGL*)texView;
|
LatteTextureViewGL* texViewGL = (LatteTextureViewGL*)texView;
|
||||||
texture_bindAndActivate(texView, 0);
|
texture_bindAndActivate(texView, 0);
|
||||||
|
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||||
|
texViewGL->samplerState.clampS = texViewGL->samplerState.clampT = 0xFF;
|
||||||
|
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, useLinearTexFilter ? GL_LINEAR : GL_NEAREST);
|
||||||
|
texViewGL->samplerState.filterMin = 0xFFFFFFFF;
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, useLinearTexFilter ? GL_LINEAR : GL_NEAREST);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, useLinearTexFilter ? GL_LINEAR : GL_NEAREST);
|
||||||
texViewGL->samplerState.filterMag = 0xFFFFFFFF;
|
texViewGL->samplerState.filterMag = 0xFFFFFFFF;
|
||||||
|
|
||||||
|
@ -2,18 +2,7 @@
|
|||||||
#include "Cafe/HW/Latte/Renderer/OpenGL/OpenGLRenderer.h"
|
#include "Cafe/HW/Latte/Renderer/OpenGL/OpenGLRenderer.h"
|
||||||
|
|
||||||
const std::string RendererOutputShader::s_copy_shader_source =
|
const std::string RendererOutputShader::s_copy_shader_source =
|
||||||
R"(#version 420
|
R"(
|
||||||
|
|
||||||
#ifdef VULKAN
|
|
||||||
layout(location = 0) in vec2 passUV;
|
|
||||||
layout(binding = 0) uniform sampler2D textureSrc;
|
|
||||||
layout(location = 0) out vec4 colorOut0;
|
|
||||||
#else
|
|
||||||
in vec2 passUV;
|
|
||||||
layout(binding=0) uniform sampler2D textureSrc;
|
|
||||||
layout(location = 0) out vec4 colorOut0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
colorOut0 = vec4(texture(textureSrc, passUV).rgb,1.0);
|
colorOut0 = vec4(texture(textureSrc, passUV).rgb,1.0);
|
||||||
@ -22,20 +11,6 @@ void main()
|
|||||||
|
|
||||||
const std::string RendererOutputShader::s_bicubic_shader_source =
|
const std::string RendererOutputShader::s_bicubic_shader_source =
|
||||||
R"(
|
R"(
|
||||||
#version 420
|
|
||||||
|
|
||||||
#ifdef VULKAN
|
|
||||||
layout(location = 0) in vec2 passUV;
|
|
||||||
layout(binding = 0) uniform sampler2D textureSrc;
|
|
||||||
layout(binding = 1) uniform vec2 textureSrcResolution;
|
|
||||||
layout(location = 0) out vec4 colorOut0;
|
|
||||||
#else
|
|
||||||
in vec2 passUV;
|
|
||||||
layout(binding=0) uniform sampler2D textureSrc;
|
|
||||||
uniform vec2 textureSrcResolution;
|
|
||||||
layout(location = 0) out vec4 colorOut0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
vec4 cubic(float x)
|
vec4 cubic(float x)
|
||||||
{
|
{
|
||||||
float x2 = x * x;
|
float x2 = x * x;
|
||||||
@ -48,24 +23,23 @@ vec4 cubic(float x)
|
|||||||
return w / 6.0;
|
return w / 6.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
vec4 bcFilter(vec2 texcoord, vec2 texscale)
|
vec4 bcFilter(vec2 uv, vec4 texelSize)
|
||||||
{
|
{
|
||||||
float fx = fract(texcoord.x);
|
vec2 pixel = uv*texelSize.zw - 0.5;
|
||||||
float fy = fract(texcoord.y);
|
vec2 pixelFrac = fract(pixel);
|
||||||
texcoord.x -= fx;
|
vec2 pixelInt = pixel - pixelFrac;
|
||||||
texcoord.y -= fy;
|
|
||||||
|
|
||||||
vec4 xcubic = cubic(fx);
|
vec4 xcubic = cubic(pixelFrac.x);
|
||||||
vec4 ycubic = cubic(fy);
|
vec4 ycubic = cubic(pixelFrac.y);
|
||||||
|
|
||||||
vec4 c = vec4(texcoord.x - 0.5, texcoord.x + 1.5, texcoord.y - 0.5, texcoord.y + 1.5);
|
vec4 c = vec4(pixelInt.x - 0.5, pixelInt.x + 1.5, pixelInt.y - 0.5, pixelInt.y + 1.5);
|
||||||
vec4 s = vec4(xcubic.x + xcubic.y, xcubic.z + xcubic.w, ycubic.x + ycubic.y, ycubic.z + ycubic.w);
|
vec4 s = vec4(xcubic.x + xcubic.y, xcubic.z + xcubic.w, ycubic.x + ycubic.y, ycubic.z + ycubic.w);
|
||||||
vec4 offset = c + vec4(xcubic.y, xcubic.w, ycubic.y, ycubic.w) / s;
|
vec4 offset = c + vec4(xcubic.y, xcubic.w, ycubic.y, ycubic.w) / s;
|
||||||
|
|
||||||
vec4 sample0 = texture(textureSrc, vec2(offset.x, offset.z) * texscale);
|
vec4 sample0 = texture(textureSrc, vec2(offset.x, offset.z) * texelSize.xy);
|
||||||
vec4 sample1 = texture(textureSrc, vec2(offset.y, offset.z) * texscale);
|
vec4 sample1 = texture(textureSrc, vec2(offset.y, offset.z) * texelSize.xy);
|
||||||
vec4 sample2 = texture(textureSrc, vec2(offset.x, offset.w) * texscale);
|
vec4 sample2 = texture(textureSrc, vec2(offset.x, offset.w) * texelSize.xy);
|
||||||
vec4 sample3 = texture(textureSrc, vec2(offset.y, offset.w) * texscale);
|
vec4 sample3 = texture(textureSrc, vec2(offset.y, offset.w) * texelSize.xy);
|
||||||
|
|
||||||
float sx = s.x / (s.x + s.y);
|
float sx = s.x / (s.x + s.y);
|
||||||
float sy = s.z / (s.z + s.w);
|
float sy = s.z / (s.z + s.w);
|
||||||
@ -76,20 +50,13 @@ vec4 bcFilter(vec2 texcoord, vec2 texscale)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void main(){
|
void main(){
|
||||||
colorOut0 = vec4(bcFilter(passUV*textureSrcResolution, vec2(1.0,1.0)/textureSrcResolution).rgb,1.0);
|
vec4 texelSize = vec4( 1.0 / textureSrcResolution.xy, textureSrcResolution.xy);
|
||||||
|
colorOut0 = vec4(bcFilter(passUV, texelSize).rgb,1.0);
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
|
|
||||||
const std::string RendererOutputShader::s_hermite_shader_source =
|
const std::string RendererOutputShader::s_hermite_shader_source =
|
||||||
R"(#version 420
|
R"(
|
||||||
|
|
||||||
in vec4 gl_FragCoord;
|
|
||||||
in vec2 passUV;
|
|
||||||
layout(binding=0) uniform sampler2D textureSrc;
|
|
||||||
uniform vec2 textureSrcResolution;
|
|
||||||
uniform vec2 outputResolution;
|
|
||||||
layout(location = 0) out vec4 colorOut0;
|
|
||||||
|
|
||||||
// https://www.shadertoy.com/view/MllSzX
|
// https://www.shadertoy.com/view/MllSzX
|
||||||
|
|
||||||
vec3 CubicHermite (vec3 A, vec3 B, vec3 C, vec3 D, float t)
|
vec3 CubicHermite (vec3 A, vec3 B, vec3 C, vec3 D, float t)
|
||||||
@ -111,7 +78,7 @@ vec3 BicubicHermiteTexture(vec2 uv, vec4 texelSize)
|
|||||||
vec2 frac = fract(pixel);
|
vec2 frac = fract(pixel);
|
||||||
pixel = floor(pixel) / texelSize.zw - vec2(texelSize.xy/2.0);
|
pixel = floor(pixel) / texelSize.zw - vec2(texelSize.xy/2.0);
|
||||||
|
|
||||||
vec4 doubleSize = texelSize*texelSize;
|
vec4 doubleSize = texelSize*2.0;
|
||||||
|
|
||||||
vec3 C00 = texture(textureSrc, pixel + vec2(-texelSize.x ,-texelSize.y)).rgb;
|
vec3 C00 = texture(textureSrc, pixel + vec2(-texelSize.x ,-texelSize.y)).rgb;
|
||||||
vec3 C10 = texture(textureSrc, pixel + vec2( 0.0 ,-texelSize.y)).rgb;
|
vec3 C10 = texture(textureSrc, pixel + vec2( 0.0 ,-texelSize.y)).rgb;
|
||||||
@ -142,15 +109,17 @@ vec3 BicubicHermiteTexture(vec2 uv, vec4 texelSize)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void main(){
|
void main(){
|
||||||
vec4 texelSize = vec4( 1.0 / outputResolution.xy, outputResolution.xy);
|
vec4 texelSize = vec4( 1.0 / textureSrcResolution.xy, textureSrcResolution.xy);
|
||||||
colorOut0 = vec4(BicubicHermiteTexture(passUV, texelSize), 1.0);
|
colorOut0 = vec4(BicubicHermiteTexture(passUV, texelSize), 1.0);
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
|
|
||||||
RendererOutputShader::RendererOutputShader(const std::string& vertex_source, const std::string& fragment_source)
|
RendererOutputShader::RendererOutputShader(const std::string& vertex_source, const std::string& fragment_source)
|
||||||
{
|
{
|
||||||
|
auto finalFragmentSrc = PrependFragmentPreamble(fragment_source);
|
||||||
|
|
||||||
m_vertex_shader = g_renderer->shader_create(RendererShader::ShaderType::kVertex, 0, 0, vertex_source, false, false);
|
m_vertex_shader = g_renderer->shader_create(RendererShader::ShaderType::kVertex, 0, 0, vertex_source, false, false);
|
||||||
m_fragment_shader = g_renderer->shader_create(RendererShader::ShaderType::kFragment, 0, 0, fragment_source, false, false);
|
m_fragment_shader = g_renderer->shader_create(RendererShader::ShaderType::kFragment, 0, 0, finalFragmentSrc, false, false);
|
||||||
|
|
||||||
m_vertex_shader->PreponeCompilation(true);
|
m_vertex_shader->PreponeCompilation(true);
|
||||||
m_fragment_shader->PreponeCompilation(true);
|
m_fragment_shader->PreponeCompilation(true);
|
||||||
@ -163,74 +132,45 @@ RendererOutputShader::RendererOutputShader(const std::string& vertex_source, con
|
|||||||
|
|
||||||
if (g_renderer->GetType() == RendererAPI::OpenGL)
|
if (g_renderer->GetType() == RendererAPI::OpenGL)
|
||||||
{
|
{
|
||||||
m_attributes[0].m_loc_texture_src_resolution = m_vertex_shader->GetUniformLocation("textureSrcResolution");
|
m_uniformLocations[0].m_loc_textureSrcResolution = m_vertex_shader->GetUniformLocation("textureSrcResolution");
|
||||||
m_attributes[0].m_loc_input_resolution = m_vertex_shader->GetUniformLocation("inputResolution");
|
m_uniformLocations[0].m_loc_nativeResolution = m_vertex_shader->GetUniformLocation("nativeResolution");
|
||||||
m_attributes[0].m_loc_output_resolution = m_vertex_shader->GetUniformLocation("outputResolution");
|
m_uniformLocations[0].m_loc_outputResolution = m_vertex_shader->GetUniformLocation("outputResolution");
|
||||||
|
|
||||||
m_attributes[1].m_loc_texture_src_resolution = m_fragment_shader->GetUniformLocation("textureSrcResolution");
|
m_uniformLocations[1].m_loc_textureSrcResolution = m_fragment_shader->GetUniformLocation("textureSrcResolution");
|
||||||
m_attributes[1].m_loc_input_resolution = m_fragment_shader->GetUniformLocation("inputResolution");
|
m_uniformLocations[1].m_loc_nativeResolution = m_fragment_shader->GetUniformLocation("nativeResolution");
|
||||||
m_attributes[1].m_loc_output_resolution = m_fragment_shader->GetUniformLocation("outputResolution");
|
m_uniformLocations[1].m_loc_outputResolution = m_fragment_shader->GetUniformLocation("outputResolution");
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
cemuLog_logDebug(LogType::Force, "RendererOutputShader() - todo for Vulkan");
|
|
||||||
m_attributes[0].m_loc_texture_src_resolution = -1;
|
|
||||||
m_attributes[0].m_loc_input_resolution = -1;
|
|
||||||
m_attributes[0].m_loc_output_resolution = -1;
|
|
||||||
|
|
||||||
m_attributes[1].m_loc_texture_src_resolution = -1;
|
|
||||||
m_attributes[1].m_loc_input_resolution = -1;
|
|
||||||
m_attributes[1].m_loc_output_resolution = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RendererOutputShader::SetUniformParameters(const LatteTextureView& texture_view, const Vector2i& input_res, const Vector2i& output_res) const
|
void RendererOutputShader::SetUniformParameters(const LatteTextureView& texture_view, const Vector2i& output_res) const
|
||||||
{
|
{
|
||||||
float res[2];
|
sint32 effectiveWidth, effectiveHeight;
|
||||||
// vertex shader
|
texture_view.baseTexture->GetEffectiveSize(effectiveWidth, effectiveHeight, 0);
|
||||||
if (m_attributes[0].m_loc_texture_src_resolution != -1)
|
auto setUniforms = [&](RendererShader* shader, const UniformLocations& locations){
|
||||||
{
|
float res[2];
|
||||||
res[0] = (float)texture_view.baseTexture->width;
|
if (locations.m_loc_textureSrcResolution != -1)
|
||||||
res[1] = (float)texture_view.baseTexture->height;
|
{
|
||||||
m_vertex_shader->SetUniform2fv(m_attributes[0].m_loc_texture_src_resolution, res, 1);
|
res[0] = (float)effectiveWidth;
|
||||||
}
|
res[1] = (float)effectiveHeight;
|
||||||
|
shader->SetUniform2fv(locations.m_loc_textureSrcResolution, res, 1);
|
||||||
|
}
|
||||||
|
|
||||||
if (m_attributes[0].m_loc_input_resolution != -1)
|
if (locations.m_loc_nativeResolution != -1)
|
||||||
{
|
{
|
||||||
res[0] = (float)input_res.x;
|
res[0] = (float)texture_view.baseTexture->width;
|
||||||
res[1] = (float)input_res.y;
|
res[1] = (float)texture_view.baseTexture->height;
|
||||||
m_vertex_shader->SetUniform2fv(m_attributes[0].m_loc_input_resolution, res, 1);
|
shader->SetUniform2fv(locations.m_loc_nativeResolution, res, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_attributes[0].m_loc_output_resolution != -1)
|
if (locations.m_loc_outputResolution != -1)
|
||||||
{
|
{
|
||||||
res[0] = (float)output_res.x;
|
res[0] = (float)output_res.x;
|
||||||
res[1] = (float)output_res.y;
|
res[1] = (float)output_res.y;
|
||||||
m_vertex_shader->SetUniform2fv(m_attributes[0].m_loc_output_resolution, res, 1);
|
shader->SetUniform2fv(locations.m_loc_outputResolution, res, 1);
|
||||||
}
|
}
|
||||||
|
};
|
||||||
// fragment shader
|
setUniforms(m_vertex_shader, m_uniformLocations[0]);
|
||||||
if (m_attributes[1].m_loc_texture_src_resolution != -1)
|
setUniforms(m_fragment_shader, m_uniformLocations[1]);
|
||||||
{
|
|
||||||
res[0] = (float)texture_view.baseTexture->width;
|
|
||||||
res[1] = (float)texture_view.baseTexture->height;
|
|
||||||
m_fragment_shader->SetUniform2fv(m_attributes[1].m_loc_texture_src_resolution, res, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_attributes[1].m_loc_input_resolution != -1)
|
|
||||||
{
|
|
||||||
res[0] = (float)input_res.x;
|
|
||||||
res[1] = (float)input_res.y;
|
|
||||||
m_fragment_shader->SetUniform2fv(m_attributes[1].m_loc_input_resolution, res, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_attributes[1].m_loc_output_resolution != -1)
|
|
||||||
{
|
|
||||||
res[0] = (float)output_res.x;
|
|
||||||
res[1] = (float)output_res.y;
|
|
||||||
m_fragment_shader->SetUniform2fv(m_attributes[1].m_loc_output_resolution, res, 1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RendererOutputShader* RendererOutputShader::s_copy_shader;
|
RendererOutputShader* RendererOutputShader::s_copy_shader;
|
||||||
@ -341,6 +281,27 @@ void main(){
|
|||||||
)";
|
)";
|
||||||
return vertex_source.str();
|
return vertex_source.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string RendererOutputShader::PrependFragmentPreamble(const std::string& shaderSrc)
|
||||||
|
{
|
||||||
|
return R"(#version 430
|
||||||
|
#ifdef VULKAN
|
||||||
|
layout(push_constant) uniform pc {
|
||||||
|
vec2 textureSrcResolution;
|
||||||
|
vec2 nativeResolution;
|
||||||
|
vec2 outputResolution;
|
||||||
|
};
|
||||||
|
#else
|
||||||
|
uniform vec2 textureSrcResolution;
|
||||||
|
uniform vec2 nativeResolution;
|
||||||
|
uniform vec2 outputResolution;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
layout(location = 0) in vec2 passUV;
|
||||||
|
layout(binding = 0) uniform sampler2D textureSrc;
|
||||||
|
layout(location = 0) out vec4 colorOut0;
|
||||||
|
)" + shaderSrc;
|
||||||
|
}
|
||||||
void RendererOutputShader::InitializeStatic()
|
void RendererOutputShader::InitializeStatic()
|
||||||
{
|
{
|
||||||
std::string vertex_source, vertex_source_ud;
|
std::string vertex_source, vertex_source_ud;
|
||||||
@ -349,28 +310,18 @@ void RendererOutputShader::InitializeStatic()
|
|||||||
{
|
{
|
||||||
vertex_source = GetOpenGlVertexSource(false);
|
vertex_source = GetOpenGlVertexSource(false);
|
||||||
vertex_source_ud = GetOpenGlVertexSource(true);
|
vertex_source_ud = GetOpenGlVertexSource(true);
|
||||||
|
|
||||||
s_copy_shader = new RendererOutputShader(vertex_source, s_copy_shader_source);
|
|
||||||
s_copy_shader_ud = new RendererOutputShader(vertex_source_ud, s_copy_shader_source);
|
|
||||||
|
|
||||||
s_bicubic_shader = new RendererOutputShader(vertex_source, s_bicubic_shader_source);
|
|
||||||
s_bicubic_shader_ud = new RendererOutputShader(vertex_source_ud, s_bicubic_shader_source);
|
|
||||||
|
|
||||||
s_hermit_shader = new RendererOutputShader(vertex_source, s_hermite_shader_source);
|
|
||||||
s_hermit_shader_ud = new RendererOutputShader(vertex_source_ud, s_hermite_shader_source);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
vertex_source = GetVulkanVertexSource(false);
|
vertex_source = GetVulkanVertexSource(false);
|
||||||
vertex_source_ud = GetVulkanVertexSource(true);
|
vertex_source_ud = GetVulkanVertexSource(true);
|
||||||
|
|
||||||
s_copy_shader = new RendererOutputShader(vertex_source, s_copy_shader_source);
|
|
||||||
s_copy_shader_ud = new RendererOutputShader(vertex_source_ud, s_copy_shader_source);
|
|
||||||
|
|
||||||
/* s_bicubic_shader = new RendererOutputShader(vertex_source, s_bicubic_shader_source); TODO
|
|
||||||
s_bicubic_shader_ud = new RendererOutputShader(vertex_source_ud, s_bicubic_shader_source);
|
|
||||||
|
|
||||||
s_hermit_shader = new RendererOutputShader(vertex_source, s_hermite_shader_source);
|
|
||||||
s_hermit_shader_ud = new RendererOutputShader(vertex_source_ud, s_hermite_shader_source);*/
|
|
||||||
}
|
}
|
||||||
|
s_copy_shader = new RendererOutputShader(vertex_source, s_copy_shader_source);
|
||||||
|
s_copy_shader_ud = new RendererOutputShader(vertex_source_ud, s_copy_shader_source);
|
||||||
|
|
||||||
|
s_bicubic_shader = new RendererOutputShader(vertex_source, s_bicubic_shader_source);
|
||||||
|
s_bicubic_shader_ud = new RendererOutputShader(vertex_source_ud, s_bicubic_shader_source);
|
||||||
|
|
||||||
|
s_hermit_shader = new RendererOutputShader(vertex_source, s_hermite_shader_source);
|
||||||
|
s_hermit_shader_ud = new RendererOutputShader(vertex_source_ud, s_hermite_shader_source);
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@ public:
|
|||||||
RendererOutputShader(const std::string& vertex_source, const std::string& fragment_source);
|
RendererOutputShader(const std::string& vertex_source, const std::string& fragment_source);
|
||||||
virtual ~RendererOutputShader() = default;
|
virtual ~RendererOutputShader() = default;
|
||||||
|
|
||||||
void SetUniformParameters(const LatteTextureView& texture_view, const Vector2i& input_res, const Vector2i& output_res) const;
|
void SetUniformParameters(const LatteTextureView& texture_view, const Vector2i& output_res) const;
|
||||||
|
|
||||||
RendererShader* GetVertexShader() const
|
RendererShader* GetVertexShader() const
|
||||||
{
|
{
|
||||||
@ -43,16 +43,18 @@ public:
|
|||||||
static std::string GetVulkanVertexSource(bool render_upside_down);
|
static std::string GetVulkanVertexSource(bool render_upside_down);
|
||||||
static std::string GetOpenGlVertexSource(bool render_upside_down);
|
static std::string GetOpenGlVertexSource(bool render_upside_down);
|
||||||
|
|
||||||
|
static std::string PrependFragmentPreamble(const std::string& shaderSrc);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
RendererShader* m_vertex_shader;
|
RendererShader* m_vertex_shader;
|
||||||
RendererShader* m_fragment_shader;
|
RendererShader* m_fragment_shader;
|
||||||
|
|
||||||
struct
|
struct UniformLocations
|
||||||
{
|
{
|
||||||
sint32 m_loc_texture_src_resolution = -1;
|
sint32 m_loc_textureSrcResolution = -1;
|
||||||
sint32 m_loc_input_resolution = -1;
|
sint32 m_loc_nativeResolution = -1;
|
||||||
sint32 m_loc_output_resolution = -1;
|
sint32 m_loc_outputResolution = -1;
|
||||||
} m_attributes[2]{};
|
} m_uniformLocations[2]{};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static const std::string s_copy_shader_source;
|
static const std::string s_copy_shader_source;
|
||||||
|
@ -202,6 +202,13 @@ VkSampler LatteTextureViewVk::GetDefaultTextureSampler(bool useLinearTexFilter)
|
|||||||
VkSamplerCreateInfo samplerInfo{};
|
VkSamplerCreateInfo samplerInfo{};
|
||||||
samplerInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
|
samplerInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
|
||||||
|
|
||||||
|
// emulate OpenGL minFilters
|
||||||
|
// see note under: https://docs.vulkan.org/spec/latest/chapters/samplers.html#VkSamplerCreateInfo
|
||||||
|
// if maxLod = 0 then magnification is always performed
|
||||||
|
samplerInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
|
||||||
|
samplerInfo.minLod = 0.0f;
|
||||||
|
samplerInfo.maxLod = 0.25f;
|
||||||
|
|
||||||
if (useLinearTexFilter)
|
if (useLinearTexFilter)
|
||||||
{
|
{
|
||||||
samplerInfo.magFilter = VK_FILTER_LINEAR;
|
samplerInfo.magFilter = VK_FILTER_LINEAR;
|
||||||
@ -212,6 +219,9 @@ VkSampler LatteTextureViewVk::GetDefaultTextureSampler(bool useLinearTexFilter)
|
|||||||
samplerInfo.magFilter = VK_FILTER_NEAREST;
|
samplerInfo.magFilter = VK_FILTER_NEAREST;
|
||||||
samplerInfo.minFilter = VK_FILTER_NEAREST;
|
samplerInfo.minFilter = VK_FILTER_NEAREST;
|
||||||
}
|
}
|
||||||
|
samplerInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
|
||||||
|
samplerInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
|
||||||
|
samplerInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
|
||||||
|
|
||||||
if (vkCreateSampler(m_device, &samplerInfo, nullptr, &sampler) != VK_SUCCESS)
|
if (vkCreateSampler(m_device, &samplerInfo, nullptr, &sampler) != VK_SUCCESS)
|
||||||
{
|
{
|
||||||
|
@ -2581,10 +2581,18 @@ VkPipeline VulkanRenderer::backbufferBlit_createGraphicsPipeline(VkDescriptorSet
|
|||||||
colorBlending.blendConstants[2] = 0.0f;
|
colorBlending.blendConstants[2] = 0.0f;
|
||||||
colorBlending.blendConstants[3] = 0.0f;
|
colorBlending.blendConstants[3] = 0.0f;
|
||||||
|
|
||||||
|
VkPushConstantRange pushConstantRange{
|
||||||
|
.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT,
|
||||||
|
.offset = 0,
|
||||||
|
.size = 3 * sizeof(float) * 2 // 3 vec2's
|
||||||
|
};
|
||||||
|
|
||||||
VkPipelineLayoutCreateInfo pipelineLayoutInfo{};
|
VkPipelineLayoutCreateInfo pipelineLayoutInfo{};
|
||||||
pipelineLayoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
|
pipelineLayoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
|
||||||
pipelineLayoutInfo.setLayoutCount = 1;
|
pipelineLayoutInfo.setLayoutCount = 1;
|
||||||
pipelineLayoutInfo.pSetLayouts = &descriptorLayout;
|
pipelineLayoutInfo.pSetLayouts = &descriptorLayout;
|
||||||
|
pipelineLayoutInfo.pushConstantRangeCount = 1;
|
||||||
|
pipelineLayoutInfo.pPushConstantRanges = &pushConstantRange;
|
||||||
|
|
||||||
VkResult result = vkCreatePipelineLayout(m_logicalDevice, &pipelineLayoutInfo, nullptr, &m_pipelineLayout);
|
VkResult result = vkCreatePipelineLayout(m_logicalDevice, &pipelineLayoutInfo, nullptr, &m_pipelineLayout);
|
||||||
if (result != VK_SUCCESS)
|
if (result != VK_SUCCESS)
|
||||||
@ -2956,6 +2964,25 @@ void VulkanRenderer::DrawBackbufferQuad(LatteTextureView* texView, RendererOutpu
|
|||||||
|
|
||||||
vkCmdBindDescriptorSets(m_state.currentCommandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipelineLayout, 0, 1, &descriptSet, 0, nullptr);
|
vkCmdBindDescriptorSets(m_state.currentCommandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipelineLayout, 0, 1, &descriptSet, 0, nullptr);
|
||||||
|
|
||||||
|
// update push constants
|
||||||
|
Vector2f pushData[3];
|
||||||
|
|
||||||
|
// textureSrcResolution
|
||||||
|
sint32 effectiveWidth, effectiveHeight;
|
||||||
|
texView->baseTexture->GetEffectiveSize(effectiveWidth, effectiveHeight, 0);
|
||||||
|
pushData[0] = {(float)effectiveWidth, (float)effectiveHeight};
|
||||||
|
|
||||||
|
// nativeResolution
|
||||||
|
pushData[1] = {
|
||||||
|
(float)texViewVk->baseTexture->width,
|
||||||
|
(float)texViewVk->baseTexture->height,
|
||||||
|
};
|
||||||
|
|
||||||
|
// outputResolution
|
||||||
|
pushData[2] = {(float)imageWidth,(float)imageHeight};
|
||||||
|
|
||||||
|
vkCmdPushConstants(m_state.currentCommandBuffer, m_pipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(float) * 2 * 3, &pushData);
|
||||||
|
|
||||||
vkCmdDraw(m_state.currentCommandBuffer, 6, 1, 0, 0);
|
vkCmdDraw(m_state.currentCommandBuffer, 6, 1, 0, 0);
|
||||||
|
|
||||||
vkCmdEndRenderPass(m_state.currentCommandBuffer);
|
vkCmdEndRenderPass(m_state.currentCommandBuffer);
|
||||||
|
Loading…
Reference in New Issue
Block a user