mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-01-17 17:52:11 +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;
|
||||
}
|
||||
|
||||
// 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)
|
||||
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
|
||||
// the row pitch and layer pitch properly.
|
||||
const DxvkImageCreateInfo& imageInfo = textureInfo->image->info();
|
||||
@ -294,6 +274,29 @@ namespace dxvk {
|
||||
levelExtent.height / formatInfo->blockSize.height,
|
||||
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.
|
||||
pMappedResource->pData = textureInfo->imageBuffer->mapPtr(0);
|
||||
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(
|
||||
uint32_t x,
|
||||
uint32_t y,
|
||||
|
@ -354,6 +354,13 @@ namespace dxvk {
|
||||
dstImage->info().layout,
|
||||
dstImage->info().stages,
|
||||
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_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(
|
||||
uint32_t x,
|
||||
uint32_t y,
|
||||
|
@ -224,7 +224,27 @@ namespace dxvk {
|
||||
VkImageSubresourceLayers srcSubresource,
|
||||
VkOffset3D srcOffset,
|
||||
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
|
||||
*
|
||||
|
Loading…
x
Reference in New Issue
Block a user