mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2024-11-14 21:37:52 -07:00
D3D: Add GeometryShaderCache.
This commit is contained in:
parent
9a312e2b83
commit
d5ebdf7a97
@ -43,6 +43,7 @@
|
||||
<ClCompile Include="D3DTexture.cpp" />
|
||||
<ClCompile Include="D3DUtil.cpp" />
|
||||
<ClCompile Include="FramebufferManager.cpp" />
|
||||
<ClCompile Include="GeometryShaderCache.cpp" />
|
||||
<ClCompile Include="LineGeometryShader.cpp" />
|
||||
<ClCompile Include="main.cpp" />
|
||||
<ClCompile Include="NativeVertexFormat.cpp" />
|
||||
@ -66,6 +67,7 @@
|
||||
<ClInclude Include="D3DTexture.h" />
|
||||
<ClInclude Include="D3DUtil.h" />
|
||||
<ClInclude Include="FramebufferManager.h" />
|
||||
<ClInclude Include="GeometryShaderCache.h" />
|
||||
<ClInclude Include="Globals.h" />
|
||||
<ClInclude Include="LineGeometryShader.h" />
|
||||
<ClInclude Include="main.h" />
|
||||
|
@ -30,6 +30,9 @@
|
||||
<ClCompile Include="FramebufferManager.cpp">
|
||||
<Filter>Render</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="GeometryShaderCache.cpp">
|
||||
<Filter>Render</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="LineGeometryShader.cpp">
|
||||
<Filter>Render</Filter>
|
||||
</ClCompile>
|
||||
@ -93,6 +96,9 @@
|
||||
<ClInclude Include="FramebufferManager.h">
|
||||
<Filter>Render</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="GeometryShaderCache.h">
|
||||
<Filter>Render</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="LineGeometryShader.h">
|
||||
<Filter>Render</Filter>
|
||||
</ClInclude>
|
||||
|
160
Source/Core/VideoBackends/D3D/GeometryShaderCache.cpp
Normal file
160
Source/Core/VideoBackends/D3D/GeometryShaderCache.cpp
Normal file
@ -0,0 +1,160 @@
|
||||
// Copyright 2013 Dolphin Emulator Project
|
||||
// Licensed under GPLv2
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "Common/FileUtil.h"
|
||||
#include "Common/LinearDiskCache.h"
|
||||
#include "Common/StringUtil.h"
|
||||
|
||||
#include "Core/ConfigManager.h"
|
||||
|
||||
#include "VideoBackends/D3D/D3DBase.h"
|
||||
#include "VideoBackends/D3D/D3DShader.h"
|
||||
#include "VideoBackends/D3D/GeometryShaderCache.h"
|
||||
#include "VideoBackends/D3D/Globals.h"
|
||||
|
||||
#include "VideoCommon/Debugger.h"
|
||||
#include "VideoCommon/GeometryShaderGen.h"
|
||||
#include "VideoCommon/VideoConfig.h"
|
||||
|
||||
namespace DX11
|
||||
{
|
||||
|
||||
GeometryShaderCache::GSCache GeometryShaderCache::GeometryShaders;
|
||||
const GeometryShaderCache::GSCacheEntry* GeometryShaderCache::last_entry;
|
||||
GeometryShaderUid GeometryShaderCache::last_uid;
|
||||
UidChecker<GeometryShaderUid,ShaderCode> GeometryShaderCache::geometry_uid_checker;
|
||||
|
||||
LinearDiskCache<GeometryShaderUid, u8> g_gs_disk_cache;
|
||||
|
||||
ID3D11Buffer* gscbuf = nullptr;
|
||||
|
||||
// this class will load the precompiled shaders into our cache
|
||||
class GeometryShaderCacheInserter : public LinearDiskCacheReader<GeometryShaderUid, u8>
|
||||
{
|
||||
public:
|
||||
void Read(const GeometryShaderUid &key, const u8 *value, u32 value_size)
|
||||
{
|
||||
GeometryShaderCache::InsertByteCode(key, value, value_size);
|
||||
}
|
||||
};
|
||||
|
||||
void GeometryShaderCache::Init()
|
||||
{
|
||||
Clear();
|
||||
|
||||
if (!File::Exists(File::GetUserPath(D_SHADERCACHE_IDX)))
|
||||
File::CreateDir(File::GetUserPath(D_SHADERCACHE_IDX));
|
||||
|
||||
std::string cache_filename = StringFromFormat("%sdx11-%s-gs.cache", File::GetUserPath(D_SHADERCACHE_IDX).c_str(),
|
||||
SConfig::GetInstance().m_LocalCoreStartupParameter.m_strUniqueID.c_str());
|
||||
GeometryShaderCacheInserter inserter;
|
||||
g_gs_disk_cache.OpenAndRead(cache_filename, inserter);
|
||||
|
||||
if (g_Config.bEnableShaderDebugging)
|
||||
Clear();
|
||||
|
||||
last_entry = nullptr;
|
||||
}
|
||||
|
||||
// ONLY to be used during shutdown.
|
||||
void GeometryShaderCache::Clear()
|
||||
{
|
||||
for (auto& iter : GeometryShaders)
|
||||
iter.second.Destroy();
|
||||
GeometryShaders.clear();
|
||||
geometry_uid_checker.Invalidate();
|
||||
|
||||
last_entry = nullptr;
|
||||
}
|
||||
|
||||
void GeometryShaderCache::Shutdown()
|
||||
{
|
||||
Clear();
|
||||
g_gs_disk_cache.Sync();
|
||||
g_gs_disk_cache.Close();
|
||||
}
|
||||
|
||||
bool GeometryShaderCache::SetShader(u32 components)
|
||||
{
|
||||
GeometryShaderUid uid;
|
||||
GetGeometryShaderUid(uid, components, API_D3D);
|
||||
if (g_ActiveConfig.bEnableShaderDebugging)
|
||||
{
|
||||
ShaderCode code;
|
||||
GenerateGeometryShaderCode(code, components, API_D3D);
|
||||
geometry_uid_checker.AddToIndexAndCheck(code, uid, "Geometry", "g");
|
||||
}
|
||||
|
||||
// Check if the shader is already set
|
||||
if (last_entry)
|
||||
{
|
||||
if (uid == last_uid)
|
||||
{
|
||||
GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE,true);
|
||||
return (last_entry->shader != nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
last_uid = uid;
|
||||
|
||||
// Check if the shader is already in the cache
|
||||
GSCache::iterator iter;
|
||||
iter = GeometryShaders.find(uid);
|
||||
if (iter != GeometryShaders.end())
|
||||
{
|
||||
const GSCacheEntry &entry = iter->second;
|
||||
last_entry = &entry;
|
||||
|
||||
return (entry.shader != nullptr);
|
||||
}
|
||||
|
||||
// Need to compile a new shader
|
||||
ShaderCode code;
|
||||
GenerateGeometryShaderCode(code, components, API_D3D);
|
||||
|
||||
D3DBlob* pbytecode;
|
||||
if (!D3D::CompileGeometryShader(code.GetBuffer(), &pbytecode))
|
||||
{
|
||||
GFX_DEBUGGER_PAUSE_AT(NEXT_ERROR, true);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Insert the bytecode into the caches
|
||||
g_gs_disk_cache.Append(uid, pbytecode->Data(), pbytecode->Size());
|
||||
|
||||
bool success = InsertByteCode(uid, pbytecode->Data(), pbytecode->Size());
|
||||
pbytecode->Release();
|
||||
|
||||
if (g_ActiveConfig.bEnableShaderDebugging && success)
|
||||
{
|
||||
GeometryShaders[uid].code = code.GetBuffer();
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
bool GeometryShaderCache::InsertByteCode(const GeometryShaderUid &uid, const void* bytecode, unsigned int bytecodelen)
|
||||
{
|
||||
ID3D11GeometryShader* shader = D3D::CreateGeometryShaderFromByteCode(bytecode, bytecodelen);
|
||||
if (shader == nullptr)
|
||||
return false;
|
||||
|
||||
// TODO: Somehow make the debug name a bit more specific
|
||||
D3D::SetDebugObjectName((ID3D11DeviceChild*)shader, "a pixel shader of GeometryShaderCache");
|
||||
|
||||
// Make an entry in the table
|
||||
GSCacheEntry newentry;
|
||||
newentry.shader = shader;
|
||||
GeometryShaders[uid] = newentry;
|
||||
last_entry = &GeometryShaders[uid];
|
||||
|
||||
if (!shader)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // DX11
|
46
Source/Core/VideoBackends/D3D/GeometryShaderCache.h
Normal file
46
Source/Core/VideoBackends/D3D/GeometryShaderCache.h
Normal file
@ -0,0 +1,46 @@
|
||||
// Copyright 2013 Dolphin Emulator Project
|
||||
// Licensed under GPLv2
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <d3d11.h>
|
||||
#include <map>
|
||||
|
||||
#include "VideoCommon/GeometryShaderGen.h"
|
||||
|
||||
namespace DX11
|
||||
{
|
||||
|
||||
class GeometryShaderCache
|
||||
{
|
||||
public:
|
||||
static void Init();
|
||||
static void Clear();
|
||||
static void Shutdown();
|
||||
static bool SetShader(u32 components); // TODO: Should be renamed to LoadShader
|
||||
static bool InsertByteCode(const GeometryShaderUid &uid, const void* bytecode, unsigned int bytecodelen);
|
||||
|
||||
static ID3D11GeometryShader* GetActiveShader() { return last_entry->shader; }
|
||||
|
||||
private:
|
||||
struct GSCacheEntry
|
||||
{
|
||||
ID3D11GeometryShader* shader;
|
||||
|
||||
std::string code;
|
||||
|
||||
GSCacheEntry() : shader(nullptr) {}
|
||||
void Destroy() { SAFE_RELEASE(shader); }
|
||||
};
|
||||
|
||||
typedef std::map<GeometryShaderUid, GSCacheEntry> GSCache;
|
||||
|
||||
static GSCache GeometryShaders;
|
||||
static const GSCacheEntry* last_entry;
|
||||
static GeometryShaderUid last_uid;
|
||||
|
||||
static UidChecker<GeometryShaderUid, ShaderCode> geometry_uid_checker;
|
||||
};
|
||||
|
||||
} // namespace DX11
|
@ -5,6 +5,7 @@
|
||||
#include "VideoBackends/D3D/BoundingBox.h"
|
||||
#include "VideoBackends/D3D/D3DBase.h"
|
||||
#include "VideoBackends/D3D/D3DState.h"
|
||||
#include "VideoBackends/D3D/GeometryShaderCache.h"
|
||||
#include "VideoBackends/D3D/PixelShaderCache.h"
|
||||
#include "VideoBackends/D3D/Render.h"
|
||||
#include "VideoBackends/D3D/VertexManager.h"
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "VideoBackends/D3D/BoundingBox.h"
|
||||
#include "VideoBackends/D3D/D3DBase.h"
|
||||
#include "VideoBackends/D3D/D3DUtil.h"
|
||||
#include "VideoBackends/D3D/GeometryShaderCache.h"
|
||||
#include "VideoBackends/D3D/Globals.h"
|
||||
#include "VideoBackends/D3D/PerfQuery.h"
|
||||
#include "VideoBackends/D3D/PixelShaderCache.h"
|
||||
@ -168,6 +169,7 @@ void VideoBackend::Video_Prepare()
|
||||
g_perf_query = new PerfQuery;
|
||||
VertexShaderCache::Init();
|
||||
PixelShaderCache::Init();
|
||||
GeometryShaderCache::Init();
|
||||
D3D::InitUtils();
|
||||
|
||||
// VideoCommon
|
||||
@ -205,6 +207,7 @@ void VideoBackend::Shutdown()
|
||||
D3D::ShutdownUtils();
|
||||
PixelShaderCache::Shutdown();
|
||||
VertexShaderCache::Shutdown();
|
||||
GeometryShaderCache::Shutdown();
|
||||
BBox::Shutdown();
|
||||
|
||||
delete g_perf_query;
|
||||
|
@ -69,7 +69,7 @@ static inline void GenerateGeometryShader(T& out, u32 components, API_TYPE ApiTy
|
||||
out.Write("\tfor (int l = 0; l < %d; ++l) {\n", g_ActiveConfig.iStereoMode > 0 ? 2 : 1);
|
||||
|
||||
out.Write("\tfor (int i = 0; i < 3; ++i) {\n");
|
||||
out.Write("\t\tlayer = l;\n");
|
||||
out.Write("\t\tgs.layer = l;\n");
|
||||
out.Write("\t\tgl_Layer = l;\n");
|
||||
out.Write("\t\tf = o[i];\n");
|
||||
out.Write("\t\tfloat4 pos = o[i].pos;\n");
|
||||
|
Loading…
Reference in New Issue
Block a user