xref: /aosp_15_r20/external/skia/src/gpu/ganesh/d3d/GrD3DBuffer.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/d3d/GrD3DBuffer.h"
9*c8dee2aaSAndroid Build Coastguard Worker 
10*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/d3d/GrD3DGpu.h"
11*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/d3d/GrD3DUtil.h"
12*c8dee2aaSAndroid Build Coastguard Worker 
13*c8dee2aaSAndroid Build Coastguard Worker #ifdef SK_DEBUG
14*c8dee2aaSAndroid Build Coastguard Worker #define VALIDATE() this->validate()
15*c8dee2aaSAndroid Build Coastguard Worker #else
16*c8dee2aaSAndroid Build Coastguard Worker #define VALIDATE() do {} while(false)
17*c8dee2aaSAndroid Build Coastguard Worker #endif
18*c8dee2aaSAndroid Build Coastguard Worker 
make_d3d_buffer(GrD3DGpu * gpu,size_t size,GrGpuBufferType intendedType,GrAccessPattern accessPattern,D3D12_RESOURCE_STATES * resourceState,sk_sp<GrD3DAlloc> * alloc)19*c8dee2aaSAndroid Build Coastguard Worker static gr_cp<ID3D12Resource> make_d3d_buffer(GrD3DGpu* gpu,
20*c8dee2aaSAndroid Build Coastguard Worker                                              size_t size,
21*c8dee2aaSAndroid Build Coastguard Worker                                              GrGpuBufferType intendedType,
22*c8dee2aaSAndroid Build Coastguard Worker                                              GrAccessPattern accessPattern,
23*c8dee2aaSAndroid Build Coastguard Worker                                              D3D12_RESOURCE_STATES* resourceState,
24*c8dee2aaSAndroid Build Coastguard Worker                                              sk_sp<GrD3DAlloc>* alloc) {
25*c8dee2aaSAndroid Build Coastguard Worker     D3D12_HEAP_TYPE heapType;
26*c8dee2aaSAndroid Build Coastguard Worker     if (accessPattern == kStatic_GrAccessPattern) {
27*c8dee2aaSAndroid Build Coastguard Worker         SkASSERT(intendedType != GrGpuBufferType::kXferCpuToGpu &&
28*c8dee2aaSAndroid Build Coastguard Worker                  intendedType != GrGpuBufferType::kXferGpuToCpu);
29*c8dee2aaSAndroid Build Coastguard Worker         heapType = D3D12_HEAP_TYPE_DEFAULT;
30*c8dee2aaSAndroid Build Coastguard Worker         // Needs to be transitioned to appropriate state to be read in shader
31*c8dee2aaSAndroid Build Coastguard Worker         *resourceState = D3D12_RESOURCE_STATE_COPY_DEST;
32*c8dee2aaSAndroid Build Coastguard Worker     } else {
33*c8dee2aaSAndroid Build Coastguard Worker         if (intendedType == GrGpuBufferType::kXferGpuToCpu) {
34*c8dee2aaSAndroid Build Coastguard Worker             heapType = D3D12_HEAP_TYPE_READBACK;
35*c8dee2aaSAndroid Build Coastguard Worker             // Cannot be changed
36*c8dee2aaSAndroid Build Coastguard Worker             *resourceState = D3D12_RESOURCE_STATE_COPY_DEST;
37*c8dee2aaSAndroid Build Coastguard Worker         } else {
38*c8dee2aaSAndroid Build Coastguard Worker             heapType = D3D12_HEAP_TYPE_UPLOAD;
39*c8dee2aaSAndroid Build Coastguard Worker             // Cannot be changed
40*c8dee2aaSAndroid Build Coastguard Worker             // Includes VERTEX_AND_CONSTANT_BUFFER, INDEX_BUFFER, INDIRECT_ARGUMENT, and COPY_SOURCE
41*c8dee2aaSAndroid Build Coastguard Worker             *resourceState = D3D12_RESOURCE_STATE_GENERIC_READ;
42*c8dee2aaSAndroid Build Coastguard Worker         }
43*c8dee2aaSAndroid Build Coastguard Worker     }
44*c8dee2aaSAndroid Build Coastguard Worker 
45*c8dee2aaSAndroid Build Coastguard Worker     D3D12_RESOURCE_DESC bufferDesc = {};
46*c8dee2aaSAndroid Build Coastguard Worker     bufferDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
47*c8dee2aaSAndroid Build Coastguard Worker     bufferDesc.Alignment = 0;  // default alignment
48*c8dee2aaSAndroid Build Coastguard Worker     bufferDesc.Width = size;
49*c8dee2aaSAndroid Build Coastguard Worker     bufferDesc.Height = 1;
50*c8dee2aaSAndroid Build Coastguard Worker     bufferDesc.DepthOrArraySize = 1;
51*c8dee2aaSAndroid Build Coastguard Worker     bufferDesc.MipLevels = 1;
52*c8dee2aaSAndroid Build Coastguard Worker     bufferDesc.Format = DXGI_FORMAT_UNKNOWN;
53*c8dee2aaSAndroid Build Coastguard Worker     bufferDesc.SampleDesc.Count = 1;
54*c8dee2aaSAndroid Build Coastguard Worker     bufferDesc.SampleDesc.Quality = 0; // Doesn't apply to buffers
55*c8dee2aaSAndroid Build Coastguard Worker     bufferDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
56*c8dee2aaSAndroid Build Coastguard Worker     bufferDesc.Flags = D3D12_RESOURCE_FLAG_NONE;
57*c8dee2aaSAndroid Build Coastguard Worker 
58*c8dee2aaSAndroid Build Coastguard Worker     gr_cp<ID3D12Resource> resource = gpu->memoryAllocator()->createResource(
59*c8dee2aaSAndroid Build Coastguard Worker             heapType, &bufferDesc, *resourceState, alloc, nullptr);
60*c8dee2aaSAndroid Build Coastguard Worker 
61*c8dee2aaSAndroid Build Coastguard Worker     return resource;
62*c8dee2aaSAndroid Build Coastguard Worker }
63*c8dee2aaSAndroid Build Coastguard Worker 
Make(GrD3DGpu * gpu,size_t size,GrGpuBufferType intendedType,GrAccessPattern accessPattern)64*c8dee2aaSAndroid Build Coastguard Worker sk_sp<GrD3DBuffer> GrD3DBuffer::Make(GrD3DGpu* gpu, size_t size, GrGpuBufferType intendedType,
65*c8dee2aaSAndroid Build Coastguard Worker                                      GrAccessPattern accessPattern) {
66*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(!gpu->protectedContext() || (accessPattern != kStatic_GrAccessPattern));
67*c8dee2aaSAndroid Build Coastguard Worker     D3D12_RESOURCE_STATES resourceState;
68*c8dee2aaSAndroid Build Coastguard Worker 
69*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<GrD3DAlloc> alloc;
70*c8dee2aaSAndroid Build Coastguard Worker     gr_cp<ID3D12Resource> resource = make_d3d_buffer(gpu, size, intendedType, accessPattern,
71*c8dee2aaSAndroid Build Coastguard Worker                                                      &resourceState, &alloc);
72*c8dee2aaSAndroid Build Coastguard Worker     if (!resource) {
73*c8dee2aaSAndroid Build Coastguard Worker         return nullptr;
74*c8dee2aaSAndroid Build Coastguard Worker     }
75*c8dee2aaSAndroid Build Coastguard Worker 
76*c8dee2aaSAndroid Build Coastguard Worker     return sk_sp<GrD3DBuffer>(new GrD3DBuffer(gpu, size, intendedType, accessPattern,
77*c8dee2aaSAndroid Build Coastguard Worker                                               std::move(resource), std::move(alloc),
78*c8dee2aaSAndroid Build Coastguard Worker                                               resourceState,
79*c8dee2aaSAndroid Build Coastguard Worker                                               /*label=*/"MakeD3DBuffer"));
80*c8dee2aaSAndroid Build Coastguard Worker }
81*c8dee2aaSAndroid Build Coastguard Worker 
GrD3DBuffer(GrD3DGpu * gpu,size_t size,GrGpuBufferType intendedType,GrAccessPattern accessPattern,gr_cp<ID3D12Resource> bufferResource,sk_sp<GrD3DAlloc> alloc,D3D12_RESOURCE_STATES resourceState,std::string_view label)82*c8dee2aaSAndroid Build Coastguard Worker GrD3DBuffer::GrD3DBuffer(GrD3DGpu* gpu, size_t size, GrGpuBufferType intendedType,
83*c8dee2aaSAndroid Build Coastguard Worker                          GrAccessPattern accessPattern, gr_cp<ID3D12Resource> bufferResource,
84*c8dee2aaSAndroid Build Coastguard Worker                          sk_sp<GrD3DAlloc> alloc,
85*c8dee2aaSAndroid Build Coastguard Worker                          D3D12_RESOURCE_STATES resourceState,
86*c8dee2aaSAndroid Build Coastguard Worker                          std::string_view label)
87*c8dee2aaSAndroid Build Coastguard Worker     : INHERITED(gpu, size, intendedType, accessPattern, label)
88*c8dee2aaSAndroid Build Coastguard Worker     , fResourceState(resourceState)
89*c8dee2aaSAndroid Build Coastguard Worker     , fD3DResource(std::move(bufferResource))
90*c8dee2aaSAndroid Build Coastguard Worker     , fAlloc(std::move(alloc)) {
91*c8dee2aaSAndroid Build Coastguard Worker     this->registerWithCache(skgpu::Budgeted::kYes);
92*c8dee2aaSAndroid Build Coastguard Worker 
93*c8dee2aaSAndroid Build Coastguard Worker     // TODO: persistently map UPLOAD resources?
94*c8dee2aaSAndroid Build Coastguard Worker 
95*c8dee2aaSAndroid Build Coastguard Worker     VALIDATE();
96*c8dee2aaSAndroid Build Coastguard Worker }
97*c8dee2aaSAndroid Build Coastguard Worker 
setResourceState(const GrD3DGpu * gpu,D3D12_RESOURCE_STATES newResourceState)98*c8dee2aaSAndroid Build Coastguard Worker void GrD3DBuffer::setResourceState(const GrD3DGpu* gpu,
99*c8dee2aaSAndroid Build Coastguard Worker                                    D3D12_RESOURCE_STATES newResourceState) {
100*c8dee2aaSAndroid Build Coastguard Worker     if (newResourceState == fResourceState ||
101*c8dee2aaSAndroid Build Coastguard Worker         // GENERIC_READ encapsulates a lot of different read states
102*c8dee2aaSAndroid Build Coastguard Worker         (fResourceState == D3D12_RESOURCE_STATE_GENERIC_READ &&
103*c8dee2aaSAndroid Build Coastguard Worker          SkToBool(newResourceState | fResourceState))) {
104*c8dee2aaSAndroid Build Coastguard Worker         return;
105*c8dee2aaSAndroid Build Coastguard Worker     }
106*c8dee2aaSAndroid Build Coastguard Worker 
107*c8dee2aaSAndroid Build Coastguard Worker     D3D12_RESOURCE_TRANSITION_BARRIER barrier = {};
108*c8dee2aaSAndroid Build Coastguard Worker     barrier.pResource = this->d3dResource();
109*c8dee2aaSAndroid Build Coastguard Worker     barrier.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
110*c8dee2aaSAndroid Build Coastguard Worker     barrier.StateBefore = fResourceState;
111*c8dee2aaSAndroid Build Coastguard Worker     barrier.StateAfter = newResourceState;
112*c8dee2aaSAndroid Build Coastguard Worker 
113*c8dee2aaSAndroid Build Coastguard Worker     gpu->addBufferResourceBarriers(this, 1, &barrier);
114*c8dee2aaSAndroid Build Coastguard Worker 
115*c8dee2aaSAndroid Build Coastguard Worker     fResourceState = newResourceState;
116*c8dee2aaSAndroid Build Coastguard Worker }
117*c8dee2aaSAndroid Build Coastguard Worker 
releaseResource()118*c8dee2aaSAndroid Build Coastguard Worker void GrD3DBuffer::releaseResource() {
119*c8dee2aaSAndroid Build Coastguard Worker     if (this->wasDestroyed()) {
120*c8dee2aaSAndroid Build Coastguard Worker         return;
121*c8dee2aaSAndroid Build Coastguard Worker     }
122*c8dee2aaSAndroid Build Coastguard Worker 
123*c8dee2aaSAndroid Build Coastguard Worker     if (fMapPtr) {
124*c8dee2aaSAndroid Build Coastguard Worker         this->unmap();
125*c8dee2aaSAndroid Build Coastguard Worker     }
126*c8dee2aaSAndroid Build Coastguard Worker 
127*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(fD3DResource);
128*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(fAlloc);
129*c8dee2aaSAndroid Build Coastguard Worker     fD3DResource.reset();
130*c8dee2aaSAndroid Build Coastguard Worker     fAlloc.reset();
131*c8dee2aaSAndroid Build Coastguard Worker }
132*c8dee2aaSAndroid Build Coastguard Worker 
onRelease()133*c8dee2aaSAndroid Build Coastguard Worker void GrD3DBuffer::onRelease() {
134*c8dee2aaSAndroid Build Coastguard Worker     this->releaseResource();
135*c8dee2aaSAndroid Build Coastguard Worker     this->INHERITED::onRelease();
136*c8dee2aaSAndroid Build Coastguard Worker }
137*c8dee2aaSAndroid Build Coastguard Worker 
onAbandon()138*c8dee2aaSAndroid Build Coastguard Worker void GrD3DBuffer::onAbandon() {
139*c8dee2aaSAndroid Build Coastguard Worker     this->releaseResource();
140*c8dee2aaSAndroid Build Coastguard Worker     this->INHERITED::onAbandon();
141*c8dee2aaSAndroid Build Coastguard Worker }
142*c8dee2aaSAndroid Build Coastguard Worker 
onMap(MapType type)143*c8dee2aaSAndroid Build Coastguard Worker void GrD3DBuffer::onMap(MapType type) {
144*c8dee2aaSAndroid Build Coastguard Worker     fMapPtr = this->internalMap(type, 0, this->size());
145*c8dee2aaSAndroid Build Coastguard Worker }
146*c8dee2aaSAndroid Build Coastguard Worker 
onUnmap(MapType type)147*c8dee2aaSAndroid Build Coastguard Worker void GrD3DBuffer::onUnmap(MapType type) {
148*c8dee2aaSAndroid Build Coastguard Worker     this->internalUnmap(type, 0, this->size());
149*c8dee2aaSAndroid Build Coastguard Worker }
150*c8dee2aaSAndroid Build Coastguard Worker 
onClearToZero()151*c8dee2aaSAndroid Build Coastguard Worker bool GrD3DBuffer::onClearToZero() {
152*c8dee2aaSAndroid Build Coastguard Worker     if (!fD3DResource) {
153*c8dee2aaSAndroid Build Coastguard Worker         return false;
154*c8dee2aaSAndroid Build Coastguard Worker     }
155*c8dee2aaSAndroid Build Coastguard Worker 
156*c8dee2aaSAndroid Build Coastguard Worker     if (this->accessPattern() == kStatic_GrAccessPattern) {
157*c8dee2aaSAndroid Build Coastguard Worker         GrStagingBufferManager::Slice slice =
158*c8dee2aaSAndroid Build Coastguard Worker                 this->getD3DGpu()->stagingBufferManager()->allocateStagingBufferSlice(this->size());
159*c8dee2aaSAndroid Build Coastguard Worker         if (!slice.fBuffer) {
160*c8dee2aaSAndroid Build Coastguard Worker             return false;
161*c8dee2aaSAndroid Build Coastguard Worker         }
162*c8dee2aaSAndroid Build Coastguard Worker         std::memset(slice.fOffsetMapPtr, 0, this->size());
163*c8dee2aaSAndroid Build Coastguard Worker         this->setResourceState(this->getD3DGpu(), D3D12_RESOURCE_STATE_COPY_DEST);
164*c8dee2aaSAndroid Build Coastguard Worker         this->getD3DGpu()->currentCommandList()->copyBufferToBuffer(
165*c8dee2aaSAndroid Build Coastguard Worker                 sk_ref_sp<GrD3DBuffer>(this),
166*c8dee2aaSAndroid Build Coastguard Worker                 0,
167*c8dee2aaSAndroid Build Coastguard Worker                 static_cast<const GrD3DBuffer*>(slice.fBuffer)->d3dResource(),
168*c8dee2aaSAndroid Build Coastguard Worker                 slice.fOffset,
169*c8dee2aaSAndroid Build Coastguard Worker                 this->size());
170*c8dee2aaSAndroid Build Coastguard Worker         return true;
171*c8dee2aaSAndroid Build Coastguard Worker     }
172*c8dee2aaSAndroid Build Coastguard Worker 
173*c8dee2aaSAndroid Build Coastguard Worker     void* ptr = this->internalMap(MapType::kWriteDiscard, 0, this->size());
174*c8dee2aaSAndroid Build Coastguard Worker     if (!ptr) {
175*c8dee2aaSAndroid Build Coastguard Worker         return false;
176*c8dee2aaSAndroid Build Coastguard Worker     }
177*c8dee2aaSAndroid Build Coastguard Worker     std::memset(ptr, 0, this->size());
178*c8dee2aaSAndroid Build Coastguard Worker     this->internalUnmap(MapType::kWriteDiscard, 0, this->size());
179*c8dee2aaSAndroid Build Coastguard Worker 
180*c8dee2aaSAndroid Build Coastguard Worker     return true;
181*c8dee2aaSAndroid Build Coastguard Worker }
182*c8dee2aaSAndroid Build Coastguard Worker 
onUpdateData(const void * src,size_t offset,size_t size,bool)183*c8dee2aaSAndroid Build Coastguard Worker bool GrD3DBuffer::onUpdateData(const void* src, size_t offset, size_t size, bool /*preserve*/) {
184*c8dee2aaSAndroid Build Coastguard Worker     if (!fD3DResource) {
185*c8dee2aaSAndroid Build Coastguard Worker         return false;
186*c8dee2aaSAndroid Build Coastguard Worker     }
187*c8dee2aaSAndroid Build Coastguard Worker 
188*c8dee2aaSAndroid Build Coastguard Worker     void* ptr = this->internalMap(MapType::kWriteDiscard, offset, size);
189*c8dee2aaSAndroid Build Coastguard Worker     if (!ptr) {
190*c8dee2aaSAndroid Build Coastguard Worker         return false;
191*c8dee2aaSAndroid Build Coastguard Worker     }
192*c8dee2aaSAndroid Build Coastguard Worker     if (this->accessPattern() == kStatic_GrAccessPattern) {
193*c8dee2aaSAndroid Build Coastguard Worker         // We should never call this method on static buffers in protected contexts.
194*c8dee2aaSAndroid Build Coastguard Worker         SkASSERT(!this->getD3DGpu()->protectedContext());
195*c8dee2aaSAndroid Build Coastguard Worker         //*** any alignment restrictions?
196*c8dee2aaSAndroid Build Coastguard Worker     }
197*c8dee2aaSAndroid Build Coastguard Worker     memcpy(ptr, src, size);
198*c8dee2aaSAndroid Build Coastguard Worker     this->internalUnmap(MapType::kWriteDiscard, offset, size);
199*c8dee2aaSAndroid Build Coastguard Worker 
200*c8dee2aaSAndroid Build Coastguard Worker     return true;
201*c8dee2aaSAndroid Build Coastguard Worker }
202*c8dee2aaSAndroid Build Coastguard Worker 
internalMap(MapType type,size_t offset,size_t size)203*c8dee2aaSAndroid Build Coastguard Worker void* GrD3DBuffer::internalMap(MapType type, size_t offset, size_t size) {
204*c8dee2aaSAndroid Build Coastguard Worker     // TODO: if UPLOAD heap type, could be persistently mapped (i.e., this would be a no-op)
205*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(fD3DResource);
206*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(!this->isMapped());
207*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(offset + size <= this->size());
208*c8dee2aaSAndroid Build Coastguard Worker 
209*c8dee2aaSAndroid Build Coastguard Worker     VALIDATE();
210*c8dee2aaSAndroid Build Coastguard Worker 
211*c8dee2aaSAndroid Build Coastguard Worker     if (this->accessPattern() == kStatic_GrAccessPattern) {
212*c8dee2aaSAndroid Build Coastguard Worker         if (type == MapType::kRead) {
213*c8dee2aaSAndroid Build Coastguard Worker             return nullptr;
214*c8dee2aaSAndroid Build Coastguard Worker         }
215*c8dee2aaSAndroid Build Coastguard Worker         SkASSERT(!fStagingBuffer);
216*c8dee2aaSAndroid Build Coastguard Worker         GrStagingBufferManager::Slice slice =
217*c8dee2aaSAndroid Build Coastguard Worker                 this->getD3DGpu()->stagingBufferManager()->allocateStagingBufferSlice(size);
218*c8dee2aaSAndroid Build Coastguard Worker         if (!slice.fBuffer) {
219*c8dee2aaSAndroid Build Coastguard Worker             return nullptr;
220*c8dee2aaSAndroid Build Coastguard Worker         }
221*c8dee2aaSAndroid Build Coastguard Worker         fStagingBuffer = static_cast<const GrD3DBuffer*>(slice.fBuffer)->d3dResource();
222*c8dee2aaSAndroid Build Coastguard Worker         fStagingOffset = slice.fOffset;
223*c8dee2aaSAndroid Build Coastguard Worker         VALIDATE();
224*c8dee2aaSAndroid Build Coastguard Worker         return slice.fOffsetMapPtr;
225*c8dee2aaSAndroid Build Coastguard Worker     }
226*c8dee2aaSAndroid Build Coastguard Worker 
227*c8dee2aaSAndroid Build Coastguard Worker     D3D12_RANGE range;
228*c8dee2aaSAndroid Build Coastguard Worker     range.Begin = offset;
229*c8dee2aaSAndroid Build Coastguard Worker     // The range passed here indicates the portion of the resource that may be
230*c8dee2aaSAndroid Build Coastguard Worker     // read. If we're only writing then pass an empty range.
231*c8dee2aaSAndroid Build Coastguard Worker     range.End = type == MapType::kRead ? offset + size : offset;
232*c8dee2aaSAndroid Build Coastguard Worker     void* result;
233*c8dee2aaSAndroid Build Coastguard Worker     if (fD3DResource->Map(0, &range, &result) != S_OK) {
234*c8dee2aaSAndroid Build Coastguard Worker         return nullptr;
235*c8dee2aaSAndroid Build Coastguard Worker     }
236*c8dee2aaSAndroid Build Coastguard Worker     if (result) {
237*c8dee2aaSAndroid Build Coastguard Worker         result = SkTAddOffset<void>(result, offset);
238*c8dee2aaSAndroid Build Coastguard Worker     }
239*c8dee2aaSAndroid Build Coastguard Worker     VALIDATE();
240*c8dee2aaSAndroid Build Coastguard Worker     return result;
241*c8dee2aaSAndroid Build Coastguard Worker }
242*c8dee2aaSAndroid Build Coastguard Worker 
internalUnmap(MapType type,size_t offset,size_t size)243*c8dee2aaSAndroid Build Coastguard Worker void GrD3DBuffer::internalUnmap(MapType type, size_t offset, size_t size) {
244*c8dee2aaSAndroid Build Coastguard Worker     // TODO: if UPLOAD heap type, could be persistently mapped (i.e., this would be a no-op)
245*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(fD3DResource);
246*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(offset + size <= this->size());
247*c8dee2aaSAndroid Build Coastguard Worker     VALIDATE();
248*c8dee2aaSAndroid Build Coastguard Worker 
249*c8dee2aaSAndroid Build Coastguard Worker     if (this->accessPattern() == kStatic_GrAccessPattern) {
250*c8dee2aaSAndroid Build Coastguard Worker         SkASSERT(type != GrGpuBuffer::MapType::kRead);
251*c8dee2aaSAndroid Build Coastguard Worker         SkASSERT(fStagingBuffer);
252*c8dee2aaSAndroid Build Coastguard Worker         this->setResourceState(this->getD3DGpu(), D3D12_RESOURCE_STATE_COPY_DEST);
253*c8dee2aaSAndroid Build Coastguard Worker         this->getD3DGpu()->currentCommandList()->copyBufferToBuffer(
254*c8dee2aaSAndroid Build Coastguard Worker                 sk_ref_sp<GrD3DBuffer>(this),
255*c8dee2aaSAndroid Build Coastguard Worker                 offset,
256*c8dee2aaSAndroid Build Coastguard Worker                 fStagingBuffer,
257*c8dee2aaSAndroid Build Coastguard Worker                 fStagingOffset,
258*c8dee2aaSAndroid Build Coastguard Worker                 size);
259*c8dee2aaSAndroid Build Coastguard Worker         fStagingBuffer = nullptr;
260*c8dee2aaSAndroid Build Coastguard Worker     } else {
261*c8dee2aaSAndroid Build Coastguard Worker         D3D12_RANGE range;
262*c8dee2aaSAndroid Build Coastguard Worker         range.Begin = offset;
263*c8dee2aaSAndroid Build Coastguard Worker         range.End = type == MapType::kWriteDiscard ? offset + size : offset;
264*c8dee2aaSAndroid Build Coastguard Worker         // For READBACK heaps, unmap requires an empty range
265*c8dee2aaSAndroid Build Coastguard Worker         SkASSERT(fResourceState != D3D12_RESOURCE_STATE_COPY_DEST || range.Begin == range.End);
266*c8dee2aaSAndroid Build Coastguard Worker         fD3DResource->Unmap(0, &range);
267*c8dee2aaSAndroid Build Coastguard Worker     }
268*c8dee2aaSAndroid Build Coastguard Worker 
269*c8dee2aaSAndroid Build Coastguard Worker     VALIDATE();
270*c8dee2aaSAndroid Build Coastguard Worker }
271*c8dee2aaSAndroid Build Coastguard Worker 
onSetLabel()272*c8dee2aaSAndroid Build Coastguard Worker void GrD3DBuffer::onSetLabel() {
273*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(fD3DResource);
274*c8dee2aaSAndroid Build Coastguard Worker     if (!this->getLabel().empty()) {
275*c8dee2aaSAndroid Build Coastguard Worker         const std::wstring label = L"_Skia_" + GrD3DMultiByteToWide(this->getLabel());
276*c8dee2aaSAndroid Build Coastguard Worker         this->d3dResource()->SetName(label.c_str());
277*c8dee2aaSAndroid Build Coastguard Worker     }
278*c8dee2aaSAndroid Build Coastguard Worker }
279*c8dee2aaSAndroid Build Coastguard Worker 
280*c8dee2aaSAndroid Build Coastguard Worker #ifdef SK_DEBUG
validate() const281*c8dee2aaSAndroid Build Coastguard Worker void GrD3DBuffer::validate() const {
282*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(this->intendedType() == GrGpuBufferType::kVertex ||
283*c8dee2aaSAndroid Build Coastguard Worker              this->intendedType() == GrGpuBufferType::kIndex ||
284*c8dee2aaSAndroid Build Coastguard Worker              this->intendedType() == GrGpuBufferType::kDrawIndirect ||
285*c8dee2aaSAndroid Build Coastguard Worker              this->intendedType() == GrGpuBufferType::kXferCpuToGpu ||
286*c8dee2aaSAndroid Build Coastguard Worker              this->intendedType() == GrGpuBufferType::kXferGpuToCpu);
287*c8dee2aaSAndroid Build Coastguard Worker }
288*c8dee2aaSAndroid Build Coastguard Worker #endif
289