VideoCommon: Merge PointGeometryShader into GeometryShaderGen.
This adds point-width emulation support to OpenGL.
This commit is contained in:
parent
55e60a9c22
commit
8ae738ff30
|
@ -48,7 +48,6 @@
|
|||
<ClCompile Include="NativeVertexFormat.cpp" />
|
||||
<ClCompile Include="PerfQuery.cpp" />
|
||||
<ClCompile Include="PixelShaderCache.cpp" />
|
||||
<ClCompile Include="PointGeometryShader.cpp" />
|
||||
<ClCompile Include="PSTextureEncoder.cpp" />
|
||||
<ClCompile Include="Render.cpp" />
|
||||
<ClCompile Include="Television.cpp" />
|
||||
|
@ -71,7 +70,6 @@
|
|||
<ClInclude Include="main.h" />
|
||||
<ClInclude Include="PerfQuery.h" />
|
||||
<ClInclude Include="PixelShaderCache.h" />
|
||||
<ClInclude Include="PointGeometryShader.h" />
|
||||
<ClInclude Include="PSTextureEncoder.h" />
|
||||
<ClInclude Include="Render.h" />
|
||||
<ClInclude Include="Television.h" />
|
||||
|
|
|
@ -42,9 +42,6 @@
|
|||
<ClCompile Include="PixelShaderCache.cpp">
|
||||
<Filter>Render</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="PointGeometryShader.cpp">
|
||||
<Filter>Render</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="PSTextureEncoder.cpp">
|
||||
<Filter>Render</Filter>
|
||||
</ClCompile>
|
||||
|
@ -102,9 +99,6 @@
|
|||
<ClInclude Include="PixelShaderCache.h">
|
||||
<Filter>Render</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="PointGeometryShader.h">
|
||||
<Filter>Render</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="PSTextureEncoder.h">
|
||||
<Filter>Render</Filter>
|
||||
</ClInclude>
|
||||
|
|
|
@ -1,233 +0,0 @@
|
|||
// Copyright 2013 Dolphin Emulator Project
|
||||
// Licensed under GPLv2
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#include "VideoBackends/D3D/D3DBase.h"
|
||||
#include "VideoBackends/D3D/D3DShader.h"
|
||||
#include "VideoBackends/D3D/D3DState.h"
|
||||
#include "VideoBackends/D3D/PointGeometryShader.h"
|
||||
#include "VideoCommon/VertexShaderGen.h"
|
||||
|
||||
namespace DX11
|
||||
{
|
||||
|
||||
struct PointGSParams
|
||||
{
|
||||
FLOAT PointSize; // In units of 1/6 of an EFB pixel
|
||||
FLOAT TexOffset;
|
||||
FLOAT VpWidth; // Width and height of viewport in EFB pixels
|
||||
FLOAT VpHeight;
|
||||
FLOAT TexOffsetEnable[8]; // For each tex coordinate, whether to apply offset to it (1 on, 0 off)
|
||||
};
|
||||
|
||||
union PointGSParams_Padded
|
||||
{
|
||||
PointGSParams params;
|
||||
// Constant buffers must be a multiple of 16 bytes in size.
|
||||
u8 pad[(sizeof(PointGSParams) + 15) & ~15];
|
||||
};
|
||||
|
||||
static const char POINT_GS_COMMON[] =
|
||||
// The struct VS_OUTPUT used by the vertex shader goes here.
|
||||
"// dolphin-emu point geometry shader common part\n"
|
||||
|
||||
"cbuffer cbParams : register(b0)\n"
|
||||
"{\n"
|
||||
"struct\n" // Should match PointGSParams above
|
||||
"{\n"
|
||||
"float PointSize;\n"
|
||||
"float TexOffset;\n"
|
||||
"float VpWidth;\n"
|
||||
"float VpHeight;\n"
|
||||
"float TexOffsetEnable[8];\n"
|
||||
"} Params;\n"
|
||||
"}\n"
|
||||
|
||||
"[maxvertexcount(4)]\n"
|
||||
"void main(point VS_OUTPUT input[1], inout TriangleStream<VS_OUTPUT> outStream)\n"
|
||||
"{\n"
|
||||
"VS_OUTPUT ptLL = input[0];\n"
|
||||
"VS_OUTPUT ptLR = ptLL;\n"
|
||||
"VS_OUTPUT ptUL = ptLL;\n"
|
||||
"VS_OUTPUT ptUR = ptLL;\n"
|
||||
|
||||
// Offset from center to upper right vertex
|
||||
// Lerp Params.PointSize/2 from [0,0..VpWidth,VpHeight] to [-1,1..1,-1]
|
||||
"float2 offset = float2(Params.PointSize/Params.VpWidth, -Params.PointSize/Params.VpHeight) * input[0].pos.w;\n"
|
||||
|
||||
"ptLL.pos.xy += float2(-1,-1) * offset;\n"
|
||||
"ptLR.pos.xy += float2(1,-1) * offset;\n"
|
||||
"ptUL.pos.xy += float2(-1,1) * offset;\n"
|
||||
"ptUR.pos.xy += offset;\n"
|
||||
|
||||
"float2 texOffset = float2(Params.TexOffset, Params.TexOffset);\n"
|
||||
|
||||
"#ifndef NUM_TEXCOORDS\n"
|
||||
"#error NUM_TEXCOORDS not defined\n"
|
||||
"#endif\n"
|
||||
|
||||
// Apply TexOffset to all tex coordinates in the vertex
|
||||
// FIXME: The game may be able to enable TexOffset for some coords and
|
||||
// disable for others, but where is that information stored?
|
||||
"#if NUM_TEXCOORDS >= 1\n"
|
||||
"ptLL.tex0.xy += float2(0,1) * texOffset * Params.TexOffsetEnable[0];\n"
|
||||
"ptLR.tex0.xy += texOffset * Params.TexOffsetEnable[0];\n"
|
||||
"ptUR.tex0.xy += float2(1,0) * texOffset * Params.TexOffsetEnable[0];\n"
|
||||
"#endif\n"
|
||||
"#if NUM_TEXCOORDS >= 2\n"
|
||||
"ptLL.tex1.xy += float2(0,1) * texOffset * Params.TexOffsetEnable[1];\n"
|
||||
"ptLR.tex1.xy += texOffset * Params.TexOffsetEnable[1];\n"
|
||||
"ptUR.tex1.xy += float2(1,0) * texOffset * Params.TexOffsetEnable[1];\n"
|
||||
"#endif\n"
|
||||
"#if NUM_TEXCOORDS >= 3\n"
|
||||
"ptLL.tex2.xy += float2(0,1) * texOffset * Params.TexOffsetEnable[2];\n"
|
||||
"ptLR.tex2.xy += texOffset * Params.TexOffsetEnable[2];\n"
|
||||
"ptUR.tex2.xy += float2(1,0) * texOffset * Params.TexOffsetEnable[2];\n"
|
||||
"#endif\n"
|
||||
"#if NUM_TEXCOORDS >= 4\n"
|
||||
"ptLL.tex3.xy += float2(0,1) * texOffset * Params.TexOffsetEnable[3];\n"
|
||||
"ptLR.tex3.xy += texOffset * Params.TexOffsetEnable[3];\n"
|
||||
"ptUR.tex3.xy += float2(1,0) * texOffset * Params.TexOffsetEnable[3];\n"
|
||||
"#endif\n"
|
||||
"#if NUM_TEXCOORDS >= 5\n"
|
||||
"ptLL.tex4.xy += float2(0,1) * texOffset * Params.TexOffsetEnable[4];\n"
|
||||
"ptLR.tex4.xy += texOffset * Params.TexOffsetEnable[4];\n"
|
||||
"ptUR.tex4.xy += float2(1,0) * texOffset * Params.TexOffsetEnable[4];\n"
|
||||
"#endif\n"
|
||||
"#if NUM_TEXCOORDS >= 6\n"
|
||||
"ptLL.tex5.xy += float2(0,1) * texOffset * Params.TexOffsetEnable[5];\n"
|
||||
"ptLR.tex5.xy += texOffset * Params.TexOffsetEnable[5];\n"
|
||||
"ptUR.tex5.xy += float2(1,0) * texOffset * Params.TexOffsetEnable[5];\n"
|
||||
"#endif\n"
|
||||
"#if NUM_TEXCOORDS >= 7\n"
|
||||
"ptLL.tex6.xy += float2(0,1) * texOffset * Params.TexOffsetEnable[6];\n"
|
||||
"ptLR.tex6.xy += texOffset * Params.TexOffsetEnable[6];\n"
|
||||
"ptUR.tex6.xy += float2(1,0) * texOffset * Params.TexOffsetEnable[6];\n"
|
||||
"#endif\n"
|
||||
"#if NUM_TEXCOORDS >= 8\n"
|
||||
"ptLL.tex7.xy += float2(0,1) * texOffset * Params.TexOffsetEnable[7];\n"
|
||||
"ptLR.tex7.xy += texOffset * Params.TexOffsetEnable[7];\n"
|
||||
"ptUR.tex7.xy += float2(1,0) * texOffset * Params.TexOffsetEnable[7];\n"
|
||||
"#endif\n"
|
||||
|
||||
"outStream.Append(ptLL);\n"
|
||||
"outStream.Append(ptLR);\n"
|
||||
"outStream.Append(ptUL);\n"
|
||||
"outStream.Append(ptUR);\n"
|
||||
"}\n"
|
||||
;
|
||||
|
||||
PointGeometryShader::PointGeometryShader()
|
||||
: m_ready(false), m_paramsBuffer(nullptr)
|
||||
{ }
|
||||
|
||||
void PointGeometryShader::Init()
|
||||
{
|
||||
m_ready = false;
|
||||
|
||||
HRESULT hr;
|
||||
|
||||
// Create constant buffer for uploading data to geometry shader
|
||||
|
||||
D3D11_BUFFER_DESC bd = CD3D11_BUFFER_DESC(sizeof(PointGSParams_Padded),
|
||||
D3D11_BIND_CONSTANT_BUFFER, D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE);
|
||||
hr = D3D::device->CreateBuffer(&bd, nullptr, &m_paramsBuffer);
|
||||
CHECK(SUCCEEDED(hr), "create point geometry shader params buffer");
|
||||
D3D::SetDebugObjectName(m_paramsBuffer, "point geometry shader params buffer");
|
||||
|
||||
m_ready = true;
|
||||
}
|
||||
|
||||
void PointGeometryShader::Shutdown()
|
||||
{
|
||||
m_ready = false;
|
||||
|
||||
for (auto& it : m_shaders)
|
||||
{
|
||||
SAFE_RELEASE(it.second);
|
||||
}
|
||||
m_shaders.clear();
|
||||
|
||||
SAFE_RELEASE(m_paramsBuffer);
|
||||
}
|
||||
|
||||
bool PointGeometryShader::SetShader(u32 components, float pointSize,
|
||||
float texOffset, float vpWidth, float vpHeight, const bool* texOffsetEnable)
|
||||
{
|
||||
if (!m_ready)
|
||||
return false;
|
||||
|
||||
// Make sure geometry shader for "components" is available
|
||||
ComboMap::iterator shaderIt = m_shaders.find(components);
|
||||
if (shaderIt == m_shaders.end())
|
||||
{
|
||||
// Generate new shader. Warning: not thread-safe.
|
||||
static char buffer[16384];
|
||||
ShaderCode code;
|
||||
code.SetBuffer(buffer);
|
||||
GenerateVSOutputStruct<ShaderCode>(code, API_D3D);
|
||||
code.Write("\n%s", POINT_GS_COMMON);
|
||||
|
||||
std::stringstream numTexCoordsStream;
|
||||
numTexCoordsStream << xfmem.numTexGen.numTexGens;
|
||||
|
||||
INFO_LOG(VIDEO, "Compiling point geometry shader for components 0x%.08X (num texcoords %d)",
|
||||
components, xfmem.numTexGen.numTexGens);
|
||||
|
||||
const std::string& numTexCoordsStr = numTexCoordsStream.str();
|
||||
D3D_SHADER_MACRO macros[] = {
|
||||
{ "NUM_TEXCOORDS", numTexCoordsStr.c_str() },
|
||||
{ nullptr, nullptr }
|
||||
};
|
||||
ID3D11GeometryShader* newShader = D3D::CompileAndCreateGeometryShader(code.GetBuffer(), macros);
|
||||
if (!newShader)
|
||||
{
|
||||
WARN_LOG(VIDEO, "Point geometry shader for components 0x%.08X failed to compile", components);
|
||||
// Add dummy shader to prevent trying to compile again
|
||||
m_shaders[components] = nullptr;
|
||||
return false;
|
||||
}
|
||||
|
||||
shaderIt = m_shaders.insert(std::make_pair(components, newShader)).first;
|
||||
}
|
||||
|
||||
if (shaderIt != m_shaders.end())
|
||||
{
|
||||
if (shaderIt->second)
|
||||
{
|
||||
D3D11_MAPPED_SUBRESOURCE map;
|
||||
HRESULT hr = D3D::context->Map(m_paramsBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &map);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
PointGSParams* params = (PointGSParams*)map.pData;
|
||||
params->PointSize = pointSize;
|
||||
|
||||
params->TexOffset = texOffset;
|
||||
params->VpWidth = vpWidth;
|
||||
params->VpHeight = vpHeight;
|
||||
for (int i = 0; i < 8; ++i)
|
||||
params->TexOffsetEnable[i] = texOffsetEnable[i] ? 1.f : 0.f;
|
||||
|
||||
D3D::context->Unmap(m_paramsBuffer, 0);
|
||||
}
|
||||
else
|
||||
ERROR_LOG(VIDEO, "Failed to map point gs params buffer");
|
||||
|
||||
DEBUG_LOG(VIDEO, "Point params: size %f, texOffset %f, vpWidth %f, vpHeight %f",
|
||||
pointSize, texOffset, vpWidth, vpHeight);
|
||||
|
||||
D3D::stateman->SetGeometryShader(shaderIt->second);
|
||||
D3D::stateman->SetGeometryConstants(m_paramsBuffer);
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
// Copyright 2013 Dolphin Emulator Project
|
||||
// Licensed under GPLv2
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "VideoCommon/VideoCommon.h"
|
||||
|
||||
struct ID3D11Buffer;
|
||||
struct ID3D11GeometryShader;
|
||||
|
||||
namespace DX11
|
||||
{
|
||||
|
||||
// This class manages a collection of point geometry shaders, one for each
|
||||
// vertex format.
|
||||
class PointGeometryShader
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
PointGeometryShader();
|
||||
|
||||
void Init();
|
||||
void Shutdown();
|
||||
// Returns true on success, false on failure
|
||||
bool SetShader(u32 components, float pointSize, float texOffset,
|
||||
float vpWidth, float vpHeight, const bool* texOffsetEnable);
|
||||
|
||||
private:
|
||||
|
||||
bool m_ready;
|
||||
|
||||
ID3D11Buffer* m_paramsBuffer;
|
||||
|
||||
typedef std::map<u32, ID3D11GeometryShader*> ComboMap;
|
||||
|
||||
ComboMap m_shaders;
|
||||
|
||||
};
|
||||
|
||||
}
|
|
@ -48,14 +48,10 @@ void VertexManager::CreateDeviceObjects()
|
|||
|
||||
m_currentBuffer = 0;
|
||||
m_bufferCursor = MAX_BUFFER_SIZE;
|
||||
|
||||
m_pointShader.Init();
|
||||
}
|
||||
|
||||
void VertexManager::DestroyDeviceObjects()
|
||||
{
|
||||
m_pointShader.Shutdown();
|
||||
|
||||
for (int i = 0; i < MAX_BUFFER_COUNT; i++)
|
||||
{
|
||||
SAFE_RELEASE(m_buffers[i]);
|
||||
|
@ -158,28 +154,16 @@ void VertexManager::Draw(u32 stride)
|
|||
}
|
||||
else //if (current_primitive_type == PRIMITIVE_POINTS)
|
||||
{
|
||||
float pointSize = float(bpmem.lineptwidth.pointsize) / 6.f;
|
||||
float texOffset = LINE_PT_TEX_OFFSETS[bpmem.lineptwidth.pointoff];
|
||||
float vpWidth = 2.0f * xfmem.viewport.wd;
|
||||
float vpHeight = -2.0f * xfmem.viewport.ht;
|
||||
D3D::stateman->SetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_POINTLIST);
|
||||
D3D::stateman->SetGeometryConstants(GeometryShaderCache::GetConstantBuffer());
|
||||
D3D::stateman->SetGeometryShader(GeometryShaderCache::GetActiveShader());
|
||||
|
||||
bool texOffsetEnable[8];
|
||||
D3D::stateman->Apply();
|
||||
D3D::context->DrawIndexed(indices, startIndex, baseVertex);
|
||||
|
||||
for (int i = 0; i < 8; ++i)
|
||||
texOffsetEnable[i] = bpmem.texcoords[i].s.point_offset;
|
||||
INCSTAT(stats.thisFrame.numDrawCalls);
|
||||
|
||||
if (m_pointShader.SetShader(components, pointSize,
|
||||
texOffset, vpWidth, vpHeight, texOffsetEnable))
|
||||
{
|
||||
D3D::stateman->SetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_POINTLIST);
|
||||
|
||||
D3D::stateman->Apply();
|
||||
D3D::context->DrawIndexed(indices, startIndex, baseVertex);
|
||||
|
||||
INCSTAT(stats.thisFrame.numDrawCalls);
|
||||
|
||||
D3D::stateman->SetGeometryShader(nullptr);
|
||||
}
|
||||
D3D::stateman->SetGeometryShader(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "VideoBackends/D3D/PointGeometryShader.h"
|
||||
#include "VideoCommon/VertexManagerBase.h"
|
||||
|
||||
namespace DX11
|
||||
|
@ -39,8 +38,6 @@ private:
|
|||
enum { MAX_BUFFER_COUNT = 2 };
|
||||
ID3D11Buffer* m_buffers[MAX_BUFFER_COUNT];
|
||||
|
||||
PointGeometryShader m_pointShader;
|
||||
|
||||
std::vector<u8> LocalVBuffer;
|
||||
std::vector<u16> LocalIBuffer;
|
||||
};
|
||||
|
|
|
@ -140,6 +140,12 @@ static inline void GenerateGeometryShader(T& out, u32 primitive_type, API_TYPE A
|
|||
out.Write("\t\toffset = float2(0, -" I_LINEPTWIDTH"[0] / " I_VIEWPORT".y);\n");
|
||||
out.Write("\t}\n");
|
||||
}
|
||||
else if (primitive_type == PRIMITIVE_POINTS)
|
||||
{
|
||||
// Offset from center to upper right vertex
|
||||
// Lerp PointSize/2 from [0,0..VpWidth,VpHeight] to [-1,1..1,-1]
|
||||
out.Write("float2 offset = float2(" I_LINEPTWIDTH"[1] / " I_VIEWPORT".x, -" I_LINEPTWIDTH"[1] / " I_VIEWPORT".y) * o[0].pos.w;\n");
|
||||
}
|
||||
|
||||
if (g_ActiveConfig.iStereoMode > 0)
|
||||
{
|
||||
|
@ -186,12 +192,38 @@ static inline void GenerateGeometryShader(T& out, u32 primitive_type, API_TYPE A
|
|||
|
||||
for (unsigned int i = 0; i < bpmem.genMode.numtexgens; ++i)
|
||||
{
|
||||
out.Write("\tr.tex%d.x += " I_LINEPTWIDTH"[2] * (" I_TEXOFFSETFLAGS"[%d] % 2);\n", i, i);
|
||||
out.Write("\tr.tex%d.x += " I_LINEPTWIDTH"[2] * (" I_TEXOFFSETFLAGS"[%d] & 0x01);\n", i, i);
|
||||
}
|
||||
|
||||
EmitVertex<T>(out, "l", ApiType);
|
||||
EmitVertex<T>(out, "r", ApiType);
|
||||
}
|
||||
else if (primitive_type == PRIMITIVE_POINTS)
|
||||
{
|
||||
out.Write("VS_OUTPUT ll = f;\n");
|
||||
out.Write("VS_OUTPUT lr = f;\n");
|
||||
out.Write("VS_OUTPUT ul = f;\n");
|
||||
out.Write("VS_OUTPUT ur = f;\n");
|
||||
|
||||
out.Write("ll.pos.xy += float2(-1,-1) * offset;\n");
|
||||
out.Write("lr.pos.xy += float2(1,-1) * offset;\n");
|
||||
out.Write("ul.pos.xy += float2(-1,1) * offset;\n");
|
||||
out.Write("ur.pos.xy += offset;\n");
|
||||
|
||||
out.Write("float2 texOffset = float2(" I_LINEPTWIDTH"[3], " I_LINEPTWIDTH"[3]);\n");
|
||||
|
||||
for (unsigned int i = 0; i < bpmem.genMode.numtexgens; ++i)
|
||||
{
|
||||
out.Write("ll.tex%d.xy += float2(0,1) * texOffset * (" I_TEXOFFSETFLAGS"[%d] & 0x10);\n", i, i);
|
||||
out.Write("lr.tex%d.xy += texOffset * (" I_TEXOFFSETFLAGS"[%d] & 0x10);\n", i, i);
|
||||
out.Write("ur.tex%d.xy += float2(1,0) * texOffset * (" I_TEXOFFSETFLAGS"[%d] & 0x10);\n", i, i);
|
||||
}
|
||||
|
||||
EmitVertex<T>(out, "ll", ApiType);
|
||||
EmitVertex<T>(out, "lr", ApiType);
|
||||
EmitVertex<T>(out, "ul", ApiType);
|
||||
EmitVertex<T>(out, "ur", ApiType);
|
||||
}
|
||||
else
|
||||
{
|
||||
EmitVertex<T>(out, "f", ApiType);
|
||||
|
|
Loading…
Reference in New Issue