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:
parent
a4e338b379
commit
e0b757fe6a
|
@ -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.
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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[])
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue