2017-12-06 12:11:59 +01:00
|
|
|
#pragma once
|
|
|
|
|
2017-12-06 13:16:54 +01:00
|
|
|
#include <unordered_map>
|
2017-12-06 12:11:59 +01:00
|
|
|
|
2017-12-11 13:03:07 +01:00
|
|
|
#include "d3d11_blend.h"
|
2017-12-11 01:43:15 +01:00
|
|
|
#include "d3d11_depth_stencil.h"
|
2017-12-10 23:27:20 +01:00
|
|
|
#include "d3d11_rasterizer.h"
|
2018-03-05 02:21:34 +01:00
|
|
|
#include "d3d11_sampler.h"
|
2017-12-06 12:11:59 +01:00
|
|
|
|
|
|
|
namespace dxvk {
|
|
|
|
|
|
|
|
class D3D11Device;
|
|
|
|
|
2017-12-06 13:16:54 +01:00
|
|
|
struct D3D11StateDescHash {
|
2018-03-18 23:27:29 +01:00
|
|
|
size_t operator () (const D3D11_BLEND_DESC1& desc) const;
|
2017-12-11 01:43:15 +01:00
|
|
|
size_t operator () (const D3D11_DEPTH_STENCILOP_DESC& desc) const;
|
|
|
|
size_t operator () (const D3D11_DEPTH_STENCIL_DESC& desc) const;
|
2019-09-16 13:33:36 +02:00
|
|
|
size_t operator () (const D3D11_RASTERIZER_DESC2& desc) const;
|
2018-03-18 23:27:29 +01:00
|
|
|
size_t operator () (const D3D11_RENDER_TARGET_BLEND_DESC1& desc) const;
|
2018-03-05 02:21:34 +01:00
|
|
|
size_t operator () (const D3D11_SAMPLER_DESC& desc) const;
|
2017-12-06 13:16:54 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
struct D3D11StateDescEqual {
|
2018-03-18 23:27:29 +01:00
|
|
|
bool operator () (const D3D11_BLEND_DESC1& a, const D3D11_BLEND_DESC1& b) const;
|
2017-12-11 01:43:15 +01:00
|
|
|
bool operator () (const D3D11_DEPTH_STENCILOP_DESC& a, const D3D11_DEPTH_STENCILOP_DESC& b) const;
|
|
|
|
bool operator () (const D3D11_DEPTH_STENCIL_DESC& a, const D3D11_DEPTH_STENCIL_DESC& b) const;
|
2019-09-16 13:33:36 +02:00
|
|
|
bool operator () (const D3D11_RASTERIZER_DESC2& a, const D3D11_RASTERIZER_DESC2& b) const;
|
2018-03-18 23:27:29 +01:00
|
|
|
bool operator () (const D3D11_RENDER_TARGET_BLEND_DESC1& a, const D3D11_RENDER_TARGET_BLEND_DESC1& b) const;
|
2018-03-05 02:21:34 +01:00
|
|
|
bool operator () (const D3D11_SAMPLER_DESC& a, const D3D11_SAMPLER_DESC& b) const;
|
2017-12-06 13:16:54 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* \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;
|
2017-12-06 12:11:59 +01:00
|
|
|
public:
|
|
|
|
|
2017-12-06 13:16:54 +01:00
|
|
|
/**
|
|
|
|
* \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) {
|
2021-06-28 19:19:29 +02:00
|
|
|
std::lock_guard<dxvk::mutex> lock(m_mutex);
|
2017-12-06 13:16:54 +01:00
|
|
|
|
2019-10-14 01:27:59 +02:00
|
|
|
auto entry = m_objects.find(desc);
|
2017-12-06 13:16:54 +01:00
|
|
|
|
2019-10-14 01:27:59 +02:00
|
|
|
if (entry != m_objects.end())
|
|
|
|
return ref(&entry->second);
|
2017-12-06 13:16:54 +01:00
|
|
|
|
2019-10-14 01:27:59 +02:00
|
|
|
auto result = m_objects.emplace(
|
|
|
|
std::piecewise_construct,
|
|
|
|
std::tuple(desc),
|
|
|
|
std::tuple(device, desc));
|
|
|
|
return ref(&result.first->second);
|
2017-12-06 12:11:59 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
2021-06-28 19:19:29 +02:00
|
|
|
dxvk::mutex m_mutex;
|
2019-10-14 01:27:59 +02:00
|
|
|
std::unordered_map<DescType, T,
|
2017-12-06 13:16:54 +01:00
|
|
|
D3D11StateDescHash, D3D11StateDescEqual> m_objects;
|
2017-12-06 12:11:59 +01:00
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
}
|