1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-01-18 02:52:10 +01:00

[d3d11] Initial support for unordered access views

Currently restricted to buffers on the API side. Typed UAVs
are not yet supported by the shader compiler. This is enough
to run very simple compute shaders.
This commit is contained in:
Philip Rebohle 2017-12-28 19:05:53 +01:00
parent 847bfdd8ae
commit a3fe40051f
4 changed files with 151 additions and 6 deletions

View File

@ -62,7 +62,7 @@ namespace dxvk {
const D3D11_BUFFER_DESC* pDesc) const { const D3D11_BUFFER_DESC* pDesc) const {
DxvkBufferCreateInfo info; DxvkBufferCreateInfo info;
info.size = pDesc->ByteWidth; info.size = pDesc->ByteWidth;
info.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT
| VK_BUFFER_USAGE_TRANSFER_DST_BIT; | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
info.stages = VK_PIPELINE_STAGE_TRANSFER_BIT; info.stages = VK_PIPELINE_STAGE_TRANSFER_BIT;
info.access = VK_ACCESS_TRANSFER_READ_BIT info.access = VK_ACCESS_TRANSFER_READ_BIT

View File

@ -138,6 +138,12 @@ namespace dxvk {
this->CSSetSamplers(i, 1, &sampler); this->CSSetSamplers(i, 1, &sampler);
} }
for (uint32_t i = 0; i < D3D11_1_UAV_SLOT_COUNT; i++) {
ID3D11UnorderedAccessView* uav = nullptr;
this->CSSetUnorderedAccessViews(i, 1, &uav, nullptr);
}
this->OMSetRenderTargets(0, nullptr, nullptr); this->OMSetRenderTargets(0, nullptr, nullptr);
this->OMSetBlendState(nullptr, nullptr, D3D11_DEFAULT_SAMPLE_MASK); this->OMSetBlendState(nullptr, nullptr, D3D11_DEFAULT_SAMPLE_MASK);
this->OMSetDepthStencilState(nullptr, 0); this->OMSetDepthStencilState(nullptr, 0);
@ -328,7 +334,35 @@ namespace dxvk {
void STDMETHODCALLTYPE D3D11DeviceContext::CopyResource( void STDMETHODCALLTYPE D3D11DeviceContext::CopyResource(
ID3D11Resource* pDstResource, ID3D11Resource* pDstResource,
ID3D11Resource* pSrcResource) { ID3D11Resource* pSrcResource) {
Logger::err("D3D11DeviceContext::CopyResource: Not implemented"); D3D11_RESOURCE_DIMENSION dstResourceDim = D3D11_RESOURCE_DIMENSION_UNKNOWN;
D3D11_RESOURCE_DIMENSION srcResourceDim = D3D11_RESOURCE_DIMENSION_UNKNOWN;
pDstResource->GetType(&dstResourceDim);
pSrcResource->GetType(&srcResourceDim);
if (dstResourceDim != srcResourceDim) {
Logger::err("D3D11DeviceContext: CopyResource: Mismatched resource types");
return;
}
if (dstResourceDim == D3D11_RESOURCE_DIMENSION_BUFFER) {
auto dstBuffer = static_cast<D3D11Buffer*>(pDstResource)->GetBufferSlice();
auto srcBuffer = static_cast<D3D11Buffer*>(pSrcResource)->GetBufferSlice();
if (dstBuffer.length() != srcBuffer.length()) {
Logger::err("D3D11DeviceContext: CopyResource: Mismatched buffer size");
return;
}
m_context->copyBuffer(
dstBuffer.buffer(),
dstBuffer.offset(),
srcBuffer.buffer(),
srcBuffer.offset(),
srcBuffer.length());
} else {
Logger::err("D3D11DeviceContext::CopyResource: Images not supported");
}
} }
@ -1299,7 +1333,15 @@ namespace dxvk {
UINT NumUAVs, UINT NumUAVs,
ID3D11UnorderedAccessView* const* ppUnorderedAccessViews, ID3D11UnorderedAccessView* const* ppUnorderedAccessViews,
const UINT* pUAVInitialCounts) { const UINT* pUAVInitialCounts) {
Logger::err("D3D11DeviceContext::CSSetUnorderedAccessViews: Not implemented"); // TODO implement append-consume buffers
if (pUAVInitialCounts != nullptr)
Logger::err("D3D11DeviceContext: pUAVInitialCounts not supported");
this->BindUnorderedAccessViews(
DxbcProgramType::ComputeShader,
m_state.cs.unorderedAccessViews,
StartSlot, NumUAVs,
ppUnorderedAccessViews);
} }
@ -1696,7 +1738,6 @@ namespace dxvk {
if (resView != nullptr) { if (resView != nullptr) {
// 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) {
// TODO support raw and structured buffers
m_context->bindResourceTexelBuffer( m_context->bindResourceTexelBuffer(
slotId + i, resView->GetDXVKBufferView()); slotId + i, resView->GetDXVKBufferView());
} else { } else {
@ -1714,6 +1755,42 @@ namespace dxvk {
} }
void D3D11DeviceContext::BindUnorderedAccessViews(
DxbcProgramType ShaderStage,
D3D11UnorderedAccessBindings& Bindings,
UINT StartSlot,
UINT NumUAVs,
ID3D11UnorderedAccessView* const* ppUnorderedAccessViews) {
const uint32_t slotId = computeResourceSlotId(
ShaderStage, DxbcBindingType::UnorderedAccessView,
StartSlot);
for (uint32_t i = 0; i < NumUAVs; i++) {
auto uav = static_cast<D3D11UnorderedAccessView*>(ppUnorderedAccessViews[i]);
if (Bindings[StartSlot + i] != uav) {
Bindings[StartSlot + i] = uav;
if (uav != nullptr) {
// Figure out what we have to bind based on the resource type
if (uav->GetResourceType() == D3D11_RESOURCE_DIMENSION_BUFFER) {
m_context->bindResourceTexelBuffer(
slotId + i, uav->GetDXVKBufferView());
} else {
m_context->bindResourceImage(
slotId + i, uav->GetDXVKImageView());
}
} else {
// When unbinding a resource, it doesn't really matter if
// the resource type is correct, so we'll just bind a null
// image to the given resource slot
m_context->bindResourceImage(slotId + i, nullptr);
}
}
}
}
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.

View File

@ -584,6 +584,13 @@ namespace dxvk {
UINT NumResources, UINT NumResources,
ID3D11ShaderResourceView* const* ppResources); ID3D11ShaderResourceView* const* ppResources);
void BindUnorderedAccessViews(
DxbcProgramType ShaderStage,
D3D11UnorderedAccessBindings& Bindings,
UINT StartSlot,
UINT NumUAVs,
ID3D11UnorderedAccessView* const* ppUnorderedAccessViews);
void ApplyViewportState(); void ApplyViewportState();
}; };

View File

@ -314,8 +314,68 @@ namespace dxvk {
ID3D11Resource* pResource, ID3D11Resource* pResource,
const D3D11_UNORDERED_ACCESS_VIEW_DESC* pDesc, const D3D11_UNORDERED_ACCESS_VIEW_DESC* pDesc,
ID3D11UnorderedAccessView** ppUAView) { ID3D11UnorderedAccessView** ppUAView) {
Logger::err("D3D11Device::CreateUnorderedAccessView: Not implemented"); D3D11_RESOURCE_DIMENSION resourceDim = D3D11_RESOURCE_DIMENSION_UNKNOWN;
return E_NOTIMPL; pResource->GetType(&resourceDim);
// The description is optional. If omitted, we'll create
// a view that covers all subresources of the image.
D3D11_UNORDERED_ACCESS_VIEW_DESC desc;
if (pDesc == nullptr) {
if (FAILED(GetUnorderedAccessViewDescFromResource(pResource, &desc)))
return E_INVALIDARG;
} else {
desc = *pDesc;
}
if (resourceDim == D3D11_RESOURCE_DIMENSION_BUFFER) {
auto resource = static_cast<D3D11Buffer*>(pResource);
D3D11_BUFFER_DESC resourceDesc;
resource->GetDesc(&resourceDesc);
DxvkBufferViewCreateInfo viewInfo;
if (desc.Buffer.Flags & D3D11_BUFFEREX_SRV_FLAG_RAW) {
viewInfo.format = VK_FORMAT_R32_UINT;
viewInfo.rangeOffset = sizeof(uint32_t) * desc.Buffer.FirstElement;
viewInfo.rangeLength = sizeof(uint32_t) * desc.Buffer.NumElements;
} else if (desc.Format == DXGI_FORMAT_UNKNOWN) {
viewInfo.format = VK_FORMAT_R32_UINT;
viewInfo.rangeOffset = resourceDesc.StructureByteStride * desc.Buffer.FirstElement;
viewInfo.rangeLength = resourceDesc.StructureByteStride * desc.Buffer.NumElements;
} else {
// Typed buffer view - must use an uncompressed color format
viewInfo.format = m_dxgiAdapter->LookupFormat(
desc.Format, DxgiFormatMode::Color).format;
const DxvkFormatInfo* formatInfo = imageFormatInfo(viewInfo.format);
viewInfo.rangeOffset = formatInfo->elementSize * desc.Buffer.FirstElement;
viewInfo.rangeLength = formatInfo->elementSize * desc.Buffer.NumElements;
if (formatInfo->flags.test(DxvkFormatFlag::BlockCompressed)) {
Logger::err("D3D11Device: Compressed formats for buffer views not supported");
return E_INVALIDARG;
}
}
if (ppUAView == nullptr)
return S_FALSE;
try {
*ppUAView = ref(new D3D11UnorderedAccessView(
this, pResource, desc,
m_dxvkDevice->createBufferView(
resource->GetBufferSlice().buffer(), viewInfo)));
return S_OK;
} catch (const DxvkError& e) {
Logger::err(e.message());
return E_FAIL;
}
} else {
Logger::err("D3D11Device::CreateUnorderedAccessView: Images not supported yet");
return E_NOTIMPL;
}
} }
@ -1352,6 +1412,7 @@ namespace dxvk {
HRESULT D3D11Device::GetUnorderedAccessViewDescFromResource( HRESULT D3D11Device::GetUnorderedAccessViewDescFromResource(
ID3D11Resource* pResource, ID3D11Resource* pResource,
D3D11_UNORDERED_ACCESS_VIEW_DESC* pDesc) { D3D11_UNORDERED_ACCESS_VIEW_DESC* pDesc) {
Logger::err("D3D11Device::GetUnorderedAccessViewDescFromResource: Not implemented");
return E_NOTIMPL; return E_NOTIMPL;
} }