mirror of
https://github.com/doitsujin/dxvk.git
synced 2024-12-02 01:24:11 +01:00
[d3d11] Allocate counter for stream output buffers
This commit is contained in:
parent
0d89dfae95
commit
97d776cc00
@ -11,92 +11,7 @@ namespace dxvk {
|
||||
const D3D11_BUFFER_DESC* pDesc)
|
||||
: m_device (pDevice),
|
||||
m_desc (*pDesc),
|
||||
m_buffer (CreateBuffer(pDesc)),
|
||||
m_mappedSlice (m_buffer->slice()),
|
||||
m_d3d10 (this) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
D3D11Buffer::~D3D11Buffer() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
HRESULT STDMETHODCALLTYPE D3D11Buffer::QueryInterface(REFIID riid, void** ppvObject) {
|
||||
*ppvObject = nullptr;
|
||||
|
||||
if (riid == __uuidof(IUnknown)
|
||||
|| riid == __uuidof(ID3D11DeviceChild)
|
||||
|| riid == __uuidof(ID3D11Resource)
|
||||
|| riid == __uuidof(ID3D11Buffer)) {
|
||||
*ppvObject = ref(this);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
if (riid == __uuidof(ID3D10DeviceChild)
|
||||
|| riid == __uuidof(ID3D10Resource)
|
||||
|| riid == __uuidof(ID3D10Buffer)) {
|
||||
*ppvObject = ref(&m_d3d10);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
Logger::warn("D3D11Buffer::QueryInterface: Unknown interface query");
|
||||
Logger::warn(str::format(riid));
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
|
||||
void STDMETHODCALLTYPE D3D11Buffer::GetDevice(ID3D11Device** ppDevice) {
|
||||
*ppDevice = m_device.ref();
|
||||
}
|
||||
|
||||
|
||||
UINT STDMETHODCALLTYPE D3D11Buffer::GetEvictionPriority() {
|
||||
Logger::warn("D3D11Buffer::GetEvictionPriority: Stub");
|
||||
return DXGI_RESOURCE_PRIORITY_NORMAL;
|
||||
}
|
||||
|
||||
|
||||
void STDMETHODCALLTYPE D3D11Buffer::SetEvictionPriority(UINT EvictionPriority) {
|
||||
Logger::warn("D3D11Buffer::SetEvictionPriority: Stub");
|
||||
}
|
||||
|
||||
|
||||
void STDMETHODCALLTYPE D3D11Buffer::GetType(D3D11_RESOURCE_DIMENSION* pResourceDimension) {
|
||||
*pResourceDimension = D3D11_RESOURCE_DIMENSION_BUFFER;
|
||||
}
|
||||
|
||||
|
||||
void STDMETHODCALLTYPE D3D11Buffer::GetDesc(D3D11_BUFFER_DESC* pDesc) {
|
||||
*pDesc = m_desc;
|
||||
}
|
||||
|
||||
|
||||
bool D3D11Buffer::CheckViewCompatibility(
|
||||
UINT BindFlags,
|
||||
DXGI_FORMAT Format) const {
|
||||
// Check whether the given bind flags are supported
|
||||
VkBufferUsageFlags usage = GetBufferUsageFlags(BindFlags);
|
||||
|
||||
if ((m_buffer->info().usage & usage) != usage)
|
||||
return false;
|
||||
|
||||
// Structured buffer views use no format
|
||||
if (Format == DXGI_FORMAT_UNKNOWN)
|
||||
return (m_desc.MiscFlags & D3D11_RESOURCE_MISC_BUFFER_STRUCTURED) != 0;
|
||||
|
||||
// Check whether the given combination of buffer view
|
||||
// type and view format is supported by the device
|
||||
DXGI_VK_FORMAT_INFO viewFormat = m_device->LookupFormat(Format, DXGI_VK_FORMAT_MODE_ANY);
|
||||
VkFormatFeatureFlags features = GetBufferFormatFeatures(BindFlags);
|
||||
|
||||
return CheckFormatFeatureSupport(viewFormat.Format, features);
|
||||
}
|
||||
|
||||
|
||||
Rc<DxvkBuffer> D3D11Buffer::CreateBuffer(
|
||||
const D3D11_BUFFER_DESC* pDesc) const {
|
||||
DxvkBufferCreateInfo info;
|
||||
info.size = pDesc->ByteWidth;
|
||||
info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT
|
||||
@ -175,7 +90,92 @@ namespace dxvk {
|
||||
if (pDesc->Usage == D3D11_USAGE_DYNAMIC && pDesc->BindFlags)
|
||||
memoryFlags |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
|
||||
|
||||
return m_device->GetDXVKDevice()->createBuffer(info, memoryFlags);
|
||||
// Create the buffer and set the entire buffer slice as mapped,
|
||||
// so that we only have to update it when invalidating th buffer
|
||||
m_buffer = m_device->GetDXVKDevice()->createBuffer(info, memoryFlags);
|
||||
m_mapped = m_buffer->slice();
|
||||
|
||||
// For Stream Output buffers we need a counter
|
||||
if (pDesc->BindFlags & D3D11_BIND_STREAM_OUTPUT)
|
||||
m_soCounter = m_device->AllocXfbCounterSlice();
|
||||
}
|
||||
|
||||
|
||||
D3D11Buffer::~D3D11Buffer() {
|
||||
if (m_soCounter.defined())
|
||||
m_device->FreeXfbCounterSlice(m_soCounter);
|
||||
}
|
||||
|
||||
|
||||
HRESULT STDMETHODCALLTYPE D3D11Buffer::QueryInterface(REFIID riid, void** ppvObject) {
|
||||
*ppvObject = nullptr;
|
||||
|
||||
if (riid == __uuidof(IUnknown)
|
||||
|| riid == __uuidof(ID3D11DeviceChild)
|
||||
|| riid == __uuidof(ID3D11Resource)
|
||||
|| riid == __uuidof(ID3D11Buffer)) {
|
||||
*ppvObject = ref(this);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
if (riid == __uuidof(ID3D10DeviceChild)
|
||||
|| riid == __uuidof(ID3D10Resource)
|
||||
|| riid == __uuidof(ID3D10Buffer)) {
|
||||
*ppvObject = ref(&m_d3d10);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
Logger::warn("D3D11Buffer::QueryInterface: Unknown interface query");
|
||||
Logger::warn(str::format(riid));
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
|
||||
void STDMETHODCALLTYPE D3D11Buffer::GetDevice(ID3D11Device** ppDevice) {
|
||||
*ppDevice = m_device.ref();
|
||||
}
|
||||
|
||||
|
||||
UINT STDMETHODCALLTYPE D3D11Buffer::GetEvictionPriority() {
|
||||
Logger::warn("D3D11Buffer::GetEvictionPriority: Stub");
|
||||
return DXGI_RESOURCE_PRIORITY_NORMAL;
|
||||
}
|
||||
|
||||
|
||||
void STDMETHODCALLTYPE D3D11Buffer::SetEvictionPriority(UINT EvictionPriority) {
|
||||
Logger::warn("D3D11Buffer::SetEvictionPriority: Stub");
|
||||
}
|
||||
|
||||
|
||||
void STDMETHODCALLTYPE D3D11Buffer::GetType(D3D11_RESOURCE_DIMENSION* pResourceDimension) {
|
||||
*pResourceDimension = D3D11_RESOURCE_DIMENSION_BUFFER;
|
||||
}
|
||||
|
||||
|
||||
void STDMETHODCALLTYPE D3D11Buffer::GetDesc(D3D11_BUFFER_DESC* pDesc) {
|
||||
*pDesc = m_desc;
|
||||
}
|
||||
|
||||
|
||||
bool D3D11Buffer::CheckViewCompatibility(
|
||||
UINT BindFlags,
|
||||
DXGI_FORMAT Format) const {
|
||||
// Check whether the given bind flags are supported
|
||||
VkBufferUsageFlags usage = GetBufferUsageFlags(BindFlags);
|
||||
|
||||
if ((m_buffer->info().usage & usage) != usage)
|
||||
return false;
|
||||
|
||||
// Structured buffer views use no format
|
||||
if (Format == DXGI_FORMAT_UNKNOWN)
|
||||
return (m_desc.MiscFlags & D3D11_RESOURCE_MISC_BUFFER_STRUCTURED) != 0;
|
||||
|
||||
// Check whether the given combination of buffer view
|
||||
// type and view format is supported by the device
|
||||
DXGI_VK_FORMAT_INFO viewFormat = m_device->LookupFormat(Format, DXGI_VK_FORMAT_MODE_ANY);
|
||||
VkFormatFeatureFlags features = GetBufferFormatFeatures(BindFlags);
|
||||
|
||||
return CheckFormatFeatureSupport(viewFormat.Format, features);
|
||||
}
|
||||
|
||||
|
||||
|
@ -11,6 +11,18 @@ namespace dxvk {
|
||||
|
||||
class D3D11Device;
|
||||
class D3D11DeviceContext;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Stream output buffer offset
|
||||
*
|
||||
* A byte offset into the buffer that
|
||||
* stores the byte offset where new
|
||||
* data will be written to.
|
||||
*/
|
||||
struct D3D11SOCounter {
|
||||
uint32_t byteOffset;
|
||||
};
|
||||
|
||||
|
||||
class D3D11Buffer : public D3D11DeviceChild<ID3D11Buffer> {
|
||||
@ -62,17 +74,21 @@ namespace dxvk {
|
||||
DxvkBufferSlice GetBufferSlice(VkDeviceSize offset, VkDeviceSize length) const {
|
||||
return DxvkBufferSlice(m_buffer, offset, length);
|
||||
}
|
||||
|
||||
DxvkBufferSlice GetSOCounter() {
|
||||
return m_soCounter;
|
||||
}
|
||||
|
||||
VkDeviceSize GetSize() const {
|
||||
return m_buffer->info().size;
|
||||
}
|
||||
|
||||
DxvkPhysicalBufferSlice GetMappedSlice() const {
|
||||
return m_mappedSlice;
|
||||
return m_mapped;
|
||||
}
|
||||
|
||||
void SetMappedSlice(const DxvkPhysicalBufferSlice& slice) {
|
||||
m_mappedSlice = slice;
|
||||
m_mapped = slice;
|
||||
}
|
||||
|
||||
D3D10Buffer* GetD3D10Iface() {
|
||||
@ -85,7 +101,8 @@ namespace dxvk {
|
||||
const D3D11_BUFFER_DESC m_desc;
|
||||
|
||||
Rc<DxvkBuffer> m_buffer;
|
||||
DxvkPhysicalBufferSlice m_mappedSlice;
|
||||
DxvkBufferSlice m_soCounter;
|
||||
DxvkPhysicalBufferSlice m_mapped;
|
||||
|
||||
D3D10Buffer m_d3d10;
|
||||
|
||||
|
@ -117,6 +117,7 @@ namespace dxvk {
|
||||
m_d3d10Device = new D3D10Device(this, m_context);
|
||||
|
||||
m_uavCounters = CreateUAVCounterBuffer();
|
||||
m_xfbCounters = CreateXFBCounterBuffer();
|
||||
}
|
||||
|
||||
|
||||
@ -1496,6 +1497,27 @@ namespace dxvk {
|
||||
return new D3D11CounterBuffer(m_dxvkDevice,
|
||||
uavCounterInfo, uavCounterSliceLength);
|
||||
}
|
||||
|
||||
|
||||
Rc<D3D11CounterBuffer> D3D11Device::CreateXFBCounterBuffer() {
|
||||
DxvkBufferCreateInfo xfbCounterInfo;
|
||||
xfbCounterInfo.size = 4096 * sizeof(D3D11SOCounter);
|
||||
xfbCounterInfo.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT
|
||||
| VK_BUFFER_USAGE_TRANSFER_SRC_BIT
|
||||
| VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT
|
||||
| VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_COUNTER_BUFFER_BIT_EXT;
|
||||
xfbCounterInfo.stages = VK_PIPELINE_STAGE_TRANSFER_BIT
|
||||
| VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT
|
||||
| VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT;
|
||||
xfbCounterInfo.access = VK_ACCESS_TRANSFER_READ_BIT
|
||||
| VK_ACCESS_TRANSFER_WRITE_BIT
|
||||
| VK_ACCESS_INDIRECT_COMMAND_READ_BIT
|
||||
| VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_READ_BIT_EXT
|
||||
| VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_WRITE_BIT_EXT;
|
||||
|
||||
return new D3D11CounterBuffer(m_dxvkDevice,
|
||||
xfbCounterInfo, sizeof(D3D11SOCounter));
|
||||
}
|
||||
|
||||
|
||||
HRESULT D3D11Device::CreateShaderModule(
|
||||
|
@ -333,14 +333,6 @@ namespace dxvk {
|
||||
DXGI_FORMAT Format,
|
||||
DXGI_VK_FORMAT_MODE Mode) const;
|
||||
|
||||
DxvkBufferSlice AllocCounterSlice() {
|
||||
return m_uavCounters->AllocSlice();
|
||||
}
|
||||
|
||||
void FreeCounterSlice(const DxvkBufferSlice& Slice) {
|
||||
m_uavCounters->FreeSlice(Slice);
|
||||
}
|
||||
|
||||
DxvkCsChunkRef AllocCsChunk() {
|
||||
DxvkCsChunk* chunk = m_csChunkPool.allocChunk();
|
||||
return DxvkCsChunkRef(chunk, &m_csChunkPool);
|
||||
@ -354,6 +346,12 @@ namespace dxvk {
|
||||
return m_d3d10Device;
|
||||
}
|
||||
|
||||
DxvkBufferSlice AllocUavCounterSlice() { return m_uavCounters->AllocSlice(); }
|
||||
DxvkBufferSlice AllocXfbCounterSlice() { return m_xfbCounters->AllocSlice(); }
|
||||
|
||||
void FreeUavCounterSlice(const DxvkBufferSlice& Slice) { m_uavCounters->FreeSlice(Slice); }
|
||||
void FreeXfbCounterSlice(const DxvkBufferSlice& Slice) { m_xfbCounters->FreeSlice(Slice); }
|
||||
|
||||
static bool CheckFeatureLevelSupport(
|
||||
const Rc<DxvkAdapter>& adapter,
|
||||
D3D_FEATURE_LEVEL featureLevel);
|
||||
@ -383,6 +381,7 @@ namespace dxvk {
|
||||
D3D10Device* m_d3d10Device = nullptr;
|
||||
|
||||
Rc<D3D11CounterBuffer> m_uavCounters;
|
||||
Rc<D3D11CounterBuffer> m_xfbCounters;
|
||||
|
||||
D3D11StateObjectSet<D3D11BlendState> m_bsStateObjects;
|
||||
D3D11StateObjectSet<D3D11DepthStencilState> m_dsStateObjects;
|
||||
@ -391,6 +390,7 @@ namespace dxvk {
|
||||
D3D11ShaderModuleSet m_shaderModules;
|
||||
|
||||
Rc<D3D11CounterBuffer> CreateUAVCounterBuffer();
|
||||
Rc<D3D11CounterBuffer> CreateXFBCounterBuffer();
|
||||
|
||||
HRESULT CreateShaderModule(
|
||||
D3D11CommonShader* pShaderModule,
|
||||
|
@ -38,7 +38,7 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
if (pDesc->Buffer.Flags & (D3D11_BUFFER_UAV_FLAG_APPEND | D3D11_BUFFER_UAV_FLAG_COUNTER))
|
||||
m_counterSlice = pDevice->AllocCounterSlice();
|
||||
m_counterSlice = pDevice->AllocUavCounterSlice();
|
||||
|
||||
m_bufferView = pDevice->GetDXVKDevice()->createBufferView(
|
||||
buffer->GetBuffer(), viewInfo);
|
||||
@ -109,7 +109,7 @@ namespace dxvk {
|
||||
ResourceReleasePrivate(m_resource);
|
||||
|
||||
if (m_counterSlice.defined())
|
||||
m_device->FreeCounterSlice(m_counterSlice);
|
||||
m_device->FreeUavCounterSlice(m_counterSlice);
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user