[d3d11] Implemented rasterizer state creation

This commit is contained in:
Philip Rebohle 2017-12-06 13:16:54 +01:00
parent f990fcaa01
commit c7e1131864
9 changed files with 247 additions and 116 deletions

View File

@ -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();
}
}

View File

@ -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;
}

View File

@ -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;
};
}

View File

@ -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;
}
}

View File

@ -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;
};

View 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;
}
}

View 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;
};
}

View File

@ -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',
]

View File

@ -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; }