diff --git a/Source/Engine/GraphicsDevice/DirectX/DX12/GPUContextDX12.cpp b/Source/Engine/GraphicsDevice/DirectX/DX12/GPUContextDX12.cpp index 2eb143857..970e55ce5 100644 --- a/Source/Engine/GraphicsDevice/DirectX/DX12/GPUContextDX12.cpp +++ b/Source/Engine/GraphicsDevice/DirectX/DX12/GPUContextDX12.cpp @@ -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); } diff --git a/Source/Engine/GraphicsDevice/Vulkan/GPUContextVulkan.cpp b/Source/Engine/GraphicsDevice/Vulkan/GPUContextVulkan.cpp index 38ef0eb68..5023bb21f 100644 --- a/Source/Engine/GraphicsDevice/Vulkan/GPUContextVulkan.cpp +++ b/Source/Engine/GraphicsDevice/Vulkan/GPUContextVulkan.cpp @@ -1311,10 +1311,6 @@ void GPUContextVulkan::UpdateBuffer(GPUBuffer* buffer, const void* data, uint32 // Use direct update for small buffers const uint32 alignedSize = Math::AlignUp(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(dstResource); const auto srcTextureVulkan = static_cast(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) diff --git a/Source/Engine/GraphicsDevice/Vulkan/GPUTextureVulkan.cpp b/Source/Engine/GraphicsDevice/Vulkan/GPUTextureVulkan.cpp index ad7b35c9e..62c0418dc 100644 --- a/Source/Engine/GraphicsDevice/Vulkan/GPUTextureVulkan.cpp +++ b/Source/Engine/GraphicsDevice/Vulkan/GPUTextureVulkan.cpp @@ -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; }