diff --git a/Source/Core/VideoBackends/D3D/D3D.vcxproj b/Source/Core/VideoBackends/D3D/D3D.vcxproj index f1334b8f8f..a83e265c34 100644 --- a/Source/Core/VideoBackends/D3D/D3D.vcxproj +++ b/Source/Core/VideoBackends/D3D/D3D.vcxproj @@ -48,7 +48,6 @@ - @@ -71,7 +70,6 @@ - diff --git a/Source/Core/VideoBackends/D3D/D3D.vcxproj.filters b/Source/Core/VideoBackends/D3D/D3D.vcxproj.filters index d6f7331c37..e5f5baf882 100644 --- a/Source/Core/VideoBackends/D3D/D3D.vcxproj.filters +++ b/Source/Core/VideoBackends/D3D/D3D.vcxproj.filters @@ -42,9 +42,6 @@ Render - - Render - Render @@ -102,9 +99,6 @@ Render - - Render - Render diff --git a/Source/Core/VideoBackends/D3D/PointGeometryShader.cpp b/Source/Core/VideoBackends/D3D/PointGeometryShader.cpp deleted file mode 100644 index 3f874b3915..0000000000 --- a/Source/Core/VideoBackends/D3D/PointGeometryShader.cpp +++ /dev/null @@ -1,233 +0,0 @@ -// Copyright 2013 Dolphin Emulator Project -// Licensed under GPLv2 -// Refer to the license.txt file included. - -#include - -#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 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(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; -} - -} diff --git a/Source/Core/VideoBackends/D3D/PointGeometryShader.h b/Source/Core/VideoBackends/D3D/PointGeometryShader.h deleted file mode 100644 index b24f73d486..0000000000 --- a/Source/Core/VideoBackends/D3D/PointGeometryShader.h +++ /dev/null @@ -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 ComboMap; - - ComboMap m_shaders; - -}; - -} diff --git a/Source/Core/VideoBackends/D3D/VertexManager.cpp b/Source/Core/VideoBackends/D3D/VertexManager.cpp index dcd1ad1569..9f2b2ba318 100644 --- a/Source/Core/VideoBackends/D3D/VertexManager.cpp +++ b/Source/Core/VideoBackends/D3D/VertexManager.cpp @@ -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); } } diff --git a/Source/Core/VideoBackends/D3D/VertexManager.h b/Source/Core/VideoBackends/D3D/VertexManager.h index 12e3bf2d4b..0b124d7512 100644 --- a/Source/Core/VideoBackends/D3D/VertexManager.h +++ b/Source/Core/VideoBackends/D3D/VertexManager.h @@ -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 LocalVBuffer; std::vector LocalIBuffer; }; diff --git a/Source/Core/VideoCommon/GeometryShaderGen.cpp b/Source/Core/VideoCommon/GeometryShaderGen.cpp index ee6da0fe4d..fabd883ded 100644 --- a/Source/Core/VideoCommon/GeometryShaderGen.cpp +++ b/Source/Core/VideoCommon/GeometryShaderGen.cpp @@ -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(out, "l", ApiType); EmitVertex(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(out, "ll", ApiType); + EmitVertex(out, "lr", ApiType); + EmitVertex(out, "ul", ApiType); + EmitVertex(out, "ur", ApiType); + } else { EmitVertex(out, "f", ApiType);