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