diff --git a/src/dawn_native/d3d12/CommandBufferD3D12.cpp b/src/dawn_native/d3d12/CommandBufferD3D12.cpp index c2a3282330..4771cde080 100644 --- a/src/dawn_native/d3d12/CommandBufferD3D12.cpp +++ b/src/dawn_native/d3d12/CommandBufferD3D12.cpp @@ -163,20 +163,18 @@ namespace dawn_native { namespace d3d12 { TextureViewBase* view = static_cast(mBindings[index][binding]); ToBackend(view->GetTexture()) - ->TrackUsageAndTransitionNow( - commandContext, kReadonlyStorageTexture, - view->GetBaseMipLevel(), view->GetLevelCount(), - view->GetBaseArrayLayer(), view->GetLayerCount()); + ->TrackUsageAndTransitionNow(commandContext, + kReadonlyStorageTexture, + view->GetSubresourceRange()); break; } case wgpu::BindingType::WriteonlyStorageTexture: { TextureViewBase* view = static_cast(mBindings[index][binding]); ToBackend(view->GetTexture()) - ->TrackUsageAndTransitionNow( - commandContext, wgpu::TextureUsage::Storage, - view->GetBaseMipLevel(), view->GetLevelCount(), - view->GetBaseArrayLayer(), view->GetLayerCount()); + ->TrackUsageAndTransitionNow(commandContext, + wgpu::TextureUsage::Storage, + view->GetSubresourceRange()); break; } case wgpu::BindingType::StorageTexture: @@ -435,14 +433,12 @@ namespace dawn_native { namespace d3d12 { Texture* resolveTexture = ToBackend(resolveTarget->GetTexture()); // Transition the usages of the color attachment and resolve target. - colorTexture->TrackUsageAndTransitionNow( - commandContext, D3D12_RESOURCE_STATE_RESOLVE_SOURCE, - colorView->GetBaseMipLevel(), colorView->GetLevelCount(), - colorView->GetBaseArrayLayer(), colorView->GetLayerCount()); - resolveTexture->TrackUsageAndTransitionNow( - commandContext, D3D12_RESOURCE_STATE_RESOLVE_DEST, - resolveTarget->GetBaseMipLevel(), resolveTarget->GetLevelCount(), - resolveTarget->GetBaseArrayLayer(), resolveTarget->GetLayerCount()); + colorTexture->TrackUsageAndTransitionNow(commandContext, + D3D12_RESOURCE_STATE_RESOLVE_SOURCE, + colorView->GetSubresourceRange()); + resolveTexture->TrackUsageAndTransitionNow(commandContext, + D3D12_RESOURCE_STATE_RESOLVE_DEST, + resolveTarget->GetSubresourceRange()); // Do MSAA resolve with ResolveSubResource(). ID3D12Resource* colorTextureHandle = colorTexture->GetD3D12Resource(); @@ -591,8 +587,7 @@ namespace dawn_native { namespace d3d12 { buffer->TrackUsageAndTransitionNow(commandContext, wgpu::BufferUsage::CopySrc); texture->TrackUsageAndTransitionNow(commandContext, wgpu::TextureUsage::CopyDst, - copy->destination.mipLevel, 1, - copy->destination.arrayLayer, 1); + subresource); auto copySplit = ComputeTextureCopySplit( copy->destination.origin, copy->copySize, texture->GetFormat(), @@ -626,13 +621,12 @@ namespace dawn_native { namespace d3d12 { ASSERT(texture->GetDimension() == wgpu::TextureDimension::e2D); ASSERT(copy->copySize.depth == 1); - texture->EnsureSubresourceContentInitialized( - commandContext, SubresourceRange::SingleSubresource( - copy->source.mipLevel, copy->source.arrayLayer)); + SubresourceRange subresource = SubresourceRange::SingleSubresource( + copy->source.mipLevel, copy->source.arrayLayer); + texture->EnsureSubresourceContentInitialized(commandContext, subresource); texture->TrackUsageAndTransitionNow(commandContext, wgpu::TextureUsage::CopySrc, - copy->source.mipLevel, 1, - copy->source.arrayLayer, 1); + subresource); buffer->TrackUsageAndTransitionNow(commandContext, wgpu::BufferUsage::CopyDst); TextureCopySplit copySplit = ComputeTextureCopySplit( @@ -692,12 +686,10 @@ namespace dawn_native { namespace d3d12 { copy->destination.arrayLayer, copy->copySize.depth)); } - source->TrackUsageAndTransitionNow( - commandContext, wgpu::TextureUsage::CopySrc, copy->source.mipLevel, 1, - copy->source.arrayLayer, copy->copySize.depth); - destination->TrackUsageAndTransitionNow( - commandContext, wgpu::TextureUsage::CopyDst, copy->destination.mipLevel, 1, - copy->destination.arrayLayer, copy->copySize.depth); + source->TrackUsageAndTransitionNow(commandContext, wgpu::TextureUsage::CopySrc, + srcRange); + destination->TrackUsageAndTransitionNow(commandContext, + wgpu::TextureUsage::CopyDst, dstRange); if (CanUseCopyResource(source, destination, copy->copySize)) { commandList->CopyResource(destination->GetD3D12Resource(), @@ -886,10 +878,7 @@ namespace dawn_native { namespace d3d12 { resolveDestinationTexture->TrackUsageAndTransitionNow( commandContext, D3D12_RESOURCE_STATE_RESOLVE_DEST, - resolveDestinationView->GetBaseMipLevel(), - resolveDestinationView->GetLevelCount(), - resolveDestinationView->GetBaseArrayLayer(), - resolveDestinationView->GetLayerCount()); + resolveDestinationView->GetSubresourceRange()); renderPassBuilder->SetRenderTargetEndingAccessResolve(i, attachmentInfo.storeOp, view, resolveDestinationView); diff --git a/src/dawn_native/d3d12/TextureD3D12.cpp b/src/dawn_native/d3d12/TextureD3D12.cpp index b2021f8cb6..f9bd2958a1 100644 --- a/src/dawn_native/d3d12/TextureD3D12.cpp +++ b/src/dawn_native/d3d12/TextureD3D12.cpp @@ -549,32 +549,24 @@ namespace dawn_native { namespace d3d12 { void Texture::TrackUsageAndTransitionNow(CommandRecordingContext* commandContext, wgpu::TextureUsage usage, - uint32_t mipLevel, - uint32_t levelCount, - uint32_t arrayLayer, - uint32_t layerCount) { - TrackUsageAndTransitionNow(commandContext, D3D12TextureUsage(usage, GetFormat()), mipLevel, - levelCount, arrayLayer, layerCount); + const SubresourceRange& range) { + TrackUsageAndTransitionNow(commandContext, D3D12TextureUsage(usage, GetFormat()), range); } void Texture::TrackAllUsageAndTransitionNow(CommandRecordingContext* commandContext, wgpu::TextureUsage usage) { - TrackUsageAndTransitionNow(commandContext, D3D12TextureUsage(usage, GetFormat()), 0, - GetNumMipLevels(), 0, GetArrayLayers()); + TrackUsageAndTransitionNow(commandContext, D3D12TextureUsage(usage, GetFormat()), + GetAllSubresources()); } void Texture::TrackAllUsageAndTransitionNow(CommandRecordingContext* commandContext, D3D12_RESOURCE_STATES newState) { - TrackUsageAndTransitionNow(commandContext, newState, 0, GetNumMipLevels(), 0, - GetArrayLayers()); + TrackUsageAndTransitionNow(commandContext, newState, GetAllSubresources()); } void Texture::TrackUsageAndTransitionNow(CommandRecordingContext* commandContext, D3D12_RESOURCE_STATES newState, - uint32_t baseMipLevel, - uint32_t levelCount, - uint32_t baseArrayLayer, - uint32_t layerCount) { + const SubresourceRange& range) { if (mResourceAllocation.GetInfo().mMethod != AllocationMethod::kExternal) { // Track the underlying heap to ensure residency. Heap* heap = ToBackend(mResourceAllocation.GetResourceHeap()); @@ -582,10 +574,9 @@ namespace dawn_native { namespace d3d12 { } std::vector barriers; - barriers.reserve(levelCount * layerCount); + barriers.reserve(range.levelCount * range.layerCount); - TransitionUsageAndGetResourceBarrier(commandContext, &barriers, newState, baseMipLevel, - levelCount, baseArrayLayer, layerCount); + TransitionUsageAndGetResourceBarrier(commandContext, &barriers, newState, range); if (barriers.size()) { commandContext->GetCommandList()->ResourceBarrier(barriers.size(), barriers.data()); } @@ -687,17 +678,14 @@ namespace dawn_native { namespace d3d12 { CommandRecordingContext* commandContext, std::vector* barriers, D3D12_RESOURCE_STATES newState, - uint32_t baseMipLevel, - uint32_t levelCount, - uint32_t baseArrayLayer, - uint32_t layerCount) { + const SubresourceRange& range) { HandleTransitionSpecialCases(commandContext); const Serial pendingCommandSerial = ToBackend(GetDevice())->GetPendingCommandSerial(); - for (uint32_t arrayLayer = 0; arrayLayer < layerCount; ++arrayLayer) { - for (uint32_t mipLevel = 0; mipLevel < levelCount; ++mipLevel) { - uint32_t index = - GetSubresourceIndex(baseMipLevel + mipLevel, baseArrayLayer + arrayLayer); + for (uint32_t arrayLayer = 0; arrayLayer < range.layerCount; ++arrayLayer) { + for (uint32_t mipLevel = 0; mipLevel < range.levelCount; ++mipLevel) { + uint32_t index = GetSubresourceIndex(range.baseMipLevel + mipLevel, + range.baseArrayLayer + arrayLayer); TransitionSingleSubresource(barriers, newState, index, pendingCommandSerial); } @@ -797,9 +785,7 @@ namespace dawn_native { namespace d3d12 { if (GetFormat().isRenderable) { if (GetFormat().HasDepthOrStencil()) { - TrackUsageAndTransitionNow(commandContext, D3D12_RESOURCE_STATE_DEPTH_WRITE, - range.baseMipLevel, range.levelCount, - range.baseArrayLayer, range.layerCount); + TrackUsageAndTransitionNow(commandContext, D3D12_RESOURCE_STATE_DEPTH_WRITE, range); D3D12_CLEAR_FLAGS clearFlags = {}; @@ -836,8 +822,7 @@ namespace dawn_native { namespace d3d12 { } } else { TrackUsageAndTransitionNow(commandContext, D3D12_RESOURCE_STATE_RENDER_TARGET, - range.baseMipLevel, range.levelCount, - range.baseArrayLayer, range.layerCount); + range); const float clearColorRGBA[4] = {fClearColor, fClearColor, fClearColor, fClearColor}; @@ -882,9 +867,7 @@ namespace dawn_native { namespace d3d12 { uploader->Allocate(bufferSize, device->GetPendingCommandSerial())); memset(uploadHandle.mappedBuffer, clearColor, bufferSize); - TrackUsageAndTransitionNow(commandContext, D3D12_RESOURCE_STATE_COPY_DEST, - range.baseMipLevel, range.levelCount, range.baseArrayLayer, - range.layerCount); + TrackUsageAndTransitionNow(commandContext, D3D12_RESOURCE_STATE_COPY_DEST, range); for (uint32_t level = range.baseMipLevel; level < range.baseMipLevel + range.levelCount; ++level) { diff --git a/src/dawn_native/d3d12/TextureD3D12.h b/src/dawn_native/d3d12/TextureD3D12.h index 7def9becfc..e1528360cf 100644 --- a/src/dawn_native/d3d12/TextureD3D12.h +++ b/src/dawn_native/d3d12/TextureD3D12.h @@ -63,16 +63,10 @@ namespace dawn_native { namespace d3d12 { const std::vector& subresourceUsages); void TrackUsageAndTransitionNow(CommandRecordingContext* commandContext, wgpu::TextureUsage usage, - uint32_t baseMipLevel, - uint32_t levelCount, - uint32_t baseArrayLayer, - uint32_t layerCount); + const SubresourceRange& range); void TrackUsageAndTransitionNow(CommandRecordingContext* commandContext, D3D12_RESOURCE_STATES newState, - uint32_t baseMipLevel, - uint32_t levelCount, - uint32_t baseArrayLayer, - uint32_t layerCount); + const SubresourceRange& range); void TrackAllUsageAndTransitionNow(CommandRecordingContext* commandContext, wgpu::TextureUsage usage); void TrackAllUsageAndTransitionNow(CommandRecordingContext* commandContext, @@ -98,10 +92,7 @@ namespace dawn_native { namespace d3d12 { void TransitionUsageAndGetResourceBarrier(CommandRecordingContext* commandContext, std::vector* barrier, D3D12_RESOURCE_STATES newState, - uint32_t baseMipLevel, - uint32_t levelCount, - uint32_t baseArrayLayer, - uint32_t layerCount); + const SubresourceRange& range); void TransitionSingleSubresource(std::vector* barriers, D3D12_RESOURCE_STATES subresourceNewState, diff --git a/src/dawn_native/vulkan/CommandBufferVk.cpp b/src/dawn_native/vulkan/CommandBufferVk.cpp index 460977c8d9..73d6bbcb9d 100644 --- a/src/dawn_native/vulkan/CommandBufferVk.cpp +++ b/src/dawn_native/vulkan/CommandBufferVk.cpp @@ -460,9 +460,7 @@ namespace dawn_native { namespace vulkan { ToBackend(src.buffer) ->TransitionUsageNow(recordingContext, wgpu::BufferUsage::CopySrc); ToBackend(dst.texture) - ->TransitionUsageNow(recordingContext, wgpu::TextureUsage::CopyDst, - subresource.mipLevel, 1, subresource.baseArrayLayer, - 1); + ->TransitionUsageNow(recordingContext, wgpu::TextureUsage::CopyDst, range); VkBuffer srcBuffer = ToBackend(src.buffer)->GetHandle(); VkImage dstImage = ToBackend(dst.texture)->GetHandle(); @@ -485,16 +483,13 @@ namespace dawn_native { namespace vulkan { ASSERT(src.texture->GetDimension() == wgpu::TextureDimension::e2D); ASSERT(copy->copySize.depth == 1); + SubresourceRange range = SubresourceRange::SingleSubresource( + subresource.mipLevel, subresource.baseArrayLayer); ToBackend(src.texture) - ->EnsureSubresourceContentInitialized( - recordingContext, - SubresourceRange::SingleSubresource(subresource.mipLevel, - subresource.baseArrayLayer)); + ->EnsureSubresourceContentInitialized(recordingContext, range); ToBackend(src.texture) - ->TransitionUsageNow(recordingContext, wgpu::TextureUsage::CopySrc, - subresource.mipLevel, 1, subresource.baseArrayLayer, - 1); + ->TransitionUsageNow(recordingContext, wgpu::TextureUsage::CopySrc, range); ToBackend(dst.buffer) ->TransitionUsageNow(recordingContext, wgpu::BufferUsage::CopyDst); @@ -538,10 +533,10 @@ namespace dawn_native { namespace vulkan { ToBackend(src.texture) ->TransitionUsageNow(recordingContext, wgpu::TextureUsage::CopySrc, - src.mipLevel, 1, src.arrayLayer, copy->copySize.depth); + srcRange); ToBackend(dst.texture) ->TransitionUsageNow(recordingContext, wgpu::TextureUsage::CopyDst, - dst.mipLevel, 1, dst.arrayLayer, copy->copySize.depth); + dstRange); // In some situations we cannot do texture-to-texture copies with vkCmdCopyImage // because as Vulkan SPEC always validates image copies with the virtual size of diff --git a/src/dawn_native/vulkan/TextureVk.cpp b/src/dawn_native/vulkan/TextureVk.cpp index 7b35f14471..110d618f91 100644 --- a/src/dawn_native/vulkan/TextureVk.cpp +++ b/src/dawn_native/vulkan/TextureVk.cpp @@ -213,10 +213,7 @@ namespace dawn_native { namespace vulkan { const VkImage& image, wgpu::TextureUsage lastUsage, wgpu::TextureUsage usage, - uint32_t baseMipLevel, - uint32_t levelCount, - uint32_t baseArrayLayer, - uint32_t layerCount) { + const SubresourceRange& range) { VkImageMemoryBarrier barrier; barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; barrier.pNext = nullptr; @@ -226,10 +223,10 @@ namespace dawn_native { namespace vulkan { barrier.newLayout = VulkanImageLayout(usage, format); barrier.image = image; barrier.subresourceRange.aspectMask = VulkanAspectMask(format); - barrier.subresourceRange.baseMipLevel = baseMipLevel; - barrier.subresourceRange.levelCount = levelCount; - barrier.subresourceRange.baseArrayLayer = baseArrayLayer; - barrier.subresourceRange.layerCount = layerCount; + barrier.subresourceRange.baseMipLevel = range.baseMipLevel; + barrier.subresourceRange.levelCount = range.levelCount; + barrier.subresourceRange.baseArrayLayer = range.baseArrayLayer; + barrier.subresourceRange.layerCount = range.layerCount; barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; @@ -682,9 +679,9 @@ namespace dawn_native { namespace vulkan { if (mExternalState == ExternalState::PendingAcquire) { if (barriers->size() == transitionBarrierStart) { - barriers->push_back(BuildMemoryBarrier(GetFormat(), mHandle, - wgpu::TextureUsage::None, - wgpu::TextureUsage::None, 0, 1, 0, 1)); + barriers->push_back(BuildMemoryBarrier( + GetFormat(), mHandle, wgpu::TextureUsage::None, wgpu::TextureUsage::None, + SubresourceRange::SingleSubresource(0, 0))); } // Transfer texture from external queue to graphics queue @@ -696,9 +693,9 @@ namespace dawn_native { namespace vulkan { mExternalState = ExternalState::Acquired; } else if (mExternalState == ExternalState::PendingRelease) { if (barriers->size() == transitionBarrierStart) { - barriers->push_back(BuildMemoryBarrier(GetFormat(), mHandle, - wgpu::TextureUsage::None, - wgpu::TextureUsage::None, 0, 1, 0, 1)); + barriers->push_back(BuildMemoryBarrier( + GetFormat(), mHandle, wgpu::TextureUsage::None, wgpu::TextureUsage::None, + SubresourceRange::SingleSubresource(0, 0))); } // Transfer texture from graphics queue to external queue @@ -727,7 +724,7 @@ namespace dawn_native { namespace vulkan { void Texture::TransitionFullUsage(CommandRecordingContext* recordingContext, wgpu::TextureUsage usage) { - TransitionUsageNow(recordingContext, usage, 0, GetNumMipLevels(), 0, GetArrayLayers()); + TransitionUsageNow(recordingContext, usage, GetAllSubresources()); } void Texture::TransitionUsageForPass(CommandRecordingContext* recordingContext, @@ -756,8 +753,7 @@ namespace dawn_native { namespace vulkan { } imageBarriers->push_back(BuildMemoryBarrier(format, mHandle, mSubresourceLastUsages[0], - textureUsages.usage, 0, GetNumMipLevels(), - 0, GetArrayLayers())); + textureUsages.usage, GetAllSubresources())); allLastUsages = mSubresourceLastUsages[0]; allUsages = textureUsages.usage; for (uint32_t i = 0; i < subresourceCount; ++i) { @@ -779,7 +775,8 @@ namespace dawn_native { namespace vulkan { } imageBarriers->push_back(BuildMemoryBarrier( format, mHandle, mSubresourceLastUsages[index], - textureUsages.subresourceUsages[index], mipLevel, 1, arrayLayer, 1)); + textureUsages.subresourceUsages[index], + SubresourceRange::SingleSubresource(mipLevel, arrayLayer))); allLastUsages |= mSubresourceLastUsages[index]; allUsages |= textureUsages.subresourceUsages[index]; mSubresourceLastUsages[index] = textureUsages.subresourceUsages[index]; @@ -799,10 +796,7 @@ namespace dawn_native { namespace vulkan { void Texture::TransitionUsageNow(CommandRecordingContext* recordingContext, wgpu::TextureUsage usage, - uint32_t baseMipLevel, - uint32_t levelCount, - uint32_t baseArrayLayer, - uint32_t layerCount) { + const SubresourceRange& range) { std::vector barriers; const Format& format = GetFormat(); @@ -816,29 +810,32 @@ namespace dawn_native { namespace vulkan { // are the same, then we can use one barrier to do state transition for all subresources. // Note that if the texture has only one mip level and one array slice, it will fall into // this category. - bool isAllSubresourcesCovered = levelCount * layerCount == subresourceCount; + bool isAllSubresourcesCovered = range.levelCount * range.layerCount == subresourceCount; if (mSameLastUsagesAcrossSubresources && isAllSubresourcesCovered) { - ASSERT(baseMipLevel == 0 && baseArrayLayer == 0); + ASSERT(range.baseMipLevel == 0 && range.baseArrayLayer == 0); if (CanReuseWithoutBarrier(mSubresourceLastUsages[0], usage)) { return; } - barriers.push_back(BuildMemoryBarrier(format, mHandle, mSubresourceLastUsages[0], usage, - 0, levelCount, 0, layerCount)); + barriers.push_back( + BuildMemoryBarrier(format, mHandle, mSubresourceLastUsages[0], usage, range)); allLastUsages = mSubresourceLastUsages[0]; for (uint32_t i = 0; i < subresourceCount; ++i) { mSubresourceLastUsages[i] = usage; } } else { - for (uint32_t layer = baseArrayLayer; layer < baseArrayLayer + layerCount; ++layer) { - for (uint32_t level = baseMipLevel; level < baseMipLevel + levelCount; ++level) { + for (uint32_t layer = range.baseArrayLayer; + layer < range.baseArrayLayer + range.layerCount; ++layer) { + for (uint32_t level = range.baseMipLevel; + level < range.baseMipLevel + range.levelCount; ++level) { uint32_t index = GetSubresourceIndex(level, layer); if (CanReuseWithoutBarrier(mSubresourceLastUsages[index], usage)) { continue; } - barriers.push_back(BuildMemoryBarrier( - format, mHandle, mSubresourceLastUsages[index], usage, level, 1, layer, 1)); + barriers.push_back( + BuildMemoryBarrier(format, mHandle, mSubresourceLastUsages[index], usage, + SubresourceRange::SingleSubresource(level, layer))); allLastUsages |= mSubresourceLastUsages[index]; mSubresourceLastUsages[index] = usage; } @@ -866,8 +863,7 @@ namespace dawn_native { namespace vulkan { uint8_t clearColor = (clearValue == TextureBase::ClearValue::Zero) ? 0 : 1; float fClearColor = (clearValue == TextureBase::ClearValue::Zero) ? 0.f : 1.f; - TransitionUsageNow(recordingContext, wgpu::TextureUsage::CopyDst, range.baseMipLevel, - range.levelCount, range.baseArrayLayer, range.layerCount); + TransitionUsageNow(recordingContext, wgpu::TextureUsage::CopyDst, range); if (GetFormat().isRenderable) { VkImageSubresourceRange imageRange = {}; imageRange.aspectMask = GetVkAspectMask(); diff --git a/src/dawn_native/vulkan/TextureVk.h b/src/dawn_native/vulkan/TextureVk.h index 4da7c489d1..8a1564af72 100644 --- a/src/dawn_native/vulkan/TextureVk.h +++ b/src/dawn_native/vulkan/TextureVk.h @@ -69,10 +69,7 @@ namespace dawn_native { namespace vulkan { void TransitionUsageNow(CommandRecordingContext* recordingContext, wgpu::TextureUsage usage, - uint32_t baseMipLevel, - uint32_t levelCount, - uint32_t baseArrayLayer, - uint32_t layerCount); + const SubresourceRange& range); void TransitionUsageForPass(CommandRecordingContext* recordingContext, const PassTextureUsage& textureUsages, std::vector* imageBarriers,