Skip to content
Permalink
Browse files

Merge pull request #8378 from stenzek/quad-buffer-stereo

Various quad-buffered ("HDMI 3D") stereo fixes
  • Loading branch information...
stenzek committed Nov 8, 2019
2 parents 93d7b3d + 33a6d26 commit 5440be96e744fffcdc4bb5e030a202deef7a1e1d
@@ -154,8 +154,8 @@ bool VideoBackend::Initialize(const WindowSystemInfo& wsi)
g_framebuffer_manager = std::make_unique<FramebufferManager>();
g_texture_cache = std::make_unique<TextureCacheBase>();
g_perf_query = std::make_unique<PerfQuery>();
if (!g_renderer->Initialize() || !g_vertex_manager->Initialize() ||
!g_shader_cache->Initialize() || !g_framebuffer_manager->Initialize() ||
if (!g_vertex_manager->Initialize() || !g_shader_cache->Initialize() ||
!g_renderer->Initialize() || !g_framebuffer_manager->Initialize() ||
!g_texture_cache->Initialize())
{
Shutdown();
@@ -14,9 +14,9 @@ static APIType GetAPIType()
static void EmitUniformBufferDeclaration(std::stringstream& ss)
{
if (GetAPIType() == APIType::D3D)
ss << "cbuffer UBO : register(b0)\n";
ss << "cbuffer PSBlock : register(b0)\n";
else
ss << "UBO_BINDING(std140, 1) uniform UBO\n";
ss << "UBO_BINDING(std140, 1) uniform PSBlock\n";
}

static void EmitSamplerDeclarations(std::stringstream& ss, u32 start = 0, u32 end = 1,
@@ -661,4 +661,43 @@ std::string GenerateEFBRestorePixelShader()
return ss.str();
}

std::string GenerateImGuiVertexShader()
{
std::stringstream ss;

// Uniform buffer contains the viewport size, and we transform in the vertex shader.
EmitUniformBufferDeclaration(ss);
ss << "{\n";
ss << "float2 u_rcp_viewport_size_mul2;\n";
ss << "};\n\n";

EmitVertexMainDeclaration(ss, 1, 1, true, 1, 1);
ss << "{\n"
<< " v_tex0 = float3(rawtex0.xy, 0.0);\n"
<< " v_col0 = rawcolor0;\n"
<< " opos = float4(rawpos.x * u_rcp_viewport_size_mul2.x - 1.0,"
<< " 1.0 - rawpos.y * u_rcp_viewport_size_mul2.y, 0.0, 1.0);\n";

// NDC space is flipped in Vulkan.
if (GetAPIType() == APIType::Vulkan)
ss << " opos.y = -opos.y;\n";

ss << "}\n";
return ss.str();
}

std::string GenerateImGuiPixelShader()
{
std::stringstream ss;
EmitSamplerDeclarations(ss, 0, 1, false);
EmitPixelMainDeclaration(ss, 1, 1);
ss << "{\n";
ss << " ocol0 = ";
EmitSampleTexture(ss, 0, "float3(v_tex0.xy, 0.0)");
ss << " * v_col0;\n";
ss << "}\n";

return ss.str();
}

} // namespace FramebufferShaderGen
@@ -31,5 +31,7 @@ std::string GenerateColorPixelShader();
std::string GenerateFormatConversionShader(EFBReinterpretType convtype, u32 samples);
std::string GenerateTextureReinterpretShader(TextureFormat from_format, TextureFormat to_format);
std::string GenerateEFBRestorePixelShader();
std::string GenerateImGuiVertexShader();
std::string GenerateImGuiPixelShader();

} // namespace FramebufferShaderGen
@@ -441,8 +441,8 @@ std::string PostProcessing::GetUniformBufferHeader() const
ss << " float4 resolution;\n";
ss << " float4 window_resolution;\n";
ss << " float4 src_rect;\n";
ss << " int src_layer;\n";
ss << " uint time;\n";
ss << " int layer;\n";
for (u32 i = 0; i < 2; i++)
ss << " uint ubo_align_" << unused_counter++ << "_;\n";
ss << "\n";
@@ -499,7 +499,18 @@ std::string PostProcessing::GetHeader() const
else
{
ss << "SAMPLER_BINDING(0) uniform sampler2DArray samp0;\n";
ss << "VARYING_LOCATION(0) in float3 v_tex0;\n";

if (g_ActiveConfig.backend_info.bSupportsGeometryShaders)
{
ss << "VARYING_LOCATION(0) in VertexData {\n";
ss << " float3 v_tex0;\n";
ss << "};\n";
}
else
{
ss << "VARYING_LOCATION(0) in float3 v_tex0;\n";
}

ss << "FRAGMENT_OUTPUT_LOCATION(0) out float4 ocol0;\n";
}

@@ -518,10 +529,10 @@ static float4 ocol0;
}

ss << R"(
float4 Sample() { return texture(samp0, float3(v_tex0.xy, float(layer))); }
float4 SampleLocation(float2 location) { return texture(samp0, float3(location, float(layer))); }
float4 Sample() { return texture(samp0, v_tex0); }
float4 SampleLocation(float2 location) { return texture(samp0, float3(location, float(v_tex0.z))); }
float4 SampleLayer(int layer) { return texture(samp0, float3(v_tex0.xy, float(layer))); }
#define SampleOffset(offset) textureOffset(samp0, float3(v_tex0.xy, float(layer)), offset)
#define SampleOffset(offset) textureOffset(samp0, v_tex0, offset)
float2 GetWindowResolution()
{
@@ -543,6 +554,11 @@ float2 GetCoordinates()
return v_tex0.xy;
}
float GetLayer()
{
return v_tex0.z;
}
uint GetTime()
{
return time;
@@ -592,14 +608,24 @@ bool PostProcessing::CompileVertexShader()
}
else
{
ss << "VARYING_LOCATION(0) out float3 v_tex0;\n";
if (g_ActiveConfig.backend_info.bSupportsGeometryShaders)
{
ss << "VARYING_LOCATION(0) out VertexData {\n";
ss << " float3 v_tex0;\n";
ss << "};\n";
}
else
{
ss << "VARYING_LOCATION(0) out float3 v_tex0;\n";
}

ss << "#define id gl_VertexID\n";
ss << "#define opos gl_Position\n";
ss << "void main() {\n";
}
ss << " v_tex0 = float3(float((id << 1) & 2), float(id & 2), 0.0f);\n";
ss << " opos = float4(v_tex0.xy * float2(2.0f, -2.0f) + float2(-1.0f, 1.0f), 0.0f, 1.0f);\n";
ss << " v_tex0 = float3(src_rect.xy + (src_rect.zw * v_tex0.xy), 0.0f);\n";
ss << " v_tex0 = float3(src_rect.xy + (src_rect.zw * v_tex0.xy), float(src_layer));\n";

if (g_ActiveConfig.backend_info.api_type == APIType::Vulkan)
ss << " opos.y = -opos.y;\n";
@@ -621,8 +647,8 @@ struct BuiltinUniforms
float resolution[4];
float window_resolution[4];
float src_rect[4];
s32 time;
u32 layer;
s32 src_layer;
u32 time;
u32 padding[2];
};

@@ -646,8 +672,8 @@ void PostProcessing::FillUniformBuffer(const MathUtil::Rectangle<int>& src,
{static_cast<float>(src.left) * rcp_src_width, static_cast<float>(src.top) * rcp_src_height,
static_cast<float>(src.GetWidth()) * rcp_src_width,
static_cast<float>(src.GetHeight()) * rcp_src_height},
static_cast<s32>(m_timer.GetTimeElapsed()),
static_cast<u32>(src_layer),
static_cast<s32>(src_layer),
static_cast<u32>(m_timer.GetTimeElapsed()),
};

u8* buf = m_uniform_staging_buffer.data();
@@ -716,9 +742,8 @@ bool PostProcessing::CompilePipeline()
{
AbstractPipelineConfig config = {};
config.vertex_shader = m_vertex_shader.get();
config.geometry_shader = g_ActiveConfig.stereo_mode == StereoMode::QuadBuffer ?
g_shader_cache->GetTexcoordGeometryShader() :
nullptr;
config.geometry_shader =
g_renderer->UseGeometryShaderForUI() ? g_shader_cache->GetTexcoordGeometryShader() : nullptr;
config.pixel_shader = m_pixel_shader.get();
config.rasterization_state = RenderState::GetNoCullRasterizationState(PrimitiveType::Triangles);
config.depth_state = RenderState::GetNoDepthTestingDepthState();

0 comments on commit 5440be9

Please sign in to comment.
You can’t perform that action at this time.