[d3d11] Implemented CopySubresourceRegion for images

This commit is contained in:
Philip Rebohle 2017-12-30 19:10:45 +01:00
parent 5332891748
commit b7ce9660c3
5 changed files with 203 additions and 1 deletions

View File

@ -327,7 +327,82 @@ namespace dxvk {
ID3D11Resource* pSrcResource,
UINT SrcSubresource,
const D3D11_BOX* pSrcBox) {
Logger::err("D3D11DeviceContext::CopySubresourceRegion: 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: CopySubresourceRegion: Mismatched resource types");
return;
}
if (dstResourceDim == D3D11_RESOURCE_DIMENSION_BUFFER) {
Logger::err("D3D11DeviceContext::CopySubresourceRegion: Buffers not supported");
} else {
D3D11TextureInfo dstTextureInfo;
D3D11TextureInfo srcTextureInfo;
if (FAILED(GetCommonTextureInfo(pDstResource, &dstTextureInfo))
|| FAILED(GetCommonTextureInfo(pSrcResource, &srcTextureInfo))) {
Logger::err("D3D11DeviceContext: Failed to retrieve DXVK images");
return;
}
VkOffset3D srcOffset = { 0, 0, 0 };
VkOffset3D dstOffset = {
static_cast<int32_t>(DstX),
static_cast<int32_t>(DstY),
static_cast<int32_t>(DstZ) };
VkExtent3D extent = srcTextureInfo.image->info().extent;
if (pSrcBox != nullptr) {
if (pSrcBox->left >= pSrcBox->right
|| pSrcBox->top >= pSrcBox->bottom
|| pSrcBox->front >= pSrcBox->back)
return; // no-op, but legal
srcOffset.x = pSrcBox->left;
srcOffset.y = pSrcBox->top;
srcOffset.z = pSrcBox->front;
extent.width = pSrcBox->right - pSrcBox->left;
extent.height = pSrcBox->bottom - pSrcBox->top;
extent.depth = pSrcBox->back - pSrcBox->front;
}
const DxvkFormatInfo* dstFormatInfo = imageFormatInfo(dstTextureInfo.image->info().format);
const DxvkFormatInfo* srcFormatInfo = imageFormatInfo(srcTextureInfo.image->info().format);
const VkImageSubresource dstSubresource =
GetSubresourceFromIndex(
dstFormatInfo->aspectMask & srcFormatInfo->aspectMask,
dstTextureInfo.image->info().mipLevels, DstSubresource);
const VkImageSubresource srcSubresource =
GetSubresourceFromIndex(
dstFormatInfo->aspectMask & srcFormatInfo->aspectMask,
srcTextureInfo.image->info().mipLevels, SrcSubresource);
VkImageSubresourceLayers dstLayers;
dstLayers.aspectMask = dstSubresource.aspectMask;
dstLayers.mipLevel = dstSubresource.mipLevel;
dstLayers.baseArrayLayer = dstSubresource.arrayLayer;
dstLayers.layerCount = 1;
VkImageSubresourceLayers srcLayers;
srcLayers.aspectMask = srcSubresource.aspectMask;
srcLayers.mipLevel = srcSubresource.mipLevel;
srcLayers.baseArrayLayer = srcSubresource.arrayLayer;
srcLayers.layerCount = 1;
m_context->copyImage(
dstTextureInfo.image, dstLayers, dstOffset,
srcTextureInfo.image, srcLayers, srcOffset,
extent);
}
}

View File

@ -217,6 +217,20 @@ namespace dxvk {
}
void DxvkCommandList::cmdCopyImage(
VkImage srcImage,
VkImageLayout srcImageLayout,
VkImage dstImage,
VkImageLayout dstImageLayout,
uint32_t regionCount,
const VkImageCopy* pRegions) {
m_vkd->vkCmdCopyImage(m_buffer,
srcImage, srcImageLayout,
dstImage, dstImageLayout,
regionCount, pRegions);
}
void DxvkCommandList::cmdDispatch(
uint32_t x,
uint32_t y,

View File

@ -133,6 +133,14 @@ namespace dxvk {
uint32_t regionCount,
const VkBufferCopy* pRegions);
void cmdCopyImage(
VkImage srcImage,
VkImageLayout srcImageLayout,
VkImage dstImage,
VkImageLayout dstImageLayout,
uint32_t regionCount,
const VkImageCopy* pRegions);
void cmdDispatch(
uint32_t x,
uint32_t y,

View File

@ -252,6 +252,8 @@ namespace dxvk {
VkDeviceSize srcOffset,
VkDeviceSize numBytes) {
if (numBytes != 0) {
this->renderPassEnd();
VkBufferCopy bufferRegion;
bufferRegion.srcOffset = srcOffset;
bufferRegion.dstOffset = dstOffset;
@ -284,6 +286,89 @@ namespace dxvk {
}
void DxvkContext::copyImage(
const Rc<DxvkImage>& dstImage,
VkImageSubresourceLayers dstSubresource,
VkOffset3D dstOffset,
const Rc<DxvkImage>& srcImage,
VkImageSubresourceLayers srcSubresource,
VkOffset3D srcOffset,
VkExtent3D extent) {
this->renderPassEnd();
VkImageSubresourceRange dstSubresourceRange;
dstSubresourceRange.aspectMask = dstSubresource.aspectMask;
dstSubresourceRange.baseMipLevel = dstSubresource.mipLevel;
dstSubresourceRange.levelCount = 1;
dstSubresourceRange.baseArrayLayer = dstSubresource.baseArrayLayer;
dstSubresourceRange.layerCount = dstSubresource.layerCount;
VkImageSubresourceRange srcSubresourceRange;
srcSubresourceRange.aspectMask = srcSubresource.aspectMask;
srcSubresourceRange.baseMipLevel = srcSubresource.mipLevel;
srcSubresourceRange.levelCount = 1;
srcSubresourceRange.baseArrayLayer = srcSubresource.baseArrayLayer;
srcSubresourceRange.layerCount = srcSubresource.layerCount;
// TODO if the entire destination resource
// gets overwritten, discard the contents.
m_barriers.accessImage(
dstImage, dstSubresourceRange,
dstImage->info().layout,
dstImage->info().stages,
dstImage->info().access,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
VK_PIPELINE_STAGE_TRANSFER_BIT,
VK_ACCESS_TRANSFER_WRITE_BIT);
m_barriers.accessImage(
srcImage, srcSubresourceRange,
srcImage->info().layout,
srcImage->info().stages,
srcImage->info().access,
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
VK_PIPELINE_STAGE_TRANSFER_BIT,
VK_ACCESS_TRANSFER_READ_BIT);
m_barriers.recordCommands(m_cmd);
VkImageCopy imageRegion;
imageRegion.srcSubresource = srcSubresource;
imageRegion.srcOffset = srcOffset;
imageRegion.dstSubresource = dstSubresource;
imageRegion.dstOffset = dstOffset;
imageRegion.extent = extent;
m_cmd->cmdCopyImage(
srcImage->handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
dstImage->handle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
1, &imageRegion);
m_barriers.accessImage(
dstImage, dstSubresourceRange,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
VK_PIPELINE_STAGE_TRANSFER_BIT,
VK_ACCESS_TRANSFER_WRITE_BIT,
dstImage->info().layout,
dstImage->info().stages,
dstImage->info().access);
m_barriers.accessImage(
srcImage, srcSubresourceRange,
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
VK_PIPELINE_STAGE_TRANSFER_BIT,
VK_ACCESS_TRANSFER_READ_BIT,
srcImage->info().layout,
srcImage->info().stages,
srcImage->info().access);
m_barriers.recordCommands(m_cmd);
m_cmd->trackResource(dstImage);
m_cmd->trackResource(srcImage);
}
void DxvkContext::dispatch(
uint32_t x,
uint32_t y,

View File

@ -185,6 +185,26 @@ namespace dxvk {
VkDeviceSize srcOffset,
VkDeviceSize numBytes);
/**
* \brief Copies data from one image to another
*
* \param [in] dstImage Destination image
* \param [in] dstSubresource Destination subresource
* \param [in] dstOffset Destination area offset
* \param [in] srcImage Source image
* \param [in] srcSubresource Source subresource
* \param [in] srcOffset Source area offset
* \param [in] extent Size of the area to copy
*/
void copyImage(
const Rc<DxvkImage>& dstImage,
VkImageSubresourceLayers dstSubresource,
VkOffset3D dstOffset,
const Rc<DxvkImage>& srcImage,
VkImageSubresourceLayers srcSubresource,
VkOffset3D srcOffset,
VkExtent3D extent);
/**
* \brief Starts compute jobs
*