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 SetInterlacingMode() = 0;
virtual void ApplyState() = 0;
virtual void UnsetTextures() = 0;
// 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.
// 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)
{
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;
memset(&blenddesc, 0, sizeof(blenddesc));
@ -71,9 +63,6 @@ EmuGfxState::EmuGfxState() : vertexshader(NULL), vsbytecode(NULL), pixelshader(N
EmuGfxState::~EmuGfxState()
{
for (unsigned int k = 0;k < 8;k++)
SAFE_RELEASE(shader_resources[k]);
SAFE_RELEASE(vsbytecode);
SAFE_RELEASE(psbytecode);
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));
}
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()
{
HRESULT hr;
@ -181,22 +163,6 @@ void EmuGfxState::ApplyState()
}
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;
hr = device->CreateBlendState(&blenddesc, &blstate);
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->VSSetShader(vertexshader, NULL, 0);
context->PSSetShaderResources(0, 8, shader_resources);
stateman->Apply();
apply_called = true;
@ -229,10 +194,6 @@ void EmuGfxState::ApplyState()
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)
{
stateman->PopBlendState();
@ -345,11 +306,6 @@ void EmuGfxState::SetDstAlpha(bool enable)
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)
{
((IUnknown*)state)->AddRef();

View file

@ -36,7 +36,6 @@ public:
void SetVShader(ID3D11VertexShader* shader, D3DBlob* bcode);
void SetPShader(ID3D11PixelShader* shader);
void SetInputElements(const D3D11_INPUT_ELEMENT_DESC* elems, UINT num);
void SetShaderResource(unsigned int stage, ID3D11ShaderResourceView* srv);
void ApplyState(); // apply current state
void Reset();
@ -50,12 +49,7 @@ public:
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_DEPTH_STENCIL_DESC depthdesc;
@ -78,7 +72,6 @@ private:
D3D11_INPUT_ELEMENT_DESC inp_elems[32];
int num_inp_elems;
ID3D11ShaderResourceView* shader_resources[8];
D3D11_BLEND_DESC blenddesc;
bool m_useDstAlpha;

View file

@ -64,6 +64,12 @@ ID3D11BlendState* resetblendstate = NULL;
ID3D11DepthStencilState* resetdepthstate = NULL;
ID3D11RasterizerState* resetraststate = NULL;
// GX pipeline state
struct
{
D3D11_SAMPLER_DESC sampdc[8];
} gx_state;
bool reset_called = false;
// State translation lookup tables
@ -338,9 +344,18 @@ Renderer::Renderer()
SetupDeviceObjects();
for (unsigned int stage = 0; stage < 8; stage++)
D3D::gfxstate->samplerdesc[stage].MaxAnisotropy = g_ActiveConfig.iMaxAnisotropy;
// Setup GX pipeline state
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 };
D3D::context->ClearRenderTargetView(FramebufferManager::GetEFBColorTexture()->GetRTV(), ClearColor);
D3D::context->ClearDepthStencilView(FramebufferManager::GetEFBDepthTexture()->GetDSV(), D3D11_CLEAR_DEPTH, 1.f, 0);
@ -1073,6 +1088,32 @@ void Renderer::RestoreAPIState()
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()
{
// 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
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
{
if (tm0.mag_filter) // linear mag filter
{
if (mip == TEXF_NONE) D3D::gfxstate->SetSamplerFilter(stage, 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_LINEAR) D3D::gfxstate->SetSamplerFilter(stage, D3D11_FILTER_MIN_MAG_MIP_LINEAR);
if (mip == TEXF_NONE) gx_state.sampdc[stage].Filter = 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) gx_state.sampdc[stage].Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
}
else // point mag filter
{
if (mip == TEXF_NONE) D3D::gfxstate->SetSamplerFilter(stage, 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_LINEAR) D3D::gfxstate->SetSamplerFilter(stage, D3D11_FILTER_MIN_LINEAR_MAG_POINT_MIP_LINEAR);
if (mip == TEXF_NONE) gx_state.sampdc[stage].Filter = 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) gx_state.sampdc[stage].Filter = D3D11_FILTER_MIN_LINEAR_MAG_POINT_MIP_LINEAR;
}
}
else // point min filter
{
if (tm0.mag_filter) // linear mag filter
{
if (mip == TEXF_NONE) D3D::gfxstate->SetSamplerFilter(stage, 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_LINEAR) D3D::gfxstate->SetSamplerFilter(stage, D3D11_FILTER_MIN_POINT_MAG_MIP_LINEAR);
if (mip == TEXF_NONE) gx_state.sampdc[stage].Filter = 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) gx_state.sampdc[stage].Filter = D3D11_FILTER_MIN_POINT_MAG_MIP_LINEAR;
}
else // point mag filter
{
if (mip == TEXF_NONE) D3D::gfxstate->SetSamplerFilter(stage, 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_LINEAR) D3D::gfxstate->SetSamplerFilter(stage, D3D11_FILTER_MIN_MAG_POINT_MIP_LINEAR);
if (mip == TEXF_NONE) gx_state.sampdc[stage].Filter = 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) gx_state.sampdc[stage].Filter = D3D11_FILTER_MIN_MAG_POINT_MIP_LINEAR;
}
}
D3D::gfxstate->samplerdesc[stage].AddressU = d3dClamps[tm0.wrap_s];
D3D::gfxstate->samplerdesc[stage].AddressV = d3dClamps[tm0.wrap_t];
gx_state.sampdc[stage].AddressU = d3dClamps[tm0.wrap_s];
gx_state.sampdc[stage].AddressV = d3dClamps[tm0.wrap_t];
D3D::gfxstate->samplerdesc[stage].MipLODBias = (float)tm0.lod_bias/32.0f;
D3D::gfxstate->samplerdesc[stage].MaxLOD = (float)tm1.max_lod/16.f;
D3D::gfxstate->samplerdesc[stage].MinLOD = (float)tm1.min_lod/16.f;
gx_state.sampdc[stage].MipLODBias = (float)tm0.lod_bias/32.0f;
gx_state.sampdc[stage].MaxLOD = (float)tm1.max_lod/16.f;
gx_state.sampdc[stage].MinLOD = (float)tm1.min_lod/16.f;
}
void Renderer::SetInterlacingMode()

View file

@ -24,6 +24,9 @@ public:
void SetSamplerState(int stage,int texindex);
void SetInterlacingMode();
void ApplyState();
void UnsetTextures();
void RenderText(const char* pstr, int left, int top, u32 color);
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)
{
D3D::gfxstate->SetShaderResource(stage, texture->GetSRV());
D3D::context->PSSetShaderResources(stage, 1, &texture->GetSRV());
}
bool TextureCache::TCacheEntry::Save(const char filename[])

View file

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

View file

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