Fix texture copy into staging one on DX12 and Vulkan
This commit is contained in:
@@ -42,18 +42,18 @@ inline bool operator!=(const D3D12_INDEX_BUFFER_VIEW& l, const D3D12_INDEX_BUFFE
|
||||
// Ensure to match the indirect commands arguments layout
|
||||
static_assert(sizeof(GPUDispatchIndirectArgs) == sizeof(D3D12_DISPATCH_ARGUMENTS), "Wrong size of GPUDrawIndirectArgs.");
|
||||
static_assert(OFFSET_OF(GPUDispatchIndirectArgs, ThreadGroupCountX) == OFFSET_OF(D3D12_DISPATCH_ARGUMENTS, ThreadGroupCountX), "Wrong offset for GPUDrawIndirectArgs::ThreadGroupCountX");
|
||||
static_assert(OFFSET_OF(GPUDispatchIndirectArgs, ThreadGroupCountY) == OFFSET_OF(D3D12_DISPATCH_ARGUMENTS, ThreadGroupCountY),"Wrong offset for GPUDrawIndirectArgs::ThreadGroupCountY");
|
||||
static_assert(OFFSET_OF(GPUDispatchIndirectArgs, ThreadGroupCountY) == OFFSET_OF(D3D12_DISPATCH_ARGUMENTS, ThreadGroupCountY), "Wrong offset for GPUDrawIndirectArgs::ThreadGroupCountY");
|
||||
static_assert(OFFSET_OF(GPUDispatchIndirectArgs, ThreadGroupCountZ) == OFFSET_OF(D3D12_DISPATCH_ARGUMENTS, ThreadGroupCountZ), "Wrong offset for GPUDrawIndirectArgs::ThreadGroupCountZ");
|
||||
//
|
||||
static_assert(sizeof(GPUDrawIndirectArgs) == sizeof(D3D12_DRAW_ARGUMENTS), "Wrong size of GPUDrawIndirectArgs.");
|
||||
static_assert(OFFSET_OF(GPUDrawIndirectArgs, VerticesCount) == OFFSET_OF(D3D12_DRAW_ARGUMENTS, VertexCountPerInstance), "Wrong offset for GPUDrawIndirectArgs::VerticesCount");
|
||||
static_assert(OFFSET_OF(GPUDrawIndirectArgs, InstanceCount) == OFFSET_OF(D3D12_DRAW_ARGUMENTS, InstanceCount),"Wrong offset for GPUDrawIndirectArgs::InstanceCount");
|
||||
static_assert(OFFSET_OF(GPUDrawIndirectArgs, InstanceCount) == OFFSET_OF(D3D12_DRAW_ARGUMENTS, InstanceCount), "Wrong offset for GPUDrawIndirectArgs::InstanceCount");
|
||||
static_assert(OFFSET_OF(GPUDrawIndirectArgs, StartVertex) == OFFSET_OF(D3D12_DRAW_ARGUMENTS, StartVertexLocation), "Wrong offset for GPUDrawIndirectArgs::StartVertex");
|
||||
static_assert(OFFSET_OF(GPUDrawIndirectArgs, StartInstance) == OFFSET_OF(D3D12_DRAW_ARGUMENTS, StartInstanceLocation), "Wrong offset for GPUDrawIndirectArgs::StartInstance");
|
||||
//
|
||||
static_assert(sizeof(GPUDrawIndexedIndirectArgs) == sizeof(D3D12_DRAW_INDEXED_ARGUMENTS), "Wrong size of GPUDrawIndexedIndirectArgs.");
|
||||
static_assert(OFFSET_OF(GPUDrawIndexedIndirectArgs, IndicesCount) == OFFSET_OF(D3D12_DRAW_INDEXED_ARGUMENTS, IndexCountPerInstance), "Wrong offset for GPUDrawIndexedIndirectArgs::IndicesCount");
|
||||
static_assert(OFFSET_OF(GPUDrawIndexedIndirectArgs, InstanceCount) == OFFSET_OF(D3D12_DRAW_INDEXED_ARGUMENTS, InstanceCount),"Wrong offset for GPUDrawIndexedIndirectArgs::InstanceCount");
|
||||
static_assert(OFFSET_OF(GPUDrawIndexedIndirectArgs, InstanceCount) == OFFSET_OF(D3D12_DRAW_INDEXED_ARGUMENTS, InstanceCount), "Wrong offset for GPUDrawIndexedIndirectArgs::InstanceCount");
|
||||
static_assert(OFFSET_OF(GPUDrawIndexedIndirectArgs, StartIndex) == OFFSET_OF(D3D12_DRAW_INDEXED_ARGUMENTS, StartIndexLocation), "Wrong offset for GPUDrawIndexedIndirectArgs::StartIndex");
|
||||
static_assert(OFFSET_OF(GPUDrawIndexedIndirectArgs, StartVertex) == OFFSET_OF(D3D12_DRAW_INDEXED_ARGUMENTS, BaseVertexLocation), "Wrong offset for GPUDrawIndexedIndirectArgs::StartVertex");
|
||||
static_assert(OFFSET_OF(GPUDrawIndexedIndirectArgs, StartInstance) == OFFSET_OF(D3D12_DRAW_INDEXED_ARGUMENTS, StartInstanceLocation), "Wrong offset for GPUDrawIndexedIndirectArgs::StartInstance");
|
||||
@@ -1259,8 +1259,23 @@ void GPUContextDX12::CopyTexture(GPUTexture* dstResource, uint32 dstSubresource,
|
||||
// Get destination copy location
|
||||
D3D12_TEXTURE_COPY_LOCATION dst;
|
||||
dst.pResource = dstTextureDX12->GetResource();
|
||||
dst.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
|
||||
dst.SubresourceIndex = dstSubresource;
|
||||
if (dstTextureDX12->IsStaging())
|
||||
{
|
||||
const int32 mipLevel = (int32)dstSubresource % dstTextureDX12->MipLevels();
|
||||
const int32 copyOffset = dstTextureDX12->ComputeBufferOffset((int32)dstSubresource, D3D12_TEXTURE_DATA_PITCH_ALIGNMENT, D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT);
|
||||
dst.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT;
|
||||
dst.PlacedFootprint.Offset = copyOffset;
|
||||
dst.PlacedFootprint.Footprint.Width = dstTextureDX12->CalculateMipSize(dstTextureDX12->Width(), mipLevel);
|
||||
dst.PlacedFootprint.Footprint.Height = dstTextureDX12->CalculateMipSize(dstTextureDX12->Height(), mipLevel);
|
||||
dst.PlacedFootprint.Footprint.Depth = dstTextureDX12->CalculateMipSize(dstTextureDX12->Depth(), mipLevel);
|
||||
dst.PlacedFootprint.Footprint.Format = RenderToolsDX::ToDxgiFormat(dstTextureDX12->Format());
|
||||
dst.PlacedFootprint.Footprint.RowPitch = dstTextureDX12->ComputeRowPitch(mipLevel, D3D12_TEXTURE_DATA_PITCH_ALIGNMENT);
|
||||
}
|
||||
else
|
||||
{
|
||||
dst.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
|
||||
dst.SubresourceIndex = dstSubresource;
|
||||
}
|
||||
|
||||
// Get source copy location
|
||||
D3D12_TEXTURE_COPY_LOCATION src;
|
||||
@@ -1455,7 +1470,7 @@ void GPUContextDX12::ForceRebindDescriptors()
|
||||
_commandList->SetComputeRootSignature(_device->GetRootSignature());
|
||||
|
||||
// Bind heaps
|
||||
ID3D12DescriptorHeap* ppHeaps[] = {_device->RingHeap_CBV_SRV_UAV.GetHeap(), _device->RingHeap_Sampler.GetHeap()};
|
||||
ID3D12DescriptorHeap* ppHeaps[] = { _device->RingHeap_CBV_SRV_UAV.GetHeap(), _device->RingHeap_Sampler.GetHeap() };
|
||||
_commandList->SetDescriptorHeaps(ARRAY_COUNT(ppHeaps), ppHeaps);
|
||||
}
|
||||
|
||||
|
||||
@@ -1311,10 +1311,6 @@ void GPUContextVulkan::UpdateBuffer(GPUBuffer* buffer, const void* data, uint32
|
||||
|
||||
// Use direct update for small buffers
|
||||
const uint32 alignedSize = Math::AlignUp<uint32>(size, 4);
|
||||
if (alignedSize > buffer->GetSize())
|
||||
{
|
||||
int a= 1;
|
||||
}
|
||||
if (size <= 16 * 1024 && alignedSize <= buffer->GetSize())
|
||||
{
|
||||
//AddBufferBarrier(bufferVulkan, VK_ACCESS_TRANSFER_WRITE_BIT);
|
||||
@@ -1413,37 +1409,77 @@ void GPUContextVulkan::CopyTexture(GPUTexture* dstResource, uint32 dstSubresourc
|
||||
const auto dstTextureVulkan = static_cast<GPUTextureVulkan*>(dstResource);
|
||||
const auto srcTextureVulkan = static_cast<GPUTextureVulkan*>(srcResource);
|
||||
|
||||
// Transition resources
|
||||
AddImageBarrier(dstTextureVulkan, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
||||
AddImageBarrier(srcTextureVulkan, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
|
||||
FlushBarriers();
|
||||
|
||||
// Prepare
|
||||
const int32 dstMipIndex = dstSubresource % dstTextureVulkan->MipLevels();
|
||||
const int32 dstArrayIndex = dstSubresource / dstTextureVulkan->MipLevels();
|
||||
const int32 srcMipIndex = srcSubresource % srcTextureVulkan->MipLevels();
|
||||
const int32 srcArrayIndex = srcSubresource / srcTextureVulkan->MipLevels();
|
||||
const int32 dstMipIndex = (int32)dstSubresource % dstTextureVulkan->MipLevels();
|
||||
const int32 dstArrayIndex = (int32)dstSubresource / dstTextureVulkan->MipLevels();
|
||||
const int32 srcMipIndex = (int32)srcSubresource % srcTextureVulkan->MipLevels();
|
||||
const int32 srcArrayIndex = (int32)srcSubresource / srcTextureVulkan->MipLevels();
|
||||
int32 mipWidth, mipHeight, mipDepth;
|
||||
srcTextureVulkan->GetMipSize(srcMipIndex, mipWidth, mipHeight, mipDepth);
|
||||
|
||||
// Copy
|
||||
VkImageCopy region;
|
||||
Platform::MemoryClear(®ion, sizeof(VkBufferImageCopy));
|
||||
region.extent.width = mipWidth;
|
||||
region.extent.height = mipHeight;
|
||||
region.extent.depth = mipDepth;
|
||||
region.dstOffset.x = dstX;
|
||||
region.dstOffset.y = dstY;
|
||||
region.dstOffset.z = dstZ;
|
||||
region.srcSubresource.baseArrayLayer = srcArrayIndex;
|
||||
region.srcSubresource.layerCount = 1;
|
||||
region.srcSubresource.mipLevel = srcMipIndex;
|
||||
region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
region.dstSubresource.baseArrayLayer = dstArrayIndex;
|
||||
region.dstSubresource.layerCount = 1;
|
||||
region.dstSubresource.mipLevel = dstMipIndex;
|
||||
region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
vkCmdCopyImage(cmdBuffer->GetHandle(), srcTextureVulkan->GetHandle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dstTextureVulkan->GetHandle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion);
|
||||
if (dstTextureVulkan->IsStaging())
|
||||
{
|
||||
// Staging Texture -> Staging Texture
|
||||
if (srcTextureVulkan->IsStaging())
|
||||
{
|
||||
ASSERT(dstTextureVulkan->StagingBuffer && srcTextureVulkan->StagingBuffer);
|
||||
CopyResource(dstTextureVulkan->StagingBuffer, srcTextureVulkan->StagingBuffer);
|
||||
}
|
||||
// Texture -> Staging Texture
|
||||
else
|
||||
{
|
||||
// Transition resources
|
||||
ASSERT(dstTextureVulkan->StagingBuffer);
|
||||
AddBufferBarrier(dstTextureVulkan->StagingBuffer, VK_ACCESS_TRANSFER_WRITE_BIT);
|
||||
AddImageBarrier(srcTextureVulkan, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
|
||||
FlushBarriers();
|
||||
|
||||
// Copy
|
||||
VkBufferImageCopy region;
|
||||
Platform::MemoryClear(®ion, sizeof(VkBufferImageCopy));
|
||||
region.bufferOffset = 0; // TODO: calculate it based on dstSubresource and dstX/dstY/dstZ
|
||||
ASSERT(dstX == dstY == dstZ == 0);
|
||||
ASSERT(dstSubresource == 0);
|
||||
region.bufferRowLength = mipWidth;
|
||||
region.bufferImageHeight = mipHeight;
|
||||
region.imageOffset.x = 0;
|
||||
region.imageOffset.y = 0;
|
||||
region.imageOffset.z = 0;
|
||||
region.imageExtent.width = mipWidth;
|
||||
region.imageExtent.height = mipHeight;
|
||||
region.imageExtent.depth = mipDepth;
|
||||
region.imageSubresource.baseArrayLayer = srcArrayIndex;
|
||||
region.imageSubresource.layerCount = 1;
|
||||
region.imageSubresource.mipLevel = srcMipIndex;
|
||||
region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
vkCmdCopyImageToBuffer(cmdBuffer->GetHandle(), srcTextureVulkan->GetHandle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dstTextureVulkan->StagingBuffer->GetHandle(), 1, ®ion);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Transition resources
|
||||
AddImageBarrier(dstTextureVulkan, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
||||
AddImageBarrier(srcTextureVulkan, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
|
||||
FlushBarriers();
|
||||
|
||||
// Copy
|
||||
VkImageCopy region;
|
||||
Platform::MemoryClear(®ion, sizeof(VkBufferImageCopy));
|
||||
region.extent.width = mipWidth;
|
||||
region.extent.height = mipHeight;
|
||||
region.extent.depth = mipDepth;
|
||||
region.dstOffset.x = (int32_t)dstX;
|
||||
region.dstOffset.y = (int32_t)dstY;
|
||||
region.dstOffset.z = (int32_t)dstZ;
|
||||
region.srcSubresource.baseArrayLayer = srcArrayIndex;
|
||||
region.srcSubresource.layerCount = 1;
|
||||
region.srcSubresource.mipLevel = srcMipIndex;
|
||||
region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
region.dstSubresource.baseArrayLayer = dstArrayIndex;
|
||||
region.dstSubresource.layerCount = 1;
|
||||
region.dstSubresource.mipLevel = dstMipIndex;
|
||||
region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
vkCmdCopyImage(cmdBuffer->GetHandle(), srcTextureVulkan->GetHandle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dstTextureVulkan->GetHandle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion);
|
||||
}
|
||||
}
|
||||
|
||||
void GPUContextVulkan::ResetCounter(GPUBuffer* buffer)
|
||||
|
||||
@@ -235,6 +235,7 @@ bool GPUTextureVulkan::OnInit()
|
||||
return true;
|
||||
}
|
||||
_memoryUsage = 1;
|
||||
initResource(VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, _desc.MipLevels, _desc.ArraySize, false);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user