DX11 code maintenance, part 1:

Move sampler state/shader resource management from EmuGfxState to Renderer.


git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@6902 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
NeoBrainX 2011-01-24 08:44:32 +00:00
parent a4e338b379
commit e0b757fe6a
9 changed files with 79 additions and 75 deletions

View File

@ -66,6 +66,9 @@ public:
virtual void SetSamplerState(int stage,int texindex) = 0; virtual void SetSamplerState(int stage,int texindex) = 0;
virtual void SetInterlacingMode() = 0; virtual void SetInterlacingMode() = 0;
virtual void ApplyState() = 0;
virtual void UnsetTextures() = 0;
// Real internal resolution: // Real internal resolution:
// D3D doesn't support viewports larger than the target size, so we need to resize the target to the viewport size for those. // D3D doesn't support viewports larger than the target size, so we need to resize the target to the viewport size for those.
// OpenGL supports this, so GetFullTargetWidth returns the same as GetTargetWidth there. // OpenGL supports this, so GetFullTargetWidth returns the same as GetTargetWidth there.

View File

@ -26,14 +26,6 @@ StateManager* stateman;
EmuGfxState::EmuGfxState() : vertexshader(NULL), vsbytecode(NULL), pixelshader(NULL), psbytecode(NULL), apply_called(false) EmuGfxState::EmuGfxState() : vertexshader(NULL), vsbytecode(NULL), pixelshader(NULL), psbytecode(NULL), apply_called(false)
{ {
for (unsigned int k = 0;k < 8;k++)
{
float border[4] = {0.f, 0.f, 0.f, 0.f};
shader_resources[k] = NULL;
samplerdesc[k] = CD3D11_SAMPLER_DESC(D3D11_FILTER_MIN_MAG_MIP_LINEAR, D3D11_TEXTURE_ADDRESS_CLAMP, D3D11_TEXTURE_ADDRESS_CLAMP, D3D11_TEXTURE_ADDRESS_CLAMP, 0.f, 16, D3D11_COMPARISON_ALWAYS, border, -D3D11_FLOAT32_MAX, D3D11_FLOAT32_MAX);
if(g_ActiveConfig.iMaxAnisotropy > 1) samplerdesc[k].Filter = D3D11_FILTER_ANISOTROPIC;
}
m_useDstAlpha = false; m_useDstAlpha = false;
memset(&blenddesc, 0, sizeof(blenddesc)); memset(&blenddesc, 0, sizeof(blenddesc));
@ -71,9 +63,6 @@ EmuGfxState::EmuGfxState() : vertexshader(NULL), vsbytecode(NULL), pixelshader(N
EmuGfxState::~EmuGfxState() EmuGfxState::~EmuGfxState()
{ {
for (unsigned int k = 0;k < 8;k++)
SAFE_RELEASE(shader_resources[k]);
SAFE_RELEASE(vsbytecode); SAFE_RELEASE(vsbytecode);
SAFE_RELEASE(psbytecode); SAFE_RELEASE(psbytecode);
SAFE_RELEASE(vertexshader); SAFE_RELEASE(vertexshader);
@ -119,13 +108,6 @@ void EmuGfxState::SetInputElements(const D3D11_INPUT_ELEMENT_DESC* elems, UINT n
memcpy(inp_elems, elems, num*sizeof(D3D11_INPUT_ELEMENT_DESC)); memcpy(inp_elems, elems, num*sizeof(D3D11_INPUT_ELEMENT_DESC));
} }
void EmuGfxState::SetShaderResource(unsigned int stage, ID3D11ShaderResourceView* srv)
{
if (shader_resources[stage]) shader_resources[stage]->Release();
shader_resources[stage] = srv;
if (srv) srv->AddRef();
}
void EmuGfxState::ApplyState() void EmuGfxState::ApplyState()
{ {
HRESULT hr; HRESULT hr;
@ -181,22 +163,6 @@ void EmuGfxState::ApplyState()
} }
D3D::context->PSSetConstantBuffers(0, 1, &pscbuf); D3D::context->PSSetConstantBuffers(0, 1, &pscbuf);
ID3D11SamplerState* samplerstate[8];
for (unsigned int stage = 0; stage < 8; stage++)
{
if (shader_resources[stage])
{
if(g_ActiveConfig.iMaxAnisotropy > 1) samplerdesc[stage].Filter = D3D11_FILTER_ANISOTROPIC;
hr = D3D::device->CreateSamplerState(&samplerdesc[stage], &samplerstate[stage]);
if (FAILED(hr)) PanicAlert("Fail %s %d, stage=%d\n", __FILE__, __LINE__, stage);
else SetDebugObjectName((ID3D11DeviceChild*)samplerstate[stage], "a sampler state of EmuGfxState");
}
else samplerstate[stage] = NULL;
}
D3D::context->PSSetSamplers(0, 8, samplerstate);
for (unsigned int stage = 0; stage < 8; stage++)
SAFE_RELEASE(samplerstate[stage]);
ID3D11BlendState* blstate; ID3D11BlendState* blstate;
hr = device->CreateBlendState(&blenddesc, &blstate); hr = device->CreateBlendState(&blenddesc, &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__);
@ -221,7 +187,6 @@ void EmuGfxState::ApplyState()
context->PSSetShader(pixelshader, NULL, 0); context->PSSetShader(pixelshader, NULL, 0);
context->VSSetShader(vertexshader, NULL, 0); context->VSSetShader(vertexshader, NULL, 0);
context->PSSetShaderResources(0, 8, shader_resources);
stateman->Apply(); stateman->Apply();
apply_called = true; apply_called = true;
@ -229,10 +194,6 @@ void EmuGfxState::ApplyState()
void EmuGfxState::Reset() void EmuGfxState::Reset()
{ {
for (unsigned int k = 0;k < 8;k++)
SAFE_RELEASE(shader_resources[k]);
context->PSSetShaderResources(0, 8, shader_resources); // unbind all textures
if (apply_called) if (apply_called)
{ {
stateman->PopBlendState(); stateman->PopBlendState();
@ -345,11 +306,6 @@ void EmuGfxState::SetDstAlpha(bool enable)
SetBlendOp(blenddesc.RenderTarget[0].BlendOp); SetBlendOp(blenddesc.RenderTarget[0].BlendOp);
} }
void EmuGfxState::SetSamplerFilter(DWORD stage, D3D11_FILTER filter)
{
samplerdesc[stage].Filter = filter;
}
template<typename T> AutoState<T>::AutoState(const T* object) : state(object) template<typename T> AutoState<T>::AutoState(const T* object) : state(object)
{ {
((IUnknown*)state)->AddRef(); ((IUnknown*)state)->AddRef();

View File

@ -36,7 +36,6 @@ public:
void SetVShader(ID3D11VertexShader* shader, D3DBlob* bcode); void SetVShader(ID3D11VertexShader* shader, D3DBlob* bcode);
void SetPShader(ID3D11PixelShader* shader); void SetPShader(ID3D11PixelShader* shader);
void SetInputElements(const D3D11_INPUT_ELEMENT_DESC* elems, UINT num); void SetInputElements(const D3D11_INPUT_ELEMENT_DESC* elems, UINT num);
void SetShaderResource(unsigned int stage, ID3D11ShaderResourceView* srv);
void ApplyState(); // apply current state void ApplyState(); // apply current state
void Reset(); void Reset();
@ -50,12 +49,7 @@ public:
void SetDstAlpha(bool enable); void SetDstAlpha(bool enable);
// sampler states
void SetSamplerFilter(DWORD stage, D3D11_FILTER filter);
// TODO: add methods for changing the other states instead of modifying them directly
D3D11_SAMPLER_DESC samplerdesc[8];
D3D11_RASTERIZER_DESC rastdesc; D3D11_RASTERIZER_DESC rastdesc;
D3D11_DEPTH_STENCIL_DESC depthdesc; D3D11_DEPTH_STENCIL_DESC depthdesc;
@ -78,7 +72,6 @@ private:
D3D11_INPUT_ELEMENT_DESC inp_elems[32]; D3D11_INPUT_ELEMENT_DESC inp_elems[32];
int num_inp_elems; int num_inp_elems;
ID3D11ShaderResourceView* shader_resources[8];
D3D11_BLEND_DESC blenddesc; D3D11_BLEND_DESC blenddesc;
bool m_useDstAlpha; bool m_useDstAlpha;

View File

@ -64,6 +64,12 @@ ID3D11BlendState* resetblendstate = NULL;
ID3D11DepthStencilState* resetdepthstate = NULL; ID3D11DepthStencilState* resetdepthstate = NULL;
ID3D11RasterizerState* resetraststate = NULL; ID3D11RasterizerState* resetraststate = NULL;
// GX pipeline state
struct
{
D3D11_SAMPLER_DESC sampdc[8];
} gx_state;
bool reset_called = false; bool reset_called = false;
// State translation lookup tables // State translation lookup tables
@ -338,9 +344,18 @@ Renderer::Renderer()
SetupDeviceObjects(); SetupDeviceObjects();
for (unsigned int stage = 0; stage < 8; stage++) // Setup GX pipeline state
D3D::gfxstate->samplerdesc[stage].MaxAnisotropy = g_ActiveConfig.iMaxAnisotropy; for (unsigned int k = 0;k < 8;k++)
{
float border[4] = {0.f, 0.f, 0.f, 0.f};
gx_state.sampdc[k] = CD3D11_SAMPLER_DESC(D3D11_FILTER_MIN_MAG_MIP_LINEAR, D3D11_TEXTURE_ADDRESS_CLAMP, D3D11_TEXTURE_ADDRESS_CLAMP, D3D11_TEXTURE_ADDRESS_CLAMP,
0.f, 1 << g_ActiveConfig.iMaxAnisotropy,
D3D11_COMPARISON_ALWAYS, border,
-D3D11_FLOAT32_MAX, D3D11_FLOAT32_MAX);
if(g_ActiveConfig.iMaxAnisotropy != 0) gx_state.sampdc[k].Filter = D3D11_FILTER_ANISOTROPIC;
}
// Clear EFB textures
float ClearColor[4] = { 0.f, 0.f, 0.f, 1.f }; float ClearColor[4] = { 0.f, 0.f, 0.f, 1.f };
D3D::context->ClearRenderTargetView(FramebufferManager::GetEFBColorTexture()->GetRTV(), ClearColor); D3D::context->ClearRenderTargetView(FramebufferManager::GetEFBColorTexture()->GetRTV(), ClearColor);
D3D::context->ClearDepthStencilView(FramebufferManager::GetEFBDepthTexture()->GetDSV(), D3D11_CLEAR_DEPTH, 1.f, 0); D3D::context->ClearDepthStencilView(FramebufferManager::GetEFBDepthTexture()->GetDSV(), D3D11_CLEAR_DEPTH, 1.f, 0);
@ -1073,6 +1088,32 @@ void Renderer::RestoreAPIState()
reset_called = false; reset_called = false;
} }
void Renderer::ApplyState()
{
ID3D11SamplerState* samplerstate[8];
for (unsigned int stage = 0; stage < 8; stage++)
{
// TODO: unnecessary state changes, we should store a list of shader resources
//if (shader_resources[stage])
{
if(g_ActiveConfig.iMaxAnisotropy > 0) gx_state.sampdc[stage].Filter = D3D11_FILTER_ANISOTROPIC;
HRESULT hr = D3D::device->CreateSamplerState(&gx_state.sampdc[stage], &samplerstate[stage]);
if (FAILED(hr)) PanicAlert("Fail %s %d, stage=%d\n", __FILE__, __LINE__, stage);
else D3D::SetDebugObjectName((ID3D11DeviceChild*)samplerstate[stage], "sampler state used to emulate the GX pipeline");
}
// else samplerstate[stage] = NULL;
}
D3D::context->PSSetSamplers(0, 8, samplerstate);
for (unsigned int stage = 0; stage < 8; stage++)
SAFE_RELEASE(samplerstate[stage]);
}
void Renderer::UnsetTextures()
{
ID3D11ShaderResourceView* shader_resources[8] = { NULL };
D3D::context->PSSetShaderResources(0, 8, shader_resources);
}
void Renderer::SetGenerationMode() void Renderer::SetGenerationMode()
{ {
// rastdesc.FrontCounterClockwise must be false for this to work // rastdesc.FrontCounterClockwise must be false for this to work
@ -1137,45 +1178,45 @@ void Renderer::SetSamplerState(int stage, int texindex)
// NOTE: since there's no "no filter" in DX11 we're using point filters in these cases // NOTE: since there's no "no filter" in DX11 we're using point filters in these cases
if (g_ActiveConfig.bForceFiltering) if (g_ActiveConfig.bForceFiltering)
{ {
D3D::gfxstate->SetSamplerFilter(stage, D3D11_FILTER_MIN_MAG_MIP_LINEAR); gx_state.sampdc[stage].Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
} }
else if (tm0.min_filter & 4) // linear min filter else if (tm0.min_filter & 4) // linear min filter
{ {
if (tm0.mag_filter) // linear mag filter if (tm0.mag_filter) // linear mag filter
{ {
if (mip == TEXF_NONE) D3D::gfxstate->SetSamplerFilter(stage, D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT); if (mip == TEXF_NONE) gx_state.sampdc[stage].Filter = D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT;
else if (mip == TEXF_POINT) D3D::gfxstate->SetSamplerFilter(stage, D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT); else if (mip == TEXF_POINT) gx_state.sampdc[stage].Filter = D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT;
else if (mip == TEXF_LINEAR) D3D::gfxstate->SetSamplerFilter(stage, D3D11_FILTER_MIN_MAG_MIP_LINEAR); else if (mip == TEXF_LINEAR) gx_state.sampdc[stage].Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
} }
else // point mag filter else // point mag filter
{ {
if (mip == TEXF_NONE) D3D::gfxstate->SetSamplerFilter(stage, D3D11_FILTER_MIN_LINEAR_MAG_MIP_POINT); if (mip == TEXF_NONE) gx_state.sampdc[stage].Filter = D3D11_FILTER_MIN_LINEAR_MAG_MIP_POINT;
else if (mip == TEXF_POINT) D3D::gfxstate->SetSamplerFilter(stage, D3D11_FILTER_MIN_LINEAR_MAG_MIP_POINT); else if (mip == TEXF_POINT) gx_state.sampdc[stage].Filter = D3D11_FILTER_MIN_LINEAR_MAG_MIP_POINT;
else if (mip == TEXF_LINEAR) D3D::gfxstate->SetSamplerFilter(stage, D3D11_FILTER_MIN_LINEAR_MAG_POINT_MIP_LINEAR); else if (mip == TEXF_LINEAR) gx_state.sampdc[stage].Filter = D3D11_FILTER_MIN_LINEAR_MAG_POINT_MIP_LINEAR;
} }
} }
else // point min filter else // point min filter
{ {
if (tm0.mag_filter) // linear mag filter if (tm0.mag_filter) // linear mag filter
{ {
if (mip == TEXF_NONE) D3D::gfxstate->SetSamplerFilter(stage, D3D11_FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT); if (mip == TEXF_NONE) gx_state.sampdc[stage].Filter = D3D11_FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT;
else if (mip == TEXF_POINT) D3D::gfxstate->SetSamplerFilter(stage, D3D11_FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT); else if (mip == TEXF_POINT) gx_state.sampdc[stage].Filter = D3D11_FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT;
else if (mip == TEXF_LINEAR) D3D::gfxstate->SetSamplerFilter(stage, D3D11_FILTER_MIN_POINT_MAG_MIP_LINEAR); else if (mip == TEXF_LINEAR) gx_state.sampdc[stage].Filter = D3D11_FILTER_MIN_POINT_MAG_MIP_LINEAR;
} }
else // point mag filter else // point mag filter
{ {
if (mip == TEXF_NONE) D3D::gfxstate->SetSamplerFilter(stage, D3D11_FILTER_MIN_MAG_MIP_POINT); if (mip == TEXF_NONE) gx_state.sampdc[stage].Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
else if (mip == TEXF_POINT) D3D::gfxstate->SetSamplerFilter(stage, D3D11_FILTER_MIN_MAG_MIP_POINT); else if (mip == TEXF_POINT) gx_state.sampdc[stage].Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
else if (mip == TEXF_LINEAR) D3D::gfxstate->SetSamplerFilter(stage, D3D11_FILTER_MIN_MAG_POINT_MIP_LINEAR); else if (mip == TEXF_LINEAR) gx_state.sampdc[stage].Filter = D3D11_FILTER_MIN_MAG_POINT_MIP_LINEAR;
} }
} }
D3D::gfxstate->samplerdesc[stage].AddressU = d3dClamps[tm0.wrap_s]; gx_state.sampdc[stage].AddressU = d3dClamps[tm0.wrap_s];
D3D::gfxstate->samplerdesc[stage].AddressV = d3dClamps[tm0.wrap_t]; gx_state.sampdc[stage].AddressV = d3dClamps[tm0.wrap_t];
D3D::gfxstate->samplerdesc[stage].MipLODBias = (float)tm0.lod_bias/32.0f; gx_state.sampdc[stage].MipLODBias = (float)tm0.lod_bias/32.0f;
D3D::gfxstate->samplerdesc[stage].MaxLOD = (float)tm1.max_lod/16.f; gx_state.sampdc[stage].MaxLOD = (float)tm1.max_lod/16.f;
D3D::gfxstate->samplerdesc[stage].MinLOD = (float)tm1.min_lod/16.f; gx_state.sampdc[stage].MinLOD = (float)tm1.min_lod/16.f;
} }
void Renderer::SetInterlacingMode() void Renderer::SetInterlacingMode()

View File

@ -24,6 +24,9 @@ public:
void SetSamplerState(int stage,int texindex); void SetSamplerState(int stage,int texindex);
void SetInterlacingMode(); void SetInterlacingMode();
void ApplyState();
void UnsetTextures();
void RenderText(const char* pstr, int left, int top, u32 color); void RenderText(const char* pstr, int left, int top, u32 color);
u32 AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data); u32 AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data);

View File

@ -53,7 +53,7 @@ TextureCache::TCacheEntry::~TCacheEntry()
void TextureCache::TCacheEntry::Bind(unsigned int stage) void TextureCache::TCacheEntry::Bind(unsigned int stage)
{ {
D3D::gfxstate->SetShaderResource(stage, texture->GetSRV()); D3D::context->PSSetShaderResources(stage, 1, &texture->GetSRV());
} }
bool TextureCache::TCacheEntry::Save(const char filename[]) bool TextureCache::TCacheEntry::Save(const char filename[])

View File

@ -139,8 +139,6 @@ void VertexManager::LoadBuffers()
void VertexManager::Draw(UINT stride) void VertexManager::Draw(UINT stride)
{ {
D3D::gfxstate->ApplyState();
D3D::context->IASetVertexBuffers(0, 1, &m_vertexBuffer, &stride, &m_vertexDrawOffset); D3D::context->IASetVertexBuffers(0, 1, &m_vertexBuffer, &stride, &m_vertexDrawOffset);
D3D::context->IASetIndexBuffer(m_indexBuffer, DXGI_FORMAT_R16_UINT, 0); D3D::context->IASetIndexBuffer(m_indexBuffer, DXGI_FORMAT_R16_UINT, 0);
@ -232,9 +230,11 @@ void VertexManager::vFlush()
unsigned int stride = g_nativeVertexFmt->GetVertexStride(); unsigned int stride = g_nativeVertexFmt->GetVertexStride();
g_nativeVertexFmt->SetupVertexPointers(); g_nativeVertexFmt->SetupVertexPointers();
D3D::gfxstate->ApplyState();
g_renderer->ApplyState();
LoadBuffers(); LoadBuffers();
Draw(stride); Draw(stride);
g_renderer->UnsetTextures();
D3D::gfxstate->Reset(); D3D::gfxstate->Reset();
GFX_DEBUGGER_PAUSE_AT(NEXT_FLUSH, true); GFX_DEBUGGER_PAUSE_AT(NEXT_FLUSH, true);

View File

@ -24,6 +24,10 @@ public:
void SetSamplerState(int stage,int texindex); void SetSamplerState(int stage,int texindex);
void SetInterlacingMode(); void SetInterlacingMode();
// No need to implement these in D3D9
void ApplyState() {}
void UnsetTextures() {}
void RenderText(const char* pstr, int left, int top, u32 color); void RenderText(const char* pstr, int left, int top, u32 color);
u32 AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data); u32 AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data);

View File

@ -24,6 +24,10 @@ public:
void SetSamplerState(int stage,int texindex); void SetSamplerState(int stage,int texindex);
void SetInterlacingMode(); void SetInterlacingMode();
// No need to implement these in OGL
void ApplyState() {}
void UnsetTextures() {}
void RenderText(const char* pstr, int left, int top, u32 color); void RenderText(const char* pstr, int left, int top, u32 color);
void DrawDebugInfo(); void DrawDebugInfo();
void FlipImageData(u8 *data, int w, int h); void FlipImageData(u8 *data, int w, int h);