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