1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2020 Google LLC 3cb93a386Sopenharmony_ci * 4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be 5cb93a386Sopenharmony_ci * found in the LICENSE file. 6cb93a386Sopenharmony_ci */ 7cb93a386Sopenharmony_ci 8cb93a386Sopenharmony_ci#include "src/gpu/GrGpuResourcePriv.h" 9cb93a386Sopenharmony_ci#include "src/gpu/d3d/GrD3DAMDMemoryAllocator.h" 10cb93a386Sopenharmony_ci#include "src/gpu/d3d/GrD3DGpu.h" 11cb93a386Sopenharmony_ci#include "src/gpu/d3d/GrD3DTextureResource.h" 12cb93a386Sopenharmony_ci 13cb93a386Sopenharmony_civoid GrD3DTextureResource::setResourceState(const GrD3DGpu* gpu, 14cb93a386Sopenharmony_ci D3D12_RESOURCE_STATES newResourceState, 15cb93a386Sopenharmony_ci unsigned int subresource) { 16cb93a386Sopenharmony_ci D3D12_RESOURCE_STATES currentResourceState = this->currentState(); 17cb93a386Sopenharmony_ci if (newResourceState == currentResourceState) { 18cb93a386Sopenharmony_ci return; 19cb93a386Sopenharmony_ci } 20cb93a386Sopenharmony_ci 21cb93a386Sopenharmony_ci D3D12_RESOURCE_TRANSITION_BARRIER barrier; 22cb93a386Sopenharmony_ci barrier.pResource = this->d3dResource(); 23cb93a386Sopenharmony_ci barrier.Subresource = subresource; 24cb93a386Sopenharmony_ci barrier.StateBefore = currentResourceState; 25cb93a386Sopenharmony_ci barrier.StateAfter = newResourceState; 26cb93a386Sopenharmony_ci gpu->addResourceBarriers(this->resource(), 1, &barrier); 27cb93a386Sopenharmony_ci 28cb93a386Sopenharmony_ci this->updateResourceState(newResourceState); 29cb93a386Sopenharmony_ci} 30cb93a386Sopenharmony_ci 31cb93a386Sopenharmony_cibool GrD3DTextureResource::InitTextureResourceInfo(GrD3DGpu* gpu, const D3D12_RESOURCE_DESC& desc, 32cb93a386Sopenharmony_ci D3D12_RESOURCE_STATES initialState, 33cb93a386Sopenharmony_ci GrProtected isProtected, 34cb93a386Sopenharmony_ci D3D12_CLEAR_VALUE* clearValue, 35cb93a386Sopenharmony_ci GrD3DTextureResourceInfo* info) { 36cb93a386Sopenharmony_ci if (0 == desc.Width || 0 == desc.Height) { 37cb93a386Sopenharmony_ci return false; 38cb93a386Sopenharmony_ci } 39cb93a386Sopenharmony_ci // TODO: We don't support protected memory at the moment 40cb93a386Sopenharmony_ci if (isProtected == GrProtected::kYes) { 41cb93a386Sopenharmony_ci return false; 42cb93a386Sopenharmony_ci } 43cb93a386Sopenharmony_ci // If MipLevels is 0, for some formats the API will automatically calculate the maximum 44cb93a386Sopenharmony_ci // number of levels supported and use that -- we don't support that. 45cb93a386Sopenharmony_ci SkASSERT(desc.MipLevels > 0); 46cb93a386Sopenharmony_ci 47cb93a386Sopenharmony_ci info->fResource = gpu->memoryAllocator()->createResource( 48cb93a386Sopenharmony_ci D3D12_HEAP_TYPE_DEFAULT, &desc, initialState, &info->fAlloc, clearValue); 49cb93a386Sopenharmony_ci if (!info->fResource) { 50cb93a386Sopenharmony_ci return false; 51cb93a386Sopenharmony_ci } 52cb93a386Sopenharmony_ci 53cb93a386Sopenharmony_ci info->fResourceState = initialState; 54cb93a386Sopenharmony_ci info->fFormat = desc.Format; 55cb93a386Sopenharmony_ci info->fLevelCount = desc.MipLevels; 56cb93a386Sopenharmony_ci info->fSampleCount = desc.SampleDesc.Count; 57cb93a386Sopenharmony_ci info->fSampleQualityPattern = desc.SampleDesc.Quality; 58cb93a386Sopenharmony_ci info->fProtected = isProtected; 59cb93a386Sopenharmony_ci 60cb93a386Sopenharmony_ci return true; 61cb93a386Sopenharmony_ci} 62cb93a386Sopenharmony_ci 63cb93a386Sopenharmony_cistd::pair<GrD3DTextureResourceInfo, sk_sp<GrD3DResourceState>> GrD3DTextureResource::CreateMSAA( 64cb93a386Sopenharmony_ci GrD3DGpu* gpu, SkISize dimensions, int sampleCnt, const GrD3DTextureResourceInfo& info, 65cb93a386Sopenharmony_ci SkColor4f clearColor) { 66cb93a386Sopenharmony_ci GrD3DTextureResourceInfo msInfo; 67cb93a386Sopenharmony_ci sk_sp<GrD3DResourceState> msState; 68cb93a386Sopenharmony_ci 69cb93a386Sopenharmony_ci // create msaa surface 70cb93a386Sopenharmony_ci D3D12_RESOURCE_DESC msTextureDesc = {}; 71cb93a386Sopenharmony_ci msTextureDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D; 72cb93a386Sopenharmony_ci msTextureDesc.Alignment = 0; // Default alignment (64KB) 73cb93a386Sopenharmony_ci msTextureDesc.Width = dimensions.fWidth; 74cb93a386Sopenharmony_ci msTextureDesc.Height = dimensions.fHeight; 75cb93a386Sopenharmony_ci msTextureDesc.DepthOrArraySize = 1; 76cb93a386Sopenharmony_ci msTextureDesc.MipLevels = 1; 77cb93a386Sopenharmony_ci msTextureDesc.Format = info.fFormat; 78cb93a386Sopenharmony_ci msTextureDesc.SampleDesc.Count = sampleCnt; 79cb93a386Sopenharmony_ci msTextureDesc.SampleDesc.Quality = DXGI_STANDARD_MULTISAMPLE_QUALITY_PATTERN; 80cb93a386Sopenharmony_ci msTextureDesc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN; // Use default for dxgi format 81cb93a386Sopenharmony_ci msTextureDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET; 82cb93a386Sopenharmony_ci 83cb93a386Sopenharmony_ci D3D12_CLEAR_VALUE clearValue = {}; 84cb93a386Sopenharmony_ci clearValue.Format = info.fFormat; 85cb93a386Sopenharmony_ci clearValue.Color[0] = clearColor.fR; 86cb93a386Sopenharmony_ci clearValue.Color[1] = clearColor.fG; 87cb93a386Sopenharmony_ci clearValue.Color[2] = clearColor.fB; 88cb93a386Sopenharmony_ci clearValue.Color[3] = clearColor.fA; 89cb93a386Sopenharmony_ci 90cb93a386Sopenharmony_ci if (!InitTextureResourceInfo(gpu, msTextureDesc, D3D12_RESOURCE_STATE_RENDER_TARGET, 91cb93a386Sopenharmony_ci info.fProtected, &clearValue, &msInfo)) { 92cb93a386Sopenharmony_ci return {}; 93cb93a386Sopenharmony_ci } 94cb93a386Sopenharmony_ci 95cb93a386Sopenharmony_ci msState.reset(new GrD3DResourceState( 96cb93a386Sopenharmony_ci static_cast<D3D12_RESOURCE_STATES>(msInfo.fResourceState))); 97cb93a386Sopenharmony_ci 98cb93a386Sopenharmony_ci return std::make_pair(msInfo, msState); 99cb93a386Sopenharmony_ci} 100cb93a386Sopenharmony_ci 101cb93a386Sopenharmony_ciGrD3DTextureResource::~GrD3DTextureResource() { 102cb93a386Sopenharmony_ci // Should have been reset() before 103cb93a386Sopenharmony_ci SkASSERT(!fResource); 104cb93a386Sopenharmony_ci SkASSERT(!fInfo.fResource); 105cb93a386Sopenharmony_ci} 106cb93a386Sopenharmony_ci 107cb93a386Sopenharmony_civoid GrD3DTextureResource::prepareForPresent(GrD3DGpu* gpu) { 108cb93a386Sopenharmony_ci this->setResourceState(gpu, D3D12_RESOURCE_STATE_PRESENT); 109cb93a386Sopenharmony_ci} 110cb93a386Sopenharmony_ci 111cb93a386Sopenharmony_civoid GrD3DTextureResource::releaseResource(GrD3DGpu* gpu) { 112cb93a386Sopenharmony_ci // TODO: do we need to migrate resource state if we change queues? 113cb93a386Sopenharmony_ci if (fResource) { 114cb93a386Sopenharmony_ci fResource.reset(); 115cb93a386Sopenharmony_ci } 116cb93a386Sopenharmony_ci fInfo.fResource.reset(); 117cb93a386Sopenharmony_ci fInfo.fAlloc.reset(); 118cb93a386Sopenharmony_ci} 119cb93a386Sopenharmony_ci 120cb93a386Sopenharmony_civoid GrD3DTextureResource::setResourceRelease(sk_sp<GrRefCntedCallback> releaseHelper) { 121cb93a386Sopenharmony_ci SkASSERT(fResource); 122cb93a386Sopenharmony_ci // Forward the release proc on to GrD3DTextureResource::Resource 123cb93a386Sopenharmony_ci fResource->setRelease(std::move(releaseHelper)); 124cb93a386Sopenharmony_ci} 125cb93a386Sopenharmony_ci 126cb93a386Sopenharmony_civoid GrD3DTextureResource::Resource::freeGPUData() const { 127cb93a386Sopenharmony_ci this->invokeReleaseProc(); 128cb93a386Sopenharmony_ci fResource.reset(); // Release our ref to the resource 129cb93a386Sopenharmony_ci fAlloc.reset(); // Release our ref to the allocation 130cb93a386Sopenharmony_ci} 131