Refactor subresource related variables to a struct

This patch put subresource related variables like baseMipLevel,
levelCount, baseArrayLayer, layerCount into a single struct at
front-end. We have a lot more at backend too, a following patch
will do that.

Bug: dawn:157

Change-Id: Iab5633a4246b6ae89b80c39f5672dbb31d7a3e78
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/22704
Reviewed-by: Kai Ninomiya <kainino@chromium.org>
Commit-Queue: Yunchao He <yunchao.he@intel.com>
This commit is contained in:
Yunchao He 2020-06-12 00:37:31 +00:00 committed by Commit Bot service account
parent c7778a27cb
commit 5fafb49c7b
16 changed files with 275 additions and 305 deletions

View File

@ -59,11 +59,11 @@ namespace dawn_native {
ASSERT(view->GetLayerCount() == 1); ASSERT(view->GetLayerCount() == 1);
ASSERT(view->GetLevelCount() == 1); ASSERT(view->GetLevelCount() == 1);
SubresourceRange range = view->GetSubresourceRange();
// If the loadOp is Load, but the subresource is not initialized, use Clear instead. // If the loadOp is Load, but the subresource is not initialized, use Clear instead.
if (attachmentInfo.loadOp == wgpu::LoadOp::Load && if (attachmentInfo.loadOp == wgpu::LoadOp::Load &&
!view->GetTexture()->IsSubresourceContentInitialized( !view->GetTexture()->IsSubresourceContentInitialized(range)) {
view->GetBaseMipLevel(), 1, view->GetBaseArrayLayer(), 1)) {
attachmentInfo.loadOp = wgpu::LoadOp::Clear; attachmentInfo.loadOp = wgpu::LoadOp::Clear;
attachmentInfo.clearColor = {0.f, 0.f, 0.f, 0.f}; attachmentInfo.clearColor = {0.f, 0.f, 0.f, 0.f};
} }
@ -73,20 +73,19 @@ namespace dawn_native {
// cleared later in the pipeline. The texture will be resolved from the // cleared later in the pipeline. The texture will be resolved from the
// source color attachment, which will be correctly initialized. // source color attachment, which will be correctly initialized.
TextureViewBase* resolveView = attachmentInfo.resolveTarget.Get(); TextureViewBase* resolveView = attachmentInfo.resolveTarget.Get();
ASSERT(resolveView->GetLayerCount() == 1);
ASSERT(resolveView->GetLevelCount() == 1);
resolveView->GetTexture()->SetIsSubresourceContentInitialized( resolveView->GetTexture()->SetIsSubresourceContentInitialized(
true, resolveView->GetBaseMipLevel(), resolveView->GetLevelCount(), true, resolveView->GetSubresourceRange());
resolveView->GetBaseArrayLayer(), resolveView->GetLayerCount());
} }
switch (attachmentInfo.storeOp) { switch (attachmentInfo.storeOp) {
case wgpu::StoreOp::Store: case wgpu::StoreOp::Store:
view->GetTexture()->SetIsSubresourceContentInitialized( view->GetTexture()->SetIsSubresourceContentInitialized(true, range);
true, view->GetBaseMipLevel(), 1, view->GetBaseArrayLayer(), 1);
break; break;
case wgpu::StoreOp::Clear: case wgpu::StoreOp::Clear:
view->GetTexture()->SetIsSubresourceContentInitialized( view->GetTexture()->SetIsSubresourceContentInitialized(false, range);
false, view->GetBaseMipLevel(), 1, view->GetBaseArrayLayer(), 1);
break; break;
default: default:
@ -98,12 +97,13 @@ namespace dawn_native {
if (renderPass->attachmentState->HasDepthStencilAttachment()) { if (renderPass->attachmentState->HasDepthStencilAttachment()) {
auto& attachmentInfo = renderPass->depthStencilAttachment; auto& attachmentInfo = renderPass->depthStencilAttachment;
TextureViewBase* view = attachmentInfo.view.Get(); TextureViewBase* view = attachmentInfo.view.Get();
ASSERT(view->GetLayerCount() == 1);
ASSERT(view->GetLevelCount() == 1);
SubresourceRange range = view->GetSubresourceRange();
// If the depth stencil texture has not been initialized, we want to use loadop // If the depth stencil texture has not been initialized, we want to use loadop
// clear to init the contents to 0's // clear to init the contents to 0's
if (!view->GetTexture()->IsSubresourceContentInitialized( if (!view->GetTexture()->IsSubresourceContentInitialized(range)) {
view->GetBaseMipLevel(), view->GetLevelCount(), view->GetBaseArrayLayer(),
view->GetLayerCount())) {
if (view->GetTexture()->GetFormat().HasDepth() && if (view->GetTexture()->GetFormat().HasDepth() &&
attachmentInfo.depthLoadOp == wgpu::LoadOp::Load) { attachmentInfo.depthLoadOp == wgpu::LoadOp::Load) {
attachmentInfo.clearDepth = 0.0f; attachmentInfo.clearDepth = 0.0f;
@ -125,15 +125,11 @@ namespace dawn_native {
if (attachmentInfo.depthStoreOp == wgpu::StoreOp::Store && if (attachmentInfo.depthStoreOp == wgpu::StoreOp::Store &&
attachmentInfo.stencilStoreOp == wgpu::StoreOp::Store) { attachmentInfo.stencilStoreOp == wgpu::StoreOp::Store) {
view->GetTexture()->SetIsSubresourceContentInitialized( view->GetTexture()->SetIsSubresourceContentInitialized(true, range);
true, view->GetBaseMipLevel(), view->GetLevelCount(), view->GetBaseArrayLayer(),
view->GetLayerCount());
} else { } else {
ASSERT(attachmentInfo.depthStoreOp == wgpu::StoreOp::Clear && ASSERT(attachmentInfo.depthStoreOp == wgpu::StoreOp::Clear &&
attachmentInfo.stencilStoreOp == wgpu::StoreOp::Clear); attachmentInfo.stencilStoreOp == wgpu::StoreOp::Clear);
view->GetTexture()->SetIsSubresourceContentInitialized( view->GetTexture()->SetIsSubresourceContentInitialized(false, range);
false, view->GetBaseMipLevel(), view->GetLevelCount(),
view->GetBaseArrayLayer(), view->GetLayerCount());
} }
} }
} }

View File

@ -178,8 +178,8 @@ namespace dawn_native {
uint32_t layerCount) { uint32_t layerCount) {
dawn_native::TextureBase* textureBase = dawn_native::TextureBase* textureBase =
reinterpret_cast<dawn_native::TextureBase*>(texture); reinterpret_cast<dawn_native::TextureBase*>(texture);
return textureBase->IsSubresourceContentInitialized(baseMipLevel, levelCount, SubresourceRange range = {baseMipLevel, levelCount, baseArrayLayer, layerCount};
baseArrayLayer, layerCount); return textureBase->IsSubresourceContentInitialized(range);
} }
std::vector<const char*> GetProcMapNamesForTestingInternal(); std::vector<const char*> GetProcMapNamesForTestingInternal();

View File

@ -346,8 +346,7 @@ namespace dawn_native {
mDimension(descriptor->dimension), mDimension(descriptor->dimension),
mFormat(device->GetValidInternalFormat(descriptor->format)), mFormat(device->GetValidInternalFormat(descriptor->format)),
mSize(descriptor->size), mSize(descriptor->size),
mArrayLayerCount(descriptor->arrayLayerCount), mRange({0, descriptor->mipLevelCount, 0, descriptor->arrayLayerCount}),
mMipLevelCount(descriptor->mipLevelCount),
mSampleCount(descriptor->sampleCount), mSampleCount(descriptor->sampleCount),
mUsage(descriptor->usage), mUsage(descriptor->usage),
mState(state) { mState(state) {
@ -388,11 +387,15 @@ namespace dawn_native {
} }
uint32_t TextureBase::GetArrayLayers() const { uint32_t TextureBase::GetArrayLayers() const {
ASSERT(!IsError()); ASSERT(!IsError());
return mArrayLayerCount; return mRange.layerCount;
} }
uint32_t TextureBase::GetNumMipLevels() const { uint32_t TextureBase::GetNumMipLevels() const {
ASSERT(!IsError()); ASSERT(!IsError());
return mMipLevelCount; return mRange.levelCount;
}
const SubresourceRange& TextureBase::GetAllSubresources() const {
ASSERT(!IsError());
return mRange;
} }
uint32_t TextureBase::GetSampleCount() const { uint32_t TextureBase::GetSampleCount() const {
ASSERT(!IsError()); ASSERT(!IsError());
@ -400,7 +403,7 @@ namespace dawn_native {
} }
uint32_t TextureBase::GetSubresourceCount() const { uint32_t TextureBase::GetSubresourceCount() const {
ASSERT(!IsError()); ASSERT(!IsError());
return mMipLevelCount * mArrayLayerCount; return mRange.levelCount * mRange.layerCount;
} }
wgpu::TextureUsage TextureBase::GetUsage() const { wgpu::TextureUsage TextureBase::GetUsage() const {
ASSERT(!IsError()); ASSERT(!IsError());
@ -421,15 +424,12 @@ namespace dawn_native {
return GetNumMipLevels() * arraySlice + mipLevel; return GetNumMipLevels() * arraySlice + mipLevel;
} }
bool TextureBase::IsSubresourceContentInitialized(uint32_t baseMipLevel, bool TextureBase::IsSubresourceContentInitialized(const SubresourceRange& range) const {
uint32_t levelCount,
uint32_t baseArrayLayer,
uint32_t layerCount) const {
ASSERT(!IsError()); ASSERT(!IsError());
for (uint32_t arrayLayer = baseArrayLayer; arrayLayer < baseArrayLayer + layerCount; for (uint32_t arrayLayer = range.baseArrayLayer;
++arrayLayer) { arrayLayer < range.baseArrayLayer + range.layerCount; ++arrayLayer) {
for (uint32_t mipLevel = baseMipLevel; mipLevel < baseMipLevel + levelCount; for (uint32_t mipLevel = range.baseMipLevel;
++mipLevel) { mipLevel < range.baseMipLevel + range.levelCount; ++mipLevel) {
uint32_t subresourceIndex = GetSubresourceIndex(mipLevel, arrayLayer); uint32_t subresourceIndex = GetSubresourceIndex(mipLevel, arrayLayer);
ASSERT(subresourceIndex < mIsSubresourceContentInitializedAtIndex.size()); ASSERT(subresourceIndex < mIsSubresourceContentInitializedAtIndex.size());
if (!mIsSubresourceContentInitializedAtIndex[subresourceIndex]) { if (!mIsSubresourceContentInitializedAtIndex[subresourceIndex]) {
@ -441,15 +441,12 @@ namespace dawn_native {
} }
void TextureBase::SetIsSubresourceContentInitialized(bool isInitialized, void TextureBase::SetIsSubresourceContentInitialized(bool isInitialized,
uint32_t baseMipLevel, const SubresourceRange& range) {
uint32_t levelCount,
uint32_t baseArrayLayer,
uint32_t layerCount) {
ASSERT(!IsError()); ASSERT(!IsError());
for (uint32_t arrayLayer = baseArrayLayer; arrayLayer < baseArrayLayer + layerCount; for (uint32_t arrayLayer = range.baseArrayLayer;
++arrayLayer) { arrayLayer < range.baseArrayLayer + range.layerCount; ++arrayLayer) {
for (uint32_t mipLevel = baseMipLevel; mipLevel < baseMipLevel + levelCount; for (uint32_t mipLevel = range.baseMipLevel;
++mipLevel) { mipLevel < range.baseMipLevel + range.levelCount; ++mipLevel) {
uint32_t subresourceIndex = GetSubresourceIndex(mipLevel, arrayLayer); uint32_t subresourceIndex = GetSubresourceIndex(mipLevel, arrayLayer);
ASSERT(subresourceIndex < mIsSubresourceContentInitializedAtIndex.size()); ASSERT(subresourceIndex < mIsSubresourceContentInitializedAtIndex.size());
mIsSubresourceContentInitializedAtIndex[subresourceIndex] = isInitialized; mIsSubresourceContentInitializedAtIndex[subresourceIndex] = isInitialized;
@ -526,10 +523,8 @@ namespace dawn_native {
mTexture(texture), mTexture(texture),
mFormat(GetDevice()->GetValidInternalFormat(descriptor->format)), mFormat(GetDevice()->GetValidInternalFormat(descriptor->format)),
mDimension(descriptor->dimension), mDimension(descriptor->dimension),
mBaseMipLevel(descriptor->baseMipLevel), mRange({descriptor->baseMipLevel, descriptor->mipLevelCount, descriptor->baseArrayLayer,
mMipLevelCount(descriptor->mipLevelCount), descriptor->arrayLayerCount}) {
mBaseArrayLayer(descriptor->baseArrayLayer),
mArrayLayerCount(descriptor->arrayLayerCount) {
} }
TextureViewBase::TextureViewBase(DeviceBase* device, ObjectBase::ErrorTag tag) TextureViewBase::TextureViewBase(DeviceBase* device, ObjectBase::ErrorTag tag)
@ -563,21 +558,26 @@ namespace dawn_native {
uint32_t TextureViewBase::GetBaseMipLevel() const { uint32_t TextureViewBase::GetBaseMipLevel() const {
ASSERT(!IsError()); ASSERT(!IsError());
return mBaseMipLevel; return mRange.baseMipLevel;
} }
uint32_t TextureViewBase::GetLevelCount() const { uint32_t TextureViewBase::GetLevelCount() const {
ASSERT(!IsError()); ASSERT(!IsError());
return mMipLevelCount; return mRange.levelCount;
} }
uint32_t TextureViewBase::GetBaseArrayLayer() const { uint32_t TextureViewBase::GetBaseArrayLayer() const {
ASSERT(!IsError()); ASSERT(!IsError());
return mBaseArrayLayer; return mRange.baseArrayLayer;
} }
uint32_t TextureViewBase::GetLayerCount() const { uint32_t TextureViewBase::GetLayerCount() const {
ASSERT(!IsError()); ASSERT(!IsError());
return mArrayLayerCount; return mRange.layerCount;
}
const SubresourceRange& TextureViewBase::GetSubresourceRange() const {
ASSERT(!IsError());
return mRange;
} }
} // namespace dawn_native } // namespace dawn_native

View File

@ -41,6 +41,17 @@ namespace dawn_native {
wgpu::TextureUsage::CopyDst | wgpu::TextureUsage::Storage | wgpu::TextureUsage::CopyDst | wgpu::TextureUsage::Storage |
wgpu::TextureUsage::OutputAttachment; wgpu::TextureUsage::OutputAttachment;
struct SubresourceRange {
uint32_t baseMipLevel;
uint32_t levelCount;
uint32_t baseArrayLayer;
uint32_t layerCount;
static SubresourceRange SingleSubresource(uint32_t baseMipLevel, uint32_t baseArrayLayer) {
return {baseMipLevel, 1, baseArrayLayer, 1};
}
};
class TextureBase : public ObjectBase { class TextureBase : public ObjectBase {
public: public:
enum class TextureState { OwnedInternal, OwnedExternal, Destroyed }; enum class TextureState { OwnedInternal, OwnedExternal, Destroyed };
@ -54,20 +65,14 @@ namespace dawn_native {
const Extent3D& GetSize() const; const Extent3D& GetSize() const;
uint32_t GetArrayLayers() const; uint32_t GetArrayLayers() const;
uint32_t GetNumMipLevels() const; uint32_t GetNumMipLevels() const;
const SubresourceRange& GetAllSubresources() const;
uint32_t GetSampleCount() const; uint32_t GetSampleCount() const;
uint32_t GetSubresourceCount() const; uint32_t GetSubresourceCount() const;
wgpu::TextureUsage GetUsage() const; wgpu::TextureUsage GetUsage() const;
TextureState GetTextureState() const; TextureState GetTextureState() const;
uint32_t GetSubresourceIndex(uint32_t mipLevel, uint32_t arraySlice) const; uint32_t GetSubresourceIndex(uint32_t mipLevel, uint32_t arraySlice) const;
bool IsSubresourceContentInitialized(uint32_t baseMipLevel, bool IsSubresourceContentInitialized(const SubresourceRange& range) const;
uint32_t levelCount, void SetIsSubresourceContentInitialized(bool isInitialized, const SubresourceRange& range);
uint32_t baseArrayLayer,
uint32_t layerCount) const;
void SetIsSubresourceContentInitialized(bool isInitialized,
uint32_t baseMipLevel,
uint32_t levelCount,
uint32_t baseArrayLayer,
uint32_t layerCount);
MaybeError ValidateCanUseInSubmitNow() const; MaybeError ValidateCanUseInSubmitNow() const;
@ -97,8 +102,7 @@ namespace dawn_native {
// TODO(cwallez@chromium.org): This should be deduplicated in the Device // TODO(cwallez@chromium.org): This should be deduplicated in the Device
const Format& mFormat; const Format& mFormat;
Extent3D mSize; Extent3D mSize;
uint32_t mArrayLayerCount; SubresourceRange mRange;
uint32_t mMipLevelCount;
uint32_t mSampleCount; uint32_t mSampleCount;
wgpu::TextureUsage mUsage = wgpu::TextureUsage::None; wgpu::TextureUsage mUsage = wgpu::TextureUsage::None;
TextureState mState; TextureState mState;
@ -122,6 +126,7 @@ namespace dawn_native {
uint32_t GetLevelCount() const; uint32_t GetLevelCount() const;
uint32_t GetBaseArrayLayer() const; uint32_t GetBaseArrayLayer() const;
uint32_t GetLayerCount() const; uint32_t GetLayerCount() const;
const SubresourceRange& GetSubresourceRange() const;
private: private:
TextureViewBase(DeviceBase* device, ObjectBase::ErrorTag tag); TextureViewBase(DeviceBase* device, ObjectBase::ErrorTag tag);
@ -131,10 +136,7 @@ namespace dawn_native {
// TODO(cwallez@chromium.org): This should be deduplicated in the Device // TODO(cwallez@chromium.org): This should be deduplicated in the Device
const Format& mFormat; const Format& mFormat;
wgpu::TextureViewDimension mDimension; wgpu::TextureViewDimension mDimension;
uint32_t mBaseMipLevel; SubresourceRange mRange;
uint32_t mMipLevelCount;
uint32_t mBaseArrayLayer;
uint32_t mArrayLayerCount;
}; };
} // namespace dawn_native } // namespace dawn_native

View File

@ -512,9 +512,8 @@ namespace dawn_native { namespace d3d12 {
// cleared during record render pass if the texture subresource has not been // cleared during record render pass if the texture subresource has not been
// initialized before the render pass. // initialized before the render pass.
if (!(usages.textureUsages[i].usage & wgpu::TextureUsage::OutputAttachment)) { if (!(usages.textureUsages[i].usage & wgpu::TextureUsage::OutputAttachment)) {
texture->EnsureSubresourceContentInitialized(commandContext, 0, texture->EnsureSubresourceContentInitialized(commandContext,
texture->GetNumMipLevels(), 0, texture->GetAllSubresources());
texture->GetArrayLayers());
} }
} }
@ -590,14 +589,15 @@ namespace dawn_native { namespace d3d12 {
Buffer* buffer = ToBackend(copy->source.buffer.Get()); Buffer* buffer = ToBackend(copy->source.buffer.Get());
Texture* texture = ToBackend(copy->destination.texture.Get()); Texture* texture = ToBackend(copy->destination.texture.Get());
ASSERT(texture->GetDimension() == wgpu::TextureDimension::e2D);
ASSERT(copy->copySize.depth == 1);
SubresourceRange subresource = SubresourceRange::SingleSubresource(
copy->destination.mipLevel, copy->destination.arrayLayer);
if (IsCompleteSubresourceCopiedTo(texture, copy->copySize, if (IsCompleteSubresourceCopiedTo(texture, copy->copySize,
copy->destination.mipLevel)) { copy->destination.mipLevel)) {
texture->SetIsSubresourceContentInitialized( texture->SetIsSubresourceContentInitialized(true, subresource);
true, copy->destination.mipLevel, 1, copy->destination.arrayLayer, 1);
} else { } else {
texture->EnsureSubresourceContentInitialized( texture->EnsureSubresourceContentInitialized(commandContext, subresource);
commandContext, copy->destination.mipLevel, 1,
copy->destination.arrayLayer, 1);
} }
buffer->TrackUsageAndTransitionNow(commandContext, wgpu::BufferUsage::CopySrc); buffer->TrackUsageAndTransitionNow(commandContext, wgpu::BufferUsage::CopySrc);
@ -635,8 +635,11 @@ namespace dawn_native { namespace d3d12 {
Texture* texture = ToBackend(copy->source.texture.Get()); Texture* texture = ToBackend(copy->source.texture.Get());
Buffer* buffer = ToBackend(copy->destination.buffer.Get()); Buffer* buffer = ToBackend(copy->destination.buffer.Get());
ASSERT(texture->GetDimension() == wgpu::TextureDimension::e2D);
ASSERT(copy->copySize.depth == 1);
texture->EnsureSubresourceContentInitialized( texture->EnsureSubresourceContentInitialized(
commandContext, copy->source.mipLevel, 1, copy->source.arrayLayer, 1); commandContext, SubresourceRange::SingleSubresource(
copy->source.mipLevel, copy->source.arrayLayer));
texture->TrackUsageAndTransitionNow(commandContext, wgpu::TextureUsage::CopySrc, texture->TrackUsageAndTransitionNow(commandContext, wgpu::TextureUsage::CopySrc,
copy->source.mipLevel, 1, copy->source.mipLevel, 1,
@ -676,19 +679,18 @@ namespace dawn_native { namespace d3d12 {
Texture* source = ToBackend(copy->source.texture.Get()); Texture* source = ToBackend(copy->source.texture.Get());
Texture* destination = ToBackend(copy->destination.texture.Get()); Texture* destination = ToBackend(copy->destination.texture.Get());
SubresourceRange srcRange = {copy->source.mipLevel, 1, copy->source.arrayLayer,
copy->copySize.depth};
SubresourceRange dstRange = {copy->destination.mipLevel, 1,
copy->destination.arrayLayer,
copy->copySize.depth};
source->EnsureSubresourceContentInitialized( source->EnsureSubresourceContentInitialized(commandContext, srcRange);
commandContext, copy->source.mipLevel, 1, copy->source.arrayLayer,
copy->copySize.depth);
if (IsCompleteSubresourceCopiedTo(destination, copy->copySize, if (IsCompleteSubresourceCopiedTo(destination, copy->copySize,
copy->destination.mipLevel)) { copy->destination.mipLevel)) {
destination->SetIsSubresourceContentInitialized( destination->SetIsSubresourceContentInitialized(true, dstRange);
true, copy->destination.mipLevel, 1, copy->destination.arrayLayer,
copy->copySize.depth);
} else { } else {
destination->EnsureSubresourceContentInitialized( destination->EnsureSubresourceContentInitialized(commandContext, dstRange);
commandContext, copy->destination.mipLevel, 1,
copy->destination.arrayLayer, copy->copySize.depth);
} }
if (copy->source.texture.Get() == copy->destination.texture.Get() && if (copy->source.texture.Get() == copy->destination.texture.Get() &&

View File

@ -397,10 +397,8 @@ namespace dawn_native { namespace d3d12 {
AcquireRef(new Texture(device, textureDescriptor, TextureState::OwnedExternal)); AcquireRef(new Texture(device, textureDescriptor, TextureState::OwnedExternal));
DAWN_TRY(dawnTexture->InitializeAsExternalTexture(textureDescriptor, sharedHandle, DAWN_TRY(dawnTexture->InitializeAsExternalTexture(textureDescriptor, sharedHandle,
acquireMutexKey, isSwapChainTexture)); acquireMutexKey, isSwapChainTexture));
dawnTexture->SetIsSubresourceContentInitialized(descriptor->isCleared,
dawnTexture->SetIsSubresourceContentInitialized(descriptor->isCleared, 0, dawnTexture->GetAllSubresources());
textureDescriptor->mipLevelCount, 0,
textureDescriptor->arrayLayerCount);
return std::move(dawnTexture); return std::move(dawnTexture);
} }
@ -479,7 +477,7 @@ namespace dawn_native { namespace d3d12 {
CommandRecordingContext* commandContext; CommandRecordingContext* commandContext;
DAWN_TRY_ASSIGN(commandContext, device->GetPendingCommandContext()); DAWN_TRY_ASSIGN(commandContext, device->GetPendingCommandContext());
DAWN_TRY(ClearTexture(commandContext, 0, GetNumMipLevels(), 0, GetArrayLayers(), DAWN_TRY(ClearTexture(commandContext, GetAllSubresources(),
TextureBase::ClearValue::NonZero)); TextureBase::ClearValue::NonZero));
} }
@ -504,8 +502,7 @@ namespace dawn_native { namespace d3d12 {
// memory management. // memory management.
mResourceAllocation = {info, 0, std::move(nativeTexture), nullptr}; mResourceAllocation = {info, 0, std::move(nativeTexture), nullptr};
SetIsSubresourceContentInitialized(true, 0, descriptor->mipLevelCount, 0, SetIsSubresourceContentInitialized(true, GetAllSubresources());
descriptor->arrayLayerCount);
} }
Texture::~Texture() { Texture::~Texture() {
@ -786,15 +783,11 @@ namespace dawn_native { namespace d3d12 {
} }
MaybeError Texture::ClearTexture(CommandRecordingContext* commandContext, MaybeError Texture::ClearTexture(CommandRecordingContext* commandContext,
uint32_t baseMipLevel, const SubresourceRange& range,
uint32_t levelCount,
uint32_t baseArrayLayer,
uint32_t layerCount,
TextureBase::ClearValue clearValue) { TextureBase::ClearValue clearValue) {
// TODO(jiawei.shao@intel.com): initialize the textures in compressed formats with copies. // TODO(jiawei.shao@intel.com): initialize the textures in compressed formats with copies.
if (GetFormat().isCompressed) { if (GetFormat().isCompressed) {
SetIsSubresourceContentInitialized(true, baseMipLevel, levelCount, baseArrayLayer, SetIsSubresourceContentInitialized(true, range);
layerCount);
return {}; return {};
} }
@ -808,15 +801,18 @@ namespace dawn_native { namespace d3d12 {
if (GetFormat().isRenderable) { if (GetFormat().isRenderable) {
if (GetFormat().HasDepthOrStencil()) { if (GetFormat().HasDepthOrStencil()) {
TrackUsageAndTransitionNow(commandContext, D3D12_RESOURCE_STATE_DEPTH_WRITE, TrackUsageAndTransitionNow(commandContext, D3D12_RESOURCE_STATE_DEPTH_WRITE,
baseMipLevel, levelCount, baseArrayLayer, layerCount); range.baseMipLevel, range.levelCount,
range.baseArrayLayer, range.layerCount);
D3D12_CLEAR_FLAGS clearFlags = {}; D3D12_CLEAR_FLAGS clearFlags = {};
for (uint32_t level = baseMipLevel; level < baseMipLevel + levelCount; ++level) { for (uint32_t level = range.baseMipLevel;
for (uint32_t layer = baseArrayLayer; layer < baseArrayLayer + layerCount; level < range.baseMipLevel + range.levelCount; ++level) {
++layer) { for (uint32_t layer = range.baseArrayLayer;
layer < range.baseArrayLayer + range.layerCount; ++layer) {
if (clearValue == TextureBase::ClearValue::Zero && if (clearValue == TextureBase::ClearValue::Zero &&
IsSubresourceContentInitialized(level, 1, layer, 1)) { IsSubresourceContentInitialized(
SubresourceRange::SingleSubresource(level, layer))) {
// Skip lazy clears if already initialized. // Skip lazy clears if already initialized.
continue; continue;
} }
@ -843,16 +839,19 @@ namespace dawn_native { namespace d3d12 {
} }
} else { } else {
TrackUsageAndTransitionNow(commandContext, D3D12_RESOURCE_STATE_RENDER_TARGET, TrackUsageAndTransitionNow(commandContext, D3D12_RESOURCE_STATE_RENDER_TARGET,
baseMipLevel, levelCount, baseArrayLayer, layerCount); range.baseMipLevel, range.levelCount,
range.baseArrayLayer, range.layerCount);
const float clearColorRGBA[4] = {fClearColor, fClearColor, fClearColor, const float clearColorRGBA[4] = {fClearColor, fClearColor, fClearColor,
fClearColor}; fClearColor};
for (uint32_t level = baseMipLevel; level < baseMipLevel + levelCount; ++level) { for (uint32_t level = range.baseMipLevel;
for (uint32_t layer = baseArrayLayer; layer < baseArrayLayer + layerCount; level < range.baseMipLevel + range.levelCount; ++level) {
++layer) { for (uint32_t layer = range.baseArrayLayer;
layer < range.baseArrayLayer + range.layerCount; ++layer) {
if (clearValue == TextureBase::ClearValue::Zero && if (clearValue == TextureBase::ClearValue::Zero &&
IsSubresourceContentInitialized(level, 1, layer, 1)) { IsSubresourceContentInitialized(
SubresourceRange::SingleSubresource(level, layer))) {
// Skip lazy clears if already initialized. // Skip lazy clears if already initialized.
continue; continue;
} }
@ -886,10 +885,12 @@ namespace dawn_native { namespace d3d12 {
uploader->Allocate(bufferSize, device->GetPendingCommandSerial())); uploader->Allocate(bufferSize, device->GetPendingCommandSerial()));
memset(uploadHandle.mappedBuffer, clearColor, bufferSize); memset(uploadHandle.mappedBuffer, clearColor, bufferSize);
TrackUsageAndTransitionNow(commandContext, D3D12_RESOURCE_STATE_COPY_DEST, baseMipLevel, TrackUsageAndTransitionNow(commandContext, D3D12_RESOURCE_STATE_COPY_DEST,
levelCount, baseArrayLayer, layerCount); range.baseMipLevel, range.levelCount, range.baseArrayLayer,
range.layerCount);
for (uint32_t level = baseMipLevel; level < baseMipLevel + levelCount; ++level) { for (uint32_t level = range.baseMipLevel; level < range.baseMipLevel + range.levelCount;
++level) {
// compute d3d12 texture copy locations for texture and buffer // compute d3d12 texture copy locations for texture and buffer
Extent3D copySize = GetMipLevelVirtualSize(level); Extent3D copySize = GetMipLevelVirtualSize(level);
@ -898,10 +899,11 @@ namespace dawn_native { namespace d3d12 {
ComputeTextureCopySplit({0, 0, 0}, copySize, GetFormat(), ComputeTextureCopySplit({0, 0, 0}, copySize, GetFormat(),
uploadHandle.startOffset, bytesPerRow, rowsPerImage); uploadHandle.startOffset, bytesPerRow, rowsPerImage);
for (uint32_t layer = baseArrayLayer; layer < baseArrayLayer + layerCount; for (uint32_t layer = range.baseArrayLayer;
++layer) { layer < range.baseArrayLayer + range.layerCount; ++layer) {
if (clearValue == TextureBase::ClearValue::Zero && if (clearValue == TextureBase::ClearValue::Zero &&
IsSubresourceContentInitialized(level, 1, layer, 1)) { IsSubresourceContentInitialized(
SubresourceRange::SingleSubresource(level, layer))) {
// Skip lazy clears if already initialized. // Skip lazy clears if already initialized.
continue; continue;
} }
@ -927,28 +929,22 @@ namespace dawn_native { namespace d3d12 {
} }
} }
if (clearValue == TextureBase::ClearValue::Zero) { if (clearValue == TextureBase::ClearValue::Zero) {
SetIsSubresourceContentInitialized(true, baseMipLevel, levelCount, baseArrayLayer, SetIsSubresourceContentInitialized(true, range);
layerCount);
GetDevice()->IncrementLazyClearCountForTesting(); GetDevice()->IncrementLazyClearCountForTesting();
} }
return {}; return {};
} }
void Texture::EnsureSubresourceContentInitialized(CommandRecordingContext* commandContext, void Texture::EnsureSubresourceContentInitialized(CommandRecordingContext* commandContext,
uint32_t baseMipLevel, const SubresourceRange& range) {
uint32_t levelCount,
uint32_t baseArrayLayer,
uint32_t layerCount) {
if (!ToBackend(GetDevice())->IsToggleEnabled(Toggle::LazyClearResourceOnFirstUse)) { if (!ToBackend(GetDevice())->IsToggleEnabled(Toggle::LazyClearResourceOnFirstUse)) {
return; return;
} }
if (!IsSubresourceContentInitialized(baseMipLevel, levelCount, baseArrayLayer, if (!IsSubresourceContentInitialized(range)) {
layerCount)) {
// If subresource has not been initialized, clear it to black as it could contain // If subresource has not been initialized, clear it to black as it could contain
// dirty bits from recycled memory // dirty bits from recycled memory
GetDevice()->ConsumedError(ClearTexture(commandContext, baseMipLevel, levelCount, GetDevice()->ConsumedError(
baseArrayLayer, layerCount, ClearTexture(commandContext, range, TextureBase::ClearValue::Zero));
TextureBase::ClearValue::Zero));
} }
} }

View File

@ -55,10 +55,7 @@ namespace dawn_native { namespace d3d12 {
uint32_t baseArrayLayer, uint32_t baseArrayLayer,
uint32_t layerCount) const; uint32_t layerCount) const;
void EnsureSubresourceContentInitialized(CommandRecordingContext* commandContext, void EnsureSubresourceContentInitialized(CommandRecordingContext* commandContext,
uint32_t baseMipLevel, const SubresourceRange& range);
uint32_t levelCount,
uint32_t baseArrayLayer,
uint32_t layerCount);
void TrackUsageAndGetResourceBarrierForPass( void TrackUsageAndGetResourceBarrierForPass(
CommandRecordingContext* commandContext, CommandRecordingContext* commandContext,
@ -95,10 +92,7 @@ namespace dawn_native { namespace d3d12 {
// Dawn API // Dawn API
void DestroyImpl() override; void DestroyImpl() override;
MaybeError ClearTexture(CommandRecordingContext* commandContext, MaybeError ClearTexture(CommandRecordingContext* commandContext,
uint32_t baseMipLevel, const SubresourceRange& range,
uint32_t levelCount,
uint32_t baseArrayLayer,
uint32_t layerCount,
TextureBase::ClearValue clearValue); TextureBase::ClearValue clearValue);
UINT16 GetDepthOrArraySize(); UINT16 GetDepthOrArraySize();

View File

@ -444,19 +444,18 @@ namespace dawn_native { namespace metal {
void EnsureSourceTextureInitialized(Texture* texture, void EnsureSourceTextureInitialized(Texture* texture,
const Extent3D& size, const Extent3D& size,
const TextureCopy& src) { const TextureCopy& src) {
texture->EnsureSubresourceContentInitialized(src.mipLevel, 1, src.arrayLayer, texture->EnsureSubresourceContentInitialized(
size.depth); {src.mipLevel, 1, src.arrayLayer, size.depth});
} }
void EnsureDestinationTextureInitialized(Texture* texture, void EnsureDestinationTextureInitialized(Texture* texture,
const Extent3D& size, const Extent3D& size,
const TextureCopy& dst) { const TextureCopy& dst) {
SubresourceRange range = {dst.mipLevel, 1, dst.arrayLayer, size.depth};
if (IsCompleteSubresourceCopiedTo(texture, size, dst.mipLevel)) { if (IsCompleteSubresourceCopiedTo(texture, size, dst.mipLevel)) {
texture->SetIsSubresourceContentInitialized(true, dst.mipLevel, 1, dst.arrayLayer, texture->SetIsSubresourceContentInitialized(true, range);
size.depth);
} else { } else {
texture->EnsureSubresourceContentInitialized(dst.mipLevel, 1, dst.arrayLayer, texture->EnsureSubresourceContentInitialized(range);
size.depth);
} }
} }
@ -691,8 +690,7 @@ namespace dawn_native { namespace metal {
// cleared in CreateMTLRenderPassDescriptor by setting the loadop to clear when the // cleared in CreateMTLRenderPassDescriptor by setting the loadop to clear when the
// texture subresource has not been initialized before the render pass. // texture subresource has not been initialized before the render pass.
if (!(usages.textureUsages[i].usage & wgpu::TextureUsage::OutputAttachment)) { if (!(usages.textureUsages[i].usage & wgpu::TextureUsage::OutputAttachment)) {
texture->EnsureSubresourceContentInitialized(0, texture->GetNumMipLevels(), 0, texture->EnsureSubresourceContentInitialized(texture->GetAllSubresources());
texture->GetArrayLayers());
} }
} }
}; };

View File

@ -42,21 +42,14 @@ namespace dawn_native { namespace metal {
id<MTLTexture> GetMTLTexture(); id<MTLTexture> GetMTLTexture();
void EnsureSubresourceContentInitialized(uint32_t baseMipLevel, void EnsureSubresourceContentInitialized(const SubresourceRange& range);
uint32_t levelCount,
uint32_t baseArrayLayer,
uint32_t layerCount);
private: private:
~Texture() override; ~Texture() override;
void DestroyImpl() override; void DestroyImpl() override;
MaybeError ClearTexture(uint32_t baseMipLevel, MaybeError ClearTexture(const SubresourceRange& range, TextureBase::ClearValue clearValue);
uint32_t levelCount,
uint32_t baseArrayLayer,
uint32_t layerCount,
TextureBase::ClearValue clearValue);
id<MTLTexture> mMtlTexture = nil; id<MTLTexture> mMtlTexture = nil;
}; };

View File

@ -326,8 +326,8 @@ namespace dawn_native { namespace metal {
[mtlDesc release]; [mtlDesc release];
if (device->IsToggleEnabled(Toggle::NonzeroClearResourcesOnCreationForTesting)) { if (device->IsToggleEnabled(Toggle::NonzeroClearResourcesOnCreationForTesting)) {
device->ConsumedError(ClearTexture(0, GetNumMipLevels(), 0, GetArrayLayers(), device->ConsumedError(
TextureBase::ClearValue::NonZero)); ClearTexture(GetAllSubresources(), TextureBase::ClearValue::NonZero));
} }
} }
@ -351,7 +351,7 @@ namespace dawn_native { namespace metal {
plane:plane]; plane:plane];
[mtlDesc release]; [mtlDesc release];
SetIsSubresourceContentInitialized(descriptor->isCleared, 0, 1, 0, 1); SetIsSubresourceContentInitialized(descriptor->isCleared, {0, 1, 0, 1});
} }
Texture::~Texture() { Texture::~Texture() {
@ -369,10 +369,7 @@ namespace dawn_native { namespace metal {
return mMtlTexture; return mMtlTexture;
} }
MaybeError Texture::ClearTexture(uint32_t baseMipLevel, MaybeError Texture::ClearTexture(const SubresourceRange& range,
uint32_t levelCount,
uint32_t baseArrayLayer,
uint32_t layerCount,
TextureBase::ClearValue clearValue) { TextureBase::ClearValue clearValue) {
Device* device = ToBackend(GetDevice()); Device* device = ToBackend(GetDevice());
@ -389,11 +386,13 @@ namespace dawn_native { namespace metal {
if (GetFormat().HasDepthOrStencil()) { if (GetFormat().HasDepthOrStencil()) {
// Create a render pass to clear each subresource. // Create a render pass to clear each subresource.
for (uint32_t level = baseMipLevel; level < baseMipLevel + levelCount; ++level) { for (uint32_t level = range.baseMipLevel;
for (uint32_t arrayLayer = baseArrayLayer; level < range.baseMipLevel + range.levelCount; ++level) {
arrayLayer < baseArrayLayer + layerCount; arrayLayer++) { for (uint32_t arrayLayer = range.baseArrayLayer;
arrayLayer < range.baseArrayLayer + range.layerCount; arrayLayer++) {
if (clearValue == TextureBase::ClearValue::Zero && if (clearValue == TextureBase::ClearValue::Zero &&
IsSubresourceContentInitialized(level, 1, arrayLayer, 1)) { IsSubresourceContentInitialized(
SubresourceRange::SingleSubresource(level, arrayLayer))) {
// Skip lazy clears if already initialized. // Skip lazy clears if already initialized.
continue; continue;
} }
@ -421,17 +420,19 @@ namespace dawn_native { namespace metal {
} }
} else { } else {
ASSERT(GetFormat().IsColor()); ASSERT(GetFormat().IsColor());
for (uint32_t level = baseMipLevel; level < baseMipLevel + levelCount; ++level) { for (uint32_t level = range.baseMipLevel;
level < range.baseMipLevel + range.levelCount; ++level) {
// Create multiple render passes with each subresource as a color attachment to // Create multiple render passes with each subresource as a color attachment to
// clear them all. Only do this for array layers to ensure all attachments have // clear them all. Only do this for array layers to ensure all attachments have
// the same size. // the same size.
MTLRenderPassDescriptor* descriptor = nil; MTLRenderPassDescriptor* descriptor = nil;
uint32_t attachment = 0; uint32_t attachment = 0;
for (uint32_t arrayLayer = baseArrayLayer; for (uint32_t arrayLayer = range.baseArrayLayer;
arrayLayer < baseArrayLayer + layerCount; arrayLayer++) { arrayLayer < range.baseArrayLayer + range.layerCount; arrayLayer++) {
if (clearValue == TextureBase::ClearValue::Zero && if (clearValue == TextureBase::ClearValue::Zero &&
IsSubresourceContentInitialized(level, 1, arrayLayer, 1)) { IsSubresourceContentInitialized(
SubresourceRange::SingleSubresource(level, arrayLayer))) {
// Skip lazy clears if already initialized. // Skip lazy clears if already initialized.
continue; continue;
} }
@ -466,7 +467,7 @@ namespace dawn_native { namespace metal {
} }
} else { } else {
// Compute the buffer size big enough to fill the largest mip. // Compute the buffer size big enough to fill the largest mip.
Extent3D largestMipSize = GetMipLevelVirtualSize(baseMipLevel); Extent3D largestMipSize = GetMipLevelVirtualSize(range.baseMipLevel);
// Metal validation layers: sourceBytesPerRow must be at least 64. // Metal validation layers: sourceBytesPerRow must be at least 64.
uint32_t largestMipBytesPerRow = std::max( uint32_t largestMipBytesPerRow = std::max(
@ -496,13 +497,15 @@ namespace dawn_native { namespace metal {
id<MTLBuffer> uploadBuffer = ToBackend(uploadHandle.stagingBuffer)->GetBufferHandle(); id<MTLBuffer> uploadBuffer = ToBackend(uploadHandle.stagingBuffer)->GetBufferHandle();
// Encode a buffer to texture copy to clear each subresource. // Encode a buffer to texture copy to clear each subresource.
for (uint32_t level = baseMipLevel; level < baseMipLevel + levelCount; ++level) { for (uint32_t level = range.baseMipLevel; level < range.baseMipLevel + range.levelCount;
++level) {
Extent3D virtualSize = GetMipLevelVirtualSize(level); Extent3D virtualSize = GetMipLevelVirtualSize(level);
for (uint32_t arrayLayer = baseArrayLayer; arrayLayer < baseArrayLayer + layerCount; for (uint32_t arrayLayer = range.baseArrayLayer;
++arrayLayer) { arrayLayer < range.baseArrayLayer + range.layerCount; ++arrayLayer) {
if (clearValue == TextureBase::ClearValue::Zero && if (clearValue == TextureBase::ClearValue::Zero &&
IsSubresourceContentInitialized(level, 1, arrayLayer, 1)) { IsSubresourceContentInitialized(
SubresourceRange::SingleSubresource(level, arrayLayer))) {
// Skip lazy clears if already initialized. // Skip lazy clears if already initialized.
continue; continue;
} }
@ -539,26 +542,20 @@ namespace dawn_native { namespace metal {
} }
if (clearValue == TextureBase::ClearValue::Zero) { if (clearValue == TextureBase::ClearValue::Zero) {
SetIsSubresourceContentInitialized(true, baseMipLevel, levelCount, baseArrayLayer, SetIsSubresourceContentInitialized(true, range);
layerCount);
device->IncrementLazyClearCountForTesting(); device->IncrementLazyClearCountForTesting();
} }
return {}; return {};
} }
void Texture::EnsureSubresourceContentInitialized(uint32_t baseMipLevel, void Texture::EnsureSubresourceContentInitialized(const SubresourceRange& range) {
uint32_t levelCount,
uint32_t baseArrayLayer,
uint32_t layerCount) {
if (!GetDevice()->IsToggleEnabled(Toggle::LazyClearResourceOnFirstUse)) { if (!GetDevice()->IsToggleEnabled(Toggle::LazyClearResourceOnFirstUse)) {
return; return;
} }
if (!IsSubresourceContentInitialized(baseMipLevel, levelCount, baseArrayLayer, if (!IsSubresourceContentInitialized(range)) {
layerCount)) {
// If subresource has not been initialized, clear it to black as it could // If subresource has not been initialized, clear it to black as it could
// contain dirty bits from recycled memory // contain dirty bits from recycled memory
GetDevice()->ConsumedError(ClearTexture(baseMipLevel, levelCount, baseArrayLayer, GetDevice()->ConsumedError(ClearTexture(range, TextureBase::ClearValue::Zero));
layerCount, TextureBase::ClearValue::Zero));
} }
} }

View File

@ -458,8 +458,7 @@ namespace dawn_native { namespace opengl {
// cleared in BeginRenderPass by setting the loadop to clear when the // cleared in BeginRenderPass by setting the loadop to clear when the
// texture subresource has not been initialized before the render pass. // texture subresource has not been initialized before the render pass.
if (!(usages.textureUsages[i].usage & wgpu::TextureUsage::OutputAttachment)) { if (!(usages.textureUsages[i].usage & wgpu::TextureUsage::OutputAttachment)) {
texture->EnsureSubresourceContentInitialized(0, texture->GetNumMipLevels(), 0, texture->EnsureSubresourceContentInitialized(texture->GetAllSubresources());
texture->GetArrayLayers());
} }
} }
}; };
@ -513,12 +512,15 @@ namespace dawn_native { namespace opengl {
Texture* texture = ToBackend(dst.texture.Get()); Texture* texture = ToBackend(dst.texture.Get());
GLenum target = texture->GetGLTarget(); GLenum target = texture->GetGLTarget();
const GLFormat& format = texture->GetGLFormat(); const GLFormat& format = texture->GetGLFormat();
ASSERT(texture->GetDimension() == wgpu::TextureDimension::e2D);
ASSERT(copy->copySize.depth == 1);
SubresourceRange subresource =
SubresourceRange::SingleSubresource(dst.mipLevel, dst.arrayLayer);
if (IsCompleteSubresourceCopiedTo(texture, copySize, dst.mipLevel)) { if (IsCompleteSubresourceCopiedTo(texture, copySize, dst.mipLevel)) {
texture->SetIsSubresourceContentInitialized(true, dst.mipLevel, 1, texture->SetIsSubresourceContentInitialized(true, subresource);
dst.arrayLayer, 1);
} else { } else {
texture->EnsureSubresourceContentInitialized(dst.mipLevel, 1, texture->EnsureSubresourceContentInitialized(subresource);
dst.arrayLayer, 1);
} }
gl.BindBuffer(GL_PIXEL_UNPACK_BUFFER, buffer->GetHandle()); gl.BindBuffer(GL_PIXEL_UNPACK_BUFFER, buffer->GetHandle());
@ -602,8 +604,10 @@ namespace dawn_native { namespace opengl {
UNREACHABLE(); UNREACHABLE();
} }
texture->EnsureSubresourceContentInitialized(src.mipLevel, 1, src.arrayLayer, ASSERT(texture->GetDimension() == wgpu::TextureDimension::e2D);
1); ASSERT(copy->copySize.depth == 1);
texture->EnsureSubresourceContentInitialized(
SubresourceRange::SingleSubresource(src.mipLevel, src.arrayLayer));
// The only way to move data from a texture to a buffer in GL is via // The only way to move data from a texture to a buffer in GL is via
// glReadPixels with a pack buffer. Create a temporary FBO for the copy. // glReadPixels with a pack buffer. Create a temporary FBO for the copy.
gl.BindTexture(target, texture->GetHandle()); gl.BindTexture(target, texture->GetHandle());
@ -675,14 +679,16 @@ namespace dawn_native { namespace opengl {
Extent3D copySize = ComputeTextureCopyExtent(dst, copy->copySize); Extent3D copySize = ComputeTextureCopyExtent(dst, copy->copySize);
Texture* srcTexture = ToBackend(src.texture.Get()); Texture* srcTexture = ToBackend(src.texture.Get());
Texture* dstTexture = ToBackend(dst.texture.Get()); Texture* dstTexture = ToBackend(dst.texture.Get());
srcTexture->EnsureSubresourceContentInitialized(src.mipLevel, 1, src.arrayLayer, SubresourceRange srcRange = {src.mipLevel, 1, src.arrayLayer,
1); copy->copySize.depth};
SubresourceRange dstRange = {dst.mipLevel, 1, dst.arrayLayer,
copy->copySize.depth};
srcTexture->EnsureSubresourceContentInitialized(srcRange);
if (IsCompleteSubresourceCopiedTo(dstTexture, copySize, dst.mipLevel)) { if (IsCompleteSubresourceCopiedTo(dstTexture, copySize, dst.mipLevel)) {
dstTexture->SetIsSubresourceContentInitialized( dstTexture->SetIsSubresourceContentInitialized(true, dstRange);
true, dst.mipLevel, 1, dst.arrayLayer, copy->copySize.depth);
} else { } else {
dstTexture->EnsureSubresourceContentInitialized( dstTexture->EnsureSubresourceContentInitialized(dstRange);
dst.mipLevel, 1, dst.arrayLayer, copy->copySize.depth);
} }
gl.CopyImageSubData(srcTexture->GetHandle(), srcTexture->GetGLTarget(), gl.CopyImageSubData(srcTexture->GetHandle(), srcTexture->GetGLTarget(),
src.mipLevel, src.origin.x, src.origin.y, src.arrayLayer, src.mipLevel, src.origin.x, src.origin.y, src.arrayLayer,

View File

@ -145,8 +145,8 @@ namespace dawn_native { namespace opengl {
gl.TexParameteri(mTarget, GL_TEXTURE_MAX_LEVEL, levels - 1); gl.TexParameteri(mTarget, GL_TEXTURE_MAX_LEVEL, levels - 1);
if (GetDevice()->IsToggleEnabled(Toggle::NonzeroClearResourcesOnCreationForTesting)) { if (GetDevice()->IsToggleEnabled(Toggle::NonzeroClearResourcesOnCreationForTesting)) {
GetDevice()->ConsumedError(ClearTexture(0, GetNumMipLevels(), 0, GetArrayLayers(), GetDevice()->ConsumedError(
TextureBase::ClearValue::NonZero)); ClearTexture(GetAllSubresources(), TextureBase::ClearValue::NonZero));
} }
} }
@ -181,10 +181,7 @@ namespace dawn_native { namespace opengl {
return ToBackend(GetDevice())->GetGLFormat(GetFormat()); return ToBackend(GetDevice())->GetGLFormat(GetFormat());
} }
MaybeError Texture::ClearTexture(GLint baseMipLevel, MaybeError Texture::ClearTexture(const SubresourceRange& range,
GLint levelCount,
GLint baseArrayLayer,
GLint layerCount,
TextureBase::ClearValue clearValue) { TextureBase::ClearValue clearValue) {
// TODO(jiawei.shao@intel.com): initialize the textures with compressed formats. // TODO(jiawei.shao@intel.com): initialize the textures with compressed formats.
if (GetFormat().isCompressed) { if (GetFormat().isCompressed) {
@ -224,31 +221,35 @@ namespace dawn_native { namespace opengl {
gl.GenFramebuffers(1, &framebuffer); gl.GenFramebuffers(1, &framebuffer);
gl.BindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer); gl.BindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer);
for (GLint level = baseMipLevel; level < baseMipLevel + levelCount; ++level) { for (uint32_t level = range.baseMipLevel;
level < range.baseMipLevel + range.levelCount; ++level) {
switch (GetDimension()) { switch (GetDimension()) {
case wgpu::TextureDimension::e2D: case wgpu::TextureDimension::e2D:
if (GetArrayLayers() == 1) { if (GetArrayLayers() == 1) {
if (clearValue == TextureBase::ClearValue::Zero && if (clearValue == TextureBase::ClearValue::Zero &&
IsSubresourceContentInitialized(level, 1, 0, 1)) { IsSubresourceContentInitialized(
SubresourceRange::SingleSubresource(level, 0))) {
// Skip lazy clears if already initialized. // Skip lazy clears if already initialized.
continue; continue;
} }
gl.FramebufferTexture2D(GL_DRAW_FRAMEBUFFER, gl.FramebufferTexture2D(GL_DRAW_FRAMEBUFFER,
GL_DEPTH_STENCIL_ATTACHMENT, GetGLTarget(), GL_DEPTH_STENCIL_ATTACHMENT, GetGLTarget(),
GetHandle(), level); GetHandle(), static_cast<GLint>(level));
DoClear(); DoClear();
} else { } else {
for (GLint layer = baseArrayLayer; for (uint32_t layer = range.baseArrayLayer;
layer < baseArrayLayer + layerCount; ++layer) { layer < range.baseArrayLayer + range.layerCount; ++layer) {
if (clearValue == TextureBase::ClearValue::Zero && if (clearValue == TextureBase::ClearValue::Zero &&
IsSubresourceContentInitialized(level, 1, layer, 1)) { IsSubresourceContentInitialized(
SubresourceRange::SingleSubresource(level, layer))) {
// Skip lazy clears if already initialized. // Skip lazy clears if already initialized.
continue; continue;
} }
gl.FramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, gl.FramebufferTextureLayer(
GL_DEPTH_STENCIL_ATTACHMENT, GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
GetHandle(), level, layer); GetHandle(), static_cast<GLint>(level),
static_cast<GLint>(layer));
DoClear(); DoClear();
} }
} }
@ -268,16 +269,19 @@ namespace dawn_native { namespace opengl {
clearColorData.fill(clearColor); clearColorData.fill(clearColor);
const GLFormat& glFormat = GetGLFormat(); const GLFormat& glFormat = GetGLFormat();
for (GLint level = baseMipLevel; level < baseMipLevel + levelCount; ++level) { for (uint32_t level = range.baseMipLevel;
level < range.baseMipLevel + range.levelCount; ++level) {
Extent3D mipSize = GetMipLevelPhysicalSize(level); Extent3D mipSize = GetMipLevelPhysicalSize(level);
for (GLint layer = baseArrayLayer; layer < baseArrayLayer + layerCount; for (uint32_t layer = range.baseArrayLayer;
++layer) { layer < range.baseArrayLayer + range.layerCount; ++layer) {
if (clearValue == TextureBase::ClearValue::Zero && if (clearValue == TextureBase::ClearValue::Zero &&
IsSubresourceContentInitialized(level, 1, layer, 1)) { IsSubresourceContentInitialized(
SubresourceRange::SingleSubresource(level, layer))) {
// Skip lazy clears if already initialized. // Skip lazy clears if already initialized.
continue; continue;
} }
gl.ClearTexSubImage(mHandle, level, 0, 0, layer, mipSize.width, gl.ClearTexSubImage(mHandle, static_cast<GLint>(level), 0, 0,
static_cast<GLint>(layer), mipSize.width,
mipSize.height, 1, glFormat.format, glFormat.type, mipSize.height, 1, glFormat.format, glFormat.type,
clearColorData.data()); clearColorData.data());
} }
@ -319,7 +323,8 @@ namespace dawn_native { namespace opengl {
gl.PixelStorei(GL_UNPACK_ROW_LENGTH, gl.PixelStorei(GL_UNPACK_ROW_LENGTH,
(bytesPerRow / GetFormat().blockByteSize) * GetFormat().blockWidth); (bytesPerRow / GetFormat().blockByteSize) * GetFormat().blockWidth);
gl.PixelStorei(GL_UNPACK_IMAGE_HEIGHT, 0); gl.PixelStorei(GL_UNPACK_IMAGE_HEIGHT, 0);
for (GLint level = baseMipLevel; level < baseMipLevel + levelCount; ++level) { for (uint32_t level = range.baseMipLevel; level < range.baseMipLevel + range.levelCount;
++level) {
gl.BindBuffer(GL_PIXEL_UNPACK_BUFFER, srcBuffer->GetHandle()); gl.BindBuffer(GL_PIXEL_UNPACK_BUFFER, srcBuffer->GetHandle());
gl.ActiveTexture(GL_TEXTURE0); gl.ActiveTexture(GL_TEXTURE0);
gl.BindTexture(GetGLTarget(), GetHandle()); gl.BindTexture(GetGLTarget(), GetHandle());
@ -329,23 +334,26 @@ namespace dawn_native { namespace opengl {
case wgpu::TextureDimension::e2D: case wgpu::TextureDimension::e2D:
if (GetArrayLayers() == 1) { if (GetArrayLayers() == 1) {
if (clearValue == TextureBase::ClearValue::Zero && if (clearValue == TextureBase::ClearValue::Zero &&
IsSubresourceContentInitialized(level, 1, 0, 1)) { IsSubresourceContentInitialized(
SubresourceRange::SingleSubresource(level, 0))) {
// Skip lazy clears if already initialized. // Skip lazy clears if already initialized.
continue; continue;
} }
gl.TexSubImage2D(GetGLTarget(), level, 0, 0, size.width, size.height, gl.TexSubImage2D(GetGLTarget(), static_cast<GLint>(level), 0, 0,
GetGLFormat().format, GetGLFormat().type, 0); size.width, size.height, GetGLFormat().format,
GetGLFormat().type, 0);
} else { } else {
for (GLint layer = baseArrayLayer; layer < baseArrayLayer + layerCount; for (uint32_t layer = range.baseArrayLayer;
++layer) { layer < range.baseArrayLayer + range.layerCount; ++layer) {
if (clearValue == TextureBase::ClearValue::Zero && if (clearValue == TextureBase::ClearValue::Zero &&
IsSubresourceContentInitialized(level, 1, layer, 1)) { IsSubresourceContentInitialized(
SubresourceRange::SingleSubresource(level, layer))) {
// Skip lazy clears if already initialized. // Skip lazy clears if already initialized.
continue; continue;
} }
gl.TexSubImage3D(GetGLTarget(), level, 0, 0, layer, size.width, gl.TexSubImage3D(GetGLTarget(), static_cast<GLint>(level), 0, 0,
size.height, 1, GetGLFormat().format, static_cast<GLint>(layer), size.width, size.height,
GetGLFormat().type, 0); 1, GetGLFormat().format, GetGLFormat().type, 0);
} }
} }
break; break;
@ -360,24 +368,18 @@ namespace dawn_native { namespace opengl {
gl.BindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); gl.BindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
} }
if (clearValue == TextureBase::ClearValue::Zero) { if (clearValue == TextureBase::ClearValue::Zero) {
SetIsSubresourceContentInitialized(true, baseMipLevel, levelCount, baseArrayLayer, SetIsSubresourceContentInitialized(true, range);
layerCount);
device->IncrementLazyClearCountForTesting(); device->IncrementLazyClearCountForTesting();
} }
return {}; return {};
} }
void Texture::EnsureSubresourceContentInitialized(uint32_t baseMipLevel, void Texture::EnsureSubresourceContentInitialized(const SubresourceRange& range) {
uint32_t levelCount,
uint32_t baseArrayLayer,
uint32_t layerCount) {
if (!GetDevice()->IsToggleEnabled(Toggle::LazyClearResourceOnFirstUse)) { if (!GetDevice()->IsToggleEnabled(Toggle::LazyClearResourceOnFirstUse)) {
return; return;
} }
if (!IsSubresourceContentInitialized(baseMipLevel, levelCount, baseArrayLayer, if (!IsSubresourceContentInitialized(range)) {
layerCount)) { GetDevice()->ConsumedError(ClearTexture(range, TextureBase::ClearValue::Zero));
GetDevice()->ConsumedError(ClearTexture(baseMipLevel, levelCount, baseArrayLayer,
layerCount, TextureBase::ClearValue::Zero));
} }
} }

View File

@ -36,20 +36,13 @@ namespace dawn_native { namespace opengl {
GLenum GetGLTarget() const; GLenum GetGLTarget() const;
const GLFormat& GetGLFormat() const; const GLFormat& GetGLFormat() const;
void EnsureSubresourceContentInitialized(uint32_t baseMipLevel, void EnsureSubresourceContentInitialized(const SubresourceRange& range);
uint32_t levelCount,
uint32_t baseArrayLayer,
uint32_t layerCount);
private: private:
~Texture() override; ~Texture() override;
void DestroyImpl() override; void DestroyImpl() override;
MaybeError ClearTexture(GLint baseMipLevel, MaybeError ClearTexture(const SubresourceRange& range, TextureBase::ClearValue clearValue);
GLint levelCount,
GLint baseArrayLayer,
GLint layerCount,
TextureBase::ClearValue clearValue);
GLuint mHandle; GLuint mHandle;
GLenum mTarget; GLenum mTarget;

View File

@ -395,9 +395,8 @@ namespace dawn_native { namespace vulkan {
// cleared in RecordBeginRenderPass by setting the loadop to clear when the // cleared in RecordBeginRenderPass by setting the loadop to clear when the
// texture subresource has not been initialized before the render pass. // texture subresource has not been initialized before the render pass.
if (!(usages.textureUsages[i].usage & wgpu::TextureUsage::OutputAttachment)) { if (!(usages.textureUsages[i].usage & wgpu::TextureUsage::OutputAttachment)) {
texture->EnsureSubresourceContentInitialized(recordingContext, 0, texture->EnsureSubresourceContentInitialized(recordingContext,
texture->GetNumMipLevels(), 0, texture->GetAllSubresources());
texture->GetArrayLayers());
} }
texture->TransitionUsageForPass(recordingContext, usages.textureUsages[i], texture->TransitionUsageForPass(recordingContext, usages.textureUsages[i],
&imageBarriers, &srcStages, &dstStages); &imageBarriers, &srcStages, &dstStages);
@ -446,16 +445,17 @@ namespace dawn_native { namespace vulkan {
ComputeBufferImageCopyRegion(src, dst, copy->copySize); ComputeBufferImageCopyRegion(src, dst, copy->copySize);
VkImageSubresourceLayers subresource = region.imageSubresource; VkImageSubresourceLayers subresource = region.imageSubresource;
ASSERT(dst.texture->GetDimension() == wgpu::TextureDimension::e2D);
ASSERT(copy->copySize.depth == 1);
SubresourceRange range = SubresourceRange::SingleSubresource(
subresource.mipLevel, subresource.baseArrayLayer);
if (IsCompleteSubresourceCopiedTo(dst.texture.Get(), copy->copySize, if (IsCompleteSubresourceCopiedTo(dst.texture.Get(), copy->copySize,
subresource.mipLevel)) { subresource.mipLevel)) {
// Since texture has been overwritten, it has been "initialized" // Since texture has been overwritten, it has been "initialized"
dst.texture->SetIsSubresourceContentInitialized( dst.texture->SetIsSubresourceContentInitialized(true, range);
true, subresource.mipLevel, 1, subresource.baseArrayLayer, 1);
} else { } else {
ToBackend(dst.texture) ToBackend(dst.texture)
->EnsureSubresourceContentInitialized(recordingContext, ->EnsureSubresourceContentInitialized(recordingContext, range);
subresource.mipLevel, 1,
subresource.baseArrayLayer, 1);
} }
ToBackend(src.buffer) ToBackend(src.buffer)
->TransitionUsageNow(recordingContext, wgpu::BufferUsage::CopySrc); ->TransitionUsageNow(recordingContext, wgpu::BufferUsage::CopySrc);
@ -483,10 +483,13 @@ namespace dawn_native { namespace vulkan {
ComputeBufferImageCopyRegion(dst, src, copy->copySize); ComputeBufferImageCopyRegion(dst, src, copy->copySize);
VkImageSubresourceLayers subresource = region.imageSubresource; VkImageSubresourceLayers subresource = region.imageSubresource;
ASSERT(src.texture->GetDimension() == wgpu::TextureDimension::e2D);
ASSERT(copy->copySize.depth == 1);
ToBackend(src.texture) ToBackend(src.texture)
->EnsureSubresourceContentInitialized(recordingContext, ->EnsureSubresourceContentInitialized(
subresource.mipLevel, 1, recordingContext,
subresource.baseArrayLayer, 1); SubresourceRange::SingleSubresource(subresource.mipLevel,
subresource.baseArrayLayer));
ToBackend(src.texture) ToBackend(src.texture)
->TransitionUsageNow(recordingContext, wgpu::TextureUsage::CopySrc, ->TransitionUsageNow(recordingContext, wgpu::TextureUsage::CopySrc,
@ -508,20 +511,20 @@ namespace dawn_native { namespace vulkan {
mCommands.NextCommand<CopyTextureToTextureCmd>(); mCommands.NextCommand<CopyTextureToTextureCmd>();
TextureCopy& src = copy->source; TextureCopy& src = copy->source;
TextureCopy& dst = copy->destination; TextureCopy& dst = copy->destination;
SubresourceRange srcRange = {src.mipLevel, 1, src.arrayLayer,
copy->copySize.depth};
SubresourceRange dstRange = {dst.mipLevel, 1, dst.arrayLayer,
copy->copySize.depth};
ToBackend(src.texture) ToBackend(src.texture)
->EnsureSubresourceContentInitialized(recordingContext, src.mipLevel, 1, ->EnsureSubresourceContentInitialized(recordingContext, srcRange);
src.arrayLayer, 1);
if (IsCompleteSubresourceCopiedTo(dst.texture.Get(), copy->copySize, if (IsCompleteSubresourceCopiedTo(dst.texture.Get(), copy->copySize,
dst.mipLevel)) { dst.mipLevel)) {
// Since destination texture has been overwritten, it has been "initialized" // Since destination texture has been overwritten, it has been "initialized"
dst.texture->SetIsSubresourceContentInitialized( dst.texture->SetIsSubresourceContentInitialized(true, dstRange);
true, dst.mipLevel, 1, dst.arrayLayer, copy->copySize.depth);
} else { } else {
ToBackend(dst.texture) ToBackend(dst.texture)
->EnsureSubresourceContentInitialized(recordingContext, dst.mipLevel, 1, ->EnsureSubresourceContentInitialized(recordingContext, dstRange);
dst.arrayLayer,
copy->copySize.depth);
} }
if (src.texture.Get() == dst.texture.Get() && src.mipLevel == dst.mipLevel) { if (src.texture.Get() == dst.texture.Get() && src.mipLevel == dst.mipLevel) {

View File

@ -539,9 +539,8 @@ namespace dawn_native { namespace vulkan {
"BindImageMemory")); "BindImageMemory"));
if (device->IsToggleEnabled(Toggle::NonzeroClearResourcesOnCreationForTesting)) { if (device->IsToggleEnabled(Toggle::NonzeroClearResourcesOnCreationForTesting)) {
DAWN_TRY(ClearTexture(ToBackend(GetDevice())->GetPendingRecordingContext(), 0, DAWN_TRY(ClearTexture(ToBackend(GetDevice())->GetPendingRecordingContext(),
GetNumMipLevels(), 0, GetArrayLayers(), GetAllSubresources(), TextureBase::ClearValue::NonZero));
TextureBase::ClearValue::NonZero));
} }
return {}; return {};
@ -595,7 +594,7 @@ namespace dawn_native { namespace vulkan {
// Don't clear imported texture if already cleared // Don't clear imported texture if already cleared
if (descriptor->isCleared) { if (descriptor->isCleared) {
SetIsSubresourceContentInitialized(true, 0, 1, 0, 1); SetIsSubresourceContentInitialized(true, {0, 1, 0, 1});
} }
// Success, acquire all the external objects. // Success, acquire all the external objects.
@ -843,50 +842,49 @@ namespace dawn_native { namespace vulkan {
} }
MaybeError Texture::ClearTexture(CommandRecordingContext* recordingContext, MaybeError Texture::ClearTexture(CommandRecordingContext* recordingContext,
uint32_t baseMipLevel, const SubresourceRange& range,
uint32_t levelCount,
uint32_t baseArrayLayer,
uint32_t layerCount,
TextureBase::ClearValue clearValue) { TextureBase::ClearValue clearValue) {
Device* device = ToBackend(GetDevice()); Device* device = ToBackend(GetDevice());
uint8_t clearColor = (clearValue == TextureBase::ClearValue::Zero) ? 0 : 1; uint8_t clearColor = (clearValue == TextureBase::ClearValue::Zero) ? 0 : 1;
float fClearColor = (clearValue == TextureBase::ClearValue::Zero) ? 0.f : 1.f; float fClearColor = (clearValue == TextureBase::ClearValue::Zero) ? 0.f : 1.f;
TransitionUsageNow(recordingContext, wgpu::TextureUsage::CopyDst, baseMipLevel, levelCount, TransitionUsageNow(recordingContext, wgpu::TextureUsage::CopyDst, range.baseMipLevel,
baseArrayLayer, layerCount); range.levelCount, range.baseArrayLayer, range.layerCount);
if (GetFormat().isRenderable) { if (GetFormat().isRenderable) {
VkImageSubresourceRange range = {}; VkImageSubresourceRange imageRange = {};
range.aspectMask = GetVkAspectMask(); imageRange.aspectMask = GetVkAspectMask();
range.levelCount = 1; imageRange.levelCount = 1;
range.layerCount = 1; imageRange.layerCount = 1;
for (uint32_t level = baseMipLevel; level < baseMipLevel + levelCount; ++level) { for (uint32_t level = range.baseMipLevel; level < range.baseMipLevel + range.levelCount;
range.baseMipLevel = level; ++level) {
for (uint32_t layer = baseArrayLayer; layer < baseArrayLayer + layerCount; imageRange.baseMipLevel = level;
++layer) { for (uint32_t layer = range.baseArrayLayer;
layer < range.baseArrayLayer + range.layerCount; ++layer) {
if (clearValue == TextureBase::ClearValue::Zero && if (clearValue == TextureBase::ClearValue::Zero &&
IsSubresourceContentInitialized(level, 1, layer, 1)) { IsSubresourceContentInitialized(
SubresourceRange::SingleSubresource(level, layer))) {
// Skip lazy clears if already initialized. // Skip lazy clears if already initialized.
continue; continue;
} }
range.baseArrayLayer = layer; imageRange.baseArrayLayer = layer;
if (GetFormat().HasDepthOrStencil()) { if (GetFormat().HasDepthOrStencil()) {
VkClearDepthStencilValue clearDepthStencilValue[1]; VkClearDepthStencilValue clearDepthStencilValue[1];
clearDepthStencilValue[0].depth = fClearColor; clearDepthStencilValue[0].depth = fClearColor;
clearDepthStencilValue[0].stencil = clearColor; clearDepthStencilValue[0].stencil = clearColor;
device->fn.CmdClearDepthStencilImage(recordingContext->commandBuffer, device->fn.CmdClearDepthStencilImage(
GetHandle(), recordingContext->commandBuffer, GetHandle(),
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, clearDepthStencilValue, 1,
clearDepthStencilValue, 1, &range); &imageRange);
} else { } else {
VkClearColorValue clearColorValue = { VkClearColorValue clearColorValue = {
{fClearColor, fClearColor, fClearColor, fClearColor}}; {fClearColor, fClearColor, fClearColor, fClearColor}};
device->fn.CmdClearColorImage(recordingContext->commandBuffer, GetHandle(), device->fn.CmdClearColorImage(recordingContext->commandBuffer, GetHandle(),
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
&clearColorValue, 1, &range); &clearColorValue, 1, &imageRange);
} }
} }
} }
@ -913,13 +911,15 @@ namespace dawn_native { namespace vulkan {
bufferCopy.offset = uploadHandle.startOffset; bufferCopy.offset = uploadHandle.startOffset;
bufferCopy.bytesPerRow = bytesPerRow; bufferCopy.bytesPerRow = bytesPerRow;
for (uint32_t level = baseMipLevel; level < baseMipLevel + levelCount; ++level) { for (uint32_t level = range.baseMipLevel; level < range.baseMipLevel + range.levelCount;
++level) {
Extent3D copySize = GetMipLevelVirtualSize(level); Extent3D copySize = GetMipLevelVirtualSize(level);
for (uint32_t layer = baseArrayLayer; layer < baseArrayLayer + layerCount; for (uint32_t layer = range.baseArrayLayer;
++layer) { layer < range.baseArrayLayer + range.layerCount; ++layer) {
if (clearValue == TextureBase::ClearValue::Zero && if (clearValue == TextureBase::ClearValue::Zero &&
IsSubresourceContentInitialized(level, 1, layer, 1)) { IsSubresourceContentInitialized(
SubresourceRange::SingleSubresource(level, layer))) {
// Skip lazy clears if already initialized. // Skip lazy clears if already initialized.
continue; continue;
} }
@ -942,23 +942,18 @@ namespace dawn_native { namespace vulkan {
} }
} }
if (clearValue == TextureBase::ClearValue::Zero) { if (clearValue == TextureBase::ClearValue::Zero) {
SetIsSubresourceContentInitialized(true, baseMipLevel, levelCount, baseArrayLayer, SetIsSubresourceContentInitialized(true, range);
layerCount);
device->IncrementLazyClearCountForTesting(); device->IncrementLazyClearCountForTesting();
} }
return {}; return {};
} }
void Texture::EnsureSubresourceContentInitialized(CommandRecordingContext* recordingContext, void Texture::EnsureSubresourceContentInitialized(CommandRecordingContext* recordingContext,
uint32_t baseMipLevel, const SubresourceRange& range) {
uint32_t levelCount,
uint32_t baseArrayLayer,
uint32_t layerCount) {
if (!GetDevice()->IsToggleEnabled(Toggle::LazyClearResourceOnFirstUse)) { if (!GetDevice()->IsToggleEnabled(Toggle::LazyClearResourceOnFirstUse)) {
return; return;
} }
if (!IsSubresourceContentInitialized(baseMipLevel, levelCount, baseArrayLayer, if (!IsSubresourceContentInitialized(range)) {
layerCount)) {
// TODO(jiawei.shao@intel.com): initialize textures in BC formats with Buffer-to-Texture // TODO(jiawei.shao@intel.com): initialize textures in BC formats with Buffer-to-Texture
// copies. // copies.
if (GetFormat().isCompressed) { if (GetFormat().isCompressed) {
@ -967,9 +962,8 @@ namespace dawn_native { namespace vulkan {
// If subresource has not been initialized, clear it to black as it could contain dirty // If subresource has not been initialized, clear it to black as it could contain dirty
// bits from recycled memory // bits from recycled memory
GetDevice()->ConsumedError(ClearTexture(recordingContext, baseMipLevel, levelCount, GetDevice()->ConsumedError(
baseArrayLayer, layerCount, ClearTexture(recordingContext, range, TextureBase::ClearValue::Zero));
TextureBase::ClearValue::Zero));
} }
} }

View File

@ -80,10 +80,7 @@ namespace dawn_native { namespace vulkan {
VkPipelineStageFlags* dstStages); VkPipelineStageFlags* dstStages);
void EnsureSubresourceContentInitialized(CommandRecordingContext* recordingContext, void EnsureSubresourceContentInitialized(CommandRecordingContext* recordingContext,
uint32_t baseMipLevel, const SubresourceRange& range);
uint32_t levelCount,
uint32_t baseArrayLayer,
uint32_t layerCount);
MaybeError SignalAndDestroy(VkSemaphore* outSignalSemaphore); MaybeError SignalAndDestroy(VkSemaphore* outSignalSemaphore);
// Binds externally allocated memory to the VkImage and on success, takes ownership of // Binds externally allocated memory to the VkImage and on success, takes ownership of
@ -104,10 +101,7 @@ namespace dawn_native { namespace vulkan {
void DestroyImpl() override; void DestroyImpl() override;
MaybeError ClearTexture(CommandRecordingContext* recordingContext, MaybeError ClearTexture(CommandRecordingContext* recordingContext,
uint32_t baseMipLevel, const SubresourceRange& range,
uint32_t levelCount,
uint32_t baseArrayLayer,
uint32_t layerCount,
TextureBase::ClearValue); TextureBase::ClearValue);
void TweakTransitionForExternalUsage(CommandRecordingContext* recordingContext, void TweakTransitionForExternalUsage(CommandRecordingContext* recordingContext,