mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-01-10 16:19:28 +01:00
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:
parent
e0c6092721
commit
f33cd7cbbd
@ -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; }
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
|
@ -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()
|
||||||
|
@ -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;
|
||||||
|
@ -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();
|
||||||
|
@ -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);
|
||||||
|
@ -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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user