mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-01-18 11:52:12 +01:00
[d3d11] Implemented D3D11 parts of append/consume buffers
This commit is contained in:
parent
8bccbbccc8
commit
c1d6c20066
@ -496,7 +496,18 @@ namespace dxvk {
|
|||||||
ID3D11Buffer* pDstBuffer,
|
ID3D11Buffer* pDstBuffer,
|
||||||
UINT DstAlignedByteOffset,
|
UINT DstAlignedByteOffset,
|
||||||
ID3D11UnorderedAccessView* pSrcView) {
|
ID3D11UnorderedAccessView* pSrcView) {
|
||||||
Logger::err("D3D11DeviceContext::CopyStructureCount: Not implemented");
|
auto buf = static_cast<D3D11Buffer*>(pDstBuffer);
|
||||||
|
auto uav = static_cast<D3D11UnorderedAccessView*>(pSrcView);
|
||||||
|
|
||||||
|
const DxvkBufferSlice dstSlice = buf->GetBufferSlice(DstAlignedByteOffset);
|
||||||
|
const DxvkBufferSlice srcSlice = uav->GetCounterSlice();
|
||||||
|
|
||||||
|
m_context->copyBuffer(
|
||||||
|
dstSlice.buffer(),
|
||||||
|
dstSlice.offset(),
|
||||||
|
srcSlice.buffer(),
|
||||||
|
srcSlice.offset(),
|
||||||
|
sizeof(uint32_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -504,7 +515,7 @@ namespace dxvk {
|
|||||||
ID3D11RenderTargetView* pRenderTargetView,
|
ID3D11RenderTargetView* pRenderTargetView,
|
||||||
const FLOAT ColorRGBA[4]) {
|
const FLOAT ColorRGBA[4]) {
|
||||||
auto rtv = static_cast<D3D11RenderTargetView*>(pRenderTargetView);
|
auto rtv = static_cast<D3D11RenderTargetView*>(pRenderTargetView);
|
||||||
const Rc<DxvkImageView> dxvkView = rtv->GetDXVKImageView();
|
const Rc<DxvkImageView> dxvkView = rtv->GetImageView();
|
||||||
|
|
||||||
// Find out whether the given attachment is currently bound
|
// Find out whether the given attachment is currently bound
|
||||||
// or not, and if it is, which attachment index it has.
|
// or not, and if it is, which attachment index it has.
|
||||||
@ -573,7 +584,7 @@ namespace dxvk {
|
|||||||
FLOAT Depth,
|
FLOAT Depth,
|
||||||
UINT8 Stencil) {
|
UINT8 Stencil) {
|
||||||
auto dsv = static_cast<D3D11DepthStencilView*>(pDepthStencilView);
|
auto dsv = static_cast<D3D11DepthStencilView*>(pDepthStencilView);
|
||||||
const Rc<DxvkImageView> dxvkView = dsv->GetDXVKImageView();
|
const Rc<DxvkImageView> dxvkView = dsv->GetImageView();
|
||||||
|
|
||||||
VkClearDepthStencilValue clearValue;
|
VkClearDepthStencilValue clearValue;
|
||||||
clearValue.depth = Depth;
|
clearValue.depth = Depth;
|
||||||
@ -1471,15 +1482,17 @@ namespace dxvk {
|
|||||||
UINT NumUAVs,
|
UINT NumUAVs,
|
||||||
ID3D11UnorderedAccessView* const* ppUnorderedAccessViews,
|
ID3D11UnorderedAccessView* const* ppUnorderedAccessViews,
|
||||||
const UINT* pUAVInitialCounts) {
|
const UINT* pUAVInitialCounts) {
|
||||||
// TODO implement append-consume buffers
|
|
||||||
// if (pUAVInitialCounts != nullptr)
|
|
||||||
// Logger::err("D3D11DeviceContext: pUAVInitialCounts not supported");
|
|
||||||
|
|
||||||
this->BindUnorderedAccessViews(
|
this->BindUnorderedAccessViews(
|
||||||
DxbcProgramType::ComputeShader,
|
DxbcProgramType::ComputeShader,
|
||||||
m_state.cs.unorderedAccessViews,
|
m_state.cs.unorderedAccessViews,
|
||||||
StartSlot, NumUAVs,
|
StartSlot, NumUAVs,
|
||||||
ppUnorderedAccessViews);
|
ppUnorderedAccessViews);
|
||||||
|
|
||||||
|
if (pUAVInitialCounts != nullptr) {
|
||||||
|
this->InitUnorderedAccessViewCounters(
|
||||||
|
NumUAVs, ppUnorderedAccessViews,
|
||||||
|
pUAVInitialCounts);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1566,11 +1579,11 @@ namespace dxvk {
|
|||||||
|
|
||||||
for (UINT i = 0; i < m_state.om.renderTargetViews.size(); i++) {
|
for (UINT i = 0; i < m_state.om.renderTargetViews.size(); i++) {
|
||||||
if (m_state.om.renderTargetViews.at(i) != nullptr)
|
if (m_state.om.renderTargetViews.at(i) != nullptr)
|
||||||
attachments.setColorTarget(i, m_state.om.renderTargetViews.at(i)->GetDXVKImageView());
|
attachments.setColorTarget(i, m_state.om.renderTargetViews.at(i)->GetImageView());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_state.om.depthStencilView != nullptr)
|
if (m_state.om.depthStencilView != nullptr)
|
||||||
attachments.setDepthTarget(m_state.om.depthStencilView->GetDXVKImageView());
|
attachments.setDepthTarget(m_state.om.depthStencilView->GetImageView());
|
||||||
|
|
||||||
if (attachments.hasAttachments())
|
if (attachments.hasAttachments())
|
||||||
framebuffer = m_device->createFramebuffer(attachments);
|
framebuffer = m_device->createFramebuffer(attachments);
|
||||||
@ -1884,10 +1897,10 @@ namespace dxvk {
|
|||||||
// Figure out what we have to bind based on the resource type
|
// Figure out what we have to bind based on the resource type
|
||||||
if (resView->GetResourceType() == D3D11_RESOURCE_DIMENSION_BUFFER) {
|
if (resView->GetResourceType() == D3D11_RESOURCE_DIMENSION_BUFFER) {
|
||||||
m_context->bindResourceTexelBuffer(
|
m_context->bindResourceTexelBuffer(
|
||||||
slotId + i, resView->GetDXVKBufferView());
|
slotId + i, resView->GetBufferView());
|
||||||
} else {
|
} else {
|
||||||
m_context->bindResourceImage(
|
m_context->bindResourceImage(
|
||||||
slotId + i, resView->GetDXVKImageView());
|
slotId + i, resView->GetImageView());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// When unbinding a resource, it doesn't really matter if
|
// When unbinding a resource, it doesn't really matter if
|
||||||
@ -1920,10 +1933,10 @@ namespace dxvk {
|
|||||||
// Figure out what we have to bind based on the resource type
|
// Figure out what we have to bind based on the resource type
|
||||||
if (uav->GetResourceType() == D3D11_RESOURCE_DIMENSION_BUFFER) {
|
if (uav->GetResourceType() == D3D11_RESOURCE_DIMENSION_BUFFER) {
|
||||||
m_context->bindResourceTexelBuffer(
|
m_context->bindResourceTexelBuffer(
|
||||||
slotId + i, uav->GetDXVKBufferView());
|
slotId + i, uav->GetBufferView());
|
||||||
} else {
|
} else {
|
||||||
m_context->bindResourceImage(
|
m_context->bindResourceImage(
|
||||||
slotId + i, uav->GetDXVKImageView());
|
slotId + i, uav->GetImageView());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// When unbinding a resource, it doesn't really matter if
|
// When unbinding a resource, it doesn't really matter if
|
||||||
@ -1936,6 +1949,29 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void D3D11DeviceContext::InitUnorderedAccessViewCounters(
|
||||||
|
UINT NumUAVs,
|
||||||
|
ID3D11UnorderedAccessView* const* ppUnorderedAccessViews,
|
||||||
|
const UINT* pUAVInitialCounts) {
|
||||||
|
for (uint32_t i = 0; i < NumUAVs; i++) {
|
||||||
|
auto uav = static_cast<D3D11UnorderedAccessView*>(ppUnorderedAccessViews[i]);
|
||||||
|
|
||||||
|
if (uav != nullptr) {
|
||||||
|
const DxvkBufferSlice counterSlice = uav->GetCounterSlice();
|
||||||
|
const D3D11UavCounter counterValue = { pUAVInitialCounts[i] };
|
||||||
|
|
||||||
|
if (counterSlice.handle() != VK_NULL_HANDLE) {
|
||||||
|
m_context->updateBuffer(
|
||||||
|
counterSlice.buffer(),
|
||||||
|
counterSlice.offset(),
|
||||||
|
counterSlice.length(),
|
||||||
|
&counterValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void D3D11DeviceContext::ApplyViewportState() {
|
void D3D11DeviceContext::ApplyViewportState() {
|
||||||
// We cannot set less than one viewport in Vulkan, and
|
// We cannot set less than one viewport in Vulkan, and
|
||||||
// rendering with no active viewport is illegal anyway.
|
// rendering with no active viewport is illegal anyway.
|
||||||
|
@ -594,6 +594,11 @@ namespace dxvk {
|
|||||||
UINT NumUAVs,
|
UINT NumUAVs,
|
||||||
ID3D11UnorderedAccessView* const* ppUnorderedAccessViews);
|
ID3D11UnorderedAccessView* const* ppUnorderedAccessViews);
|
||||||
|
|
||||||
|
void InitUnorderedAccessViewCounters(
|
||||||
|
UINT NumUAVs,
|
||||||
|
ID3D11UnorderedAccessView* const* ppUnorderedAccessViews,
|
||||||
|
const UINT* pUAVInitialCounts);
|
||||||
|
|
||||||
void ApplyViewportState();
|
void ApplyViewportState();
|
||||||
|
|
||||||
Rc<DxvkSampler> CreateDefaultSampler();
|
Rc<DxvkSampler> CreateDefaultSampler();
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include "d3d11_sampler.h"
|
#include "d3d11_sampler.h"
|
||||||
#include "d3d11_shader.h"
|
#include "d3d11_shader.h"
|
||||||
#include "d3d11_state.h"
|
#include "d3d11_state.h"
|
||||||
|
#include "d3d11_uav.h"
|
||||||
#include "d3d11_view.h"
|
#include "d3d11_view.h"
|
||||||
|
|
||||||
namespace dxvk {
|
namespace dxvk {
|
||||||
|
@ -37,6 +37,8 @@ namespace dxvk {
|
|||||||
|
|
||||||
m_context = new D3D11DeviceContext(this, m_dxvkDevice);
|
m_context = new D3D11DeviceContext(this, m_dxvkDevice);
|
||||||
m_resourceInitContext = m_dxvkDevice->createContext();
|
m_resourceInitContext = m_dxvkDevice->createContext();
|
||||||
|
|
||||||
|
CreateCounterBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -378,10 +380,18 @@ namespace dxvk {
|
|||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
// Fetch a buffer slice for atomic
|
||||||
|
// append/consume functionality.
|
||||||
|
DxvkBufferSlice counterSlice;
|
||||||
|
|
||||||
|
if (desc.Buffer.Flags & (D3D11_BUFFER_UAV_FLAG_APPEND | D3D11_BUFFER_UAV_FLAG_COUNTER))
|
||||||
|
counterSlice = AllocateCounterSlice();
|
||||||
|
|
||||||
*ppUAView = ref(new D3D11UnorderedAccessView(
|
*ppUAView = ref(new D3D11UnorderedAccessView(
|
||||||
this, pResource, desc,
|
this, pResource, desc,
|
||||||
m_dxvkDevice->createBufferView(
|
m_dxvkDevice->createBufferView(
|
||||||
resource->GetBufferSlice().buffer(), viewInfo)));
|
resource->GetBufferSlice().buffer(), viewInfo),
|
||||||
|
counterSlice));
|
||||||
return S_OK;
|
return S_OK;
|
||||||
} catch (const DxvkError& e) {
|
} catch (const DxvkError& e) {
|
||||||
Logger::err(e.message());
|
Logger::err(e.message());
|
||||||
@ -458,7 +468,8 @@ namespace dxvk {
|
|||||||
*ppUAView = ref(new D3D11UnorderedAccessView(
|
*ppUAView = ref(new D3D11UnorderedAccessView(
|
||||||
this, pResource, desc,
|
this, pResource, desc,
|
||||||
m_dxvkDevice->createImageView(
|
m_dxvkDevice->createImageView(
|
||||||
textureInfo->image, viewInfo)));
|
textureInfo->image, viewInfo),
|
||||||
|
DxvkBufferSlice()));
|
||||||
return S_OK;
|
return S_OK;
|
||||||
} catch (const DxvkError& e) {
|
} catch (const DxvkError& e) {
|
||||||
Logger::err(e.message());
|
Logger::err(e.message());
|
||||||
@ -1273,6 +1284,27 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DxvkBufferSlice D3D11Device::AllocateCounterSlice() {
|
||||||
|
std::lock_guard<std::mutex> lock(m_counterMutex);
|
||||||
|
|
||||||
|
if (m_counterSlices.size() == 0)
|
||||||
|
throw DxvkError("D3D11Device: Failed to allocate counter slice");
|
||||||
|
|
||||||
|
uint32_t sliceId = m_counterSlices.back();
|
||||||
|
m_counterSlices.pop_back();
|
||||||
|
|
||||||
|
return DxvkBufferSlice(m_counterBuffer,
|
||||||
|
sizeof(D3D11UavCounter) * sliceId,
|
||||||
|
sizeof(D3D11UavCounter));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void D3D11Device::FreeCounterSlice(const DxvkBufferSlice& Slice) {
|
||||||
|
std::lock_guard<std::mutex> lock(m_counterMutex);
|
||||||
|
m_counterSlices.push_back(Slice.offset() / sizeof(D3D11UavCounter));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
VkPipelineStageFlags D3D11Device::GetEnabledShaderStages() const {
|
VkPipelineStageFlags D3D11Device::GetEnabledShaderStages() const {
|
||||||
VkPipelineStageFlags enabledShaderPipelineStages
|
VkPipelineStageFlags enabledShaderPipelineStages
|
||||||
= VK_PIPELINE_STAGE_VERTEX_SHADER_BIT
|
= VK_PIPELINE_STAGE_VERTEX_SHADER_BIT
|
||||||
@ -1751,4 +1783,30 @@ namespace dxvk {
|
|||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void D3D11Device::CreateCounterBuffer() {
|
||||||
|
const uint32_t MaxCounterStructs = 1 << 16;
|
||||||
|
|
||||||
|
// The counter buffer is used as a storage buffer
|
||||||
|
DxvkBufferCreateInfo info;
|
||||||
|
info.size = MaxCounterStructs * sizeof(D3D11UavCounter);
|
||||||
|
info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT
|
||||||
|
| VK_BUFFER_USAGE_TRANSFER_DST_BIT
|
||||||
|
| VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
|
||||||
|
info.stages = VK_PIPELINE_STAGE_TRANSFER_BIT
|
||||||
|
| GetEnabledShaderStages();
|
||||||
|
info.access = VK_ACCESS_TRANSFER_READ_BIT
|
||||||
|
| VK_ACCESS_TRANSFER_WRITE_BIT
|
||||||
|
| VK_ACCESS_SHADER_READ_BIT
|
||||||
|
| VK_ACCESS_SHADER_WRITE_BIT;
|
||||||
|
m_counterBuffer = m_dxvkDevice->createBuffer(
|
||||||
|
info, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
|
||||||
|
|
||||||
|
// Init the counter struct allocator as well
|
||||||
|
m_counterSlices.resize(MaxCounterStructs);
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < MaxCounterStructs; i++)
|
||||||
|
m_counterSlices[i] = MaxCounterStructs - i - 1;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <mutex>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "../dxbc/dxbc_options.h"
|
#include "../dxbc/dxbc_options.h"
|
||||||
|
|
||||||
#include "../dxgi/dxgi_object.h"
|
#include "../dxgi/dxgi_object.h"
|
||||||
@ -231,6 +234,10 @@ namespace dxvk {
|
|||||||
return m_dxvkDevice;
|
return m_dxvkDevice;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DxvkBufferSlice AllocateCounterSlice();
|
||||||
|
|
||||||
|
void FreeCounterSlice(const DxvkBufferSlice& Slice);
|
||||||
|
|
||||||
VkPipelineStageFlags GetEnabledShaderStages() const;
|
VkPipelineStageFlags GetEnabledShaderStages() const;
|
||||||
|
|
||||||
DxgiFormatInfo STDMETHODCALLTYPE LookupFormat(
|
DxgiFormatInfo STDMETHODCALLTYPE LookupFormat(
|
||||||
@ -261,6 +268,10 @@ namespace dxvk {
|
|||||||
|
|
||||||
D3D11DeviceContext* m_context = nullptr;
|
D3D11DeviceContext* m_context = nullptr;
|
||||||
|
|
||||||
|
std::mutex m_counterMutex;
|
||||||
|
std::vector<uint32_t> m_counterSlices;
|
||||||
|
Rc<DxvkBuffer> m_counterBuffer;
|
||||||
|
|
||||||
std::mutex m_resourceInitMutex;
|
std::mutex m_resourceInitMutex;
|
||||||
Rc<DxvkContext> m_resourceInitContext;
|
Rc<DxvkContext> m_resourceInitContext;
|
||||||
|
|
||||||
@ -303,6 +314,8 @@ namespace dxvk {
|
|||||||
|
|
||||||
HRESULT GetFormatSupportFlags(DXGI_FORMAT Format, UINT* pFlags) const;
|
HRESULT GetFormatSupportFlags(DXGI_FORMAT Format, UINT* pFlags) const;
|
||||||
|
|
||||||
|
void CreateCounterBuffer();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,11 @@ typedef struct D3D11_FEATURE_DATA_D3D10_X_HARDWARE_OPTIONS {
|
|||||||
typedef enum D3D11_BUFFEREX_SRV_FLAG {
|
typedef enum D3D11_BUFFEREX_SRV_FLAG {
|
||||||
D3D11_BUFFEREX_SRV_FLAG_RAW = 1
|
D3D11_BUFFEREX_SRV_FLAG_RAW = 1
|
||||||
} D3D11_BUFFEREX_SRV_FLAG;
|
} D3D11_BUFFEREX_SRV_FLAG;
|
||||||
|
typedef enum D3D11_UAV_FLAG {
|
||||||
|
D3D11_BUFFER_UAV_FLAG_RAW = 0x1,
|
||||||
|
D3D11_BUFFER_UAV_FLAG_APPEND = 0x2,
|
||||||
|
D3D11_BUFFER_UAV_FLAG_COUNTER = 0x4
|
||||||
|
} D3D11_UAV_FLAG;
|
||||||
typedef struct D3D11_QUERY_DATA_PIPELINE_STATISTICS {
|
typedef struct D3D11_QUERY_DATA_PIPELINE_STATISTICS {
|
||||||
UINT64 IAVertices;
|
UINT64 IAVertices;
|
||||||
UINT64 IAPrimitives;
|
UINT64 IAPrimitives;
|
||||||
|
59
src/d3d11/d3d11_uav.cpp
Normal file
59
src/d3d11/d3d11_uav.cpp
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
#include "d3d11_device.h"
|
||||||
|
#include "d3d11_uav.h"
|
||||||
|
|
||||||
|
namespace dxvk {
|
||||||
|
|
||||||
|
D3D11UnorderedAccessView::D3D11UnorderedAccessView(
|
||||||
|
D3D11Device* device,
|
||||||
|
ID3D11Resource* resource,
|
||||||
|
const D3D11_UNORDERED_ACCESS_VIEW_DESC& desc,
|
||||||
|
const Rc<DxvkBufferView>& bufferView,
|
||||||
|
const DxvkBufferSlice& counterSlice)
|
||||||
|
: m_device(device), m_resource(resource),
|
||||||
|
m_desc(desc), m_bufferView(bufferView),
|
||||||
|
m_counterSlice(counterSlice) { }
|
||||||
|
|
||||||
|
|
||||||
|
D3D11UnorderedAccessView::D3D11UnorderedAccessView(
|
||||||
|
D3D11Device* device,
|
||||||
|
ID3D11Resource* resource,
|
||||||
|
const D3D11_UNORDERED_ACCESS_VIEW_DESC& desc,
|
||||||
|
const Rc<DxvkImageView>& imageView,
|
||||||
|
const DxvkBufferSlice& counterSlice)
|
||||||
|
: m_device(device), m_resource(resource),
|
||||||
|
m_desc(desc), m_imageView(imageView),
|
||||||
|
m_counterSlice(counterSlice) { }
|
||||||
|
|
||||||
|
|
||||||
|
D3D11UnorderedAccessView::~D3D11UnorderedAccessView() {
|
||||||
|
if (m_counterSlice.handle() != VK_NULL_HANDLE)
|
||||||
|
m_device->FreeCounterSlice(m_counterSlice);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
HRESULT STDMETHODCALLTYPE D3D11UnorderedAccessView::QueryInterface(REFIID riid, void** ppvObject) {
|
||||||
|
COM_QUERY_IFACE(riid, ppvObject, IUnknown);
|
||||||
|
COM_QUERY_IFACE(riid, ppvObject, ID3D11DeviceChild);
|
||||||
|
COM_QUERY_IFACE(riid, ppvObject, ID3D11View);
|
||||||
|
COM_QUERY_IFACE(riid, ppvObject, ID3D11UnorderedAccessView);
|
||||||
|
|
||||||
|
Logger::warn("ID3D11UnorderedAccessView::QueryInterface: Unknown interface query");
|
||||||
|
return E_NOINTERFACE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void STDMETHODCALLTYPE D3D11UnorderedAccessView::GetDevice(ID3D11Device** ppDevice) {
|
||||||
|
*ppDevice = m_device.ref();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void STDMETHODCALLTYPE D3D11UnorderedAccessView::GetResource(ID3D11Resource** ppResource) {
|
||||||
|
*ppResource = m_resource.ref();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void STDMETHODCALLTYPE D3D11UnorderedAccessView::GetDesc(D3D11_UNORDERED_ACCESS_VIEW_DESC* pDesc) {
|
||||||
|
*pDesc = m_desc;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
80
src/d3d11/d3d11_uav.h
Normal file
80
src/d3d11/d3d11_uav.h
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "../dxvk/dxvk_device.h"
|
||||||
|
|
||||||
|
#include "d3d11_device_child.h"
|
||||||
|
|
||||||
|
namespace dxvk {
|
||||||
|
|
||||||
|
class D3D11Device;
|
||||||
|
|
||||||
|
struct D3D11UavCounter {
|
||||||
|
uint32_t atomicCtr;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Unordered access view
|
||||||
|
*
|
||||||
|
* Unordered access views are special in that they can
|
||||||
|
* have counters, which can be used inside shaders to
|
||||||
|
* atomically append or consume structures.
|
||||||
|
*/
|
||||||
|
class D3D11UnorderedAccessView : public D3D11DeviceChild<ID3D11UnorderedAccessView> {
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
D3D11UnorderedAccessView(
|
||||||
|
D3D11Device* device,
|
||||||
|
ID3D11Resource* resource,
|
||||||
|
const D3D11_UNORDERED_ACCESS_VIEW_DESC& desc,
|
||||||
|
const Rc<DxvkBufferView>& bufferView,
|
||||||
|
const DxvkBufferSlice& counterSlice);
|
||||||
|
|
||||||
|
D3D11UnorderedAccessView(
|
||||||
|
D3D11Device* device,
|
||||||
|
ID3D11Resource* resource,
|
||||||
|
const D3D11_UNORDERED_ACCESS_VIEW_DESC& desc,
|
||||||
|
const Rc<DxvkImageView>& imageView,
|
||||||
|
const DxvkBufferSlice& counterSlice);
|
||||||
|
|
||||||
|
~D3D11UnorderedAccessView();
|
||||||
|
|
||||||
|
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject) final;
|
||||||
|
|
||||||
|
void STDMETHODCALLTYPE GetDevice(ID3D11Device** ppDevice) final;
|
||||||
|
|
||||||
|
void STDMETHODCALLTYPE GetResource(ID3D11Resource** ppResource) final;
|
||||||
|
|
||||||
|
void STDMETHODCALLTYPE GetDesc(D3D11_UNORDERED_ACCESS_VIEW_DESC* pDesc) final;
|
||||||
|
|
||||||
|
D3D11_RESOURCE_DIMENSION GetResourceType() const {
|
||||||
|
D3D11_RESOURCE_DIMENSION type;
|
||||||
|
m_resource->GetType(&type);
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
Rc<DxvkBufferView> GetBufferView() const {
|
||||||
|
return m_bufferView;
|
||||||
|
}
|
||||||
|
|
||||||
|
Rc<DxvkImageView> GetImageView() const {
|
||||||
|
return m_imageView;
|
||||||
|
}
|
||||||
|
|
||||||
|
DxvkBufferSlice GetCounterSlice() const {
|
||||||
|
return m_counterSlice;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
Com<D3D11Device> m_device;
|
||||||
|
Com<ID3D11Resource> m_resource;
|
||||||
|
D3D11_UNORDERED_ACCESS_VIEW_DESC m_desc;
|
||||||
|
Rc<DxvkBufferView> m_bufferView;
|
||||||
|
Rc<DxvkImageView> m_imageView;
|
||||||
|
DxvkBufferSlice m_counterSlice;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <dxvk_device.h>
|
#include "../dxvk/dxvk_device.h"
|
||||||
|
|
||||||
#include "d3d11_device_child.h"
|
#include "d3d11_device_child.h"
|
||||||
|
|
||||||
@ -60,17 +60,17 @@ namespace dxvk {
|
|||||||
*pDesc = m_desc;
|
*pDesc = m_desc;
|
||||||
}
|
}
|
||||||
|
|
||||||
D3D11_RESOURCE_DIMENSION GetResourceType() {
|
D3D11_RESOURCE_DIMENSION GetResourceType() const {
|
||||||
D3D11_RESOURCE_DIMENSION type;
|
D3D11_RESOURCE_DIMENSION type;
|
||||||
m_resource->GetType(&type);
|
m_resource->GetType(&type);
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
Rc<DxvkBufferView> GetDXVKBufferView() {
|
Rc<DxvkBufferView> GetBufferView() const {
|
||||||
return m_bufferView;
|
return m_bufferView;
|
||||||
}
|
}
|
||||||
|
|
||||||
Rc<DxvkImageView> GetDXVKImageView() {
|
Rc<DxvkImageView> GetImageView() const {
|
||||||
return m_imageView;
|
return m_imageView;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,7 +94,4 @@ namespace dxvk {
|
|||||||
using D3D11DepthStencilView = D3D11ResourceView<
|
using D3D11DepthStencilView = D3D11ResourceView<
|
||||||
ID3D11DepthStencilView, D3D11_DEPTH_STENCIL_VIEW_DESC>;
|
ID3D11DepthStencilView, D3D11_DEPTH_STENCIL_VIEW_DESC>;
|
||||||
|
|
||||||
using D3D11UnorderedAccessView = D3D11ResourceView<
|
|
||||||
ID3D11UnorderedAccessView, D3D11_UNORDERED_ACCESS_VIEW_DESC>;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,7 @@ d3d11_src = [
|
|||||||
'd3d11_shader.cpp',
|
'd3d11_shader.cpp',
|
||||||
'd3d11_state.cpp',
|
'd3d11_state.cpp',
|
||||||
'd3d11_texture.cpp',
|
'd3d11_texture.cpp',
|
||||||
|
'd3d11_uav.cpp',
|
||||||
'd3d11_util.cpp',
|
'd3d11_util.cpp',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -11,13 +11,14 @@ namespace dxvk {
|
|||||||
// 14 - 29: Samplers
|
// 14 - 29: Samplers
|
||||||
// 30 - 157: Shader resources
|
// 30 - 157: Shader resources
|
||||||
// 158 - 221: Uniform access views
|
// 158 - 221: Uniform access views
|
||||||
const uint32_t stageOffset = 12 + 158 * 5;
|
const uint32_t stageOffset = 20 + 158 * 5;
|
||||||
|
|
||||||
switch (bindingType) {
|
switch (bindingType) {
|
||||||
case DxbcBindingType::ConstantBuffer: return bindingIndex + stageOffset + 0;
|
case DxbcBindingType::ConstantBuffer: return bindingIndex + stageOffset + 0;
|
||||||
case DxbcBindingType::ImageSampler: return bindingIndex + stageOffset + 14;
|
case DxbcBindingType::ImageSampler: return bindingIndex + stageOffset + 14;
|
||||||
case DxbcBindingType::ShaderResource: return bindingIndex + stageOffset + 30;
|
case DxbcBindingType::ShaderResource: return bindingIndex + stageOffset + 30;
|
||||||
case DxbcBindingType::UnorderedAccessView:return bindingIndex + stageOffset + 158;
|
case DxbcBindingType::UnorderedAccessView:return bindingIndex + stageOffset + 158;
|
||||||
|
case DxbcBindingType::UavCounter: return bindingIndex + stageOffset + 222;
|
||||||
default: Logger::err("computeResourceSlotId: Invalid resource type");
|
default: Logger::err("computeResourceSlotId: Invalid resource type");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -28,11 +29,12 @@ namespace dxvk {
|
|||||||
// 0 - 13: Constant buffers
|
// 0 - 13: Constant buffers
|
||||||
// 14 - 29: Samplers
|
// 14 - 29: Samplers
|
||||||
// 30 - 157: Shader resources
|
// 30 - 157: Shader resources
|
||||||
const uint32_t stageOffset = 12 + 158 * static_cast<uint32_t>(shaderStage);
|
const uint32_t stageOffset = 20 + 158 * static_cast<uint32_t>(shaderStage);
|
||||||
|
|
||||||
switch (bindingType) {
|
switch (bindingType) {
|
||||||
case DxbcBindingType::UnorderedAccessView:return bindingIndex + 0;
|
case DxbcBindingType::UnorderedAccessView:return bindingIndex + 0;
|
||||||
case DxbcBindingType::StreamOutputBuffer: return bindingIndex + 8;
|
case DxbcBindingType::UavCounter: return bindingIndex + 8;
|
||||||
|
case DxbcBindingType::StreamOutputBuffer: return bindingIndex + 16;
|
||||||
case DxbcBindingType::ConstantBuffer: return bindingIndex + stageOffset + 0;
|
case DxbcBindingType::ConstantBuffer: return bindingIndex + stageOffset + 0;
|
||||||
case DxbcBindingType::ImageSampler: return bindingIndex + stageOffset + 14;
|
case DxbcBindingType::ImageSampler: return bindingIndex + stageOffset + 14;
|
||||||
case DxbcBindingType::ShaderResource: return bindingIndex + stageOffset + 30;
|
case DxbcBindingType::ShaderResource: return bindingIndex + stageOffset + 30;
|
||||||
|
@ -17,6 +17,7 @@ namespace dxvk {
|
|||||||
ImageSampler = 2,
|
ImageSampler = 2,
|
||||||
UnorderedAccessView = 3,
|
UnorderedAccessView = 3,
|
||||||
StreamOutputBuffer = 4,
|
StreamOutputBuffer = 4,
|
||||||
|
UavCounter = 5,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ namespace dxvk {
|
|||||||
MaxNumVertexBindings = 32,
|
MaxNumVertexBindings = 32,
|
||||||
MaxNumOutputStreams = 4,
|
MaxNumOutputStreams = 4,
|
||||||
MaxNumViewports = 16,
|
MaxNumViewports = 16,
|
||||||
MaxNumResourceSlots = 1024,
|
MaxNumResourceSlots = 1096,
|
||||||
MaxNumActiveBindings = 128,
|
MaxNumActiveBindings = 128,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user