Ported vertex shader creation and activation
For this, introduced and used CxbxCreateVertexShader, and refactored CxbxUpdateHostVertexShader, to perform local state tracking and switch active host vertex shader only when required Removed ResetD3DDevice method
This commit is contained in:
parent
aa98efbc1a
commit
391741a075
|
@ -2443,9 +2443,6 @@ static void CreateDefaultD3D9Device
|
|||
|
||||
DrawInitialBlackScreen();
|
||||
|
||||
// Set up cache
|
||||
g_VertexShaderCache.ResetD3DDevice(g_pD3DDevice);
|
||||
|
||||
// Set up ImGui's render backend
|
||||
#ifdef CXBX_USE_D3D11
|
||||
ImGui_ImplDX11_Init(g_pD3DDevice);
|
||||
|
|
|
@ -5,10 +5,10 @@
|
|||
#include "core/kernel/init/CxbxKrnl.h"
|
||||
#include "util/hasher.h"
|
||||
#include "core/kernel/support/Emu.h"
|
||||
#include "core\hle\D3D8\Direct3D9\Direct3D9.h" // For g_pD3DDevice
|
||||
|
||||
VertexShaderCache g_VertexShaderCache = VertexShaderCache();
|
||||
// FIXME : This should really be released and created in step with the D3D device lifecycle rather than being a thing on its own
|
||||
// (And the ResetD3DDevice method should be removed)
|
||||
|
||||
|
||||
ID3DBlob* AsyncCreateVertexShader(IntermediateVertexShader intermediateShader, ShaderKey key) {
|
||||
|
@ -86,6 +86,45 @@ ShaderKey VertexShaderCache::CreateShader(const xbox::dword_xt* pXboxFunction, D
|
|||
return key;
|
||||
}
|
||||
|
||||
IDirect3DVertexShader* CxbxCreateVertexShader(ID3DBlob* pCompiledShader, const char *shader_category)
|
||||
{
|
||||
IDirect3DVertexShader* pHostVertexShader = nullptr;
|
||||
|
||||
// If there's no D3DDevice set, return nullptr
|
||||
if (g_pD3DDevice == nullptr) {
|
||||
EmuLog(LOG_LEVEL::WARNING, "Can't create %s vertex shader - no D3D device is set!", shader_category);
|
||||
}
|
||||
else {
|
||||
assert(pCompiledShader);
|
||||
|
||||
HRESULT hRet;
|
||||
#ifdef CXBX_USE_D3D11
|
||||
hRet = g_pD3DDevice->CreateVertexShader(
|
||||
(const void*)pCompiledShader->GetBufferPointer(),
|
||||
pCompiledShader->GetBufferSize(), // BytecodeLength
|
||||
nullptr, // pClassLinkage
|
||||
&pHostVertexShader
|
||||
);
|
||||
#else
|
||||
hRet = g_pD3DDevice->CreateVertexShader(
|
||||
(DWORD *)pCompiledShader->GetBufferPointer(),
|
||||
&pHostVertexShader
|
||||
);
|
||||
#endif
|
||||
if (FAILED(hRet)) CxbxrAbort("Failed to create %s vertex shader", shader_category);
|
||||
|
||||
// TODO DEBUG_D3DRESULT(hRet, "g_pD3DDevice->CreateVertexShader");
|
||||
if (SUCCEEDED(hRet)) {
|
||||
EmuLog(LOG_LEVEL::DEBUG, "Created new %s vertex shader instance", shader_category);
|
||||
}
|
||||
else {
|
||||
EmuLog(LOG_LEVEL::ERROR2, "Failed creating new %s vertex shader instance", shader_category);
|
||||
}
|
||||
}
|
||||
|
||||
return pHostVertexShader;
|
||||
}
|
||||
|
||||
// Get a shader using the given key
|
||||
IDirect3DVertexShader* VertexShaderCache::GetShader(ShaderKey key)
|
||||
{
|
||||
|
@ -101,12 +140,6 @@ IDirect3DVertexShader* VertexShaderCache::GetShader(ShaderKey key)
|
|||
return pLazyShader->pHostVertexShader;
|
||||
}
|
||||
|
||||
// If there's no D3DDevice set, return nullptr
|
||||
if (pD3DDevice == nullptr) {
|
||||
EmuLog(LOG_LEVEL::WARNING, "Can't create shader - no D3D device is set!");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// We need to get the compiled HLSL and create a shader from it
|
||||
ID3DBlob* pCompiledShader = nullptr;
|
||||
try {
|
||||
|
@ -121,19 +154,9 @@ IDirect3DVertexShader* VertexShaderCache::GetShader(ShaderKey key)
|
|||
}
|
||||
|
||||
// Create the shader
|
||||
auto hRet = pD3DDevice->CreateVertexShader
|
||||
(
|
||||
(DWORD*)pCompiledShader->GetBufferPointer(),
|
||||
&pLazyShader->pHostVertexShader
|
||||
);
|
||||
// TODO : incorporate key into "regular" shader category string
|
||||
pLazyShader->pHostVertexShader = CxbxCreateVertexShader(pCompiledShader, "regular");
|
||||
|
||||
// TODO DEBUG_D3DRESULT(hRet, "g_pD3DDevice->CreateVertexShader");
|
||||
if (SUCCEEDED(hRet)) {
|
||||
EmuLog(LOG_LEVEL::DEBUG, "Created new vertex shader instance for %llx", key);
|
||||
}
|
||||
else {
|
||||
EmuLog(LOG_LEVEL::ERROR2, "Failed creating new vertex shader instance for %llx", key);
|
||||
}
|
||||
}
|
||||
catch (const std::exception & e) {
|
||||
EmuLog(LOG_LEVEL::ERROR2, "Failed compiling shader %llx: %s", e.what());
|
||||
|
@ -172,13 +195,6 @@ void VertexShaderCache::ReleaseShader(ShaderKey key)
|
|||
}
|
||||
}
|
||||
|
||||
void VertexShaderCache::ResetD3DDevice(IDirect3DDevice* newDevice)
|
||||
{
|
||||
EmuLog(LOG_LEVEL::DEBUG, "Resetting D3D device");
|
||||
cache.clear();
|
||||
this->pD3DDevice = newDevice;
|
||||
}
|
||||
|
||||
void VertexShaderCache::Clear()
|
||||
{
|
||||
for (auto& x : cache) {
|
||||
|
|
|
@ -15,9 +15,7 @@ public:
|
|||
IDirect3DVertexShader *GetShader(ShaderKey key);
|
||||
void ReleaseShader(ShaderKey key);
|
||||
|
||||
void ResetD3DDevice(IDirect3DDevice* pD3DDevice);
|
||||
void Clear();
|
||||
|
||||
// TODO
|
||||
// WriteCacheToDisk
|
||||
// LoadCacheFromDisk
|
||||
|
@ -36,7 +34,6 @@ private:
|
|||
// OptimizationLevel?
|
||||
};
|
||||
|
||||
IDirect3DDevice9* pD3DDevice;
|
||||
std::mutex cacheMutex;
|
||||
std::map<ShaderKey, LazyVertexShader> cache;
|
||||
|
||||
|
|
|
@ -1184,15 +1184,31 @@ IDirect3DVertexDeclaration* CxbxCreateHostVertexDeclaration(D3DVERTEXELEMENT *pD
|
|||
return pHostVertexDeclaration;
|
||||
}
|
||||
|
||||
HRESULT CxbxSetVertexShader(IDirect3DVertexShader* pHostVertexShader)
|
||||
{
|
||||
HRESULT hRet;
|
||||
#ifdef CXBX_USE_D3D11
|
||||
hRet = g_pD3DDevice->VSSetShader(
|
||||
pHostVertexShader,
|
||||
nullptr, // ppClassInstances
|
||||
0 // NumClassInstances
|
||||
);
|
||||
#else
|
||||
hRet = g_pD3DDevice->SetVertexShader(pHostVertexShader);
|
||||
#endif
|
||||
return hRet;
|
||||
}
|
||||
|
||||
extern IDirect3DVertexShader* CxbxCreateVertexShader(ID3DBlob* pCompiledShader, const char *shader_category); // Implemented in VertexShaderCache.cpp
|
||||
|
||||
IDirect3DVertexShader* InitShader(void (*compileFunc)(ID3DBlob**), const char* label) {
|
||||
IDirect3DVertexShader* shader = nullptr;
|
||||
|
||||
ID3DBlob* pBlob = nullptr;
|
||||
compileFunc(&pBlob);
|
||||
if (pBlob) {
|
||||
HRESULT hRet = g_pD3DDevice->CreateVertexShader((DWORD*)pBlob->GetBufferPointer(), &shader);
|
||||
shader = CxbxCreateVertexShader(pBlob, label);
|
||||
pBlob->Release();
|
||||
if (FAILED(hRet)) CxbxrAbort("Failed to create shader: %s", label);
|
||||
}
|
||||
|
||||
return shader;
|
||||
|
@ -1209,7 +1225,7 @@ void CxbxUpdateHostVertexShader()
|
|||
int shaderVersion = g_ShaderSources.Update();
|
||||
if (vertexShaderVersion != shaderVersion) {
|
||||
vertexShaderVersion = shaderVersion;
|
||||
g_pD3DDevice->SetVertexShader(nullptr);
|
||||
CxbxSetVertexShader(nullptr);
|
||||
|
||||
EmuLog(LOG_LEVEL::INFO, "Loading vertex shaders...");
|
||||
|
||||
|
@ -1234,11 +1250,11 @@ void CxbxUpdateHostVertexShader()
|
|||
LOG_INIT; // Allows use of DEBUG_D3DRESULT
|
||||
|
||||
if (g_Xbox_VertexShaderMode == VertexShaderMode::FixedFunction) {
|
||||
HRESULT hRet = g_pD3DDevice->SetVertexShader(fixedFunctionShader);
|
||||
HRESULT hRet = CxbxSetVertexShader(fixedFunctionShader);
|
||||
if (FAILED(hRet)) CxbxrAbort("Failed to set fixed-function shader");
|
||||
}
|
||||
else if (g_Xbox_VertexShaderMode == VertexShaderMode::Passthrough && g_bUsePassthroughHLSL) {
|
||||
HRESULT hRet = g_pD3DDevice->SetVertexShader(passthroughShader);
|
||||
HRESULT hRet = CxbxSetVertexShader(passthroughShader);
|
||||
if (FAILED(hRet)) CxbxrAbort("Failed to set passthrough shader");
|
||||
}
|
||||
else {
|
||||
|
@ -1248,7 +1264,7 @@ void CxbxUpdateHostVertexShader()
|
|||
DWORD shaderSize;
|
||||
auto VertexShaderKey = g_VertexShaderCache.CreateShader(pTokens, &shaderSize);
|
||||
IDirect3DVertexShader* pHostVertexShader = g_VertexShaderCache.GetShader(VertexShaderKey);
|
||||
HRESULT hRet = g_pD3DDevice->SetVertexShader(pHostVertexShader);
|
||||
HRESULT hRet = CxbxSetVertexShader(pHostVertexShader);
|
||||
DEBUG_D3DRESULT(hRet, "g_pD3DDevice->SetVertexShader");
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue