mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-23 14:19:46 -06:00
Renderer: Move cull mode to a rasterization state object
Also moves logic for primitive handling to VideoCommon.
This commit is contained in:
@ -434,25 +434,27 @@ ID3D11BlendState* StateCache::Get(BlendingState state)
|
||||
return res;
|
||||
}
|
||||
|
||||
ID3D11RasterizerState* StateCache::Get(RasterizerState state)
|
||||
ID3D11RasterizerState* StateCache::Get(RasterizationState state)
|
||||
{
|
||||
auto it = m_raster.find(state.packed);
|
||||
|
||||
auto it = m_raster.find(state.hex);
|
||||
if (it != m_raster.end())
|
||||
return it->second;
|
||||
|
||||
D3D11_RASTERIZER_DESC rastdc = CD3D11_RASTERIZER_DESC(D3D11_FILL_SOLID, state.cull_mode, false, 0,
|
||||
0.f, 0, false, true, false, false);
|
||||
static constexpr std::array<D3D11_CULL_MODE, 4> cull_modes = {
|
||||
{D3D11_CULL_NONE, D3D11_CULL_BACK, D3D11_CULL_FRONT, D3D11_CULL_BACK}};
|
||||
|
||||
D3D11_RASTERIZER_DESC desc = {};
|
||||
desc.FillMode = D3D11_FILL_SOLID;
|
||||
desc.CullMode = cull_modes[state.cullmode];
|
||||
desc.ScissorEnable = TRUE;
|
||||
|
||||
ID3D11RasterizerState* res = nullptr;
|
||||
|
||||
HRESULT hr = D3D::device->CreateRasterizerState(&rastdc, &res);
|
||||
HRESULT hr = D3D::device->CreateRasterizerState(&desc, &res);
|
||||
if (FAILED(hr))
|
||||
PanicAlert("Failed to create rasterizer state at %s %d\n", __FILE__, __LINE__);
|
||||
|
||||
D3D::SetDebugObjectName(res, "rasterizer state used to emulate the GX pipeline");
|
||||
m_raster.emplace(state.packed, res);
|
||||
|
||||
m_raster.emplace(state.hex, res);
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -531,4 +533,12 @@ void StateCache::Clear()
|
||||
m_sampler.clear();
|
||||
}
|
||||
|
||||
D3D11_PRIMITIVE_TOPOLOGY StateCache::GetPrimitiveTopology(PrimitiveType primitive)
|
||||
{
|
||||
static constexpr std::array<D3D11_PRIMITIVE_TOPOLOGY, 4> primitives = {
|
||||
{D3D11_PRIMITIVE_TOPOLOGY_POINTLIST, D3D11_PRIMITIVE_TOPOLOGY_LINELIST,
|
||||
D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP}};
|
||||
return primitives[static_cast<u32>(primitive)];
|
||||
}
|
||||
|
||||
} // namespace DX11
|
||||
|
@ -20,13 +20,6 @@ struct ID3D11RasterizerState;
|
||||
|
||||
namespace DX11
|
||||
{
|
||||
union RasterizerState
|
||||
{
|
||||
BitField<0, 2, D3D11_CULL_MODE> cull_mode;
|
||||
|
||||
u32 packed;
|
||||
};
|
||||
|
||||
union SamplerState
|
||||
{
|
||||
BitField<0, 3, u64> min_filter;
|
||||
@ -48,12 +41,15 @@ public:
|
||||
// Returned objects is owned by the cache and does not need to be released.
|
||||
ID3D11SamplerState* Get(SamplerState state);
|
||||
ID3D11BlendState* Get(BlendingState state);
|
||||
ID3D11RasterizerState* Get(RasterizerState state);
|
||||
ID3D11RasterizerState* Get(RasterizationState state);
|
||||
ID3D11DepthStencilState* Get(DepthState state);
|
||||
|
||||
// Release all cached states and clear hash tables.
|
||||
void Clear();
|
||||
|
||||
// Convert RasterState primitive type to D3D11 primitive topology.
|
||||
static D3D11_PRIMITIVE_TOPOLOGY GetPrimitiveTopology(PrimitiveType primitive);
|
||||
|
||||
private:
|
||||
std::unordered_map<u32, ID3D11DepthStencilState*> m_depth;
|
||||
std::unordered_map<u32, ID3D11RasterizerState*> m_raster;
|
||||
|
@ -207,7 +207,7 @@ void GeometryShaderCache::Shutdown()
|
||||
g_gs_disk_cache.Close();
|
||||
}
|
||||
|
||||
bool GeometryShaderCache::SetShader(u32 primitive_type)
|
||||
bool GeometryShaderCache::SetShader(PrimitiveType primitive_type)
|
||||
{
|
||||
GeometryShaderUid uid = GetGeometryShaderUid(primitive_type);
|
||||
if (last_entry && uid == last_uid)
|
||||
|
@ -18,7 +18,7 @@ public:
|
||||
static void Reload();
|
||||
static void Clear();
|
||||
static void Shutdown();
|
||||
static bool SetShader(u32 primitive_type);
|
||||
static bool SetShader(PrimitiveType primitive_type);
|
||||
static bool CompileShader(const GeometryShaderUid& uid);
|
||||
static bool InsertByteCode(const GeometryShaderUid& uid, const u8* bytecode, size_t len);
|
||||
static void PrecompileShaders();
|
||||
|
@ -61,7 +61,7 @@ struct GXPipelineState
|
||||
std::array<SamplerState, 8> samplers;
|
||||
BlendingState blend;
|
||||
DepthState zmode;
|
||||
RasterizerState raster;
|
||||
RasterizationState raster;
|
||||
};
|
||||
|
||||
static u32 s_last_multisamples = 1;
|
||||
@ -254,8 +254,7 @@ Renderer::Renderer() : ::Renderer(D3D::GetBackBufferWidth(), D3D::GetBackBufferH
|
||||
s_gx_state.zmode.testenable = false;
|
||||
s_gx_state.zmode.updateenable = false;
|
||||
s_gx_state.zmode.func = ZMode::NEVER;
|
||||
|
||||
s_gx_state.raster.cull_mode = D3D11_CULL_NONE;
|
||||
s_gx_state.raster.cullmode = GenMode::CULL_NONE;
|
||||
|
||||
// Clear EFB textures
|
||||
constexpr std::array<float, 4> clear_color{{0.f, 0.f, 0.f, 1.f}};
|
||||
@ -867,6 +866,8 @@ void Renderer::ApplyState()
|
||||
D3D::stateman->PushBlendState(s_gx_state_cache.Get(s_gx_state.blend));
|
||||
D3D::stateman->PushDepthState(s_gx_state_cache.Get(s_gx_state.zmode));
|
||||
D3D::stateman->PushRasterizerState(s_gx_state_cache.Get(s_gx_state.raster));
|
||||
D3D::stateman->SetPrimitiveTopology(
|
||||
StateCache::GetPrimitiveTopology(s_gx_state.raster.primitive));
|
||||
FramebufferManager::SetIntegerEFBRenderTarget(s_gx_state.blend.logicopenable);
|
||||
|
||||
for (size_t stage = 0; stage < s_gx_state.samplers.size(); stage++)
|
||||
@ -891,29 +892,9 @@ void Renderer::RestoreState()
|
||||
D3D::stateman->PopRasterizerState();
|
||||
}
|
||||
|
||||
void Renderer::ApplyCullDisable()
|
||||
void Renderer::SetRasterizationState(const RasterizationState& state)
|
||||
{
|
||||
RasterizerState rast = s_gx_state.raster;
|
||||
rast.cull_mode = D3D11_CULL_NONE;
|
||||
|
||||
ID3D11RasterizerState* raststate = s_gx_state_cache.Get(rast);
|
||||
D3D::stateman->PushRasterizerState(raststate);
|
||||
}
|
||||
|
||||
void Renderer::RestoreCull()
|
||||
{
|
||||
D3D::stateman->PopRasterizerState();
|
||||
}
|
||||
|
||||
void Renderer::SetGenerationMode()
|
||||
{
|
||||
constexpr std::array<D3D11_CULL_MODE, 4> d3d_cull_modes{{
|
||||
D3D11_CULL_NONE, D3D11_CULL_BACK, D3D11_CULL_FRONT, D3D11_CULL_BACK,
|
||||
}};
|
||||
|
||||
// rastdc.FrontCounterClockwise must be false for this to work
|
||||
// TODO: GX_CULL_ALL not supported, yet!
|
||||
s_gx_state.raster.cull_mode = d3d_cull_modes[bpmem.genMode.cullmode];
|
||||
s_gx_state.raster.hex = state.hex;
|
||||
}
|
||||
|
||||
void Renderer::SetDepthState(const DepthState& state)
|
||||
|
@ -21,7 +21,7 @@ public:
|
||||
|
||||
void SetBlendingState(const BlendingState& state) override;
|
||||
void SetScissorRect(const EFBRectangle& rc) override;
|
||||
void SetGenerationMode() override;
|
||||
void SetRasterizationState(const RasterizationState& state) override;
|
||||
void SetDepthState(const DepthState& state) override;
|
||||
void SetSamplerState(int stage, int texindex, bool custom_tex) override;
|
||||
void SetInterlacingMode() override;
|
||||
@ -33,9 +33,6 @@ public:
|
||||
void ApplyState() override;
|
||||
void RestoreState() override;
|
||||
|
||||
void ApplyCullDisable();
|
||||
void RestoreCull();
|
||||
|
||||
void RenderText(const std::string& text, int left, int top, u32 color) override;
|
||||
|
||||
u32 AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data) override;
|
||||
|
@ -127,28 +127,10 @@ void VertexManager::Draw(u32 stride)
|
||||
u32 baseVertex = m_vertexDrawOffset / stride;
|
||||
u32 startIndex = m_indexDrawOffset / sizeof(u16);
|
||||
|
||||
switch (m_current_primitive_type)
|
||||
{
|
||||
case PRIMITIVE_POINTS:
|
||||
D3D::stateman->SetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_POINTLIST);
|
||||
static_cast<Renderer*>(g_renderer.get())->ApplyCullDisable();
|
||||
break;
|
||||
case PRIMITIVE_LINES:
|
||||
D3D::stateman->SetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_LINELIST);
|
||||
static_cast<Renderer*>(g_renderer.get())->ApplyCullDisable();
|
||||
break;
|
||||
case PRIMITIVE_TRIANGLES:
|
||||
D3D::stateman->SetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
|
||||
break;
|
||||
}
|
||||
|
||||
D3D::stateman->Apply();
|
||||
D3D::context->DrawIndexed(indices, startIndex, baseVertex);
|
||||
|
||||
INCSTAT(stats.thisFrame.numDrawCalls);
|
||||
|
||||
if (m_current_primitive_type != PRIMITIVE_TRIANGLES)
|
||||
static_cast<Renderer*>(g_renderer.get())->RestoreCull();
|
||||
}
|
||||
|
||||
void VertexManager::vFlush()
|
||||
|
Reference in New Issue
Block a user