Merge pull request #1503 from kayru/d3d_optimization_cache

D3D: Filter redundant API calls by caching state in StateManager
This commit is contained in:
Dolphin Bot 2014-12-11 23:38:35 +01:00
commit 971a95aece
12 changed files with 452 additions and 138 deletions

View File

@ -33,46 +33,170 @@ template<typename T> AutoState<T>::~AutoState()
state = nullptr;
}
StateManager::StateManager() : cur_blendstate(nullptr), cur_depthstate(nullptr), cur_raststate(nullptr) {}
StateManager::StateManager()
: m_currentBlendState(nullptr)
, m_currentDepthState(nullptr)
, m_currentRasterizerState(nullptr)
, m_dirtyFlags(~0u)
, m_pending()
, m_current()
{
}
void StateManager::PushBlendState(const ID3D11BlendState* state) { blendstates.push(AutoBlendState(state)); }
void StateManager::PushDepthState(const ID3D11DepthStencilState* state) { depthstates.push(AutoDepthStencilState(state)); }
void StateManager::PushRasterizerState(const ID3D11RasterizerState* state) { raststates.push(AutoRasterizerState(state)); }
void StateManager::PopBlendState() { blendstates.pop(); }
void StateManager::PopDepthState() { depthstates.pop(); }
void StateManager::PopRasterizerState() { raststates.pop(); }
void StateManager::PushBlendState(const ID3D11BlendState* state) { m_blendStates.push(AutoBlendState(state)); }
void StateManager::PushDepthState(const ID3D11DepthStencilState* state) { m_depthStates.push(AutoDepthStencilState(state)); }
void StateManager::PushRasterizerState(const ID3D11RasterizerState* state) { m_rasterizerStates.push(AutoRasterizerState(state)); }
void StateManager::PopBlendState() { m_blendStates.pop(); }
void StateManager::PopDepthState() { m_depthStates.pop(); }
void StateManager::PopRasterizerState() { m_rasterizerStates.pop(); }
void StateManager::Apply()
{
if (!blendstates.empty())
if (!m_blendStates.empty())
{
if (cur_blendstate != blendstates.top().GetPtr())
if (m_currentBlendState != m_blendStates.top().GetPtr())
{
cur_blendstate = (ID3D11BlendState*)blendstates.top().GetPtr();
D3D::context->OMSetBlendState(cur_blendstate, nullptr, 0xFFFFFFFF);
m_currentBlendState = (ID3D11BlendState*)m_blendStates.top().GetPtr();
D3D::context->OMSetBlendState(m_currentBlendState, nullptr, 0xFFFFFFFF);
}
}
else ERROR_LOG(VIDEO, "Tried to apply without blend state!");
if (!depthstates.empty())
if (!m_depthStates.empty())
{
if (cur_depthstate != depthstates.top().GetPtr())
if (m_currentDepthState != m_depthStates.top().GetPtr())
{
cur_depthstate = (ID3D11DepthStencilState*)depthstates.top().GetPtr();
D3D::context->OMSetDepthStencilState(cur_depthstate, 0);
m_currentDepthState = (ID3D11DepthStencilState*)m_depthStates.top().GetPtr();
D3D::context->OMSetDepthStencilState(m_currentDepthState, 0);
}
}
else ERROR_LOG(VIDEO, "Tried to apply without depth state!");
if (!raststates.empty())
if (!m_rasterizerStates.empty())
{
if (cur_raststate != raststates.top().GetPtr())
if (m_currentRasterizerState != m_rasterizerStates.top().GetPtr())
{
cur_raststate = (ID3D11RasterizerState*)raststates.top().GetPtr();
D3D::context->RSSetState(cur_raststate);
m_currentRasterizerState = (ID3D11RasterizerState*)m_rasterizerStates.top().GetPtr();
D3D::context->RSSetState(m_currentRasterizerState);
}
}
else ERROR_LOG(VIDEO, "Tried to apply without rasterizer state!");
if (!m_dirtyFlags)
{
return;
}
const u32 dirtyTextures = DirtyFlag_Texture0 | DirtyFlag_Texture1 | DirtyFlag_Texture2 | DirtyFlag_Texture3
| DirtyFlag_Texture4 | DirtyFlag_Texture5 | DirtyFlag_Texture6 | DirtyFlag_Texture7;
const u32 dirtySamplers = DirtyFlag_Sampler0 | DirtyFlag_Sampler1 | DirtyFlag_Sampler2 | DirtyFlag_Sampler3
| DirtyFlag_Sampler4 | DirtyFlag_Sampler5 | DirtyFlag_Sampler6 | DirtyFlag_Sampler7;
const u32 dirtyConstants = DirtyFlag_PixelConstants | DirtyFlag_VertexConstants | DirtyFlag_GeometryConstants;
const u32 dirtyShaders = DirtyFlag_PixelShader | DirtyFlag_VertexShader | DirtyFlag_GeometryShader;
const u32 dirtyBuffers = DirtyFlag_VertexBuffer | DirtyFlag_IndexBuffer;
if (m_dirtyFlags & dirtyConstants)
{
if (m_current.pixelConstants[0] != m_pending.pixelConstants[0] ||
m_current.pixelConstants[1] != m_pending.pixelConstants[1])
{
D3D::context->PSSetConstantBuffers(0, m_pending.pixelConstants[1] ? 2 : 1, m_pending.pixelConstants);
m_current.pixelConstants[0] = m_pending.pixelConstants[0];
m_current.pixelConstants[1] = m_pending.pixelConstants[1];
}
if (m_current.vertexConstants != m_pending.vertexConstants)
{
D3D::context->VSSetConstantBuffers(0, 1, &m_pending.vertexConstants);
m_current.vertexConstants = m_pending.vertexConstants;
}
if (m_current.geometryConstants != m_pending.geometryConstants)
{
D3D::context->GSSetConstantBuffers(0, 1, &m_pending.geometryConstants);
m_current.geometryConstants = m_pending.geometryConstants;
}
}
if (m_dirtyFlags & (dirtyBuffers|DirtyFlag_InputAssembler))
{
if (m_current.vertexBuffer != m_pending.vertexBuffer ||
m_current.vertexBufferStride != m_pending.vertexBufferStride ||
m_current.vertexBufferOffset != m_pending.vertexBufferOffset)
{
D3D::context->IASetVertexBuffers(0, 1, &m_pending.vertexBuffer, &m_pending.vertexBufferStride, &m_pending.vertexBufferOffset);
m_current.vertexBuffer = m_pending.vertexBuffer;
m_current.vertexBufferStride = m_pending.vertexBufferStride;
m_current.vertexBufferOffset = m_pending.vertexBufferOffset;
}
if (m_current.indexBuffer != m_pending.indexBuffer)
{
D3D::context->IASetIndexBuffer(m_pending.indexBuffer, DXGI_FORMAT_R16_UINT, 0);
m_current.indexBuffer = m_pending.indexBuffer;
}
if (m_current.topology != m_pending.topology)
{
D3D::context->IASetPrimitiveTopology(m_pending.topology);
m_current.topology = m_pending.topology;
}
if (m_current.inputLayout != m_pending.inputLayout)
{
D3D::context->IASetInputLayout(m_pending.inputLayout);
m_current.inputLayout = m_pending.inputLayout;
}
}
if (m_dirtyFlags & dirtyTextures)
{
for (int i = 0; i < 8; ++i)
{
// TODO: bit scan through dirty flags
if (m_current.textures[i] != m_pending.textures[i])
{
D3D::context->PSSetShaderResources(i, 1, &m_pending.textures[i]);
m_current.textures[i] = m_pending.textures[i];
}
}
}
if (m_dirtyFlags & dirtySamplers)
{
for (int i = 0; i < 8; ++i)
{
// TODO: bit scan through dirty flags
if (m_current.samplers[i] != m_pending.samplers[i])
{
D3D::context->PSSetSamplers(i, 1, &m_pending.samplers[i]);
m_current.samplers[i] = m_pending.samplers[i];
}
}
}
if (m_dirtyFlags & dirtyShaders)
{
if (m_current.pixelShader != m_pending.pixelShader)
{
D3D::context->PSSetShader(m_pending.pixelShader, nullptr, 0);
m_current.pixelShader = m_pending.pixelShader;
}
if (m_current.vertexShader != m_pending.vertexShader)
{
D3D::context->VSSetShader(m_pending.vertexShader, nullptr, 0);
m_current.vertexShader = m_pending.vertexShader;
}
if (m_current.geometryShader != m_pending.geometryShader)
{
D3D::context->GSSetShader(m_pending.geometryShader, nullptr, 0);
m_current.geometryShader = m_pending.geometryShader;
}
}
m_dirtyFlags = 0;
}
} // namespace D3D

View File

@ -73,7 +73,6 @@ private:
std::unordered_map<u32, ID3D11RasterizerState*> m_raster;
std::unordered_map<u32, ID3D11BlendState*> m_blend;
std::unordered_map<u64, ID3D11SamplerState*> m_sampler;
};
namespace D3D
@ -111,16 +110,199 @@ public:
void PopDepthState();
void PopRasterizerState();
// call this before any drawing operation if states could have changed meanwhile
void SetTexture(u32 index, ID3D11ShaderResourceView* texture)
{
if (m_current.textures[index] != texture)
{
m_dirtyFlags |= DirtyFlag_Texture0 << index;
m_pending.textures[index] = texture;
}
}
void SetSampler(u32 index, ID3D11SamplerState* sampler)
{
if (m_current.samplers[index] != sampler)
{
m_dirtyFlags |= DirtyFlag_Sampler0 << index;
m_pending.samplers[index] = sampler;
}
}
void SetPixelConstants(ID3D11Buffer* buffer0, ID3D11Buffer* buffer1 = nullptr)
{
if (m_current.pixelConstants[0] != buffer0)
{
m_dirtyFlags |= DirtyFlag_PixelConstants;
m_pending.pixelConstants[0] = buffer0;
}
if (m_current.pixelConstants[1] != buffer1)
{
m_dirtyFlags |= DirtyFlag_PixelConstants;
m_pending.pixelConstants[1] = buffer1;
}
}
void SetVertexConstants(ID3D11Buffer* buffer)
{
if (m_current.vertexConstants != buffer)
{
m_dirtyFlags |= DirtyFlag_VertexConstants;
m_pending.vertexConstants = buffer;
}
}
void SetGeometryConstants(ID3D11Buffer* buffer)
{
if (m_current.geometryConstants != buffer)
{
m_dirtyFlags |= DirtyFlag_GeometryConstants;
m_pending.geometryConstants = buffer;
}
}
void SetVertexBuffer(ID3D11Buffer* buffer, u32 stride, u32 offset)
{
if (m_current.vertexBuffer != buffer ||
m_current.vertexBufferStride != stride ||
m_current.vertexBufferOffset != offset)
{
m_dirtyFlags |= DirtyFlag_VertexBuffer;
m_pending.vertexBuffer = buffer;
m_pending.vertexBufferStride = stride;
m_pending.vertexBufferOffset = offset;
}
}
void SetIndexBuffer(ID3D11Buffer* buffer)
{
if (m_current.indexBuffer != buffer)
{
m_dirtyFlags |= DirtyFlag_IndexBuffer;
m_pending.indexBuffer = buffer;
}
}
void SetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY topology)
{
if (m_current.topology != topology)
{
m_dirtyFlags |= DirtyFlag_InputAssembler;
m_pending.topology = topology;
}
}
void SetInputLayout(ID3D11InputLayout* layout)
{
if (m_current.inputLayout != layout)
{
m_dirtyFlags |= DirtyFlag_InputAssembler;
m_pending.inputLayout = layout;
}
}
void SetPixelShader(ID3D11PixelShader* shader)
{
if (m_current.pixelShader != shader)
{
m_dirtyFlags |= DirtyFlag_PixelShader;
m_pending.pixelShader = shader;
}
}
void SetPixelShaderDynamic(ID3D11PixelShader* shader, ID3D11ClassInstance * const * classInstances, u32 classInstancesCount)
{
D3D::context->PSSetShader(shader, classInstances, classInstancesCount);
m_pending.pixelShader = shader;
}
void SetVertexShader(ID3D11VertexShader* shader)
{
if (m_current.vertexShader != shader)
{
m_dirtyFlags |= DirtyFlag_VertexShader;
m_pending.vertexShader = shader;
}
}
void SetGeometryShader(ID3D11GeometryShader* shader)
{
if (m_current.geometryShader != shader)
{
m_dirtyFlags |= DirtyFlag_GeometryShader;
m_pending.geometryShader = shader;
}
}
// call this immediately before any drawing operation or to explicitly apply pending resource state changes
void Apply();
private:
std::stack<AutoBlendState> blendstates;
std::stack<AutoDepthStencilState> depthstates;
std::stack<AutoRasterizerState> raststates;
ID3D11BlendState* cur_blendstate;
ID3D11DepthStencilState* cur_depthstate;
ID3D11RasterizerState* cur_raststate;
std::stack<AutoBlendState> m_blendStates;
std::stack<AutoDepthStencilState> m_depthStates;
std::stack<AutoRasterizerState> m_rasterizerStates;
ID3D11BlendState* m_currentBlendState;
ID3D11DepthStencilState* m_currentDepthState;
ID3D11RasterizerState* m_currentRasterizerState;
enum DirtyFlags
{
DirtyFlag_Texture0 = 1 << 0,
DirtyFlag_Texture1 = 1 << 1,
DirtyFlag_Texture2 = 1 << 2,
DirtyFlag_Texture3 = 1 << 3,
DirtyFlag_Texture4 = 1 << 4,
DirtyFlag_Texture5 = 1 << 5,
DirtyFlag_Texture6 = 1 << 6,
DirtyFlag_Texture7 = 1 << 7,
DirtyFlag_Sampler0 = 1 << 8,
DirtyFlag_Sampler1 = 1 << 9,
DirtyFlag_Sampler2 = 1 << 10,
DirtyFlag_Sampler3 = 1 << 11,
DirtyFlag_Sampler4 = 1 << 12,
DirtyFlag_Sampler5 = 1 << 13,
DirtyFlag_Sampler6 = 1 << 14,
DirtyFlag_Sampler7 = 1 << 15,
DirtyFlag_PixelConstants = 1 << 16,
DirtyFlag_VertexConstants = 1 << 17,
DirtyFlag_GeometryConstants = 1 << 18,
DirtyFlag_VertexBuffer = 1 << 19,
DirtyFlag_IndexBuffer = 1 << 20,
DirtyFlag_PixelShader = 1 << 21,
DirtyFlag_VertexShader = 1 << 22,
DirtyFlag_GeometryShader = 1 << 23,
DirtyFlag_InputAssembler = 1 << 24,
};
u32 m_dirtyFlags;
struct Resources
{
ID3D11ShaderResourceView* textures[8];
ID3D11SamplerState* samplers[8];
ID3D11Buffer* pixelConstants[2];
ID3D11Buffer* vertexConstants;
ID3D11Buffer* geometryConstants;
ID3D11Buffer* vertexBuffer;
ID3D11Buffer* indexBuffer;
u32 vertexBufferStride;
u32 vertexBufferOffset;
D3D11_PRIMITIVE_TOPOLOGY topology;
ID3D11InputLayout* inputLayout;
ID3D11PixelShader* pixelShader;
ID3D11VertexShader* vertexShader;
ID3D11GeometryShader* geometryShader;
};
Resources m_pending;
Resources m_current;
};
extern StateManager* stateman;

View File

@ -346,14 +346,13 @@ int CD3DFont::DrawTextScaled(float x, float y, float size, float spacing, u32 dw
// set general pipeline state
D3D::stateman->PushBlendState(m_blendstate);
D3D::stateman->PushRasterizerState(m_raststate);
D3D::stateman->Apply();
D3D::context->PSSetShader(m_pshader, nullptr, 0);
D3D::context->VSSetShader(m_vshader, nullptr, 0);
D3D::stateman->SetPixelShader(m_pshader);
D3D::stateman->SetVertexShader(m_vshader);
D3D::context->IASetInputLayout(m_InputLayout);
D3D::context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
D3D::context->PSSetShaderResources(0, 1, &m_pTexture);
D3D::stateman->SetInputLayout(m_InputLayout);
D3D::stateman->SetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
D3D::stateman->SetTexture(0, m_pTexture);
float fStartX = sx;
for (char c : text)
@ -392,7 +391,9 @@ int CD3DFont::DrawTextScaled(float x, float y, float size, float spacing, u32 dw
{
context->Unmap(m_pVB, 0);
D3D::context->IASetVertexBuffers(0, 1, &m_pVB, &stride, &bufoffset);
D3D::stateman->SetVertexBuffer(m_pVB, stride, bufoffset);
D3D::stateman->Apply();
D3D::context->Draw(3 * dwNumTriangles, 0);
dwNumTriangles = 0;
@ -408,7 +409,9 @@ int CD3DFont::DrawTextScaled(float x, float y, float size, float spacing, u32 dw
context->Unmap(m_pVB, 0);
if (dwNumTriangles > 0)
{
D3D::context->IASetVertexBuffers(0, 1, &m_pVB, &stride, &bufoffset);
D3D::stateman->SetVertexBuffer(m_pVB, stride, bufoffset);
D3D::stateman->Apply();
D3D::context->Draw(3 * dwNumTriangles, 0);
}
D3D::stateman->PopBlendState();
@ -494,12 +497,12 @@ void ShutdownUtils()
void SetPointCopySampler()
{
D3D::context->PSSetSamplers(0, 1, &point_copy_sampler);
D3D::stateman->SetSampler(0, point_copy_sampler);
}
void SetLinearCopySampler()
{
D3D::context->PSSetSamplers(0, 1, &linear_copy_sampler);
D3D::stateman->SetSampler(0, linear_copy_sampler);
}
void drawShadedTexQuad(ID3D11ShaderResourceView* texture,
@ -543,17 +546,18 @@ void drawShadedTexQuad(ID3D11ShaderResourceView* texture,
UINT stride = sizeof(STQVertex);
UINT offset = 0;
D3D::context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
D3D::context->IASetInputLayout(layout);
D3D::context->IASetVertexBuffers(0, 1, &util_vbuf->GetBuffer(), &stride, &offset);
D3D::context->PSSetShader(PShader, nullptr, 0);
D3D::context->PSSetShaderResources(0, 1, &texture);
D3D::context->VSSetShader(Vshader, nullptr, 0);
D3D::stateman->SetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
D3D::stateman->SetInputLayout(layout);
D3D::stateman->SetVertexBuffer(util_vbuf->GetBuffer(), stride, offset);
D3D::stateman->SetPixelShader(PShader);
D3D::stateman->SetTexture(0, texture);
D3D::stateman->SetVertexShader(Vshader);
D3D::stateman->Apply();
D3D::context->Draw(4, stq_offset);
ID3D11ShaderResourceView* texres = nullptr;
context->PSSetShaderResources(0, 1, &texres); // immediately unbind the texture
D3D::stateman->SetTexture(0, nullptr); // immediately unbind the texture
D3D::stateman->Apply();
}
void drawShadedTexSubQuad(ID3D11ShaderResourceView* texture,
@ -600,17 +604,18 @@ void drawShadedTexSubQuad(ID3D11ShaderResourceView* texture,
UINT stride = sizeof(STSQVertex);
UINT offset = 0;
context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
context->IASetVertexBuffers(0, 1, &util_vbuf->GetBuffer(), &stride, &offset);
context->IASetInputLayout(layout);
context->PSSetShaderResources(0, 1, &texture);
context->PSSetShader(PShader, nullptr, 0);
context->VSSetShader(Vshader, nullptr, 0);
stateman->SetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
stateman->SetVertexBuffer(util_vbuf->GetBuffer(), stride, offset);
stateman->SetInputLayout(layout);
stateman->SetTexture(0, texture);
stateman->SetPixelShader(PShader);
stateman->SetVertexShader(Vshader);
stateman->Apply();
context->Draw(4, stsq_offset);
ID3D11ShaderResourceView* texres = nullptr;
context->PSSetShaderResources(0, 1, &texres); // immediately unbind the texture
stateman->SetTexture(0, nullptr); // immediately unbind the texture
stateman->Apply();
}
// Fills a certain area of the current render target with the specified color
@ -639,14 +644,14 @@ void drawColorQuad(u32 Color, float x1, float y1, float x2, float y2)
draw_quad_data.col = Color;
}
context->VSSetShader(VertexShaderCache::GetClearVertexShader(), nullptr, 0);
context->PSSetShader(PixelShaderCache::GetClearProgram(), nullptr, 0);
context->IASetInputLayout(VertexShaderCache::GetClearInputLayout());
stateman->SetVertexShader(VertexShaderCache::GetClearVertexShader());
stateman->SetPixelShader(PixelShaderCache::GetClearProgram());
stateman->SetInputLayout(VertexShaderCache::GetClearInputLayout());
UINT stride = sizeof(ColVertex);
UINT offset = 0;
context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
context->IASetVertexBuffers(0, 1, &util_vbuf->GetBuffer(), &stride, &offset);
stateman->SetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
stateman->SetVertexBuffer(util_vbuf->GetBuffer(), stride, offset);
stateman->Apply();
context->Draw(4, cq_offset);
@ -669,14 +674,16 @@ void drawClearQuad(u32 Color, float z, ID3D11PixelShader* PShader, ID3D11VertexS
clear_quad_data.col = Color;
clear_quad_data.z = z;
}
context->VSSetShader(Vshader, nullptr, 0);
context->PSSetShader(PShader, nullptr, 0);
context->IASetInputLayout(layout);
stateman->SetVertexShader(Vshader);
stateman->SetPixelShader(PShader);
stateman->SetInputLayout(layout);
UINT stride = sizeof(ClearVertex);
UINT offset = 0;
context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
context->IASetVertexBuffers(0, 1, &util_vbuf->GetBuffer(), &stride, &offset);
stateman->SetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
stateman->SetVertexBuffer(util_vbuf->GetBuffer(), stride, offset);
stateman->Apply();
context->Draw(4, clearq_offset);
}

View File

@ -6,6 +6,7 @@
#include "VideoBackends/D3D/D3DBase.h"
#include "VideoBackends/D3D/D3DShader.h"
#include "VideoBackends/D3D/D3DState.h"
#include "VideoBackends/D3D/LineGeometryShader.h"
#include "VideoCommon/VertexShaderGen.h"
@ -223,8 +224,8 @@ bool LineGeometryShader::SetShader(u32 components, float lineWidth,
DEBUG_LOG(VIDEO, "Line params: width %f, texOffset %f, vpWidth %f, vpHeight %f",
lineWidth, texOffset, vpWidth, vpHeight);
D3D::context->GSSetShader(shaderIt->second, nullptr, 0);
D3D::context->GSSetConstantBuffers(0, 1, &m_paramsBuffer);
D3D::stateman->SetGeometryShader(shaderIt->second);
D3D::stateman->SetGeometryConstants(m_paramsBuffer);
return true;
}

View File

@ -4,6 +4,7 @@
#include "VideoBackends/D3D/D3DBase.h"
#include "VideoBackends/D3D/D3DBlob.h"
#include "VideoBackends/D3D/D3DState.h"
#include "VideoBackends/D3D/VertexManager.h"
#include "VideoBackends/D3D/VertexShaderCache.h"
#include "VideoCommon/NativeVertexFormat.h"
@ -137,7 +138,7 @@ void D3DVertexFormat::SetupVertexPointers()
if (FAILED(hr)) PanicAlert("Failed to create input layout, %s %d\n", __FILE__, __LINE__);
DX11::D3D::SetDebugObjectName((ID3D11DeviceChild*)m_layout, "input layout used to emulate the GX pipeline");
}
DX11::D3D::context->IASetInputLayout(m_layout);
DX11::D3D::stateman->SetInputLayout(m_layout);
}
} // namespace DX11

View File

@ -1083,21 +1083,20 @@ size_t PSTextureEncoder::Encode(u8* dst, unsigned int dstFormat,
if (SetStaticShader(dstFormat, srcFormat, isIntensity, scaleByHalf))
#endif
{
D3D::context->VSSetShader(m_vShader, nullptr, 0);
D3D::stateman->SetVertexShader(m_vShader);
D3D::stateman->PushBlendState(m_efbEncodeBlendState);
D3D::stateman->PushDepthState(m_efbEncodeDepthState);
D3D::stateman->PushRasterizerState(m_efbEncodeRastState);
D3D::stateman->Apply();
D3D11_VIEWPORT vp = CD3D11_VIEWPORT(0.f, 0.f, FLOAT(cacheLinesPerRow*2), FLOAT(numBlocksY));
D3D::context->RSSetViewports(1, &vp);
D3D::context->IASetInputLayout(m_quadLayout);
D3D::context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
D3D::stateman->SetInputLayout(m_quadLayout);
D3D::stateman->SetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
UINT stride = sizeof(QuadVertex);
UINT offset = 0;
D3D::context->IASetVertexBuffers(0, 1, &m_quad, &stride, &offset);
D3D::stateman->SetVertexBuffer(m_quad, stride, offset);
EFBRectangle fullSrcRect;
fullSrcRect.left = 0;
@ -1117,8 +1116,6 @@ size_t PSTextureEncoder::Encode(u8* dst, unsigned int dstFormat,
params.TexBottom = float(targetRect.bottom) / g_renderer->GetTargetHeight();
D3D::context->UpdateSubresource(m_encodeParams, 0, nullptr, &params, 0, 0);
D3D::context->VSSetConstantBuffers(0, 1, &m_encodeParams);
D3D::context->OMSetRenderTargets(1, &m_outRTV, nullptr);
ID3D11ShaderResourceView* pEFB = (srcFormat == PEControl::Z24) ?
@ -1128,12 +1125,14 @@ size_t PSTextureEncoder::Encode(u8* dst, unsigned int dstFormat,
// expecting the blurred edges around multisampled shapes.
FramebufferManager::GetResolvedEFBColorTexture()->GetSRV();
D3D::context->PSSetConstantBuffers(0, 1, &m_encodeParams);
D3D::context->PSSetShaderResources(0, 1, &pEFB);
D3D::context->PSSetSamplers(0, 1, &m_efbSampler);
D3D::stateman->SetVertexConstants(m_encodeParams);
D3D::stateman->SetPixelConstants(m_encodeParams);
D3D::stateman->SetTexture(0, pEFB);
D3D::stateman->SetSampler(0, m_efbSampler);
// Encode!
D3D::stateman->Apply();
D3D::context->Draw(4, 0);
// Copy to staging buffer
@ -1143,22 +1142,21 @@ size_t PSTextureEncoder::Encode(u8* dst, unsigned int dstFormat,
// Clean up state
IUnknown* nullDummy = nullptr;
D3D::context->PSSetSamplers(0, 1, (ID3D11SamplerState**)&nullDummy);
D3D::context->PSSetShaderResources(0, 1, (ID3D11ShaderResourceView**)&nullDummy);
D3D::context->PSSetConstantBuffers(0, 1, (ID3D11Buffer**)&nullDummy);
D3D::context->OMSetRenderTargets(0, nullptr, nullptr);
D3D::context->VSSetConstantBuffers(0, 1, (ID3D11Buffer**)&nullDummy);
D3D::stateman->SetSampler(0, nullptr);
D3D::stateman->SetTexture(0, nullptr);
D3D::stateman->SetPixelConstants(nullptr);
D3D::stateman->SetVertexConstants(nullptr);
D3D::stateman->SetPixelShader(nullptr);
D3D::stateman->SetVertexBuffer(nullptr, 0, 0);
D3D::stateman->PopRasterizerState();
D3D::stateman->PopDepthState();
D3D::stateman->PopBlendState();
D3D::context->PSSetShader(nullptr, nullptr, 0);
D3D::context->VSSetShader(nullptr, nullptr, 0);
D3D::stateman->Apply();
// Transfer staging buffer to GameCube/Wii RAM
@ -1276,7 +1274,7 @@ bool PSTextureEncoder::SetStaticShader(unsigned int dstFormat, PEControl::PixelF
{
if (it->second)
{
D3D::context->PSSetShader(it->second, nullptr, 0);
D3D::stateman->SetPixelShader(it->second);
return true;
}
else
@ -1436,7 +1434,7 @@ bool PSTextureEncoder::SetDynamicShader(unsigned int dstFormat,
if (m_generatorSlot != UINT(-1))
m_linkageArray[m_generatorSlot] = m_generatorClass[generatorNum];
D3D::context->PSSetShader(m_dynamicShader,
D3D::stateman->SetPixelShaderDynamic(m_dynamicShader,
m_linkageArray.empty() ? nullptr : &m_linkageArray[0],
(UINT)m_linkageArray.size());

View File

@ -6,6 +6,7 @@
#include "VideoBackends/D3D/D3DBase.h"
#include "VideoBackends/D3D/D3DShader.h"
#include "VideoBackends/D3D/D3DState.h"
#include "VideoBackends/D3D/PointGeometryShader.h"
#include "VideoCommon/VertexShaderGen.h"
@ -217,8 +218,8 @@ bool PointGeometryShader::SetShader(u32 components, float pointSize,
DEBUG_LOG(VIDEO, "Point params: size %f, texOffset %f, vpWidth %f, vpHeight %f",
pointSize, texOffset, vpWidth, vpHeight);
D3D::context->GSSetShader(shaderIt->second, nullptr, 0);
D3D::context->GSSetConstantBuffers(0, 1, &m_paramsBuffer);
D3D::stateman->SetGeometryShader(shaderIt->second);
D3D::stateman->SetGeometryConstants(m_paramsBuffer);
return true;
}

View File

@ -357,7 +357,7 @@ u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data)
// depth buffers can only be completely CopySubresourceRegion'ed, so we're using drawShadedTexQuad instead
D3D11_VIEWPORT vp = CD3D11_VIEWPORT(0.f, 0.f, 1.f, 1.f);
D3D::context->RSSetViewports(1, &vp);
D3D::context->PSSetConstantBuffers(0, 1, &access_efb_cbuf);
D3D::stateman->SetPixelConstants(0, access_efb_cbuf);
D3D::context->OMSetRenderTargets(1, &FramebufferManager::GetEFBDepthReadTexture()->GetRTV(), nullptr);
D3D::SetPointCopySampler();
D3D::drawShadedTexQuad(FramebufferManager::GetEFBDepthTexture()->GetSRV(),
@ -1007,15 +1007,12 @@ void Renderer::ApplyState(bool bUseDstAlpha)
gx_state.raster.wireframe = g_ActiveConfig.bWireFrame;
D3D::stateman->PushRasterizerState(gx_state_cache.Get(gx_state.raster));
ID3D11SamplerState* samplerstate[8];
for (unsigned int stage = 0; stage < 8; stage++)
{
// TODO: cache SamplerState directly, not d3d object
gx_state.sampler[stage].max_anisotropy = g_ActiveConfig.iMaxAnisotropy;
samplerstate[stage] = gx_state_cache.Get(gx_state.sampler[stage]);
D3D::stateman->SetSampler(stage, gx_state_cache.Get(gx_state.sampler[stage]));
}
D3D::context->PSSetSamplers(0, 8, samplerstate);
D3D::stateman->Apply();
if (bUseDstAlpha)
{
@ -1024,12 +1021,14 @@ void Renderer::ApplyState(bool bUseDstAlpha)
SetLogicOpMode();
}
ID3D11Buffer* const_buffers[2] = {PixelShaderCache::GetConstantBuffer(), VertexShaderCache::GetConstantBuffer()};
D3D::context->PSSetConstantBuffers(0, 1 + g_ActiveConfig.bEnablePixelLighting, const_buffers);
D3D::context->VSSetConstantBuffers(0, 1, const_buffers+1);
ID3D11Buffer* vertexConstants = VertexShaderCache::GetConstantBuffer();
ID3D11Buffer* pixelConstants = PixelShaderCache::GetConstantBuffer();
D3D::context->PSSetShader(PixelShaderCache::GetActiveShader(), nullptr, 0);
D3D::context->VSSetShader(VertexShaderCache::GetActiveShader(), nullptr, 0);
D3D::stateman->SetPixelConstants(pixelConstants, g_ActiveConfig.bEnablePixelLighting ? vertexConstants : nullptr);
D3D::stateman->SetVertexConstants(vertexConstants);
D3D::stateman->SetPixelShader(PixelShaderCache::GetActiveShader());
D3D::stateman->SetVertexShader(VertexShaderCache::GetActiveShader());
}
void Renderer::RestoreState()
@ -1046,8 +1045,6 @@ void Renderer::ApplyCullDisable()
ID3D11RasterizerState* raststate = gx_state_cache.Get(rast);
D3D::stateman->PushRasterizerState(raststate);
D3D::stateman->Apply();
}
void Renderer::RestoreCull()

View File

@ -7,6 +7,7 @@
#include "Core/HW/Memmap.h"
#include "VideoBackends/D3D/D3DBase.h"
#include "VideoBackends/D3D/D3DShader.h"
#include "VideoBackends/D3D/D3DState.h"
#include "VideoBackends/D3D/D3DUtil.h"
#include "VideoBackends/D3D/Television.h"
#include "VideoBackends/D3D/VertexShaderCache.h"
@ -150,7 +151,7 @@ void Television::Render()
MathUtil::Rectangle<int> sourceRc(0, 0, int(m_curWidth), int(m_curHeight));
MathUtil::Rectangle<float> destRc(-1.f, 1.f, 1.f, -1.f);
D3D::context->PSSetSamplers(0, 1, &m_samplerState);
D3D::stateman->SetSampler(0, m_samplerState);
D3D::drawShadedTexSubQuad(
m_yuyvTextureSRV, &sourceRc,

View File

@ -4,6 +4,7 @@
#include "Core/HW/Memmap.h"
#include "VideoBackends/D3D/D3DBase.h"
#include "VideoBackends/D3D/D3DState.h"
#include "VideoBackends/D3D/D3DUtil.h"
#include "VideoBackends/D3D/FramebufferManager.h"
#include "VideoBackends/D3D/PixelShaderCache.h"
@ -29,7 +30,7 @@ TextureCache::TCacheEntry::~TCacheEntry()
void TextureCache::TCacheEntry::Bind(unsigned int stage)
{
D3D::context->PSSetShaderResources(stage, 1, &texture->GetSRV());
D3D::stateman->SetTexture(stage, texture->GetSRV());
}
bool TextureCache::TCacheEntry::Save(const std::string& filename, unsigned int level)
@ -143,7 +144,7 @@ void TextureCache::TCacheEntry::FromRenderTarget(u32 dstAddr, unsigned int dstFo
CHECK(SUCCEEDED(hr), "Create efb copy constant buffer %d", cbufid);
D3D::SetDebugObjectName((ID3D11DeviceChild*)efbcopycbuf[cbufid], "a constant buffer used in TextureCache::CopyRenderTargetToTexture");
}
D3D::context->PSSetConstantBuffers(0, 1, &efbcopycbuf[cbufid]);
D3D::stateman->SetPixelConstants(efbcopycbuf[cbufid]);
const TargetRectangle targetSource = g_renderer->ConvertEFBRectangle(srcRect);
// TODO: try targetSource.asRECT();

View File

@ -4,6 +4,7 @@
#include "VideoBackends/D3D/BoundingBox.h"
#include "VideoBackends/D3D/D3DBase.h"
#include "VideoBackends/D3D/D3DState.h"
#include "VideoBackends/D3D/PixelShaderCache.h"
#include "VideoBackends/D3D/Render.h"
#include "VideoBackends/D3D/VertexManager.h"
@ -129,17 +130,19 @@ void VertexManager::Draw(u32 stride)
u32 components = VertexLoaderManager::GetCurrentVertexFormat()->m_components;
u32 indices = IndexGenerator::GetIndexLen();
u32 zero = 0;
D3D::context->IASetVertexBuffers(0, 1, &m_buffers[m_currentBuffer], &stride, &zero);
D3D::context->IASetIndexBuffer(m_buffers[m_currentBuffer], DXGI_FORMAT_R16_UINT, 0);
D3D::stateman->SetVertexBuffer(m_buffers[m_currentBuffer], stride, 0);
D3D::stateman->SetIndexBuffer(m_buffers[m_currentBuffer]);
u32 baseVertex = m_vertexDrawOffset / stride;
u32 startIndex = m_indexDrawOffset / sizeof(u16);
if (current_primitive_type == PRIMITIVE_TRIANGLES)
{
D3D::context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
D3D::stateman->SetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
D3D::stateman->Apply();
D3D::context->DrawIndexed(indices, startIndex, baseVertex);
INCSTAT(stats.thisFrame.numDrawCalls);
}
else if (current_primitive_type == PRIMITIVE_LINES)
@ -157,13 +160,14 @@ void VertexManager::Draw(u32 stride)
if (m_lineShader.SetShader(components, lineWidth,
texOffset, vpWidth, vpHeight, texOffsetEnable))
{
((DX11::Renderer*)g_renderer)->ApplyCullDisable(); // Disable culling for lines and points
D3D::context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_LINELIST);
D3D::stateman->SetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_LINELIST);
D3D::stateman->Apply();
D3D::context->DrawIndexed(indices, startIndex, baseVertex);
INCSTAT(stats.thisFrame.numDrawCalls);
D3D::context->GSSetShader(nullptr, nullptr, 0);
((DX11::Renderer*)g_renderer)->RestoreCull();
D3D::stateman->SetGeometryShader(nullptr);
}
}
else //if (current_primitive_type == PRIMITIVE_POINTS)
@ -181,13 +185,14 @@ void VertexManager::Draw(u32 stride)
if (m_pointShader.SetShader(components, pointSize,
texOffset, vpWidth, vpHeight, texOffsetEnable))
{
((DX11::Renderer*)g_renderer)->ApplyCullDisable(); // Disable culling for lines and points
D3D::context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_POINTLIST);
D3D::stateman->SetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_POINTLIST);
D3D::stateman->Apply();
D3D::context->DrawIndexed(indices, startIndex, baseVertex);
INCSTAT(stats.thisFrame.numDrawCalls);
D3D::context->GSSetShader(nullptr, nullptr, 0);
((DX11::Renderer*)g_renderer)->RestoreCull();
D3D::stateman->SetGeometryShader(nullptr);
}
}
}

View File

@ -280,22 +280,21 @@ void XFBEncoder::Encode(u8* dst, u32 width, u32 height, const EFBRectangle& srcR
// Set up all the state for XFB encoding
D3D::context->PSSetShader(m_pShader, nullptr, 0);
D3D::context->VSSetShader(m_vShader, nullptr, 0);
D3D::stateman->SetPixelShader(m_pShader);
D3D::stateman->SetVertexShader(m_vShader);
D3D::stateman->PushBlendState(m_xfbEncodeBlendState);
D3D::stateman->PushDepthState(m_xfbEncodeDepthState);
D3D::stateman->PushRasterizerState(m_xfbEncodeRastState);
D3D::stateman->Apply();
D3D11_VIEWPORT vp = CD3D11_VIEWPORT(0.f, 0.f, FLOAT(width/2), FLOAT(height));
D3D::context->RSSetViewports(1, &vp);
D3D::context->IASetInputLayout(m_quadLayout);
D3D::context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
D3D::stateman->SetInputLayout(m_quadLayout);
D3D::stateman->SetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
UINT stride = sizeof(QuadVertex);
UINT offset = 0;
D3D::context->IASetVertexBuffers(0, 1, &m_quad, &stride, &offset);
D3D::stateman->SetVertexBuffer(m_quad, stride, offset);
TargetRectangle targetRect = g_renderer->ConvertEFBRectangle(srcRect);
@ -309,18 +308,18 @@ void XFBEncoder::Encode(u8* dst, u32 width, u32 height, const EFBRectangle& srcR
params.Gamma = gamma;
D3D::context->UpdateSubresource(m_encodeParams, 0, nullptr, &params, 0, 0);
D3D::context->VSSetConstantBuffers(0, 1, &m_encodeParams);
D3D::context->OMSetRenderTargets(1, &m_outRTV, nullptr);
ID3D11ShaderResourceView* pEFB = FramebufferManager::GetEFBColorTexture()->GetSRV();
D3D::context->PSSetConstantBuffers(0, 1, &m_encodeParams);
D3D::context->PSSetShaderResources(0, 1, &pEFB);
D3D::context->PSSetSamplers(0, 1, &m_efbSampler);
D3D::stateman->SetVertexConstants(m_encodeParams);
D3D::stateman->SetPixelConstants(m_encodeParams);
D3D::stateman->SetTexture(0, pEFB);
D3D::stateman->SetSampler(0, m_efbSampler);
// Encode!
D3D::stateman->Apply();
D3D::context->Draw(4, 0);
// Copy to staging buffer
@ -330,23 +329,20 @@ void XFBEncoder::Encode(u8* dst, u32 width, u32 height, const EFBRectangle& srcR
// Clean up state
IUnknown* nullDummy = nullptr;
D3D::context->PSSetSamplers(0, 1, (ID3D11SamplerState**)&nullDummy);
D3D::context->PSSetShaderResources(0, 1, (ID3D11ShaderResourceView**)&nullDummy);
D3D::context->PSSetConstantBuffers(0, 1, (ID3D11Buffer**)&nullDummy);
D3D::context->OMSetRenderTargets(0, nullptr, nullptr);
D3D::context->VSSetConstantBuffers(0, 1, (ID3D11Buffer**)&nullDummy);
D3D::stateman->SetSampler(0, nullptr);
D3D::stateman->SetTexture(0, nullptr);
D3D::stateman->SetPixelConstants(nullptr);
D3D::stateman->SetVertexConstants(nullptr);
D3D::stateman->SetPixelShader(nullptr);
D3D::stateman->SetVertexShader(nullptr);
D3D::stateman->PopRasterizerState();
D3D::stateman->PopDepthState();
D3D::stateman->PopBlendState();
D3D::context->PSSetShader(nullptr, nullptr, 0);
D3D::context->VSSetShader(nullptr, nullptr, 0);
// Transfer staging buffer to GameCube/Wii RAM
D3D11_MAPPED_SUBRESOURCE map = { 0 };