mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-02-21 22:54:16 +01:00
[d3d11] Lock textures in place when used with CUDA interop
Prevents images from being relocated by the backend.
This commit is contained in:
parent
c59d6bd12c
commit
9f0bd8e17f
@ -2558,21 +2558,9 @@ namespace dxvk {
|
|||||||
ID3D11Resource* pResource = static_cast<ID3D11Resource*>(hObject);
|
ID3D11Resource* pResource = static_cast<ID3D11Resource*>(hObject);
|
||||||
|
|
||||||
D3D11_COMMON_RESOURCE_DESC resourceDesc;
|
D3D11_COMMON_RESOURCE_DESC resourceDesc;
|
||||||
if (FAILED(GetCommonResourceDesc(pResource, &resourceDesc))) {
|
|
||||||
Logger::warn("GetResourceHandleGPUVirtualAddressAndSize() - GetCommonResourceDesc() failed");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (resourceDesc.Dim) {
|
if (FAILED(GetCommonResourceDesc(pResource, &resourceDesc))) {
|
||||||
case D3D11_RESOURCE_DIMENSION_BUFFER:
|
Logger::warn("GetResourceHandleGPUVirtualAddressAndSize: Invalid resource");
|
||||||
case D3D11_RESOURCE_DIMENSION_TEXTURE2D:
|
|
||||||
// okay - we can deal with those two dimensions
|
|
||||||
break;
|
|
||||||
case D3D11_RESOURCE_DIMENSION_TEXTURE1D:
|
|
||||||
case D3D11_RESOURCE_DIMENSION_TEXTURE3D:
|
|
||||||
case D3D11_RESOURCE_DIMENSION_UNKNOWN:
|
|
||||||
default:
|
|
||||||
Logger::warn(str::format("GetResourceHandleGPUVirtualAddressAndSize(?) - failure - unsupported dimension: ", resourceDesc.Dim));
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2581,47 +2569,58 @@ namespace dxvk {
|
|||||||
|
|
||||||
if (resourceDesc.Dim == D3D11_RESOURCE_DIMENSION_TEXTURE2D) {
|
if (resourceDesc.Dim == D3D11_RESOURCE_DIMENSION_TEXTURE2D) {
|
||||||
D3D11CommonTexture *texture = GetCommonTexture(pResource);
|
D3D11CommonTexture *texture = GetCommonTexture(pResource);
|
||||||
|
|
||||||
|
// Ensure that the image has a stable GPU address and
|
||||||
|
// won't be relocated by the backend going forward
|
||||||
Rc<DxvkImage> dxvkImage = texture->GetImage();
|
Rc<DxvkImage> dxvkImage = texture->GetImage();
|
||||||
if (0 == (dxvkImage->info().usage & (VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_SAMPLED_BIT))) {
|
|
||||||
Logger::warn(str::format("GetResourceHandleGPUVirtualAddressAndSize(res=", pResource,") image info missing required usage bit(s); can't be used for vkGetImageViewHandleNVX - failure"));
|
if (dxvkImage->canRelocate()) {
|
||||||
return false;
|
auto chunk = m_device->AllocCsChunk(DxvkCsChunkFlag::SingleUse);
|
||||||
|
bool feedback = false;
|
||||||
|
|
||||||
|
chunk->push([cImage = dxvkImage, &feedback] (DxvkContext* ctx) {
|
||||||
|
DxvkImageUsageInfo usageInfo;
|
||||||
|
usageInfo.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
|
||||||
|
usageInfo.stableGpuAddress = VK_TRUE;
|
||||||
|
|
||||||
|
feedback = ctx->ensureImageCompatibility(cImage, usageInfo);
|
||||||
|
});
|
||||||
|
|
||||||
|
m_device->GetContext()->EmitCsChunkExternal(std::move(chunk), true);
|
||||||
|
|
||||||
|
if (!feedback) {
|
||||||
|
Logger::err(str::format("GetResourceHandleGPUVirtualAddressAndSize(res=", pResource,"): Failed to lock resource"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// The d3d11 nvapi provides us a texture but vulkan only lets us get the GPU address from an imageview. So, make a private imageview and get the address from that...
|
// The d3d11 nvapi provides us a texture, but vulkan only lets us
|
||||||
|
// get the GPU address from an image view. So, make a private image
|
||||||
|
// view and get the address from that.
|
||||||
|
DxvkImageViewKey viewInfo;
|
||||||
|
viewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
|
||||||
|
viewInfo.format = dxvkImage->info().format;
|
||||||
|
viewInfo.aspects = dxvkImage->formatInfo()->aspectMask;
|
||||||
|
viewInfo.mipIndex = 0;
|
||||||
|
viewInfo.mipCount = dxvkImage->info().mipLevels;
|
||||||
|
viewInfo.layerIndex = 0;
|
||||||
|
viewInfo.layerCount = 1;
|
||||||
|
viewInfo.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
|
||||||
|
|
||||||
D3D11_SHADER_RESOURCE_VIEW_DESC resourceViewDesc;
|
auto dxvkView = dxvkImage->createView(viewInfo);
|
||||||
|
VkImageViewAddressPropertiesNVX imageViewAddressProperties = { VK_STRUCTURE_TYPE_IMAGE_VIEW_ADDRESS_PROPERTIES_NVX };
|
||||||
|
|
||||||
const D3D11_COMMON_TEXTURE_DESC *texDesc = texture->Desc();
|
VkResult vr = dxvkDevice->vkd()->vkGetImageViewAddressNVX(vkDevice,
|
||||||
if (texDesc->ArraySize != 1) {
|
dxvkView->handle(), &imageViewAddressProperties);
|
||||||
Logger::debug(str::format("GetResourceHandleGPUVirtualAddressAndSize(?) - unexpected array size: ", texDesc->ArraySize));
|
|
||||||
}
|
|
||||||
resourceViewDesc.Format = texDesc->Format;
|
|
||||||
resourceViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
|
|
||||||
resourceViewDesc.Texture2D.MostDetailedMip = 0;
|
|
||||||
resourceViewDesc.Texture2D.MipLevels = texDesc->MipLevels;
|
|
||||||
|
|
||||||
Com<ID3D11ShaderResourceView> pNewSRV;
|
if (vr != VK_SUCCESS) {
|
||||||
HRESULT hr = m_device->CreateShaderResourceView(pResource, &resourceViewDesc, &pNewSRV);
|
Logger::warn(str::format("GetResourceHandleGPUVirtualAddressAndSize(): Failed: vr = ", vr));
|
||||||
if (FAILED(hr)) {
|
|
||||||
Logger::warn("GetResourceHandleGPUVirtualAddressAndSize() - private CreateShaderResourceView() failed");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Rc<DxvkImageView> dxvkImageView = static_cast<D3D11ShaderResourceView*>(pNewSRV.ptr())->GetImageView();
|
|
||||||
VkImageView vkImageView = dxvkImageView->handle();
|
|
||||||
|
|
||||||
VkImageViewAddressPropertiesNVX imageViewAddressProperties = {VK_STRUCTURE_TYPE_IMAGE_VIEW_ADDRESS_PROPERTIES_NVX};
|
|
||||||
|
|
||||||
VkResult res = dxvkDevice->vkd()->vkGetImageViewAddressNVX(vkDevice, vkImageView, &imageViewAddressProperties);
|
|
||||||
if (res != VK_SUCCESS) {
|
|
||||||
Logger::warn(str::format("GetResourceHandleGPUVirtualAddressAndSize(): vkGetImageViewAddressNVX() result is failure: ", res));
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
*gpuVAStart = imageViewAddressProperties.deviceAddress;
|
*gpuVAStart = imageViewAddressProperties.deviceAddress;
|
||||||
*gpuVASize = imageViewAddressProperties.size;
|
*gpuVASize = imageViewAddressProperties.size;
|
||||||
}
|
} else if (resourceDesc.Dim == D3D11_RESOURCE_DIMENSION_BUFFER) {
|
||||||
else if (resourceDesc.Dim == D3D11_RESOURCE_DIMENSION_BUFFER) {
|
|
||||||
D3D11Buffer *buffer = GetCommonBuffer(pResource);
|
D3D11Buffer *buffer = GetCommonBuffer(pResource);
|
||||||
const DxvkBufferSliceHandle bufSliceHandle = buffer->GetBuffer()->getSliceHandle();
|
const DxvkBufferSliceHandle bufSliceHandle = buffer->GetBuffer()->getSliceHandle();
|
||||||
VkBuffer vkBuffer = bufSliceHandle.handle;
|
VkBuffer vkBuffer = bufSliceHandle.handle;
|
||||||
@ -2632,6 +2631,9 @@ namespace dxvk {
|
|||||||
VkDeviceAddress bufAddr = dxvkDevice->vkd()->vkGetBufferDeviceAddress(vkDevice, &bdaInfo);
|
VkDeviceAddress bufAddr = dxvkDevice->vkd()->vkGetBufferDeviceAddress(vkDevice, &bdaInfo);
|
||||||
*gpuVAStart = uint64_t(bufAddr) + bufSliceHandle.offset;
|
*gpuVAStart = uint64_t(bufAddr) + bufSliceHandle.offset;
|
||||||
*gpuVASize = bufSliceHandle.length;
|
*gpuVASize = bufSliceHandle.length;
|
||||||
|
} else {
|
||||||
|
Logger::warn(str::format("GetResourceHandleGPUVirtualAddressAndSize(): Unsupported resource type: ", resourceDesc.Dim));
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!*gpuVAStart)
|
if (!*gpuVAStart)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user