DX11 code maintenance, part 5:

Move shader and input layout management from EmuGfxState to Vertex/PixelShaderCache and D3DVertexFormat.


git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@6906 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
NeoBrainX 2011-01-24 11:57:17 +00:00
parent e0c6092721
commit f33cd7cbbd
11 changed files with 40 additions and 89 deletions

View File

@ -94,7 +94,7 @@ public:
virtual ~NativeVertexFormat() {} virtual ~NativeVertexFormat() {}
virtual void Initialize(const PortableVertexDeclaration &vtx_decl) = 0; virtual void Initialize(const PortableVertexDeclaration &vtx_decl) = 0;
virtual void SetupVertexPointers() const = 0; virtual void SetupVertexPointers() = 0;
virtual void EnableComponents(u32 components) {} virtual void EnableComponents(u32 components) {}
int GetVertexStride() const { return vertex_stride; } int GetVertexStride() const { return vertex_stride; }

View File

@ -17,6 +17,7 @@
#include "VideoConfig.h" #include "VideoConfig.h"
#include "GfxState.h" #include "GfxState.h"
#include "VertexShaderCache.h"
namespace D3D namespace D3D
{ {
@ -24,13 +25,10 @@ namespace D3D
EmuGfxState* gfxstate; EmuGfxState* gfxstate;
StateManager* stateman; StateManager* stateman;
EmuGfxState::EmuGfxState() : vertexshader(NULL), vsbytecode(NULL), pixelshader(NULL), psbytecode(NULL), apply_called(false) EmuGfxState::EmuGfxState() : apply_called(false)
{ {
pscbuf = NULL; pscbuf = NULL;
vscbuf = NULL; vscbuf = NULL;
vshaderchanged = false;
inp_layout = NULL;
num_inp_elems = 0;
pscbufchanged = false; pscbufchanged = false;
vscbufchanged = false; vscbufchanged = false;
@ -38,66 +36,14 @@ EmuGfxState::EmuGfxState() : vertexshader(NULL), vsbytecode(NULL), pixelshader(N
EmuGfxState::~EmuGfxState() EmuGfxState::~EmuGfxState()
{ {
SAFE_RELEASE(vsbytecode);
SAFE_RELEASE(psbytecode);
SAFE_RELEASE(vertexshader);
SAFE_RELEASE(pixelshader);
SAFE_RELEASE(pscbuf); SAFE_RELEASE(pscbuf);
SAFE_RELEASE(vscbuf); SAFE_RELEASE(vscbuf);
SAFE_RELEASE(inp_layout);
}
// TODO: No need to store the whole bytecode, signature might be enough (?)
void EmuGfxState::SetVShader(ID3D11VertexShader* shader, D3DBlob* bcode)
{
// TODO: vshaderchanged actually just needs to be true if the signature changed
if (bcode && vsbytecode != bcode) vshaderchanged = true;
SAFE_RELEASE(vsbytecode);
SAFE_RELEASE(vertexshader);
if (shader && bcode)
{
vertexshader = shader;
shader->AddRef();
vsbytecode = bcode;
bcode->AddRef();
}
else if (shader || bcode)
{
PanicAlert("Invalid parameters!\n");
}
}
void EmuGfxState::SetPShader(ID3D11PixelShader* shader)
{
if (pixelshader) pixelshader->Release();
pixelshader = shader;
if (shader) shader->AddRef();
}
void EmuGfxState::SetInputElements(const D3D11_INPUT_ELEMENT_DESC* elems, UINT num)
{
num_inp_elems = num;
memcpy(inp_elems, elems, num*sizeof(D3D11_INPUT_ELEMENT_DESC));
} }
void EmuGfxState::ApplyState() void EmuGfxState::ApplyState()
{ {
HRESULT hr; HRESULT hr;
// input layout (only needs to be updated if the vertex shader signature changed)
if (vshaderchanged)
{
SAFE_RELEASE(inp_layout);
hr = D3D::device->CreateInputLayout(inp_elems, num_inp_elems, vsbytecode->Data(), vsbytecode->Size(), &inp_layout);
if (FAILED(hr)) PanicAlert("Failed to create input layout, %s %d\n", __FILE__, __LINE__);
SetDebugObjectName((ID3D11DeviceChild*)inp_layout, "an input layout of EmuGfxState");
vshaderchanged = false;
}
D3D::context->IASetInputLayout(inp_layout);
// vertex shader // vertex shader
// TODO: divide the global variables of the generated shaders into about 5 constant buffers // TODO: divide the global variables of the generated shaders into about 5 constant buffers
// TODO: improve interaction between EmuGfxState and global state management, so that we don't need to set the constant buffers every time // TODO: improve interaction between EmuGfxState and global state management, so that we don't need to set the constant buffers every time
@ -138,9 +84,6 @@ void EmuGfxState::ApplyState()
} }
D3D::context->PSSetConstantBuffers(0, 1, &pscbuf); D3D::context->PSSetConstantBuffers(0, 1, &pscbuf);
context->PSSetShader(pixelshader, NULL, 0);
context->VSSetShader(vertexshader, NULL, 0);
apply_called = true; apply_called = true;
} }

View File

@ -33,10 +33,6 @@ public:
EmuGfxState(); EmuGfxState();
~EmuGfxState(); ~EmuGfxState();
void SetVShader(ID3D11VertexShader* shader, D3DBlob* bcode);
void SetPShader(ID3D11PixelShader* shader);
void SetInputElements(const D3D11_INPUT_ELEMENT_DESC* elems, UINT num);
void ApplyState(); // apply current state void ApplyState(); // apply current state
void Reset(); void Reset();
@ -47,19 +43,9 @@ public:
bool pscbufchanged; bool pscbufchanged;
private: private:
ID3D11VertexShader* vertexshader;
D3DBlob* vsbytecode;
ID3D11PixelShader* pixelshader;
D3DBlob* psbytecode;
bool vshaderchanged;
ID3D11Buffer* vscbuf; ID3D11Buffer* vscbuf;
ID3D11Buffer* pscbuf; ID3D11Buffer* pscbuf;
ID3D11InputLayout* inp_layout;
D3D11_INPUT_ELEMENT_DESC inp_elems[32];
int num_inp_elems;
bool apply_called; bool apply_called;
}; };

View File

@ -27,16 +27,22 @@
#include "CPMemory.h" #include "CPMemory.h"
#include "NativeVertexFormat.h" #include "NativeVertexFormat.h"
#include "VertexManager.h" #include "VertexManager.h"
#include "VertexShaderCache.h"
class D3DVertexFormat : public NativeVertexFormat class D3DVertexFormat : public NativeVertexFormat
{ {
D3D11_INPUT_ELEMENT_DESC m_elems[32]; D3D11_INPUT_ELEMENT_DESC m_elems[32];
UINT m_num_elems; UINT m_num_elems;
D3DBlob* m_vs_bytecode;
ID3D11InputLayout* m_layout;
public: public:
D3DVertexFormat() : m_num_elems(0) {} D3DVertexFormat() : m_num_elems(0), m_vs_bytecode(NULL), m_layout(NULL) {}
~D3DVertexFormat() { SAFE_RELEASE(m_vs_bytecode); SAFE_RELEASE(m_layout); }
void Initialize(const PortableVertexDeclaration &_vtx_decl); void Initialize(const PortableVertexDeclaration &_vtx_decl);
void SetupVertexPointers() const; void SetupVertexPointers();
}; };
namespace DX11 namespace DX11
@ -140,7 +146,19 @@ void D3DVertexFormat::Initialize(const PortableVertexDeclaration &_vtx_decl)
} }
} }
void D3DVertexFormat::SetupVertexPointers() const void D3DVertexFormat::SetupVertexPointers()
{ {
D3D::gfxstate->SetInputElements(m_elems, m_num_elems); if (m_vs_bytecode != VertexShaderCache::GetActiveShaderBytecode())
{
SAFE_RELEASE(m_vs_bytecode);
SAFE_RELEASE(m_layout);
m_vs_bytecode = VertexShaderCache::GetActiveShaderBytecode();
m_vs_bytecode->AddRef();
HRESULT hr = D3D::device->CreateInputLayout(m_elems, m_num_elems, m_vs_bytecode->Data(), m_vs_bytecode->Size(), &m_layout);
if (FAILED(hr)) PanicAlert("Failed to create input layout, %s %d\n", __FILE__, __LINE__);
D3D::SetDebugObjectName((ID3D11DeviceChild*)m_layout, "input layout used to emulate the GX pipeline");
}
D3D::context->IASetInputLayout(m_layout);
} }

View File

@ -348,7 +348,6 @@ bool PixelShaderCache::SetShader(DSTALPHA_MODE dstAlphaMode, u32 components)
const PSCacheEntry &entry = iter->second; const PSCacheEntry &entry = iter->second;
last_entry = &entry; last_entry = &entry;
D3D::gfxstate->SetPShader(entry.shader);
GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE,true); GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE,true);
return (entry.shader != NULL); return (entry.shader != NULL);
} }
@ -369,7 +368,6 @@ bool PixelShaderCache::SetShader(DSTALPHA_MODE dstAlphaMode, u32 components)
g_ps_disk_cache.Sync(); g_ps_disk_cache.Sync();
bool result = InsertByteCode(uid, pbytecode->Data(), pbytecode->Size()); bool result = InsertByteCode(uid, pbytecode->Data(), pbytecode->Size());
D3D::gfxstate->SetPShader(last_entry->shader);
pbytecode->Release(); pbytecode->Release();
GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE, true); GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE, true);
return result; return result;

View File

@ -32,9 +32,11 @@ public:
static void Init(); static void Init();
static void Clear(); static void Clear();
static void Shutdown(); static void Shutdown();
static bool SetShader(DSTALPHA_MODE dstAlphaMode, u32 components); static bool SetShader(DSTALPHA_MODE dstAlphaMode, u32 components); // TODO: Should be renamed to LoadShader
static bool InsertByteCode(const PIXELSHADERUID &uid, const void* bytecode, unsigned int bytecodelen); static bool InsertByteCode(const PIXELSHADERUID &uid, const void* bytecode, unsigned int bytecodelen);
static ID3D11PixelShader* GetActiveShader() { return last_entry->shader; }
static ID3D11PixelShader* GetColorMatrixProgram(bool multisampled); static ID3D11PixelShader* GetColorMatrixProgram(bool multisampled);
static ID3D11PixelShader* GetColorCopyProgram(bool multisampled); static ID3D11PixelShader* GetColorCopyProgram(bool multisampled);
static ID3D11PixelShader* GetDepthMatrixProgram(bool multisampled); static ID3D11PixelShader* GetDepthMatrixProgram(bool multisampled);

View File

@ -1190,7 +1190,7 @@ void Renderer::ApplyState(bool bUseDstAlpha)
hr = D3D::device->CreateBlendState(&gx_state.blenddc, &blstate); hr = D3D::device->CreateBlendState(&gx_state.blenddc, &blstate);
if (FAILED(hr)) PanicAlert("Failed to create blend state at %s %d\n", __FILE__, __LINE__); if (FAILED(hr)) PanicAlert("Failed to create blend state at %s %d\n", __FILE__, __LINE__);
D3D::stateman->PushBlendState(blstate); D3D::stateman->PushBlendState(blstate);
D3D::SetDebugObjectName((ID3D11DeviceChild*)blstate, "a blend state of EmuGfxState"); D3D::SetDebugObjectName((ID3D11DeviceChild*)blstate, "blend state used to emulate the GX pipeline");
SAFE_RELEASE(blstate); SAFE_RELEASE(blstate);
ID3D11DepthStencilState* depth_state; ID3D11DepthStencilState* depth_state;
@ -1233,6 +1233,9 @@ void Renderer::ApplyState(bool bUseDstAlpha)
SetBlendMode(false); SetBlendMode(false);
SetLogicOpMode(); SetLogicOpMode();
} }
D3D::context->PSSetShader(PixelShaderCache::GetActiveShader(), NULL, 0);
D3D::context->VSSetShader(VertexShaderCache::GetActiveShader(), NULL, 0);
} }
void Renderer::RestoreState() void Renderer::RestoreState()

View File

@ -225,7 +225,6 @@ bool VertexShaderCache::SetShader(u32 components)
const VSCacheEntry &entry = iter->second; const VSCacheEntry &entry = iter->second;
last_entry = &entry; last_entry = &entry;
if (entry.shader) D3D::gfxstate->SetVShader(entry.shader, iter->second.bytecode);
GFX_DEBUGGER_PAUSE_AT(NEXT_VERTEX_SHADER_CHANGE, true); GFX_DEBUGGER_PAUSE_AT(NEXT_VERTEX_SHADER_CHANGE, true);
return (entry.shader != NULL); return (entry.shader != NULL);
} }
@ -245,7 +244,6 @@ bool VertexShaderCache::SetShader(u32 components)
g_vs_disk_cache.Sync(); g_vs_disk_cache.Sync();
bool result = InsertByteCode(uid, pbytecode); bool result = InsertByteCode(uid, pbytecode);
D3D::gfxstate->SetVShader(last_entry->shader, last_entry->bytecode);
pbytecode->Release(); pbytecode->Release();
GFX_DEBUGGER_PAUSE_AT(NEXT_VERTEX_SHADER_CHANGE, true); GFX_DEBUGGER_PAUSE_AT(NEXT_VERTEX_SHADER_CHANGE, true);
return result; return result;

View File

@ -28,7 +28,10 @@ public:
static void Init(); static void Init();
static void Clear(); static void Clear();
static void Shutdown(); static void Shutdown();
static bool SetShader(u32 components); static bool SetShader(u32 components); // TODO: Should be renamed to LoadShader
static ID3D11VertexShader* GetActiveShader() { return last_entry->shader; }
static D3DBlob* GetActiveShaderBytecode() { return last_entry->bytecode; }
static ID3D11VertexShader* GetSimpleVertexShader(); static ID3D11VertexShader* GetSimpleVertexShader();
static ID3D11VertexShader* GetClearVertexShader(); static ID3D11VertexShader* GetClearVertexShader();

View File

@ -36,7 +36,7 @@ public:
D3DVertexFormat() : d3d_decl(NULL) {} D3DVertexFormat() : d3d_decl(NULL) {}
~D3DVertexFormat(); ~D3DVertexFormat();
virtual void Initialize(const PortableVertexDeclaration &_vtx_decl); virtual void Initialize(const PortableVertexDeclaration &_vtx_decl);
virtual void SetupVertexPointers() const; virtual void SetupVertexPointers();
#if defined(_DEBUG) || defined(DEBUGFAST) #if defined(_DEBUG) || defined(DEBUGFAST)
D3DVERTEXELEMENT9 elements[32]; D3DVERTEXELEMENT9 elements[32];
@ -185,7 +185,7 @@ void D3DVertexFormat::Initialize(const PortableVertexDeclaration &_vtx_decl)
#endif #endif
} }
void D3DVertexFormat::SetupVertexPointers() const void D3DVertexFormat::SetupVertexPointers()
{ {
if (d3d_decl) if (d3d_decl)
D3D::SetVertexDeclaration(d3d_decl); D3D::SetVertexDeclaration(d3d_decl);

View File

@ -64,7 +64,7 @@ public:
~GLVertexFormat(); ~GLVertexFormat();
virtual void Initialize(const PortableVertexDeclaration &_vtx_decl); virtual void Initialize(const PortableVertexDeclaration &_vtx_decl);
virtual void SetupVertexPointers() const; virtual void SetupVertexPointers();
virtual void EnableComponents(u32 components); virtual void EnableComponents(u32 components);
}; };
@ -180,7 +180,7 @@ void GLVertexFormat::Initialize(const PortableVertexDeclaration &_vtx_decl)
this->vtx_decl = _vtx_decl; this->vtx_decl = _vtx_decl;
} }
void GLVertexFormat::SetupVertexPointers() const { void GLVertexFormat::SetupVertexPointers() {
// Cast a pointer to compiled code to a pointer to a function taking no parameters, through a (void *) cast first to // Cast a pointer to compiled code to a pointer to a function taking no parameters, through a (void *) cast first to
// get around type checking errors, and call it. // get around type checking errors, and call it.
#ifdef USE_JIT #ifdef USE_JIT