1
0
mirror of https://github.com/EduApps-CDG/OpenDX synced 2024-12-30 09:45:37 +01:00

[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) { void D3D11DeviceContext::RSSetState(ID3D11RasterizerState* pRasterizerState) {
auto rasterizerState = static_cast<D3D11RasterizerState*>(pRasterizerState); auto rasterizerState = static_cast<D3D11RasterizerState*>(pRasterizerState);
m_state.rs.state = rasterizerState;
// Use default state if the rasterizer if (m_state.rs.state != rasterizerState) {
// state is not explicitly defined. m_state.rs.state = rasterizerState;
m_context->setRasterizerState(
rasterizerState != nullptr // Use default state if the rasterizer
? rasterizerState->GetDXVKStateObject() // state is not explicitly defined.
: m_defaultRsState); m_context->setRasterizerState(
rasterizerState != nullptr
// In D3D11, the rasterizer state defines ? rasterizerState->GetDXVKStateObject()
// whether the scissor test is enabled, so : m_defaultRsState);
// we have to update the scissor rectangles.
this->ApplyViewportState(); // 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( HRESULT D3D11Device::CreateRasterizerState(
const D3D11_RASTERIZER_DESC* pRasterizerDesc, const D3D11_RASTERIZER_DESC* pRasterizerDesc,
ID3D11RasterizerState** ppRasterizerState) { ID3D11RasterizerState** ppRasterizerState) {
Logger::err("D3D11Device::CreateRasterizerState: Not implemented"); D3D11_RASTERIZER_DESC desc;
return E_NOTIMPL;
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 <dxgi_resource.h>
#include "d3d11_interfaces.h" #include "d3d11_interfaces.h"
#include "d3d11_state.h"
#include "../util/com/com_private_data.h" #include "../util/com/com_private_data.h"
@ -242,6 +243,8 @@ namespace dxvk {
Com<ID3D11DeviceContext> m_context; Com<ID3D11DeviceContext> m_context;
D3D11StateObjectSet<D3D11RasterizerState> m_rsStateObjects;
}; };
} }

View File

@ -1,87 +1,34 @@
#include "d3d11_device.h"
#include "d3d11_state.h" #include "d3d11_state.h"
namespace dxvk { namespace dxvk {
D3D11RasterizerState::D3D11RasterizerState( size_t D3D11StateDescHash::operator () (const D3D11_RASTERIZER_DESC& desc) const {
D3D11Device* device, DxvkHashState hash;
const D3D11_RASTERIZER_DESC& desc) hash.add(desc.FillMode);
: m_device(device), m_desc(desc) { hash.add(desc.CullMode);
hash.add(desc.FrontCounterClockwise);
// Polygon mode. Determines whether the rasterizer fills hash.add(desc.DepthBias);
// a polygon or renders lines connecting the vertices. hash.add(desc.SlopeScaledDepthBias);
VkPolygonMode polygonMode = VK_POLYGON_MODE_FILL; hash.add(desc.DepthBiasClamp);
hash.add(desc.DepthClipEnable);
switch (desc.FillMode) { hash.add(desc.ScissorEnable);
case D3D11_FILL_WIREFRAME: polygonMode = VK_POLYGON_MODE_LINE; break; hash.add(desc.MultisampleEnable);
case D3D11_FILL_SOLID: polygonMode = VK_POLYGON_MODE_FILL; break; hash.add(desc.AntialiasedLineEnable);
return hash;
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);
} }
D3D11RasterizerState::~D3D11RasterizerState() { 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
HRESULT D3D11RasterizerState::QueryInterface(REFIID riid, void** ppvObject) { && a.SlopeScaledDepthBias == b.SlopeScaledDepthBias
COM_QUERY_IFACE(riid, ppvObject, IUnknown); && a.DepthBiasClamp == b.DepthBiasClamp
COM_QUERY_IFACE(riid, ppvObject, ID3D11DeviceChild); && a.DepthClipEnable == b.DepthClipEnable
COM_QUERY_IFACE(riid, ppvObject, ID3D11RasterizerState); && a.ScissorEnable == b.ScissorEnable
&& a.MultisampleEnable == b.MultisampleEnable
Logger::warn("D3D11RasterizerState::QueryInterface: Unknown interface query"); && a.AntialiasedLineEnable == b.AntialiasedLineEnable;
return E_NOINTERFACE;
}
void D3D11RasterizerState::GetDevice(ID3D11Device** ppDevice) {
*ppDevice = m_device.ref();
}
void D3D11RasterizerState::GetDesc(D3D11_RASTERIZER_DESC* pDesc) {
*pDesc = m_desc;
} }
} }

View File

@ -1,42 +1,63 @@
#pragma once #pragma once
#include <dxvk_device.h> #include <unordered_map>
#include "d3d11_device_child.h" #include "d3d11_state_rs.h"
namespace dxvk { namespace dxvk {
class D3D11Device; 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: public:
D3D11RasterizerState( /**
D3D11Device* device, * \brief Retrieves a state object
const D3D11_RASTERIZER_DESC& desc); *
~D3D11RasterizerState(); * Returns an object with the same description or
* creates a new one if no such object exists.
HRESULT QueryInterface( * \param [in] device The calling D3D11 device
REFIID riid, * \param [in] desc State object description
void** ppvObject) final; * \returns Pointer to the state object
*/
void GetDevice( T* Create(D3D11Device* device, const DescType& desc) {
ID3D11Device **ppDevice) final; std::lock_guard<std::mutex> lock(m_mutex);
void GetDesc( auto pair = m_objects.find(desc);
D3D11_RASTERIZER_DESC* pDesc) final;
if (pair != m_objects.end())
Rc<DxvkRasterizerState> GetDXVKStateObject() { return pair->second.ptr();
return m_state;
Com<T> result = new T(device, desc);
m_objects.insert({ desc, result });
return result.ptr();
} }
private: private:
Com<D3D11Device> m_device; std::mutex m_mutex;
std::unordered_map<DescType, Com<T>,
D3D11_RASTERIZER_DESC m_desc; D3D11StateDescHash, D3D11StateDescEqual> m_objects;
Rc<DxvkRasterizerState> m_state;
}; };

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_main.cpp',
'd3d11_present.cpp', 'd3d11_present.cpp',
'd3d11_state.cpp', 'd3d11_state.cpp',
'd3d11_state_rs.cpp',
'd3d11_texture.cpp', 'd3d11_texture.cpp',
'd3d11_view.cpp', 'd3d11_view.cpp',
] ]

View File

@ -63,6 +63,12 @@ namespace dxvk {
T** operator & () { return &m_ptr; } T** operator & () { return &m_ptr; }
T* const* operator & () const { 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; }
bool operator != (std::nullptr_t) const { return m_ptr != nullptr; } bool operator != (std::nullptr_t) const { return m_ptr != nullptr; }