Clear D3D12 texture on first usage if not yet initialized
This prevents dirty textures to be used when memory is recycled while destroying/creating new textures. If a texture is being used for the first time and has not yet been initialized, it will be cleared to zeros. Bug: dawn:145 Change-Id: I8b9571c5a8fdd366717ffbd0fafca89b86653cea Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/8062 Commit-Queue: Natasha Lee <natlee@microsoft.com> Reviewed-by: Austin Eng <enga@chromium.org>
This commit is contained in:
parent
5dee3e826b
commit
99b76d1b8f
|
@ -440,6 +440,14 @@ namespace dawn_native { namespace d3d12 {
|
||||||
ToBackend(usages.buffers[i])->SetUsage(usages.bufferUsages[i]);
|
ToBackend(usages.buffers[i])->SetUsage(usages.bufferUsages[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < usages.textures.size(); ++i) {
|
||||||
|
Texture* texture = ToBackend(usages.textures[i]);
|
||||||
|
// TODO(natlee@microsoft.com): Update clearing here when subresource tracking is
|
||||||
|
// implemented
|
||||||
|
texture->EnsureSubresourceContentInitialized(
|
||||||
|
commandList, 0, texture->GetNumMipLevels(), 0, texture->GetArrayLayers());
|
||||||
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < usages.textures.size(); ++i) {
|
for (size_t i = 0; i < usages.textures.size(); ++i) {
|
||||||
D3D12_RESOURCE_BARRIER barrier;
|
D3D12_RESOURCE_BARRIER barrier;
|
||||||
if (ToBackend(usages.textures[i])
|
if (ToBackend(usages.textures[i])
|
||||||
|
@ -500,6 +508,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());
|
||||||
|
|
||||||
|
if (IsCompleteSubresourceCopiedTo(texture, copy->copySize,
|
||||||
|
copy->destination.level)) {
|
||||||
|
texture->SetIsSubresourceContentInitialized(copy->destination.level, 1,
|
||||||
|
copy->destination.slice, 1);
|
||||||
|
} else {
|
||||||
|
texture->EnsureSubresourceContentInitialized(
|
||||||
|
commandList, copy->destination.level, 1, copy->destination.slice, 1);
|
||||||
|
}
|
||||||
|
|
||||||
buffer->TransitionUsageNow(commandList, dawn::BufferUsageBit::TransferSrc);
|
buffer->TransitionUsageNow(commandList, dawn::BufferUsageBit::TransferSrc);
|
||||||
texture->TransitionUsageNow(commandList, dawn::TextureUsageBit::TransferDst);
|
texture->TransitionUsageNow(commandList, dawn::TextureUsageBit::TransferDst);
|
||||||
|
|
||||||
|
@ -544,6 +561,9 @@ 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());
|
||||||
|
|
||||||
|
texture->EnsureSubresourceContentInitialized(commandList, copy->source.level, 1,
|
||||||
|
copy->source.slice, 1);
|
||||||
|
|
||||||
texture->TransitionUsageNow(commandList, dawn::TextureUsageBit::TransferSrc);
|
texture->TransitionUsageNow(commandList, dawn::TextureUsageBit::TransferSrc);
|
||||||
buffer->TransitionUsageNow(commandList, dawn::BufferUsageBit::TransferDst);
|
buffer->TransitionUsageNow(commandList, dawn::BufferUsageBit::TransferDst);
|
||||||
|
|
||||||
|
@ -591,6 +611,16 @@ 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());
|
||||||
|
|
||||||
|
source->EnsureSubresourceContentInitialized(commandList, copy->source.level, 1,
|
||||||
|
copy->source.slice, 1);
|
||||||
|
if (IsCompleteSubresourceCopiedTo(destination, copy->copySize,
|
||||||
|
copy->destination.level)) {
|
||||||
|
destination->SetIsSubresourceContentInitialized(copy->destination.level, 1,
|
||||||
|
copy->destination.slice, 1);
|
||||||
|
} else {
|
||||||
|
destination->EnsureSubresourceContentInitialized(
|
||||||
|
commandList, copy->destination.level, 1, copy->destination.slice, 1);
|
||||||
|
}
|
||||||
source->TransitionUsageNow(commandList, dawn::TextureUsageBit::TransferSrc);
|
source->TransitionUsageNow(commandList, dawn::TextureUsageBit::TransferSrc);
|
||||||
destination->TransitionUsageNow(commandList,
|
destination->TransitionUsageNow(commandList,
|
||||||
dawn::TextureUsageBit::TransferDst);
|
dawn::TextureUsageBit::TransferDst);
|
||||||
|
@ -599,7 +629,6 @@ namespace dawn_native { namespace d3d12 {
|
||||||
destination->GetSize(), copy->copySize)) {
|
destination->GetSize(), copy->copySize)) {
|
||||||
commandList->CopyResource(destination->GetD3D12Resource(),
|
commandList->CopyResource(destination->GetD3D12Resource(),
|
||||||
source->GetD3D12Resource());
|
source->GetD3D12Resource());
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
D3D12_TEXTURE_COPY_LOCATION srcLocation =
|
D3D12_TEXTURE_COPY_LOCATION srcLocation =
|
||||||
CreateTextureCopyLocationForTexture(*source, copy->source.level,
|
CreateTextureCopyLocationForTexture(*source, copy->source.level,
|
||||||
|
@ -732,18 +761,43 @@ namespace dawn_native { namespace d3d12 {
|
||||||
{
|
{
|
||||||
for (uint32_t i : IterateBitSet(renderPass->colorAttachmentsSet)) {
|
for (uint32_t i : IterateBitSet(renderPass->colorAttachmentsSet)) {
|
||||||
auto& attachmentInfo = renderPass->colorAttachments[i];
|
auto& attachmentInfo = renderPass->colorAttachments[i];
|
||||||
|
TextureView* view = ToBackend(attachmentInfo.view.Get());
|
||||||
|
|
||||||
// Load op - color
|
// Load op - color
|
||||||
|
ASSERT(view->GetLevelCount() == 1);
|
||||||
|
ASSERT(view->GetLayerCount() == 1);
|
||||||
if (attachmentInfo.loadOp == dawn::LoadOp::Clear) {
|
if (attachmentInfo.loadOp == dawn::LoadOp::Clear) {
|
||||||
D3D12_CPU_DESCRIPTOR_HANDLE handle = args.RTVs[i];
|
D3D12_CPU_DESCRIPTOR_HANDLE handle = args.RTVs[i];
|
||||||
commandList->ClearRenderTargetView(handle, &attachmentInfo.clearColor.r, 0,
|
commandList->ClearRenderTargetView(handle, &attachmentInfo.clearColor.r, 0,
|
||||||
nullptr);
|
nullptr);
|
||||||
|
} else if (attachmentInfo.loadOp == dawn::LoadOp::Load && view->GetTexture()) {
|
||||||
|
ToBackend(view->GetTexture())
|
||||||
|
->EnsureSubresourceContentInitialized(commandList, view->GetBaseMipLevel(),
|
||||||
|
1, view->GetBaseArrayLayer(), 1);
|
||||||
|
}
|
||||||
|
switch (attachmentInfo.storeOp) {
|
||||||
|
case dawn::StoreOp::Store: {
|
||||||
|
view->GetTexture()->SetIsSubresourceContentInitialized(
|
||||||
|
view->GetBaseMipLevel(), 1, view->GetBaseArrayLayer(), 1);
|
||||||
|
} break;
|
||||||
|
|
||||||
|
default: { UNREACHABLE(); } break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (renderPass->hasDepthStencilAttachment) {
|
if (renderPass->hasDepthStencilAttachment) {
|
||||||
auto& attachmentInfo = renderPass->depthStencilAttachment;
|
auto& attachmentInfo = renderPass->depthStencilAttachment;
|
||||||
Texture* texture = ToBackend(renderPass->depthStencilAttachment.view->GetTexture());
|
Texture* texture = ToBackend(renderPass->depthStencilAttachment.view->GetTexture());
|
||||||
|
if ((texture->GetFormat().HasDepth() &&
|
||||||
|
attachmentInfo.depthLoadOp == dawn::LoadOp::Load) ||
|
||||||
|
(texture->GetFormat().HasStencil() &&
|
||||||
|
attachmentInfo.stencilLoadOp == dawn::LoadOp::Load)) {
|
||||||
|
texture->EnsureSubresourceContentInitialized(
|
||||||
|
commandList, attachmentInfo.view->GetBaseMipLevel(),
|
||||||
|
attachmentInfo.view->GetLevelCount(),
|
||||||
|
attachmentInfo.view->GetBaseArrayLayer(),
|
||||||
|
attachmentInfo.view->GetLayerCount());
|
||||||
|
}
|
||||||
|
|
||||||
// Load op - depth/stencil
|
// Load op - depth/stencil
|
||||||
bool doDepthClear = texture->GetFormat().HasDepth() &&
|
bool doDepthClear = texture->GetFormat().HasDepth() &&
|
||||||
|
@ -766,6 +820,11 @@ namespace dawn_native { namespace d3d12 {
|
||||||
uint8_t clearStencil = static_cast<uint8_t>(attachmentInfo.clearStencil);
|
uint8_t clearStencil = static_cast<uint8_t>(attachmentInfo.clearStencil);
|
||||||
commandList->ClearDepthStencilView(
|
commandList->ClearDepthStencilView(
|
||||||
handle, clearFlags, attachmentInfo.clearDepth, clearStencil, 0, nullptr);
|
handle, clearFlags, attachmentInfo.clearDepth, clearStencil, 0, nullptr);
|
||||||
|
texture->SetIsSubresourceContentInitialized(
|
||||||
|
attachmentInfo.view->GetBaseMipLevel(),
|
||||||
|
attachmentInfo.view->GetLevelCount(),
|
||||||
|
attachmentInfo.view->GetBaseArrayLayer(),
|
||||||
|
attachmentInfo.view->GetLayerCount());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,6 +72,12 @@ namespace dawn_native { namespace d3d12 {
|
||||||
} else {
|
} else {
|
||||||
flags |= D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET;
|
flags |= D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET;
|
||||||
}
|
}
|
||||||
|
} else if ((usage & dawn::TextureUsageBit::TransferDst) ||
|
||||||
|
(usage & dawn::TextureUsageBit::TransferSrc)) {
|
||||||
|
// if texture is used as copy source or destination, it may need to be
|
||||||
|
// cleared/initialized, which requires it to be a render target
|
||||||
|
// TODO(natlee@microsoft.com): optimize texture clearing without render target
|
||||||
|
flags |= D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET;
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT(!(flags & D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL) ||
|
ASSERT(!(flags & D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL) ||
|
||||||
|
@ -140,21 +146,43 @@ namespace dawn_native { namespace d3d12 {
|
||||||
mResourcePtr = mResource.Get();
|
mResourcePtr = mResource.Get();
|
||||||
|
|
||||||
if (device->IsToggleEnabled(Toggle::NonzeroClearResourcesOnCreationForTesting)) {
|
if (device->IsToggleEnabled(Toggle::NonzeroClearResourcesOnCreationForTesting)) {
|
||||||
TransitionUsageNow(device->GetPendingCommandList(), D3D12_RESOURCE_STATE_RENDER_TARGET);
|
|
||||||
uint32_t arrayLayerCount = GetArrayLayers();
|
|
||||||
|
|
||||||
DescriptorHeapAllocator* descriptorHeapAllocator = device->GetDescriptorHeapAllocator();
|
DescriptorHeapAllocator* descriptorHeapAllocator = device->GetDescriptorHeapAllocator();
|
||||||
DescriptorHeapHandle rtvHeap =
|
if (GetFormat().HasDepthOrStencil()) {
|
||||||
descriptorHeapAllocator->AllocateCPUHeap(D3D12_DESCRIPTOR_HEAP_TYPE_RTV, 1);
|
TransitionUsageNow(device->GetPendingCommandList(),
|
||||||
D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle = rtvHeap.GetCPUHandle(0);
|
D3D12_RESOURCE_STATE_DEPTH_WRITE);
|
||||||
|
DescriptorHeapHandle dsvHeap =
|
||||||
|
descriptorHeapAllocator->AllocateCPUHeap(D3D12_DESCRIPTOR_HEAP_TYPE_DSV, 1);
|
||||||
|
D3D12_CPU_DESCRIPTOR_HANDLE dsvHandle = dsvHeap.GetCPUHandle(0);
|
||||||
|
D3D12_DEPTH_STENCIL_VIEW_DESC dsvDesc = GetDSVDescriptor(0);
|
||||||
|
device->GetD3D12Device()->CreateDepthStencilView(mResourcePtr, &dsvDesc, dsvHandle);
|
||||||
|
|
||||||
const float clearColor[4] = {1.0f, 1.0f, 1.0f, 1.0f};
|
D3D12_CLEAR_FLAGS clearFlags = {};
|
||||||
// TODO(natlee@microsoft.com): clear all array layers for 2D array textures
|
if (GetFormat().HasDepth()) {
|
||||||
for (int i = 0; i < resourceDescriptor.MipLevels; i++) {
|
clearFlags |= D3D12_CLEAR_FLAG_DEPTH;
|
||||||
D3D12_RENDER_TARGET_VIEW_DESC rtvDesc = GetRTVDescriptor(i, arrayLayerCount, 0);
|
}
|
||||||
device->GetD3D12Device()->CreateRenderTargetView(mResourcePtr, &rtvDesc, rtvHandle);
|
if (GetFormat().HasStencil()) {
|
||||||
device->GetPendingCommandList()->ClearRenderTargetView(rtvHandle, clearColor, 0,
|
clearFlags |= D3D12_CLEAR_FLAG_STENCIL;
|
||||||
nullptr);
|
}
|
||||||
|
|
||||||
|
device->GetPendingCommandList()->ClearDepthStencilView(dsvHandle, clearFlags, 1.0f,
|
||||||
|
1u, 0, nullptr);
|
||||||
|
} else {
|
||||||
|
TransitionUsageNow(device->GetPendingCommandList(),
|
||||||
|
D3D12_RESOURCE_STATE_RENDER_TARGET);
|
||||||
|
DescriptorHeapHandle rtvHeap =
|
||||||
|
descriptorHeapAllocator->AllocateCPUHeap(D3D12_DESCRIPTOR_HEAP_TYPE_RTV, 1);
|
||||||
|
D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle = rtvHeap.GetCPUHandle(0);
|
||||||
|
|
||||||
|
const float clearColor[4] = {1.0f, 1.0f, 1.0f, 1.0f};
|
||||||
|
// TODO(natlee@microsoft.com): clear all array layers for 2D array textures
|
||||||
|
for (int i = 0; i < resourceDescriptor.MipLevels; i++) {
|
||||||
|
D3D12_RENDER_TARGET_VIEW_DESC rtvDesc =
|
||||||
|
GetRTVDescriptor(i, 0, GetArrayLayers());
|
||||||
|
device->GetD3D12Device()->CreateRenderTargetView(mResourcePtr, &rtvDesc,
|
||||||
|
rtvHandle);
|
||||||
|
device->GetPendingCommandList()->ClearRenderTargetView(rtvHandle, clearColor, 0,
|
||||||
|
nullptr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -259,17 +287,17 @@ namespace dawn_native { namespace d3d12 {
|
||||||
mLastState = newState;
|
mLastState = newState;
|
||||||
}
|
}
|
||||||
|
|
||||||
D3D12_RENDER_TARGET_VIEW_DESC Texture::GetRTVDescriptor(uint32_t mipSlice,
|
D3D12_RENDER_TARGET_VIEW_DESC Texture::GetRTVDescriptor(uint32_t baseMipLevel,
|
||||||
uint32_t arrayLayers,
|
uint32_t baseArrayLayer,
|
||||||
uint32_t baseArrayLayer) const {
|
uint32_t layerCount) const {
|
||||||
ASSERT(GetDimension() == dawn::TextureDimension::e2D);
|
ASSERT(GetDimension() == dawn::TextureDimension::e2D);
|
||||||
D3D12_RENDER_TARGET_VIEW_DESC rtvDesc;
|
D3D12_RENDER_TARGET_VIEW_DESC rtvDesc;
|
||||||
rtvDesc.Format = GetD3D12Format();
|
rtvDesc.Format = GetD3D12Format();
|
||||||
if (IsMultisampledTexture()) {
|
if (IsMultisampledTexture()) {
|
||||||
ASSERT(GetNumMipLevels() == 1);
|
ASSERT(GetNumMipLevels() == 1);
|
||||||
ASSERT(arrayLayers == 1);
|
ASSERT(layerCount == 1);
|
||||||
ASSERT(baseArrayLayer == 0);
|
ASSERT(baseArrayLayer == 0);
|
||||||
ASSERT(mipSlice == 0);
|
ASSERT(baseMipLevel == 0);
|
||||||
rtvDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2DMS;
|
rtvDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2DMS;
|
||||||
} else {
|
} else {
|
||||||
// Currently we always use D3D12_TEX2D_ARRAY_RTV because we cannot specify base array
|
// Currently we always use D3D12_TEX2D_ARRAY_RTV because we cannot specify base array
|
||||||
|
@ -280,13 +308,88 @@ namespace dawn_native { namespace d3d12 {
|
||||||
// _rtv
|
// _rtv
|
||||||
rtvDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2DARRAY;
|
rtvDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2DARRAY;
|
||||||
rtvDesc.Texture2DArray.FirstArraySlice = baseArrayLayer;
|
rtvDesc.Texture2DArray.FirstArraySlice = baseArrayLayer;
|
||||||
rtvDesc.Texture2DArray.ArraySize = arrayLayers;
|
rtvDesc.Texture2DArray.ArraySize = layerCount;
|
||||||
rtvDesc.Texture2DArray.MipSlice = mipSlice;
|
rtvDesc.Texture2DArray.MipSlice = baseMipLevel;
|
||||||
rtvDesc.Texture2DArray.PlaneSlice = 0;
|
rtvDesc.Texture2DArray.PlaneSlice = 0;
|
||||||
}
|
}
|
||||||
return rtvDesc;
|
return rtvDesc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
D3D12_DEPTH_STENCIL_VIEW_DESC Texture::GetDSVDescriptor(uint32_t baseMipLevel) const {
|
||||||
|
D3D12_DEPTH_STENCIL_VIEW_DESC dsvDesc;
|
||||||
|
dsvDesc.Format = GetD3D12Format();
|
||||||
|
dsvDesc.Flags = D3D12_DSV_FLAG_NONE;
|
||||||
|
ASSERT(baseMipLevel == 0);
|
||||||
|
|
||||||
|
if (IsMultisampledTexture()) {
|
||||||
|
dsvDesc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2DMS;
|
||||||
|
} else {
|
||||||
|
dsvDesc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2D;
|
||||||
|
dsvDesc.Texture2D.MipSlice = baseMipLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
return dsvDesc;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Texture::ClearTexture(ComPtr<ID3D12GraphicsCommandList> commandList,
|
||||||
|
uint32_t baseMipLevel,
|
||||||
|
uint32_t levelCount,
|
||||||
|
uint32_t baseArrayLayer,
|
||||||
|
uint32_t layerCount) {
|
||||||
|
Device* device = ToBackend(GetDevice());
|
||||||
|
DescriptorHeapAllocator* descriptorHeapAllocator = device->GetDescriptorHeapAllocator();
|
||||||
|
|
||||||
|
if (GetFormat().HasDepthOrStencil()) {
|
||||||
|
TransitionUsageNow(commandList, D3D12_RESOURCE_STATE_DEPTH_WRITE);
|
||||||
|
DescriptorHeapHandle dsvHeap =
|
||||||
|
descriptorHeapAllocator->AllocateCPUHeap(D3D12_DESCRIPTOR_HEAP_TYPE_DSV, 1);
|
||||||
|
D3D12_CPU_DESCRIPTOR_HANDLE dsvHandle = dsvHeap.GetCPUHandle(0);
|
||||||
|
D3D12_DEPTH_STENCIL_VIEW_DESC dsvDesc = GetDSVDescriptor(baseMipLevel);
|
||||||
|
device->GetD3D12Device()->CreateDepthStencilView(mResourcePtr, &dsvDesc, dsvHandle);
|
||||||
|
|
||||||
|
D3D12_CLEAR_FLAGS clearFlags = {};
|
||||||
|
if (GetFormat().HasDepth()) {
|
||||||
|
clearFlags |= D3D12_CLEAR_FLAG_DEPTH;
|
||||||
|
}
|
||||||
|
if (GetFormat().HasStencil()) {
|
||||||
|
clearFlags |= D3D12_CLEAR_FLAG_STENCIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
commandList->ClearDepthStencilView(dsvHandle, clearFlags, 0.0f, 0u, 0, nullptr);
|
||||||
|
} else {
|
||||||
|
TransitionUsageNow(commandList, D3D12_RESOURCE_STATE_RENDER_TARGET);
|
||||||
|
DescriptorHeapHandle rtvHeap =
|
||||||
|
descriptorHeapAllocator->AllocateCPUHeap(D3D12_DESCRIPTOR_HEAP_TYPE_RTV, 1);
|
||||||
|
D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle = rtvHeap.GetCPUHandle(0);
|
||||||
|
const float clearColor[4] = {0.0f, 0.0f, 0.0f, 0.0f};
|
||||||
|
|
||||||
|
// TODO(natlee@microsoft.com): clear all array layers for 2D array textures
|
||||||
|
for (uint32_t i = baseMipLevel; i < baseMipLevel + levelCount; i++) {
|
||||||
|
D3D12_RENDER_TARGET_VIEW_DESC rtvDesc =
|
||||||
|
GetRTVDescriptor(i, baseArrayLayer, layerCount);
|
||||||
|
device->GetD3D12Device()->CreateRenderTargetView(mResourcePtr, &rtvDesc, rtvHandle);
|
||||||
|
commandList->ClearRenderTargetView(rtvHandle, clearColor, 0, nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SetIsSubresourceContentInitialized(baseMipLevel, levelCount, baseArrayLayer, layerCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Texture::EnsureSubresourceContentInitialized(ComPtr<ID3D12GraphicsCommandList> commandList,
|
||||||
|
uint32_t baseMipLevel,
|
||||||
|
uint32_t levelCount,
|
||||||
|
uint32_t baseArrayLayer,
|
||||||
|
uint32_t layerCount) {
|
||||||
|
if (!ToBackend(GetDevice())->IsToggleEnabled(Toggle::LazyClearResourceOnFirstUse)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!IsSubresourceContentInitialized(baseMipLevel, levelCount, baseArrayLayer,
|
||||||
|
layerCount)) {
|
||||||
|
// If subresource has not been initialized, clear it to black as it could contain
|
||||||
|
// dirty bits from recycled memory
|
||||||
|
ClearTexture(commandList, baseMipLevel, levelCount, baseArrayLayer, layerCount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TextureView::TextureView(TextureBase* texture, const TextureViewDescriptor* descriptor)
|
TextureView::TextureView(TextureBase* texture, const TextureViewDescriptor* descriptor)
|
||||||
: TextureViewBase(texture, descriptor) {
|
: TextureViewBase(texture, descriptor) {
|
||||||
mSrvDesc.Format = D3D12TextureFormat(descriptor->format);
|
mSrvDesc.Format = D3D12TextureFormat(descriptor->format);
|
||||||
|
@ -337,26 +440,16 @@ namespace dawn_native { namespace d3d12 {
|
||||||
|
|
||||||
D3D12_RENDER_TARGET_VIEW_DESC TextureView::GetRTVDescriptor() const {
|
D3D12_RENDER_TARGET_VIEW_DESC TextureView::GetRTVDescriptor() const {
|
||||||
return ToBackend(GetTexture())
|
return ToBackend(GetTexture())
|
||||||
->GetRTVDescriptor(GetBaseMipLevel(), GetLayerCount(), GetBaseArrayLayer());
|
->GetRTVDescriptor(GetBaseMipLevel(), GetBaseArrayLayer(), GetLayerCount());
|
||||||
}
|
}
|
||||||
|
|
||||||
D3D12_DEPTH_STENCIL_VIEW_DESC TextureView::GetDSVDescriptor() const {
|
D3D12_DEPTH_STENCIL_VIEW_DESC TextureView::GetDSVDescriptor() const {
|
||||||
D3D12_DEPTH_STENCIL_VIEW_DESC dsvDesc;
|
|
||||||
dsvDesc.Format = ToBackend(GetTexture())->GetD3D12Format();
|
|
||||||
dsvDesc.Flags = D3D12_DSV_FLAG_NONE;
|
|
||||||
|
|
||||||
// TODO(jiawei.shao@intel.com): support rendering into a layer of a texture.
|
// TODO(jiawei.shao@intel.com): support rendering into a layer of a texture.
|
||||||
ASSERT(GetTexture()->GetArrayLayers() == 1 && GetTexture()->GetNumMipLevels() == 1 &&
|
ASSERT(GetLayerCount() == 1);
|
||||||
GetBaseArrayLayer() == 0 && GetBaseMipLevel() == 0);
|
ASSERT(GetLevelCount() == 1);
|
||||||
|
ASSERT(GetBaseMipLevel() == 0);
|
||||||
if (GetTexture()->IsMultisampledTexture()) {
|
ASSERT(GetBaseArrayLayer() == 0);
|
||||||
dsvDesc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2DMS;
|
return ToBackend(GetTexture())->GetDSVDescriptor(GetBaseMipLevel());
|
||||||
} else {
|
|
||||||
dsvDesc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2D;
|
|
||||||
dsvDesc.Texture2D.MipSlice = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return dsvDesc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}} // namespace dawn_native::d3d12
|
}} // namespace dawn_native::d3d12
|
||||||
|
|
|
@ -43,13 +43,24 @@ namespace dawn_native { namespace d3d12 {
|
||||||
void TransitionUsageNow(ComPtr<ID3D12GraphicsCommandList> commandList,
|
void TransitionUsageNow(ComPtr<ID3D12GraphicsCommandList> commandList,
|
||||||
D3D12_RESOURCE_STATES newState);
|
D3D12_RESOURCE_STATES newState);
|
||||||
|
|
||||||
D3D12_RENDER_TARGET_VIEW_DESC GetRTVDescriptor(uint32_t mipSlice,
|
D3D12_RENDER_TARGET_VIEW_DESC GetRTVDescriptor(uint32_t baseMipLevel,
|
||||||
uint32_t arrayLayers,
|
uint32_t baseArrayLayer,
|
||||||
uint32_t baseArrayLayer) const;
|
uint32_t layerCount) const;
|
||||||
|
D3D12_DEPTH_STENCIL_VIEW_DESC GetDSVDescriptor(uint32_t baseMipLevel) const;
|
||||||
|
void EnsureSubresourceContentInitialized(ComPtr<ID3D12GraphicsCommandList> commandList,
|
||||||
|
uint32_t baseMipLevel,
|
||||||
|
uint32_t levelCount,
|
||||||
|
uint32_t baseArrayLayer,
|
||||||
|
uint32_t layerCount);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Dawn API
|
// Dawn API
|
||||||
void DestroyImpl() override;
|
void DestroyImpl() override;
|
||||||
|
void ClearTexture(ComPtr<ID3D12GraphicsCommandList> commandList,
|
||||||
|
uint32_t baseMipLevel,
|
||||||
|
uint32_t levelCount,
|
||||||
|
uint32_t baseArrayLayer,
|
||||||
|
uint32_t layerCount);
|
||||||
|
|
||||||
UINT16 GetDepthOrArraySize();
|
UINT16 GetDepthOrArraySize();
|
||||||
|
|
||||||
|
|
|
@ -400,5 +400,7 @@ TEST_P(TextureZeroInitTest, DepthStencilClear) {
|
||||||
}
|
}
|
||||||
|
|
||||||
DAWN_INSTANTIATE_TEST(TextureZeroInitTest,
|
DAWN_INSTANTIATE_TEST(TextureZeroInitTest,
|
||||||
|
ForceWorkarounds(D3D12Backend,
|
||||||
|
{"nonzero_clear_resources_on_creation_for_testing"}),
|
||||||
ForceWorkarounds(VulkanBackend,
|
ForceWorkarounds(VulkanBackend,
|
||||||
{"nonzero_clear_resources_on_creation_for_testing"}));
|
{"nonzero_clear_resources_on_creation_for_testing"}));
|
||||||
|
|
Loading…
Reference in New Issue