D3DUtil: Use a geometry shader to clear all slices.

This commit is contained in:
Jules Blok 2014-11-23 02:13:25 +01:00
parent 799697ad80
commit 3355d8086d
5 changed files with 56 additions and 6 deletions

View File

@ -10,6 +10,7 @@
#include "VideoBackends/D3D/D3DShader.h" #include "VideoBackends/D3D/D3DShader.h"
#include "VideoBackends/D3D/D3DState.h" #include "VideoBackends/D3D/D3DState.h"
#include "VideoBackends/D3D/D3DUtil.h" #include "VideoBackends/D3D/D3DUtil.h"
#include "VideoBackends/D3D/GeometryShaderCache.h"
#include "VideoBackends/D3D/PixelShaderCache.h" #include "VideoBackends/D3D/PixelShaderCache.h"
#include "VideoBackends/D3D/VertexShaderCache.h" #include "VideoBackends/D3D/VertexShaderCache.h"
@ -653,6 +654,7 @@ void drawColorQuad(u32 Color, float x1, float y1, float x2, float y2)
} }
stateman->SetVertexShader(VertexShaderCache::GetClearVertexShader()); stateman->SetVertexShader(VertexShaderCache::GetClearVertexShader());
stateman->SetGeometryShader(g_ActiveConfig.iStereoMode > 0 ? GeometryShaderCache::GetClearGeometryShader() : nullptr);
stateman->SetPixelShader(PixelShaderCache::GetClearProgram()); stateman->SetPixelShader(PixelShaderCache::GetClearProgram());
stateman->SetInputLayout(VertexShaderCache::GetClearInputLayout()); stateman->SetInputLayout(VertexShaderCache::GetClearInputLayout());
@ -663,9 +665,11 @@ void drawColorQuad(u32 Color, float x1, float y1, float x2, float y2)
stateman->Apply(); stateman->Apply();
context->Draw(4, cq_offset); context->Draw(4, cq_offset);
stateman->SetGeometryShader(nullptr);
} }
void drawClearQuad(u32 Color, float z, ID3D11PixelShader* PShader, ID3D11VertexShader* Vshader, ID3D11InputLayout* layout) void drawClearQuad(u32 Color, float z)
{ {
ClearVertex coords[4] = { ClearVertex coords[4] = {
{-1.0f, 1.0f, z, Color}, {-1.0f, 1.0f, z, Color},
@ -683,9 +687,10 @@ void drawClearQuad(u32 Color, float z, ID3D11PixelShader* PShader, ID3D11VertexS
clear_quad_data.z = z; clear_quad_data.z = z;
} }
stateman->SetVertexShader(Vshader); stateman->SetVertexShader(VertexShaderCache::GetClearVertexShader());
stateman->SetPixelShader(PShader); stateman->SetGeometryShader(g_ActiveConfig.iStereoMode > 0 ? GeometryShaderCache::GetClearGeometryShader() : nullptr);
stateman->SetInputLayout(layout); stateman->SetPixelShader(PixelShaderCache::GetClearProgram());
stateman->SetInputLayout(VertexShaderCache::GetClearInputLayout());
UINT stride = sizeof(ClearVertex); UINT stride = sizeof(ClearVertex);
UINT offset = 0; UINT offset = 0;
@ -694,6 +699,8 @@ void drawClearQuad(u32 Color, float z, ID3D11PixelShader* PShader, ID3D11VertexS
stateman->Apply(); stateman->Apply();
context->Draw(4, clearq_offset); context->Draw(4, clearq_offset);
stateman->SetGeometryShader(nullptr);
} }
} // namespace D3D } // namespace D3D

View File

@ -74,7 +74,7 @@ namespace D3D
ID3D11InputLayout* layout, ID3D11InputLayout* layout,
float Gamma = 1.0f, float Gamma = 1.0f,
u32 slice = 0); u32 slice = 0);
void drawClearQuad(u32 Color, float z, ID3D11PixelShader* PShader, ID3D11VertexShader* Vshader, ID3D11InputLayout* layout); void drawClearQuad(u32 Color, float z);
void drawColorQuad(u32 Color, float x1, float y1, float x2, float y2); void drawColorQuad(u32 Color, float x1, float y1, float x2, float y2);
} }

View File

@ -27,8 +27,12 @@ const GeometryShaderCache::GSCacheEntry* GeometryShaderCache::last_entry;
GeometryShaderUid GeometryShaderCache::last_uid; GeometryShaderUid GeometryShaderCache::last_uid;
UidChecker<GeometryShaderUid,ShaderCode> GeometryShaderCache::geometry_uid_checker; UidChecker<GeometryShaderUid,ShaderCode> GeometryShaderCache::geometry_uid_checker;
ID3D11GeometryShader* ClearGeometryShader = nullptr;
LinearDiskCache<GeometryShaderUid, u8> g_gs_disk_cache; LinearDiskCache<GeometryShaderUid, u8> g_gs_disk_cache;
ID3D11GeometryShader* GeometryShaderCache::GetClearGeometryShader() { return ClearGeometryShader; }
ID3D11Buffer* gscbuf = nullptr; ID3D11Buffer* gscbuf = nullptr;
// this class will load the precompiled shaders into our cache // this class will load the precompiled shaders into our cache
@ -41,8 +45,43 @@ public:
} }
}; };
const char clear_shader_code[] = {
"struct VSOUTPUT\n"
"{\n"
"float4 vPosition : POSITION;\n"
"float4 vColor0 : COLOR0;\n"
"};\n"
"struct GSOUTPUT\n"
"{\n"
"float4 vPosition : POSITION;\n"
"float4 vColor0 : COLOR0;\n"
"uint slice : SV_RenderTargetArrayIndex;\n"
"};\n"
"[maxvertexcount(6)]\n"
"void main(triangle VSOUTPUT o[3], inout TriangleStream<GSOUTPUT> Output)\n"
"{\n"
"for(int slice = 0; slice < 2; slice++)\n"
"{\n"
"for(int i = 0; i < 3; i++)\n"
"{\n"
"GSOUTPUT OUT;\n"
"OUT.vPosition = o[i].vPosition;\n"
"OUT.vColor0 = o[i].vColor0;\n"
"OUT.slice = slice;\n"
"Output.Append(OUT);\n"
"}\n"
"Output.RestartStrip();\n"
"}\n"
"}\n"
};
void GeometryShaderCache::Init() void GeometryShaderCache::Init()
{ {
// used when drawing clear quads
ClearGeometryShader = D3D::CompileAndCreateGeometryShader(clear_shader_code);
CHECK(ClearGeometryShader != nullptr, "Create clear geometry shader");
D3D::SetDebugObjectName((ID3D11DeviceChild*)ClearGeometryShader, "clear geometry shader");
Clear(); Clear();
if (!File::Exists(File::GetUserPath(D_SHADERCACHE_IDX))) if (!File::Exists(File::GetUserPath(D_SHADERCACHE_IDX)))
@ -72,6 +111,8 @@ void GeometryShaderCache::Clear()
void GeometryShaderCache::Shutdown() void GeometryShaderCache::Shutdown()
{ {
SAFE_RELEASE(ClearGeometryShader);
Clear(); Clear();
g_gs_disk_cache.Sync(); g_gs_disk_cache.Sync();
g_gs_disk_cache.Close(); g_gs_disk_cache.Close();

View File

@ -21,6 +21,8 @@ public:
static bool SetShader(u32 components); // TODO: Should be renamed to LoadShader static bool SetShader(u32 components); // TODO: Should be renamed to LoadShader
static bool InsertByteCode(const GeometryShaderUid &uid, const void* bytecode, unsigned int bytecodelen); static bool InsertByteCode(const GeometryShaderUid &uid, const void* bytecode, unsigned int bytecodelen);
static ID3D11GeometryShader* GeometryShaderCache::GetClearGeometryShader();
static ID3D11GeometryShader* GetActiveShader() { return last_entry->shader; } static ID3D11GeometryShader* GetActiveShader() { return last_entry->shader; }
private: private:

View File

@ -547,7 +547,7 @@ void Renderer::ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaE
// Color is passed in bgra mode so we need to convert it to rgba // Color is passed in bgra mode so we need to convert it to rgba
u32 rgbaColor = (color & 0xFF00FF00) | ((color >> 16) & 0xFF) | ((color << 16) & 0xFF0000); u32 rgbaColor = (color & 0xFF00FF00) | ((color >> 16) & 0xFF) | ((color << 16) & 0xFF0000);
D3D::drawClearQuad(rgbaColor, (z & 0xFFFFFF) / float(0xFFFFFF), PixelShaderCache::GetClearProgram(), VertexShaderCache::GetClearVertexShader(), VertexShaderCache::GetClearInputLayout()); D3D::drawClearQuad(rgbaColor, (z & 0xFFFFFF) / float(0xFFFFFF));
D3D::stateman->PopDepthState(); D3D::stateman->PopDepthState();
D3D::stateman->PopBlendState(); D3D::stateman->PopBlendState();