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