mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-02-20 10:54:16 +01:00
[d3d11] Implemented rasterizer state creation
This commit is contained in:
parent
f990fcaa01
commit
c7e1131864
@ -995,19 +995,22 @@ namespace dxvk {
|
||||
|
||||
void D3D11DeviceContext::RSSetState(ID3D11RasterizerState* pRasterizerState) {
|
||||
auto rasterizerState = static_cast<D3D11RasterizerState*>(pRasterizerState);
|
||||
m_state.rs.state = rasterizerState;
|
||||
|
||||
// Use default state if the rasterizer
|
||||
// state is not explicitly defined.
|
||||
m_context->setRasterizerState(
|
||||
rasterizerState != nullptr
|
||||
? rasterizerState->GetDXVKStateObject()
|
||||
: m_defaultRsState);
|
||||
|
||||
// In D3D11, the rasterizer state defines
|
||||
// whether the scissor test is enabled, so
|
||||
// we have to update the scissor rectangles.
|
||||
this->ApplyViewportState();
|
||||
if (m_state.rs.state != rasterizerState) {
|
||||
m_state.rs.state = rasterizerState;
|
||||
|
||||
// Use default state if the rasterizer
|
||||
// state is not explicitly defined.
|
||||
m_context->setRasterizerState(
|
||||
rasterizerState != nullptr
|
||||
? rasterizerState->GetDXVKStateObject()
|
||||
: m_defaultRsState);
|
||||
|
||||
// In D3D11, the rasterizer state defines
|
||||
// whether the scissor test is enabled, so
|
||||
// we have to update the scissor rectangles.
|
||||
this->ApplyViewportState();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -365,8 +365,26 @@ namespace dxvk {
|
||||
HRESULT D3D11Device::CreateRasterizerState(
|
||||
const D3D11_RASTERIZER_DESC* pRasterizerDesc,
|
||||
ID3D11RasterizerState** ppRasterizerState) {
|
||||
Logger::err("D3D11Device::CreateRasterizerState: Not implemented");
|
||||
return E_NOTIMPL;
|
||||
D3D11_RASTERIZER_DESC desc;
|
||||
|
||||
if (pRasterizerDesc != nullptr) {
|
||||
desc = *pRasterizerDesc;
|
||||
} else {
|
||||
desc.FillMode = D3D11_FILL_SOLID;
|
||||
desc.CullMode = D3D11_CULL_BACK;
|
||||
desc.FrontCounterClockwise = FALSE;
|
||||
desc.DepthBias = 0;
|
||||
desc.SlopeScaledDepthBias = 0.0f;
|
||||
desc.DepthBiasClamp = 0.0f;
|
||||
desc.DepthClipEnable = TRUE;
|
||||
desc.ScissorEnable = FALSE;
|
||||
desc.MultisampleEnable = FALSE;
|
||||
desc.AntialiasedLineEnable = FALSE;
|
||||
}
|
||||
|
||||
if (ppRasterizerState != nullptr)
|
||||
*ppRasterizerState = m_rsStateObjects.Create(this, desc);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include <dxgi_resource.h>
|
||||
|
||||
#include "d3d11_interfaces.h"
|
||||
#include "d3d11_state.h"
|
||||
|
||||
#include "../util/com/com_private_data.h"
|
||||
|
||||
@ -242,6 +243,8 @@ namespace dxvk {
|
||||
|
||||
Com<ID3D11DeviceContext> m_context;
|
||||
|
||||
D3D11StateObjectSet<D3D11RasterizerState> m_rsStateObjects;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -1,87 +1,34 @@
|
||||
#include "d3d11_device.h"
|
||||
#include "d3d11_state.h"
|
||||
|
||||
namespace dxvk {
|
||||
|
||||
D3D11RasterizerState::D3D11RasterizerState(
|
||||
D3D11Device* device,
|
||||
const D3D11_RASTERIZER_DESC& desc)
|
||||
: m_device(device), m_desc(desc) {
|
||||
|
||||
// Polygon mode. Determines whether the rasterizer fills
|
||||
// a polygon or renders lines connecting the vertices.
|
||||
VkPolygonMode polygonMode = VK_POLYGON_MODE_FILL;
|
||||
|
||||
switch (desc.FillMode) {
|
||||
case D3D11_FILL_WIREFRAME: polygonMode = VK_POLYGON_MODE_LINE; break;
|
||||
case D3D11_FILL_SOLID: polygonMode = VK_POLYGON_MODE_FILL; break;
|
||||
|
||||
default:
|
||||
Logger::err(str::format(
|
||||
"D3D11RasterizerState: Unsupported fill mode: ",
|
||||
desc.FillMode));
|
||||
}
|
||||
|
||||
// Face culling properties. The rasterizer may discard
|
||||
// polygons that are facing towards or away from the
|
||||
// viewer, depending on the options below.
|
||||
VkCullModeFlags cullMode = 0;
|
||||
|
||||
switch (desc.CullMode) {
|
||||
case D3D11_CULL_NONE: cullMode = 0; break;
|
||||
case D3D11_CULL_FRONT: cullMode = VK_CULL_MODE_FRONT_BIT; break;
|
||||
case D3D11_CULL_BACK: cullMode = VK_CULL_MODE_BACK_BIT; break;
|
||||
|
||||
default:
|
||||
Logger::err(str::format(
|
||||
"D3D11RasterizerState: Unsupported cull mode: ",
|
||||
desc.CullMode));
|
||||
}
|
||||
|
||||
VkFrontFace frontFace = desc.FrontCounterClockwise
|
||||
? VK_FRONT_FACE_COUNTER_CLOCKWISE
|
||||
: VK_FRONT_FACE_CLOCKWISE;
|
||||
|
||||
// TODO implement depth bias
|
||||
if (desc.DepthBias != 0)
|
||||
Logger::err("D3D11RasterizerState: Depth bias not supported");
|
||||
|
||||
// TODO implement depth clipping
|
||||
if (desc.DepthClipEnable)
|
||||
Logger::err("D3D11RasterizerState: Depth clip not supported");
|
||||
|
||||
if (desc.AntialiasedLineEnable)
|
||||
Logger::err("D3D11RasterizerState: Antialiased lines not supported");
|
||||
|
||||
m_state = new DxvkRasterizerState(
|
||||
VK_FALSE, VK_FALSE,
|
||||
polygonMode, cullMode, frontFace,
|
||||
VK_FALSE, 0.0f, 0.0f, 0.0f, 1.0f);
|
||||
size_t D3D11StateDescHash::operator () (const D3D11_RASTERIZER_DESC& desc) const {
|
||||
DxvkHashState hash;
|
||||
hash.add(desc.FillMode);
|
||||
hash.add(desc.CullMode);
|
||||
hash.add(desc.FrontCounterClockwise);
|
||||
hash.add(desc.DepthBias);
|
||||
hash.add(desc.SlopeScaledDepthBias);
|
||||
hash.add(desc.DepthBiasClamp);
|
||||
hash.add(desc.DepthClipEnable);
|
||||
hash.add(desc.ScissorEnable);
|
||||
hash.add(desc.MultisampleEnable);
|
||||
hash.add(desc.AntialiasedLineEnable);
|
||||
return hash;
|
||||
}
|
||||
|
||||
|
||||
D3D11RasterizerState::~D3D11RasterizerState() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
HRESULT D3D11RasterizerState::QueryInterface(REFIID riid, void** ppvObject) {
|
||||
COM_QUERY_IFACE(riid, ppvObject, IUnknown);
|
||||
COM_QUERY_IFACE(riid, ppvObject, ID3D11DeviceChild);
|
||||
COM_QUERY_IFACE(riid, ppvObject, ID3D11RasterizerState);
|
||||
|
||||
Logger::warn("D3D11RasterizerState::QueryInterface: Unknown interface query");
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
|
||||
void D3D11RasterizerState::GetDevice(ID3D11Device** ppDevice) {
|
||||
*ppDevice = m_device.ref();
|
||||
}
|
||||
|
||||
|
||||
void D3D11RasterizerState::GetDesc(D3D11_RASTERIZER_DESC* pDesc) {
|
||||
*pDesc = m_desc;
|
||||
bool D3D11StateDescEqual::operator () (const D3D11_RASTERIZER_DESC& a, const D3D11_RASTERIZER_DESC& b) const {
|
||||
return a.FillMode == b.FillMode
|
||||
&& a.CullMode == b.CullMode
|
||||
&& a.FrontCounterClockwise == b.FrontCounterClockwise
|
||||
&& a.DepthBias == b.DepthBias
|
||||
&& a.SlopeScaledDepthBias == b.SlopeScaledDepthBias
|
||||
&& a.DepthBiasClamp == b.DepthBiasClamp
|
||||
&& a.DepthClipEnable == b.DepthClipEnable
|
||||
&& a.ScissorEnable == b.ScissorEnable
|
||||
&& a.MultisampleEnable == b.MultisampleEnable
|
||||
&& a.AntialiasedLineEnable == b.AntialiasedLineEnable;
|
||||
}
|
||||
|
||||
}
|
@ -1,42 +1,63 @@
|
||||
#pragma once
|
||||
|
||||
#include <dxvk_device.h>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "d3d11_device_child.h"
|
||||
#include "d3d11_state_rs.h"
|
||||
|
||||
namespace dxvk {
|
||||
|
||||
class D3D11Device;
|
||||
|
||||
class D3D11RasterizerState : public D3D11DeviceChild<ID3D11RasterizerState> {
|
||||
|
||||
struct D3D11StateDescHash {
|
||||
size_t operator () (const D3D11_RASTERIZER_DESC& desc) const;
|
||||
};
|
||||
|
||||
|
||||
struct D3D11StateDescEqual {
|
||||
bool operator () (const D3D11_RASTERIZER_DESC& a, const D3D11_RASTERIZER_DESC& b) const;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* \brief Unique state object set
|
||||
*
|
||||
* When creating state objects, D3D11 first checks if
|
||||
* an object with the same description already exists
|
||||
* and returns it if that is the case. This class
|
||||
* implements that behaviour.
|
||||
*/
|
||||
template<typename T>
|
||||
class D3D11StateObjectSet {
|
||||
using DescType = typename T::DescType;
|
||||
public:
|
||||
|
||||
D3D11RasterizerState(
|
||||
D3D11Device* device,
|
||||
const D3D11_RASTERIZER_DESC& desc);
|
||||
~D3D11RasterizerState();
|
||||
|
||||
HRESULT QueryInterface(
|
||||
REFIID riid,
|
||||
void** ppvObject) final;
|
||||
|
||||
void GetDevice(
|
||||
ID3D11Device **ppDevice) final;
|
||||
|
||||
void GetDesc(
|
||||
D3D11_RASTERIZER_DESC* pDesc) final;
|
||||
|
||||
Rc<DxvkRasterizerState> GetDXVKStateObject() {
|
||||
return m_state;
|
||||
/**
|
||||
* \brief Retrieves a state object
|
||||
*
|
||||
* Returns an object with the same description or
|
||||
* creates a new one if no such object exists.
|
||||
* \param [in] device The calling D3D11 device
|
||||
* \param [in] desc State object description
|
||||
* \returns Pointer to the state object
|
||||
*/
|
||||
T* Create(D3D11Device* device, const DescType& desc) {
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
|
||||
auto pair = m_objects.find(desc);
|
||||
|
||||
if (pair != m_objects.end())
|
||||
return pair->second.ptr();
|
||||
|
||||
Com<T> result = new T(device, desc);
|
||||
m_objects.insert({ desc, result });
|
||||
return result.ptr();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
Com<D3D11Device> m_device;
|
||||
|
||||
D3D11_RASTERIZER_DESC m_desc;
|
||||
Rc<DxvkRasterizerState> m_state;
|
||||
std::mutex m_mutex;
|
||||
std::unordered_map<DescType, Com<T>,
|
||||
D3D11StateDescHash, D3D11StateDescEqual> m_objects;
|
||||
|
||||
};
|
||||
|
||||
|
87
src/d3d11/d3d11_state_rs.cpp
Normal file
87
src/d3d11/d3d11_state_rs.cpp
Normal file
@ -0,0 +1,87 @@
|
||||
#include "d3d11_device.h"
|
||||
#include "d3d11_state_rs.h"
|
||||
|
||||
namespace dxvk {
|
||||
|
||||
D3D11RasterizerState::D3D11RasterizerState(
|
||||
D3D11Device* device,
|
||||
const D3D11_RASTERIZER_DESC& desc)
|
||||
: m_device(device), m_desc(desc) {
|
||||
|
||||
// Polygon mode. Determines whether the rasterizer fills
|
||||
// a polygon or renders lines connecting the vertices.
|
||||
VkPolygonMode polygonMode = VK_POLYGON_MODE_FILL;
|
||||
|
||||
switch (desc.FillMode) {
|
||||
case D3D11_FILL_WIREFRAME: polygonMode = VK_POLYGON_MODE_LINE; break;
|
||||
case D3D11_FILL_SOLID: polygonMode = VK_POLYGON_MODE_FILL; break;
|
||||
|
||||
default:
|
||||
Logger::err(str::format(
|
||||
"D3D11RasterizerState: Unsupported fill mode: ",
|
||||
desc.FillMode));
|
||||
}
|
||||
|
||||
// Face culling properties. The rasterizer may discard
|
||||
// polygons that are facing towards or away from the
|
||||
// viewer, depending on the options below.
|
||||
VkCullModeFlags cullMode = 0;
|
||||
|
||||
switch (desc.CullMode) {
|
||||
case D3D11_CULL_NONE: cullMode = 0; break;
|
||||
case D3D11_CULL_FRONT: cullMode = VK_CULL_MODE_FRONT_BIT; break;
|
||||
case D3D11_CULL_BACK: cullMode = VK_CULL_MODE_BACK_BIT; break;
|
||||
|
||||
default:
|
||||
Logger::err(str::format(
|
||||
"D3D11RasterizerState: Unsupported cull mode: ",
|
||||
desc.CullMode));
|
||||
}
|
||||
|
||||
VkFrontFace frontFace = desc.FrontCounterClockwise
|
||||
? VK_FRONT_FACE_COUNTER_CLOCKWISE
|
||||
: VK_FRONT_FACE_CLOCKWISE;
|
||||
|
||||
// TODO implement depth bias
|
||||
if (desc.DepthBias != 0)
|
||||
Logger::err("D3D11RasterizerState: Depth bias not supported");
|
||||
|
||||
// TODO implement depth clamp
|
||||
if (!desc.DepthClipEnable)
|
||||
Logger::err("D3D11RasterizerState: Depth clip not supported");
|
||||
|
||||
if (desc.AntialiasedLineEnable)
|
||||
Logger::err("D3D11RasterizerState: Antialiased lines not supported");
|
||||
|
||||
m_state = new DxvkRasterizerState(
|
||||
VK_FALSE, VK_FALSE,
|
||||
polygonMode, cullMode, frontFace,
|
||||
VK_FALSE, 0.0f, 0.0f, 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
|
||||
D3D11RasterizerState::~D3D11RasterizerState() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
HRESULT D3D11RasterizerState::QueryInterface(REFIID riid, void** ppvObject) {
|
||||
COM_QUERY_IFACE(riid, ppvObject, IUnknown);
|
||||
COM_QUERY_IFACE(riid, ppvObject, ID3D11DeviceChild);
|
||||
COM_QUERY_IFACE(riid, ppvObject, ID3D11RasterizerState);
|
||||
|
||||
Logger::warn("D3D11RasterizerState::QueryInterface: Unknown interface query");
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
|
||||
void D3D11RasterizerState::GetDevice(ID3D11Device** ppDevice) {
|
||||
*ppDevice = m_device.ref();
|
||||
}
|
||||
|
||||
|
||||
void D3D11RasterizerState::GetDesc(D3D11_RASTERIZER_DESC* pDesc) {
|
||||
*pDesc = m_desc;
|
||||
}
|
||||
|
||||
}
|
45
src/d3d11/d3d11_state_rs.h
Normal file
45
src/d3d11/d3d11_state_rs.h
Normal file
@ -0,0 +1,45 @@
|
||||
#pragma once
|
||||
|
||||
#include <dxvk_device.h>
|
||||
|
||||
#include "d3d11_device_child.h"
|
||||
|
||||
namespace dxvk {
|
||||
|
||||
class D3D11Device;
|
||||
|
||||
class D3D11RasterizerState : public D3D11DeviceChild<ID3D11RasterizerState> {
|
||||
|
||||
public:
|
||||
|
||||
using DescType = D3D11_RASTERIZER_DESC;
|
||||
|
||||
D3D11RasterizerState(
|
||||
D3D11Device* device,
|
||||
const D3D11_RASTERIZER_DESC& desc);
|
||||
~D3D11RasterizerState();
|
||||
|
||||
HRESULT QueryInterface(
|
||||
REFIID riid,
|
||||
void** ppvObject) final;
|
||||
|
||||
void GetDevice(
|
||||
ID3D11Device **ppDevice) final;
|
||||
|
||||
void GetDesc(
|
||||
D3D11_RASTERIZER_DESC* pDesc) final;
|
||||
|
||||
Rc<DxvkRasterizerState> GetDXVKStateObject() {
|
||||
return m_state;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
Com<D3D11Device> m_device;
|
||||
|
||||
D3D11_RASTERIZER_DESC m_desc;
|
||||
Rc<DxvkRasterizerState> m_state;
|
||||
|
||||
};
|
||||
|
||||
}
|
@ -6,6 +6,7 @@ d3d11_src = [
|
||||
'd3d11_main.cpp',
|
||||
'd3d11_present.cpp',
|
||||
'd3d11_state.cpp',
|
||||
'd3d11_state_rs.cpp',
|
||||
'd3d11_texture.cpp',
|
||||
'd3d11_view.cpp',
|
||||
]
|
||||
|
@ -63,6 +63,12 @@ namespace dxvk {
|
||||
T** operator & () { return &m_ptr; }
|
||||
T* const* operator & () const { return &m_ptr; }
|
||||
|
||||
bool operator == (const Com<T>& other) const { return m_ptr == other.m_ptr; }
|
||||
bool operator != (const Com<T>& other) const { return m_ptr != other.m_ptr; }
|
||||
|
||||
bool operator == (const T* other) const { return m_ptr == other; }
|
||||
bool operator != (const T* other) const { return m_ptr != other; }
|
||||
|
||||
bool operator == (std::nullptr_t) const { return m_ptr == nullptr; }
|
||||
bool operator != (std::nullptr_t) const { return m_ptr != nullptr; }
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user