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