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:
parent
847bfdd8ae
commit
a3fe40051f
@ -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
|
||||||
|
@ -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.
|
||||||
|
@ -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();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -314,9 +314,69 @@ 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;
|
||||||
|
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;
|
return E_NOTIMPL;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE D3D11Device::CreateRenderTargetView(
|
HRESULT STDMETHODCALLTYPE D3D11Device::CreateRenderTargetView(
|
||||||
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user