mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-01-29 17:52:18 +01:00
[d3d11] Implemented image mapping for reads
This commit is contained in:
parent
0bb98eb03e
commit
2a364c557b
@ -254,29 +254,9 @@ namespace dxvk {
|
|||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME copy current image contents into the
|
|
||||||
// buffer unless D3D11_MAP_DISCARD is used.
|
|
||||||
if (MapType == D3D11_MAP_READ || MapType == D3D11_MAP_READ_WRITE) {
|
|
||||||
Logger::err("D3D11DeviceContext: Read-only and Read-Write mapping of images currently not supported");
|
|
||||||
return E_INVALIDARG;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pMappedResource == nullptr)
|
if (pMappedResource == nullptr)
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
|
|
||||||
if (textureInfo->imageBuffer->isInUse()) {
|
|
||||||
// Don't wait if the application tells us not to
|
|
||||||
if (MapFlags & D3D11_MAP_FLAG_DO_NOT_WAIT)
|
|
||||||
return DXGI_ERROR_WAS_STILL_DRAWING;
|
|
||||||
|
|
||||||
if (MapType == D3D11_MAP_WRITE_DISCARD) {
|
|
||||||
m_context->invalidateBuffer(textureInfo->imageBuffer);
|
|
||||||
} else if (MapType != D3D11_MAP_WRITE_NO_OVERWRITE) {
|
|
||||||
this->Flush();
|
|
||||||
this->Synchronize();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Query format and subresource in order to compute
|
// Query format and subresource in order to compute
|
||||||
// the row pitch and layer pitch properly.
|
// the row pitch and layer pitch properly.
|
||||||
const DxvkImageCreateInfo& imageInfo = textureInfo->image->info();
|
const DxvkImageCreateInfo& imageInfo = textureInfo->image->info();
|
||||||
@ -294,6 +274,29 @@ namespace dxvk {
|
|||||||
levelExtent.height / formatInfo->blockSize.height,
|
levelExtent.height / formatInfo->blockSize.height,
|
||||||
levelExtent.depth / formatInfo->blockSize.depth };
|
levelExtent.depth / formatInfo->blockSize.depth };
|
||||||
|
|
||||||
|
// When using any map mode which requires the image contents
|
||||||
|
// to be preserved, copy image contents into the buffer.
|
||||||
|
if (MapType != D3D11_MAP_WRITE_DISCARD) {
|
||||||
|
const VkImageSubresourceLayers subresourceLayers = {
|
||||||
|
textureInfo->mappedSubresource.aspectMask,
|
||||||
|
textureInfo->mappedSubresource.mipLevel,
|
||||||
|
textureInfo->mappedSubresource.arrayLayer, 1 };
|
||||||
|
|
||||||
|
m_context->copyImageToBuffer(
|
||||||
|
textureInfo->imageBuffer, 0, { 0u, 0u },
|
||||||
|
textureInfo->image, subresourceLayers,
|
||||||
|
VkOffset3D { 0, 0, 0 }, levelExtent);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (textureInfo->imageBuffer->isInUse()) {
|
||||||
|
if (MapType == D3D11_MAP_WRITE_DISCARD) {
|
||||||
|
m_context->invalidateBuffer(textureInfo->imageBuffer);
|
||||||
|
} else {
|
||||||
|
this->Flush();
|
||||||
|
this->Synchronize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Set up map pointer. Data is tightly packed within the mapped buffer.
|
// Set up map pointer. Data is tightly packed within the mapped buffer.
|
||||||
pMappedResource->pData = textureInfo->imageBuffer->mapPtr(0);
|
pMappedResource->pData = textureInfo->imageBuffer->mapPtr(0);
|
||||||
pMappedResource->RowPitch = formatInfo->elementSize * blockCount.width;
|
pMappedResource->RowPitch = formatInfo->elementSize * blockCount.width;
|
||||||
|
@ -213,6 +213,18 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void cmdCopyImageToBuffer(
|
||||||
|
VkImage srcImage,
|
||||||
|
VkImageLayout srcImageLayout,
|
||||||
|
VkBuffer dstBuffer,
|
||||||
|
uint32_t regionCount,
|
||||||
|
const VkBufferImageCopy* pRegions) {
|
||||||
|
m_vkd->vkCmdCopyImageToBuffer(m_buffer,
|
||||||
|
srcImage, srcImageLayout, dstBuffer,
|
||||||
|
regionCount, pRegions);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void cmdDispatch(
|
void cmdDispatch(
|
||||||
uint32_t x,
|
uint32_t x,
|
||||||
uint32_t y,
|
uint32_t y,
|
||||||
|
@ -354,6 +354,13 @@ namespace dxvk {
|
|||||||
dstImage->info().layout,
|
dstImage->info().layout,
|
||||||
dstImage->info().stages,
|
dstImage->info().stages,
|
||||||
dstImage->info().access);
|
dstImage->info().access);
|
||||||
|
|
||||||
|
m_barriers.accessBuffer(srcSlice,
|
||||||
|
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||||
|
VK_ACCESS_TRANSFER_READ_BIT,
|
||||||
|
srcBuffer->info().stages,
|
||||||
|
srcBuffer->info().access);
|
||||||
|
|
||||||
m_barriers.recordCommands(m_cmd);
|
m_barriers.recordCommands(m_cmd);
|
||||||
|
|
||||||
m_cmd->trackResource(dstImage);
|
m_cmd->trackResource(dstImage);
|
||||||
@ -442,6 +449,70 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DxvkContext::copyImageToBuffer(
|
||||||
|
const Rc<DxvkBuffer>& dstBuffer,
|
||||||
|
VkDeviceSize dstOffset,
|
||||||
|
VkExtent2D dstExtent,
|
||||||
|
const Rc<DxvkImage>& srcImage,
|
||||||
|
VkImageSubresourceLayers srcSubresource,
|
||||||
|
VkOffset3D srcOffset,
|
||||||
|
VkExtent3D srcExtent) {
|
||||||
|
this->renderPassEnd();
|
||||||
|
|
||||||
|
auto dstSlice = dstBuffer->subSlice(dstOffset, 0);
|
||||||
|
|
||||||
|
const VkImageSubresourceRange srcSubresourceRange = {
|
||||||
|
srcSubresource.aspectMask,
|
||||||
|
srcSubresource.mipLevel, 1,
|
||||||
|
srcSubresource.baseArrayLayer,
|
||||||
|
srcSubresource.layerCount };
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
VkBufferImageCopy copyRegion;
|
||||||
|
copyRegion.bufferOffset = dstSlice.offset();
|
||||||
|
copyRegion.bufferRowLength = dstExtent.width;
|
||||||
|
copyRegion.bufferImageHeight = dstExtent.height;
|
||||||
|
copyRegion.imageSubresource = srcSubresource;
|
||||||
|
copyRegion.imageOffset = srcOffset;
|
||||||
|
copyRegion.imageExtent = srcExtent;
|
||||||
|
|
||||||
|
m_cmd->cmdCopyImageToBuffer(
|
||||||
|
srcImage->handle(),
|
||||||
|
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
|
||||||
|
dstSlice.handle(),
|
||||||
|
1, ©Region);
|
||||||
|
|
||||||
|
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.accessBuffer(dstSlice,
|
||||||
|
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||||
|
VK_ACCESS_TRANSFER_WRITE_BIT,
|
||||||
|
dstBuffer->info().stages,
|
||||||
|
dstBuffer->info().access);
|
||||||
|
|
||||||
|
m_barriers.recordCommands(m_cmd);
|
||||||
|
|
||||||
|
m_cmd->trackResource(srcImage);
|
||||||
|
m_cmd->trackResource(dstSlice.resource());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void DxvkContext::dispatch(
|
void DxvkContext::dispatch(
|
||||||
uint32_t x,
|
uint32_t x,
|
||||||
uint32_t y,
|
uint32_t y,
|
||||||
|
@ -224,7 +224,27 @@ namespace dxvk {
|
|||||||
VkImageSubresourceLayers srcSubresource,
|
VkImageSubresourceLayers srcSubresource,
|
||||||
VkOffset3D srcOffset,
|
VkOffset3D srcOffset,
|
||||||
VkExtent3D extent);
|
VkExtent3D extent);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Copies data from an image into a buffer
|
||||||
|
*
|
||||||
|
* \param [in] dstBuffer Destination buffer
|
||||||
|
* \param [in] dstOffset Destination offset, in bytes
|
||||||
|
* \param [in] dstExtent Destination data extent
|
||||||
|
* \param [in] srcImage Source image
|
||||||
|
* \param [in] srcSubresource Source subresource
|
||||||
|
* \param [in] srcOffset Source area offset
|
||||||
|
* \param [in] srcExtent Source area size
|
||||||
|
*/
|
||||||
|
void copyImageToBuffer(
|
||||||
|
const Rc<DxvkBuffer>& dstBuffer,
|
||||||
|
VkDeviceSize dstOffset,
|
||||||
|
VkExtent2D dstExtent,
|
||||||
|
const Rc<DxvkImage>& srcImage,
|
||||||
|
VkImageSubresourceLayers srcSubresource,
|
||||||
|
VkOffset3D srcOffset,
|
||||||
|
VkExtent3D srcExtent);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Starts compute jobs
|
* \brief Starts compute jobs
|
||||||
*
|
*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user