mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-03-06 20:58:37 +01:00
Avoids keeping draw buffers alive when the app stops using indirect draws. Unlikely to have caused issues in practice, but draw buffers are not part of the API state to begin with.
350 lines
8.6 KiB
C++
350 lines
8.6 KiB
C++
#pragma once
|
|
|
|
#include <array>
|
|
|
|
#include "d3d11_buffer.h"
|
|
#include "d3d11_input_layout.h"
|
|
#include "d3d11_query.h"
|
|
#include "d3d11_sampler.h"
|
|
#include "d3d11_shader.h"
|
|
#include "d3d11_state.h"
|
|
#include "d3d11_view_dsv.h"
|
|
#include "d3d11_view_rtv.h"
|
|
#include "d3d11_view_srv.h"
|
|
#include "d3d11_view_uav.h"
|
|
|
|
namespace dxvk {
|
|
|
|
/**
|
|
* \brief Per-stage state
|
|
*
|
|
* Stores an object of the given type for each shader stage.
|
|
* \tparam Object type
|
|
*/
|
|
template<typename T>
|
|
class D3D11ShaderStageState {
|
|
|
|
public:
|
|
|
|
T& operator [] (DxbcProgramType type) { return m_state[uint32_t(type)]; }
|
|
const T& operator [] (DxbcProgramType type) const { return m_state[uint32_t(type)]; }
|
|
|
|
/**
|
|
* \brief Calls reset method on all objects
|
|
*/
|
|
void reset() {
|
|
for (auto& state : m_state)
|
|
state.reset();
|
|
}
|
|
|
|
private:
|
|
|
|
std::array<T, 6> m_state = { };
|
|
|
|
};
|
|
|
|
|
|
/**
|
|
* \brief Constant buffer bindings
|
|
*
|
|
* Stores the bound buffer range from a runtime point of view,
|
|
* as well as the range that is actually bound to the context.
|
|
*/
|
|
struct D3D11ConstantBufferBinding {
|
|
Com<D3D11Buffer, false> buffer = nullptr;
|
|
UINT constantOffset = 0;
|
|
UINT constantCount = 0;
|
|
UINT constantBound = 0;
|
|
};
|
|
|
|
struct D3D11ShaderStageCbvBinding {
|
|
std::array<D3D11ConstantBufferBinding, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT> buffers = { };
|
|
|
|
uint32_t maxCount = 0;
|
|
|
|
void reset() {
|
|
for (uint32_t i = 0; i < maxCount; i++)
|
|
buffers[i] = D3D11ConstantBufferBinding();
|
|
|
|
maxCount = 0;
|
|
}
|
|
};
|
|
|
|
using D3D11CbvBindings = D3D11ShaderStageState<D3D11ShaderStageCbvBinding>;
|
|
|
|
/**
|
|
* \brief Shader resource bindings
|
|
*
|
|
* Stores bound shader resource views, as well as a bit
|
|
* set of views that are potentially hazardous.
|
|
*/
|
|
struct D3D11ShaderStageSrvBinding {
|
|
std::array<Com<D3D11ShaderResourceView, false>, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT> views = { };
|
|
DxvkBindingSet<D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT> hazardous = { };
|
|
|
|
uint32_t maxCount = 0;
|
|
|
|
void reset() {
|
|
for (uint32_t i = 0; i < maxCount; i++)
|
|
views[i] = nullptr;
|
|
|
|
hazardous.clear();
|
|
maxCount = 0;
|
|
}
|
|
};
|
|
|
|
using D3D11SrvBindings = D3D11ShaderStageState<D3D11ShaderStageSrvBinding>;
|
|
|
|
/**
|
|
* \brief Sampler bindings
|
|
*
|
|
* Stores bound samplers.
|
|
*/
|
|
struct D3D11ShaderStageSamplerBinding {
|
|
std::array<D3D11SamplerState*, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT> samplers = { };
|
|
|
|
uint32_t maxCount = 0;
|
|
|
|
void reset() {
|
|
for (uint32_t i = 0; i < maxCount; i++)
|
|
samplers[i] = nullptr;
|
|
|
|
maxCount = 0;
|
|
}
|
|
};
|
|
|
|
using D3D11SamplerBindings = D3D11ShaderStageState<D3D11ShaderStageSamplerBinding>;
|
|
|
|
/**
|
|
* \brief UAV bindings
|
|
*
|
|
* Stores bound UAVs. For compute shader UAVs,
|
|
* we also store a bit mask of bound UAVs.
|
|
*/
|
|
using D3D11ShaderStageUavBinding = std::array<Com<D3D11UnorderedAccessView, false>, D3D11_1_UAV_SLOT_COUNT>;
|
|
|
|
struct D3D11UavBindings {
|
|
D3D11ShaderStageUavBinding views = { };
|
|
DxvkBindingSet<D3D11_1_UAV_SLOT_COUNT> mask = { };
|
|
|
|
uint32_t maxCount = 0;
|
|
|
|
void reset() {
|
|
for (uint32_t i = 0; i < maxCount; i++)
|
|
views[i] = nullptr;
|
|
|
|
mask.clear();
|
|
maxCount = 0;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* \brief Input assembly state
|
|
*
|
|
* Stores vertex buffers, the index buffer, the
|
|
* input layout, and the dynamic primitive topology.
|
|
*/
|
|
struct D3D11VertexBufferBinding {
|
|
Com<D3D11Buffer, false> buffer = nullptr;
|
|
UINT offset = 0;
|
|
UINT stride = 0;
|
|
};
|
|
|
|
struct D3D11IndexBufferBinding {
|
|
Com<D3D11Buffer, false> buffer = nullptr;
|
|
UINT offset = 0;
|
|
DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN;
|
|
};
|
|
|
|
struct D3D11ContextStateIA {
|
|
Com<D3D11InputLayout, false> inputLayout = nullptr;
|
|
D3D11_PRIMITIVE_TOPOLOGY primitiveTopology = D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED;
|
|
|
|
std::array<D3D11VertexBufferBinding, D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT> vertexBuffers = { };
|
|
D3D11IndexBufferBinding indexBuffer = { };
|
|
|
|
uint32_t maxVbCount = 0;
|
|
|
|
void reset() {
|
|
inputLayout = nullptr;
|
|
|
|
primitiveTopology = D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED;
|
|
|
|
for (uint32_t i = 0; i < maxVbCount; i++)
|
|
vertexBuffers[i] = D3D11VertexBufferBinding();
|
|
|
|
indexBuffer = D3D11IndexBufferBinding();
|
|
}
|
|
};
|
|
|
|
/**
|
|
* \brief Output merger state
|
|
*
|
|
* Stores RTV, DSV, and graphics UAV bindings, as well as related state.
|
|
*/
|
|
using D3D11RenderTargetViewBinding = std::array<Com<D3D11RenderTargetView, false>, D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT>;
|
|
|
|
struct D3D11ContextStateOM {
|
|
D3D11ShaderStageUavBinding uavs = { };
|
|
D3D11RenderTargetViewBinding rtvs = { };
|
|
Com<D3D11DepthStencilView, false> dsv = { };
|
|
|
|
D3D11BlendState* cbState = nullptr;
|
|
D3D11DepthStencilState* dsState = nullptr;
|
|
|
|
FLOAT blendFactor[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
|
|
|
|
UINT sampleCount = 0u;
|
|
UINT sampleMask = D3D11_DEFAULT_SAMPLE_MASK;
|
|
UINT stencilRef = D3D11_DEFAULT_STENCIL_REFERENCE;
|
|
|
|
UINT maxRtv = 0u;
|
|
UINT maxUav = 0u;
|
|
|
|
void reset() {
|
|
for (uint32_t i = 0; i < maxUav; i++)
|
|
uavs[i] = nullptr;
|
|
|
|
for (uint32_t i = 0; i < maxRtv; i++)
|
|
rtvs[i] = nullptr;
|
|
|
|
dsv = nullptr;
|
|
|
|
cbState = nullptr;
|
|
dsState = nullptr;
|
|
|
|
for (uint32_t i = 0; i < 4; i++)
|
|
blendFactor[i] = 1.0f;
|
|
|
|
sampleCount = 0u;
|
|
sampleMask = D3D11_DEFAULT_SAMPLE_MASK;
|
|
stencilRef = D3D11_DEFAULT_STENCIL_REFERENCE;
|
|
|
|
maxRtv = 0;
|
|
maxUav = 0;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* \brief Indirect draw state
|
|
*
|
|
* Stores the current indirct draw
|
|
* argument and draw count buffer.
|
|
*/
|
|
struct D3D11ContextStateID {
|
|
uint64_t argBufferCookie = 0u;
|
|
uint64_t cntBufferCookie = 0u;
|
|
|
|
void reset() {
|
|
argBufferCookie = 0u;
|
|
cntBufferCookie = 0u;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* \brief Rasterizer state
|
|
*
|
|
* Stores viewport info and the rasterizer state object.
|
|
*/
|
|
struct D3D11ContextStateRS {
|
|
uint32_t numViewports = 0;
|
|
uint32_t numScissors = 0;
|
|
|
|
std::array<D3D11_VIEWPORT, D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE> viewports = { };
|
|
std::array<D3D11_RECT, D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE> scissors = { };
|
|
|
|
D3D11RasterizerState* state = nullptr;
|
|
|
|
void reset() {
|
|
for (uint32_t i = 0; i < numViewports; i++)
|
|
viewports[i] = D3D11_VIEWPORT();
|
|
|
|
for (uint32_t i = 0; i < numScissors; i++)
|
|
scissors[i] = D3D11_RECT();
|
|
|
|
numViewports = 0;
|
|
numScissors = 0;
|
|
|
|
state = nullptr;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* \brief Stream output binding
|
|
*
|
|
* Stores stream output buffers with offset.
|
|
*/
|
|
struct D3D11ContextSoTarget {
|
|
Com<D3D11Buffer, false> buffer = nullptr;
|
|
UINT offset = 0;
|
|
};
|
|
|
|
struct D3D11ContextStateSO {
|
|
std::array<D3D11ContextSoTarget, D3D11_SO_BUFFER_SLOT_COUNT> targets = { };
|
|
|
|
void reset() {
|
|
for (uint32_t i = 0; i < targets.size(); i++)
|
|
targets[i] = D3D11ContextSoTarget();
|
|
}
|
|
};
|
|
|
|
/**
|
|
* \brief Predication state
|
|
*
|
|
* Stores predication info.
|
|
*/
|
|
struct D3D11ContextStatePR {
|
|
Com<D3D11Query, false> predicateObject = nullptr;
|
|
BOOL predicateValue = false;
|
|
|
|
void reset() {
|
|
predicateObject = nullptr;
|
|
predicateValue = false;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* \brief Context state
|
|
*/
|
|
struct D3D11ContextState {
|
|
Com<D3D11VertexShader, false> vs;
|
|
Com<D3D11HullShader, false> hs;
|
|
Com<D3D11DomainShader, false> ds;
|
|
Com<D3D11GeometryShader, false> gs;
|
|
Com<D3D11PixelShader, false> ps;
|
|
Com<D3D11ComputeShader, false> cs;
|
|
|
|
D3D11ContextStateID id;
|
|
D3D11ContextStateIA ia;
|
|
D3D11ContextStateOM om;
|
|
D3D11ContextStateRS rs;
|
|
D3D11ContextStateSO so;
|
|
D3D11ContextStatePR pr;
|
|
|
|
D3D11CbvBindings cbv;
|
|
D3D11SrvBindings srv;
|
|
D3D11UavBindings uav;
|
|
D3D11SamplerBindings samplers;
|
|
};
|
|
|
|
/**
|
|
* \brief Maximum used binding numbers in a shader stage
|
|
*/
|
|
struct D3D11MaxUsedStageBindings {
|
|
uint32_t cbvCount : 5;
|
|
uint32_t srvCount : 9;
|
|
uint32_t uavCount : 7;
|
|
uint32_t samplerCount : 5;
|
|
uint32_t reserved : 6;
|
|
};
|
|
|
|
/**
|
|
* \brief Maximum used binding numbers for all context state
|
|
*/
|
|
struct D3D11MaxUsedBindings {
|
|
std::array<D3D11MaxUsedStageBindings, 6> stages;
|
|
uint32_t vbCount;
|
|
uint32_t soCount;
|
|
};
|
|
|
|
}
|