mirror of
https://github.com/doitsujin/dxvk.git
synced 2024-12-04 16:24:29 +01:00
[d3d11] Fix remaining synchronization issues with CUDA interop
This commit is contained in:
parent
c26c21edb4
commit
e83446f5c9
@ -2492,15 +2492,15 @@ namespace dxvk {
|
|||||||
|
|
||||||
D3D11SamplerState* pSS = static_cast<D3D11SamplerState*>(samplerState);
|
D3D11SamplerState* pSS = static_cast<D3D11SamplerState*>(samplerState);
|
||||||
Rc<DxvkSampler> pDSS = pSS->GetDXVKSampler();
|
Rc<DxvkSampler> pDSS = pSS->GetDXVKSampler();
|
||||||
VkSampler vkSampler = pDSS->handle();
|
|
||||||
|
|
||||||
D3D11ShaderResourceView* pSRV = static_cast<D3D11ShaderResourceView*>(srv);
|
D3D11ShaderResourceView* pSRV = static_cast<D3D11ShaderResourceView*>(srv);
|
||||||
Rc<DxvkImageView> pIV = pSRV->GetImageView();
|
Rc<DxvkImageView> pIV = pSRV->GetImageView();
|
||||||
VkImageView vkImageView = pIV->handle();
|
|
||||||
|
LockImage(pIV->image(), 0u);
|
||||||
|
|
||||||
VkImageViewHandleInfoNVX imageViewHandleInfo = { VK_STRUCTURE_TYPE_IMAGE_VIEW_HANDLE_INFO_NVX };
|
VkImageViewHandleInfoNVX imageViewHandleInfo = { VK_STRUCTURE_TYPE_IMAGE_VIEW_HANDLE_INFO_NVX };
|
||||||
imageViewHandleInfo.imageView = vkImageView;
|
imageViewHandleInfo.imageView = pIV->handle();
|
||||||
imageViewHandleInfo.sampler = vkSampler;
|
imageViewHandleInfo.sampler = pDSS->handle();
|
||||||
imageViewHandleInfo.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
imageViewHandleInfo.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
||||||
|
|
||||||
// note: there's no implicit lifetime management here; it's up to the
|
// note: there's no implicit lifetime management here; it's up to the
|
||||||
@ -2574,25 +2574,8 @@ namespace dxvk {
|
|||||||
// won't be relocated by the backend going forward
|
// won't be relocated by the backend going forward
|
||||||
Rc<DxvkImage> dxvkImage = texture->GetImage();
|
Rc<DxvkImage> dxvkImage = texture->GetImage();
|
||||||
|
|
||||||
if (dxvkImage->canRelocate()) {
|
if (!LockImage(dxvkImage, VK_IMAGE_USAGE_SAMPLED_BIT))
|
||||||
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;
|
return false;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// The d3d11 nvapi provides us a texture, but vulkan only lets us
|
// 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
|
// get the GPU address from an image view. So, make a private image
|
||||||
@ -2622,16 +2605,7 @@ namespace dxvk {
|
|||||||
*gpuVASize = imageViewAddressProperties.size;
|
*gpuVASize = imageViewAddressProperties.size;
|
||||||
} else if (resourceDesc.Dim == D3D11_RESOURCE_DIMENSION_BUFFER) {
|
} else if (resourceDesc.Dim == D3D11_RESOURCE_DIMENSION_BUFFER) {
|
||||||
Rc<DxvkBuffer> dxvkBuffer = GetCommonBuffer(pResource)->GetBuffer();
|
Rc<DxvkBuffer> dxvkBuffer = GetCommonBuffer(pResource)->GetBuffer();
|
||||||
|
LockBuffer(dxvkBuffer);
|
||||||
if (dxvkBuffer->canRelocate()) {
|
|
||||||
auto chunk = m_device->AllocCsChunk(DxvkCsChunkFlag::SingleUse);
|
|
||||||
|
|
||||||
chunk->push([cBuffer = dxvkBuffer] (DxvkContext* ctx) {
|
|
||||||
ctx->ensureBufferAddress(cBuffer);
|
|
||||||
});
|
|
||||||
|
|
||||||
m_device->GetContext()->EmitCsChunkExternal(std::move(chunk), true);
|
|
||||||
}
|
|
||||||
|
|
||||||
*gpuVAStart = dxvkBuffer->gpuAddress();
|
*gpuVAStart = dxvkBuffer->gpuAddress();
|
||||||
*gpuVASize = dxvkBuffer->info().size;
|
*gpuVASize = dxvkBuffer->info().size;
|
||||||
@ -2647,102 +2621,99 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool STDMETHODCALLTYPE D3D11DeviceExt::CreateUnorderedAccessViewAndGetDriverHandleNVX(ID3D11Resource* pResource, const D3D11_UNORDERED_ACCESS_VIEW_DESC* pDesc, ID3D11UnorderedAccessView** ppUAV, uint32_t* pDriverHandle) {
|
bool STDMETHODCALLTYPE D3D11DeviceExt::CreateUnorderedAccessViewAndGetDriverHandleNVX(
|
||||||
D3D11_COMMON_RESOURCE_DESC resourceDesc;
|
ID3D11Resource* pResource,
|
||||||
if (!SUCCEEDED(GetCommonResourceDesc(pResource, &resourceDesc))) {
|
const D3D11_UNORDERED_ACCESS_VIEW_DESC* pDesc,
|
||||||
Logger::warn("CreateUnorderedAccessViewAndGetDriverHandleNVX() - GetCommonResourceDesc() failed");
|
ID3D11UnorderedAccessView** ppUAV,
|
||||||
return false;
|
uint32_t* pDriverHandle) {
|
||||||
}
|
D3D11_COMMON_RESOURCE_DESC resourceDesc = { };
|
||||||
|
GetCommonResourceDesc(pResource, &resourceDesc);
|
||||||
|
|
||||||
if (resourceDesc.Dim != D3D11_RESOURCE_DIMENSION_TEXTURE2D) {
|
if (resourceDesc.Dim != D3D11_RESOURCE_DIMENSION_TEXTURE2D) {
|
||||||
Logger::warn(str::format("CreateUnorderedAccessViewAndGetDriverHandleNVX() - failure - unsupported dimension: ", resourceDesc.Dim));
|
Logger::warn(str::format("CreateUnorderedAccessViewAndGetDriverHandleNVX(): Unsupported dimension: ", resourceDesc.Dim));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto texture = GetCommonTexture(pResource);
|
Rc<DxvkImage> dxvkImage = GetCommonTexture(pResource)->GetImage();
|
||||||
Rc<DxvkImage> dxvkImage = texture->GetImage();
|
|
||||||
if (0 == (dxvkImage->info().usage & (VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_SAMPLED_BIT))) {
|
if (!(dxvkImage->info().usage & VK_IMAGE_USAGE_STORAGE_BIT)) {
|
||||||
Logger::warn(str::format("CreateUnorderedAccessViewAndGetDriverHandleNVX(res=", pResource, ") image info missing required usage bit(s); can't be used for vkGetImageViewHandleNVX - failure"));
|
Logger::warn(str::format("CreateUnorderedAccessViewAndGetDriverHandleNVX(res=", pResource, "): Image not UAV compatible"));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!SUCCEEDED(m_device->CreateUnorderedAccessView(pResource, pDesc, ppUAV))) {
|
Com<ID3D11UnorderedAccessView> uav;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
D3D11UnorderedAccessView *pUAV = static_cast<D3D11UnorderedAccessView *>(*ppUAV);
|
if (FAILED(m_device->CreateUnorderedAccessView(pResource, pDesc, &uav)))
|
||||||
Rc<DxvkDevice> dxvkDevice = m_device->GetDXVKDevice();
|
return false;
|
||||||
VkDevice vkDevice = dxvkDevice->handle();
|
|
||||||
|
Rc<DxvkImageView> dxvkImageView = static_cast<D3D11UnorderedAccessView*>(uav.ptr())->GetImageView();
|
||||||
|
LockImage(dxvkImageView->image(), 0u);
|
||||||
|
|
||||||
VkImageViewHandleInfoNVX imageViewHandleInfo = {VK_STRUCTURE_TYPE_IMAGE_VIEW_HANDLE_INFO_NVX};
|
VkImageViewHandleInfoNVX imageViewHandleInfo = {VK_STRUCTURE_TYPE_IMAGE_VIEW_HANDLE_INFO_NVX};
|
||||||
Rc<DxvkImageView> dxvkImageView = pUAV->GetImageView();
|
imageViewHandleInfo.imageView = dxvkImageView->handle();
|
||||||
VkImageView vkImageView = dxvkImageView->handle();
|
|
||||||
|
|
||||||
imageViewHandleInfo.imageView = vkImageView;
|
|
||||||
imageViewHandleInfo.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
|
imageViewHandleInfo.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
|
||||||
|
|
||||||
*pDriverHandle = dxvkDevice->vkd()->vkGetImageViewHandleNVX(vkDevice, &imageViewHandleInfo);
|
Rc<DxvkDevice> dxvkDevice = m_device->GetDXVKDevice();
|
||||||
|
*pDriverHandle = dxvkDevice->vkd()->vkGetImageViewHandleNVX(
|
||||||
|
dxvkDevice->handle(), &imageViewHandleInfo);
|
||||||
|
|
||||||
if (!*pDriverHandle) {
|
if (!*pDriverHandle) {
|
||||||
Logger::warn("CreateUnorderedAccessViewAndGetDriverHandleNVX() handle==0 - failure");
|
Logger::warn("CreateUnorderedAccessViewAndGetDriverHandleNVX(): Handle is 0");
|
||||||
pUAV->Release();
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*ppUAV = uav.ref();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool STDMETHODCALLTYPE D3D11DeviceExt::CreateShaderResourceViewAndGetDriverHandleNVX(ID3D11Resource* pResource, const D3D11_SHADER_RESOURCE_VIEW_DESC* pDesc, ID3D11ShaderResourceView** ppSRV, uint32_t* pDriverHandle) {
|
bool STDMETHODCALLTYPE D3D11DeviceExt::CreateShaderResourceViewAndGetDriverHandleNVX(ID3D11Resource* pResource, const D3D11_SHADER_RESOURCE_VIEW_DESC* pDesc, ID3D11ShaderResourceView** ppSRV, uint32_t* pDriverHandle) {
|
||||||
D3D11_COMMON_RESOURCE_DESC resourceDesc;
|
D3D11_COMMON_RESOURCE_DESC resourceDesc = { };
|
||||||
if (!SUCCEEDED(GetCommonResourceDesc(pResource, &resourceDesc))) {
|
GetCommonResourceDesc(pResource, &resourceDesc);
|
||||||
Logger::warn("CreateShaderResourceViewAndGetDriverHandleNVX() - GetCommonResourceDesc() failed");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (resourceDesc.Dim != D3D11_RESOURCE_DIMENSION_TEXTURE2D) {
|
if (resourceDesc.Dim != D3D11_RESOURCE_DIMENSION_TEXTURE2D) {
|
||||||
Logger::warn(str::format("CreateShaderResourceViewAndGetDriverHandleNVX() - failure - unsupported dimension: ", resourceDesc.Dim));
|
Logger::warn(str::format("CreateShaderResourceViewAndGetDriverHandleNVX(): Unsupported dimension: ", resourceDesc.Dim));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto texture = GetCommonTexture(pResource);
|
Rc<DxvkImage> dxvkImage = GetCommonTexture(pResource)->GetImage();
|
||||||
Rc<DxvkImage> dxvkImage = texture->GetImage();
|
|
||||||
if (0 == (dxvkImage->info().usage & (VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_SAMPLED_BIT))) {
|
if (!(dxvkImage->info().usage & VK_IMAGE_USAGE_SAMPLED_BIT)) {
|
||||||
Logger::warn(str::format("CreateShaderResourceViewAndGetDriverHandleNVX(res=", pResource, ") image info missing required usage bit(s); can't be used for vkGetImageViewHandleNVX - failure"));
|
Logger::warn(str::format("CreateShaderResourceViewAndGetDriverHandleNVX(res=", pResource, "): Image not SRV compatible"));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!SUCCEEDED(m_device->CreateShaderResourceView(pResource, pDesc, ppSRV))) {
|
Com<ID3D11ShaderResourceView> srv;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
D3D11ShaderResourceView* pSRV = static_cast<D3D11ShaderResourceView*>(*ppSRV);
|
if (FAILED(m_device->CreateShaderResourceView(pResource, pDesc, &srv)))
|
||||||
Rc<DxvkDevice> dxvkDevice = m_device->GetDXVKDevice();
|
return false;
|
||||||
VkDevice vkDevice = dxvkDevice->handle();
|
|
||||||
|
Rc<DxvkImageView> dxvkImageView = static_cast<D3D11ShaderResourceView*>(srv.ptr())->GetImageView();
|
||||||
|
LockImage(dxvkImageView->image(), 0u);
|
||||||
|
|
||||||
VkImageViewHandleInfoNVX imageViewHandleInfo = {VK_STRUCTURE_TYPE_IMAGE_VIEW_HANDLE_INFO_NVX};
|
VkImageViewHandleInfoNVX imageViewHandleInfo = {VK_STRUCTURE_TYPE_IMAGE_VIEW_HANDLE_INFO_NVX};
|
||||||
Rc<DxvkImageView> dxvkImageView = pSRV->GetImageView();
|
imageViewHandleInfo.imageView = dxvkImageView->handle();
|
||||||
VkImageView vkImageView = dxvkImageView->handle();
|
|
||||||
|
|
||||||
imageViewHandleInfo.imageView = vkImageView;
|
|
||||||
imageViewHandleInfo.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
|
imageViewHandleInfo.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
|
||||||
|
|
||||||
*pDriverHandle = dxvkDevice->vkd()->vkGetImageViewHandleNVX(vkDevice, &imageViewHandleInfo);
|
Rc<DxvkDevice> dxvkDevice = m_device->GetDXVKDevice();
|
||||||
|
*pDriverHandle = dxvkDevice->vkd()->vkGetImageViewHandleNVX(
|
||||||
|
dxvkDevice->handle(), &imageViewHandleInfo);
|
||||||
|
|
||||||
if (!*pDriverHandle) {
|
if (!*pDriverHandle) {
|
||||||
Logger::warn("CreateShaderResourceViewAndGetDriverHandleNVX() handle==0 - failure");
|
Logger::warn("CreateShaderResourceViewAndGetDriverHandleNVX(): Handle is 0");
|
||||||
pSRV->Release();
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// will need to look-up resource from uint32 handle later
|
// will need to look-up resource from uint32 handle later
|
||||||
AddSrvAndHandleNVX(*ppSRV, *pDriverHandle);
|
*ppSRV = srv.ref();
|
||||||
|
AddSrvAndHandleNVX(srv.ptr(), *pDriverHandle);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool STDMETHODCALLTYPE D3D11DeviceExt::CreateSamplerStateAndGetDriverHandleNVX(const D3D11_SAMPLER_DESC* pSamplerDesc, ID3D11SamplerState** ppSamplerState, uint32_t* pDriverHandle) {
|
bool STDMETHODCALLTYPE D3D11DeviceExt::CreateSamplerStateAndGetDriverHandleNVX(const D3D11_SAMPLER_DESC* pSamplerDesc, ID3D11SamplerState** ppSamplerState, uint32_t* pDriverHandle) {
|
||||||
if (!SUCCEEDED(m_device->CreateSamplerState(pSamplerDesc, ppSamplerState))) {
|
if (FAILED(m_device->CreateSamplerState(pSamplerDesc, ppSamplerState)))
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
// for our purposes the actual value doesn't matter, only its uniqueness
|
// for our purposes the actual value doesn't matter, only its uniqueness
|
||||||
static std::atomic<ULONG> s_seqNum = 0;
|
static std::atomic<ULONG> s_seqNum = 0;
|
||||||
@ -2788,6 +2759,55 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool D3D11DeviceExt::LockImage(
|
||||||
|
const Rc<DxvkImage>& Image,
|
||||||
|
VkImageUsageFlags Usage) {
|
||||||
|
if (!Image->canRelocate() && (Image->info().usage & Usage))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
bool feedback = false;
|
||||||
|
|
||||||
|
auto chunk = m_device->AllocCsChunk(DxvkCsChunkFlag::SingleUse);
|
||||||
|
|
||||||
|
chunk->push([
|
||||||
|
cImage = Image,
|
||||||
|
cUsage = Usage,
|
||||||
|
&feedback
|
||||||
|
] (DxvkContext* ctx) {
|
||||||
|
DxvkImageUsageInfo usageInfo;
|
||||||
|
usageInfo.usage = cUsage;
|
||||||
|
usageInfo.stableGpuAddress = VK_TRUE;
|
||||||
|
|
||||||
|
feedback = ctx->ensureImageCompatibility(cImage, usageInfo);
|
||||||
|
});
|
||||||
|
|
||||||
|
m_device->GetContext()->EmitCsChunkExternal(std::move(chunk), true);
|
||||||
|
|
||||||
|
if (!feedback) {
|
||||||
|
Logger::err(str::format("Failed to lock image:"
|
||||||
|
"\n Image format: ", Image->info().format,
|
||||||
|
"\n Image usage: ", std::hex, Image->info().usage,
|
||||||
|
"\n Desired usage: ", std::hex, Usage));
|
||||||
|
}
|
||||||
|
|
||||||
|
return feedback;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void D3D11DeviceExt::LockBuffer(
|
||||||
|
const Rc<DxvkBuffer>& Buffer) {
|
||||||
|
if (!Buffer->canRelocate())
|
||||||
|
return;
|
||||||
|
|
||||||
|
auto chunk = m_device->AllocCsChunk(DxvkCsChunkFlag::SingleUse);
|
||||||
|
|
||||||
|
chunk->push([cBuffer = Buffer] (DxvkContext* ctx) {
|
||||||
|
ctx->ensureBufferAddress(cBuffer);
|
||||||
|
});
|
||||||
|
|
||||||
|
m_device->GetContext()->EmitCsChunkExternal(std::move(chunk), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -593,6 +593,13 @@ namespace dxvk {
|
|||||||
ID3D11ShaderResourceView* HandleToSrvNVX(
|
ID3D11ShaderResourceView* HandleToSrvNVX(
|
||||||
uint32_t Handle);
|
uint32_t Handle);
|
||||||
|
|
||||||
|
bool LockImage(
|
||||||
|
const Rc<DxvkImage>& Image,
|
||||||
|
VkImageUsageFlags Usage);
|
||||||
|
|
||||||
|
void LockBuffer(
|
||||||
|
const Rc<DxvkBuffer>& Buffer);
|
||||||
|
|
||||||
dxvk::mutex m_mapLock;
|
dxvk::mutex m_mapLock;
|
||||||
std::unordered_map<uint32_t, ID3D11SamplerState*> m_samplerHandleToPtr;
|
std::unordered_map<uint32_t, ID3D11SamplerState*> m_samplerHandleToPtr;
|
||||||
std::unordered_map<uint32_t, ID3D11ShaderResourceView*> m_srvHandleToPtr;
|
std::unordered_map<uint32_t, ID3D11ShaderResourceView*> m_srvHandleToPtr;
|
||||||
|
Loading…
Reference in New Issue
Block a user