mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2024-11-14 13:27:45 -07:00
D3D: Add geometry shader stereoscopy support.
This commit is contained in:
parent
d5ebdf7a97
commit
9253bb7d96
@ -57,7 +57,7 @@ FramebufferManager::FramebufferManager()
|
||||
D3D11_TEXTURE2D_DESC texdesc;
|
||||
HRESULT hr;
|
||||
|
||||
m_efb.slices = 1;
|
||||
m_efb.slices = (g_ActiveConfig.iStereoMode > 0) ? 2 : 1;
|
||||
|
||||
// EFB color texture - primary render target
|
||||
texdesc = CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R8G8B8A8_UNORM, target_width, target_height, m_efb.slices, 1, D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET, D3D11_USAGE_DEFAULT, 0, sample_desc.Count, sample_desc.Quality);
|
||||
|
@ -173,7 +173,7 @@ bool LineGeometryShader::SetShader(u32 components, float lineWidth,
|
||||
static char buffer[16384];
|
||||
ShaderCode code;
|
||||
code.SetBuffer(buffer);
|
||||
GenerateVSOutputStruct(code, API_D3D);
|
||||
GenerateVSOutputStruct<ShaderCode>(code, API_D3D);
|
||||
code.Write("\n%s", LINE_GS_COMMON);
|
||||
|
||||
std::stringstream numTexCoordsStream;
|
||||
|
@ -167,7 +167,7 @@ bool PointGeometryShader::SetShader(u32 components, float pointSize,
|
||||
static char buffer[16384];
|
||||
ShaderCode code;
|
||||
code.SetBuffer(buffer);
|
||||
GenerateVSOutputStruct(code, API_D3D);
|
||||
GenerateVSOutputStruct<ShaderCode>(code, API_D3D);
|
||||
code.Write("\n%s", POINT_GS_COMMON);
|
||||
|
||||
std::stringstream numTexCoordsStream;
|
||||
|
@ -214,10 +214,20 @@ void VertexManager::vFlush(bool useDstAlpha)
|
||||
GFX_DEBUGGER_PAUSE_LOG_AT(NEXT_ERROR,true,{printf("Fail to set pixel shader\n");});
|
||||
return;
|
||||
}
|
||||
|
||||
if (g_ActiveConfig.iStereoMode > 0)
|
||||
{
|
||||
if (!GeometryShaderCache::SetShader(components))
|
||||
{
|
||||
GFX_DEBUGGER_PAUSE_LOG_AT(NEXT_ERROR, true, { printf("Fail to set pixel shader\n"); });
|
||||
}
|
||||
}
|
||||
|
||||
if (g_ActiveConfig.backend_info.bSupportsBBox && BoundingBox::active)
|
||||
{
|
||||
D3D::context->OMSetRenderTargetsAndUnorderedAccessViews(D3D11_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL, nullptr, nullptr, 2, 1, &BBox::GetUAV(), nullptr);
|
||||
}
|
||||
|
||||
u32 stride = VertexLoaderManager::GetCurrentVertexFormat()->GetVertexStride();
|
||||
|
||||
PrepareDrawBuffers(stride);
|
||||
|
@ -79,7 +79,8 @@ void InitBackendInfo()
|
||||
g_Config.backend_info.bSupportsDualSourceBlend = true;
|
||||
g_Config.backend_info.bSupportsPrimitiveRestart = true;
|
||||
g_Config.backend_info.bSupportsOversizedViewports = false;
|
||||
g_Config.backend_info.bSupportsStereoscopy = false; // TODO: not implemented
|
||||
g_Config.backend_info.bSupportsStereoscopy = true;
|
||||
g_Config.backend_info.bSupportsGSInstancing = false;
|
||||
|
||||
IDXGIFactory* factory;
|
||||
IDXGIAdapter* ad;
|
||||
|
@ -52,14 +52,25 @@ static inline void GenerateGeometryShader(T& out, u32 components, API_TYPE ApiTy
|
||||
uid_data->numTexGens = xfmem.numTexGen.numTexGens;
|
||||
uid_data->pixel_lighting = g_ActiveConfig.bEnablePixelLighting;
|
||||
|
||||
GenerateVSOutputStruct(out, ApiType);
|
||||
GenerateVSOutputStruct<T>(out, ApiType);
|
||||
GenerateGSOutputStruct<T>(out, ApiType);
|
||||
|
||||
out.Write("centroid in VS_OUTPUT o[3];\n");
|
||||
out.Write("centroid out VS_OUTPUT f;\n");
|
||||
if (ApiType == API_OPENGL)
|
||||
{
|
||||
out.Write("centroid in VS_OUTPUT o[3];\n");
|
||||
out.Write("centroid out GS_OUTPUT gs;\n");
|
||||
|
||||
out.Write("flat out int layer;\n");
|
||||
out.Write("void main()\n{\n");
|
||||
}
|
||||
else // D3D
|
||||
{
|
||||
out.Write("[maxvertexcount(6)]\n");
|
||||
out.Write("void main(triangle VS_OUTPUT o[3], inout TriangleStream<GS_OUTPUT> Output)\n{\n");
|
||||
|
||||
out.Write("void main()\n{\n");
|
||||
out.Write("\tGS_OUTPUT gs;\n");
|
||||
}
|
||||
|
||||
out.Write("\tVS_OUTPUT f;\n");
|
||||
|
||||
// If the GPU supports invocation we don't need a for loop and can simply use the
|
||||
// invocation identifier to determine which layer we're rendering.
|
||||
@ -70,7 +81,10 @@ static inline void GenerateGeometryShader(T& out, u32 components, API_TYPE ApiTy
|
||||
|
||||
out.Write("\tfor (int i = 0; i < 3; ++i) {\n");
|
||||
out.Write("\t\tgs.layer = l;\n");
|
||||
out.Write("\t\tgl_Layer = l;\n");
|
||||
|
||||
if (ApiType == API_OPENGL)
|
||||
out.Write("\t\tgl_Layer = l;\n");
|
||||
|
||||
out.Write("\t\tf = o[i];\n");
|
||||
out.Write("\t\tfloat4 pos = o[i].pos;\n");
|
||||
|
||||
@ -88,10 +102,23 @@ static inline void GenerateGeometryShader(T& out, u32 components, API_TYPE ApiTy
|
||||
}
|
||||
|
||||
out.Write("\t\tf.pos.x = pos.x;\n");
|
||||
out.Write("\t\tgl_Position = pos;\n");
|
||||
out.Write("\t\tEmitVertex();\n");
|
||||
|
||||
if (ApiType == API_OPENGL)
|
||||
out.Write("\t\tgl_Position = pos;\n");
|
||||
|
||||
out.Write("\t\tgs.vs = f;\n");
|
||||
|
||||
if (ApiType == API_OPENGL)
|
||||
out.Write("\t\tEmitVertex();\n");
|
||||
else
|
||||
out.Write("\t\tOutput.Append(gs);\n");
|
||||
|
||||
out.Write("\t}\n");
|
||||
out.Write("\tEndPrimitive();\n");
|
||||
|
||||
if (ApiType == API_OPENGL)
|
||||
out.Write("\tEndPrimitive();\n");
|
||||
else
|
||||
out.Write("\t\tOutput.RestartStrip();\n");
|
||||
|
||||
if (!g_ActiveConfig.backend_info.bSupportsGSInstancing)
|
||||
out.Write("\t}\n");
|
||||
|
@ -264,7 +264,8 @@ static inline void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_T
|
||||
}
|
||||
}
|
||||
|
||||
GenerateVSOutputStruct(out, ApiType);
|
||||
GenerateVSOutputStruct<T>(out, ApiType);
|
||||
GenerateGSOutputStruct<T>(out, ApiType);
|
||||
|
||||
const bool forced_early_z = g_ActiveConfig.backend_info.bSupportsEarlyZ && bpmem.UseEarlyDepthTest() && (g_ActiveConfig.bFastDepthCalc || bpmem.alpha_test.TestResult() == AlphaTest::UNDETERMINED);
|
||||
const bool per_pixel_depth = (bpmem.ztex2.op != ZTEXTURE_DISABLE && bpmem.UseLateDepthTest()) || (!g_ActiveConfig.bFastDepthCalc && bpmem.zmode.testenable && !forced_early_z);
|
||||
@ -319,8 +320,7 @@ static inline void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_T
|
||||
uid_data->stereo = g_ActiveConfig.iStereoMode > 0;
|
||||
if (g_ActiveConfig.iStereoMode > 0)
|
||||
{
|
||||
out.Write("centroid in VS_OUTPUT f;\n");
|
||||
out.Write("flat in int layer;\n");
|
||||
out.Write("centroid in GS_OUTPUT gs;\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -348,19 +348,19 @@ static inline void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_T
|
||||
// Let's set up attributes
|
||||
for (unsigned int i = 0; i < numTexgen; ++i)
|
||||
{
|
||||
out.Write("\tfloat3 uv%d = f.tex%d;\n", i, i);
|
||||
out.Write("\tfloat3 uv%d = gs.vs.tex%d;\n", i, i);
|
||||
}
|
||||
out.Write("\tfloat4 clipPos = f.clipPos;\n");
|
||||
out.Write("\tfloat4 clipPos = gs.vs.clipPos;\n");
|
||||
if (g_ActiveConfig.bEnablePixelLighting)
|
||||
{
|
||||
out.Write("\tfloat4 Normal = f.Normal;\n");
|
||||
out.Write("\tfloat4 Normal = gs.vs.Normal;\n");
|
||||
}
|
||||
}
|
||||
|
||||
// On Mali, global variables must be initialized as constants.
|
||||
// This is why we initialize these variables locally instead.
|
||||
out.Write("\tfloat4 colors_0 = %s;\n", (g_ActiveConfig.iStereoMode > 0) ? "f.colors_0" : "colors_02");
|
||||
out.Write("\tfloat4 colors_1 = %s;\n", (g_ActiveConfig.iStereoMode > 0) ? "f.colors_1" : "colors_12");
|
||||
out.Write("\tfloat4 colors_0 = %s;\n", (g_ActiveConfig.iStereoMode > 0) ? "gs.vs.colors_0" : "colors_02");
|
||||
out.Write("\tfloat4 colors_1 = %s;\n", (g_ActiveConfig.iStereoMode > 0) ? "gs.vs.colors_1" : "colors_12");
|
||||
|
||||
out.Write("\tfloat4 rawpos = gl_FragCoord;\n");
|
||||
}
|
||||
@ -940,7 +940,7 @@ static inline void SampleTexture(T& out, const char *texcoords, const char *texs
|
||||
if (ApiType == API_D3D)
|
||||
out.Write("iround(255.0 * Tex%d.Sample(samp%d,%s.xy * " I_TEXDIMS"[%d].xy)).%s;\n", texmap,texmap, texcoords, texmap, texswap);
|
||||
else
|
||||
out.Write("iround(255.0 * texture(samp%d, float3(%s.xy * " I_TEXDIMS"[%d].xy, %s))).%s;\n", texmap, texcoords, texmap, g_ActiveConfig.iStereoMode > 0 ? "layer" : "0.0", texswap);
|
||||
out.Write("iround(255.0 * texture(samp%d, float3(%s.xy * " I_TEXDIMS"[%d].xy, %s))).%s;\n", texmap, texcoords, texmap, g_ActiveConfig.iStereoMode > 0 ? "gs.layer" : "0.0", texswap);
|
||||
}
|
||||
|
||||
static const char *tevAlphaFuncsTable[] =
|
||||
|
@ -14,6 +14,8 @@
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Common/StringUtil.h"
|
||||
#include "VideoCommon/VideoCommon.h"
|
||||
#include "VideoCommon/VideoConfig.h"
|
||||
#include "VideoCommon/XFMemory.h"
|
||||
|
||||
/**
|
||||
* Common interface for classes that need to go through the shader generation path (GenerateVertexShader, GeneratePixelShader)
|
||||
@ -218,6 +220,55 @@ private:
|
||||
std::vector<UidT> m_uids;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
static void DefineOutputStructMember(T& object, API_TYPE api_type, const char* type, const char* name, int var_index, const char* semantic = "", int semantic_index = -1)
|
||||
{
|
||||
object.Write(" %s %s", type, name);
|
||||
if (var_index != -1)
|
||||
object.Write("%d", var_index);
|
||||
|
||||
if (api_type == API_D3D && strlen(semantic) > 0)
|
||||
{
|
||||
if (semantic_index != -1)
|
||||
object.Write(" : %s%d", semantic, semantic_index);
|
||||
else
|
||||
object.Write(" : %s", semantic);
|
||||
}
|
||||
|
||||
object.Write(";\n");
|
||||
}
|
||||
|
||||
template<class T>
|
||||
static inline void GenerateVSOutputStruct(T& object, API_TYPE api_type)
|
||||
{
|
||||
object.Write("struct VS_OUTPUT {\n");
|
||||
|
||||
DefineOutputStructMember(object, api_type, "float4", "pos", -1, "POSITION");
|
||||
DefineOutputStructMember(object, api_type, "float4", "colors_", 0, "COLOR", 0);
|
||||
DefineOutputStructMember(object, api_type, "float4", "colors_", 1, "COLOR", 1);
|
||||
|
||||
for (unsigned int i = 0; i < xfmem.numTexGen.numTexGens; ++i)
|
||||
DefineOutputStructMember(object, api_type, "float3", "tex", i, "TEXCOORD", i);
|
||||
|
||||
DefineOutputStructMember(object, api_type, "float4", "clipPos", -1, "TEXCOORD", xfmem.numTexGen.numTexGens);
|
||||
|
||||
if (g_ActiveConfig.bEnablePixelLighting)
|
||||
DefineOutputStructMember(object, api_type, "float4", "Normal", -1, "TEXCOORD", xfmem.numTexGen.numTexGens + 1);
|
||||
|
||||
object.Write("};\n");
|
||||
}
|
||||
|
||||
template<class T>
|
||||
static inline void GenerateGSOutputStruct(T& object, API_TYPE api_type)
|
||||
{
|
||||
object.Write("struct GS_OUTPUT {\n");
|
||||
|
||||
DefineOutputStructMember(object, api_type, "VS_OUTPUT", "vs", -1, "");
|
||||
DefineOutputStructMember(object, api_type, (api_type == API_OPENGL) ? "flat int" : "uint", "layer", -1, "SV_RenderTargetArrayIndex");
|
||||
|
||||
object.Write("};\n");
|
||||
}
|
||||
|
||||
// Constant variable names
|
||||
#define I_COLORS "color"
|
||||
#define I_KCOLORS "k"
|
||||
|
@ -14,43 +14,6 @@
|
||||
|
||||
static char text[16768];
|
||||
|
||||
template<class T>
|
||||
static void DefineVSOutputStructMember(T& object, API_TYPE api_type, const char* type, const char* name, int var_index, const char* semantic, int semantic_index = -1)
|
||||
{
|
||||
object.Write(" %s %s", type, name);
|
||||
if (var_index != -1)
|
||||
object.Write("%d", var_index);
|
||||
|
||||
if (api_type == API_OPENGL)
|
||||
object.Write(";\n");
|
||||
else // D3D
|
||||
{
|
||||
if (semantic_index != -1)
|
||||
object.Write(" : %s%d;\n", semantic, semantic_index);
|
||||
else
|
||||
object.Write(" : %s;\n", semantic);
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
static inline void GenerateVSOutputStruct(T& object, API_TYPE api_type)
|
||||
{
|
||||
object.Write("struct VS_OUTPUT {\n");
|
||||
DefineVSOutputStructMember(object, api_type, "float4", "pos", -1, "POSITION");
|
||||
DefineVSOutputStructMember(object, api_type, "float4", "colors_", 0, "COLOR", 0);
|
||||
DefineVSOutputStructMember(object, api_type, "float4", "colors_", 1, "COLOR", 1);
|
||||
|
||||
for (unsigned int i = 0; i < xfmem.numTexGen.numTexGens; ++i)
|
||||
DefineVSOutputStructMember(object, api_type, "float3", "tex", i, "TEXCOORD", i);
|
||||
|
||||
DefineVSOutputStructMember(object, api_type, "float4", "clipPos", -1, "TEXCOORD", xfmem.numTexGen.numTexGens);
|
||||
|
||||
if (g_ActiveConfig.bEnablePixelLighting)
|
||||
DefineVSOutputStructMember(object, api_type, "float4", "Normal", -1, "TEXCOORD", xfmem.numTexGen.numTexGens + 1);
|
||||
|
||||
object.Write("};\n");
|
||||
}
|
||||
|
||||
template<class T>
|
||||
static inline void GenerateVertexShader(T& out, u32 components, API_TYPE api_type)
|
||||
{
|
||||
@ -79,7 +42,7 @@ static inline void GenerateVertexShader(T& out, u32 components, API_TYPE api_typ
|
||||
out.Write(s_shader_uniforms);
|
||||
out.Write("};\n");
|
||||
|
||||
GenerateVSOutputStruct(out, api_type);
|
||||
GenerateVSOutputStruct<T>(out, api_type);
|
||||
|
||||
uid_data->numTexGens = xfmem.numTexGen.numTexGens;
|
||||
uid_data->components = components;
|
||||
@ -464,13 +427,3 @@ void GenerateVertexShaderCode(VertexShaderCode& object, u32 components, API_TYPE
|
||||
{
|
||||
GenerateVertexShader<VertexShaderCode>(object, components, api_type);
|
||||
}
|
||||
|
||||
void GenerateVSOutputStruct(ShaderCode& object, API_TYPE api_type)
|
||||
{
|
||||
GenerateVSOutputStruct<ShaderCode>(object, api_type);
|
||||
}
|
||||
|
||||
void GenerateVSOutputStruct(ShaderGeneratorInterface& object, API_TYPE api_type)
|
||||
{
|
||||
// Ignore unknown types
|
||||
}
|
||||
|
@ -7,7 +7,6 @@
|
||||
#include "VideoCommon/LightingShaderGen.h"
|
||||
#include "VideoCommon/ShaderGenCommon.h"
|
||||
#include "VideoCommon/VideoCommon.h"
|
||||
#include "VideoCommon/XFMemory.h"
|
||||
|
||||
// TODO should be reordered
|
||||
#define SHADER_POSITION_ATTRIB 0
|
||||
@ -64,5 +63,3 @@ typedef ShaderCode VertexShaderCode; // TODO: Obsolete..
|
||||
|
||||
void GetVertexShaderUid(VertexShaderUid& object, u32 components, API_TYPE api_type);
|
||||
void GenerateVertexShaderCode(VertexShaderCode& object, u32 components, API_TYPE api_type);
|
||||
void GenerateVSOutputStruct(ShaderCode& object, API_TYPE api_type);
|
||||
void GenerateVSOutputStruct(ShaderGeneratorInterface& object, API_TYPE api_type);
|
||||
|
Loading…
Reference in New Issue
Block a user