| /* |
| * Copyright 2020 Google LLC |
| * |
| * Use of this source code is governed by a BSD-style license that can be |
| * found in the LICENSE file. |
| */ |
| |
| #include "src/gpu/ganesh/GrGpuResourcePriv.h" |
| #include "src/gpu/ganesh/d3d/GrD3DAMDMemoryAllocator.h" |
| #include "src/gpu/ganesh/d3d/GrD3DGpu.h" |
| #include "src/gpu/ganesh/d3d/GrD3DTextureResource.h" |
| |
| void GrD3DTextureResource::setResourceState(const GrD3DGpu* gpu, |
| D3D12_RESOURCE_STATES newResourceState, |
| unsigned int subresource) { |
| D3D12_RESOURCE_STATES currentResourceState = this->currentState(); |
| if (newResourceState == currentResourceState) { |
| return; |
| } |
| |
| D3D12_RESOURCE_TRANSITION_BARRIER barrier; |
| barrier.pResource = this->d3dResource(); |
| barrier.Subresource = subresource; |
| barrier.StateBefore = currentResourceState; |
| barrier.StateAfter = newResourceState; |
| gpu->addResourceBarriers(this->resource(), 1, &barrier); |
| |
| this->updateResourceState(newResourceState); |
| } |
| |
| bool GrD3DTextureResource::InitTextureResourceInfo(GrD3DGpu* gpu, const D3D12_RESOURCE_DESC& desc, |
| D3D12_RESOURCE_STATES initialState, |
| GrProtected isProtected, |
| D3D12_CLEAR_VALUE* clearValue, |
| GrD3DTextureResourceInfo* info) { |
| if (0 == desc.Width || 0 == desc.Height) { |
| return false; |
| } |
| // TODO: We don't support protected memory at the moment |
| if (isProtected == GrProtected::kYes) { |
| return false; |
| } |
| // If MipLevels is 0, for some formats the API will automatically calculate the maximum |
| // number of levels supported and use that -- we don't support that. |
| SkASSERT(desc.MipLevels > 0); |
| |
| info->fResource = gpu->memoryAllocator()->createResource( |
| D3D12_HEAP_TYPE_DEFAULT, &desc, initialState, &info->fAlloc, clearValue); |
| if (!info->fResource) { |
| return false; |
| } |
| |
| info->fResourceState = initialState; |
| info->fFormat = desc.Format; |
| info->fLevelCount = desc.MipLevels; |
| info->fSampleCount = desc.SampleDesc.Count; |
| info->fSampleQualityPattern = desc.SampleDesc.Quality; |
| info->fProtected = isProtected; |
| |
| return true; |
| } |
| |
| std::pair<GrD3DTextureResourceInfo, sk_sp<GrD3DResourceState>> GrD3DTextureResource::CreateMSAA( |
| GrD3DGpu* gpu, SkISize dimensions, int sampleCnt, const GrD3DTextureResourceInfo& info, |
| SkColor4f clearColor) { |
| GrD3DTextureResourceInfo msInfo; |
| sk_sp<GrD3DResourceState> msState; |
| |
| // create msaa surface |
| D3D12_RESOURCE_DESC msTextureDesc = {}; |
| msTextureDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D; |
| msTextureDesc.Alignment = 0; // Default alignment (64KB) |
| msTextureDesc.Width = dimensions.fWidth; |
| msTextureDesc.Height = dimensions.fHeight; |
| msTextureDesc.DepthOrArraySize = 1; |
| msTextureDesc.MipLevels = 1; |
| msTextureDesc.Format = info.fFormat; |
| msTextureDesc.SampleDesc.Count = sampleCnt; |
| msTextureDesc.SampleDesc.Quality = DXGI_STANDARD_MULTISAMPLE_QUALITY_PATTERN; |
| msTextureDesc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN; // Use default for dxgi format |
| msTextureDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET; |
| |
| D3D12_CLEAR_VALUE clearValue = {}; |
| clearValue.Format = info.fFormat; |
| clearValue.Color[0] = clearColor.fR; |
| clearValue.Color[1] = clearColor.fG; |
| clearValue.Color[2] = clearColor.fB; |
| clearValue.Color[3] = clearColor.fA; |
| |
| if (!InitTextureResourceInfo(gpu, msTextureDesc, D3D12_RESOURCE_STATE_RENDER_TARGET, |
| info.fProtected, &clearValue, &msInfo)) { |
| return {}; |
| } |
| |
| msState.reset(new GrD3DResourceState( |
| static_cast<D3D12_RESOURCE_STATES>(msInfo.fResourceState))); |
| |
| return std::make_pair(msInfo, msState); |
| } |
| |
| GrD3DTextureResource::~GrD3DTextureResource() { |
| // Should have been reset() before |
| SkASSERT(!fResource); |
| SkASSERT(!fInfo.fResource); |
| } |
| |
| void GrD3DTextureResource::prepareForPresent(GrD3DGpu* gpu) { |
| this->setResourceState(gpu, D3D12_RESOURCE_STATE_PRESENT); |
| } |
| |
| void GrD3DTextureResource::releaseResource(GrD3DGpu* gpu) { |
| // TODO: do we need to migrate resource state if we change queues? |
| if (fResource) { |
| fResource.reset(); |
| } |
| fInfo.fResource.reset(); |
| fInfo.fAlloc.reset(); |
| } |
| |
| void GrD3DTextureResource::setResourceRelease(sk_sp<GrSurface::RefCntedReleaseProc> releaseHelper) { |
| SkASSERT(fResource); |
| // Forward the release proc on to GrD3DTextureResource::Resource |
| fResource->setRelease(std::move(releaseHelper)); |
| } |
| |
| void GrD3DTextureResource::Resource::freeGPUData() const { |
| this->invokeReleaseProc(); |
| fResource.reset(); // Release our ref to the resource |
| fAlloc.reset(); // Release our ref to the allocation |
| } |