• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2019 Google Inc.
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/ganesh/dawn/GrDawnProgramDataManager.h"
9 
10 #include "src/gpu/ganesh/dawn/GrDawnGpu.h"
11 
GrDawnProgramDataManager(const UniformInfoArray & uniforms,uint32_t uniformBufferSize)12 GrDawnProgramDataManager::GrDawnProgramDataManager(const UniformInfoArray& uniforms,
13                                                    uint32_t uniformBufferSize)
14         : GrUniformDataManager(
15                   uniforms.count(),
16                   // Dawn uses a std140-like layout for uniform data which requires certain types to
17                   // have an alignment of 16. This layout will often involve padding to be inserted
18                   // at the end of data last uniform entry as described in
19                   // https://www.w3.org/TR/WGSL/#alignment-and-size.
20                   //
21                   // Dawn enforces buffers to appropriately sized to accommodate such padding, even
22                   // if it involves trailing bytes that will never get written or read. We make sure
23                   // that the buffers we bind for uniforms abide by this validation rule.
24                   SkAlignTo(uniformBufferSize, 16)) {
25     memset(fUniformData.get(), 0, uniformBufferSize);
26     // We must add uniforms in same order is the UniformInfoArray so that UniformHandles already
27     // owned by other objects will still match up here.
28     int i = 0;
29     for (const auto& uniformInfo : uniforms.items()) {
30         Uniform& uniform = fUniforms[i];
31         SkDEBUGCODE(
32             uniform.fArrayCount = uniformInfo.fVariable.getArrayCount();
33             uniform.fType = uniformInfo.fVariable.getType();
34         )
35         uniform.fOffset = uniformInfo.fUBOOffset;
36         ++i;
37     }
38 }
39 
make_bind_group_entry(uint32_t binding,const wgpu::Buffer & buffer,uint32_t offset,uint32_t size)40 static wgpu::BindGroupEntry make_bind_group_entry(uint32_t binding, const wgpu::Buffer& buffer,
41                                                   uint32_t offset, uint32_t size) {
42     wgpu::BindGroupEntry result;
43     result.binding = binding;
44     result.buffer = buffer;
45     result.offset = offset;
46     result.size = size;
47     result.sampler = nullptr;
48     result.textureView = nullptr;
49     return result;
50 }
51 
uploadUniformBuffers(GrDawnGpu * gpu,wgpu::BindGroupLayout layout)52 wgpu::BindGroup GrDawnProgramDataManager::uploadUniformBuffers(GrDawnGpu* gpu,
53                                                                wgpu::BindGroupLayout layout) {
54     if (fUniformsDirty && 0 != fUniformSize) {
55         std::vector<wgpu::BindGroupEntry> bindings;
56         GrDawnRingBuffer::Slice slice;
57         slice = gpu->allocateUniformRingBufferSlice(fUniformSize);
58         gpu->queue().WriteBuffer(slice.fBuffer, slice.fOffset, fUniformData.get(), fUniformSize);
59         bindings.push_back(make_bind_group_entry(GrSPIRVUniformHandler::kUniformBinding,
60                                                  slice.fBuffer, slice.fOffset,
61                                                  fUniformSize));
62         wgpu::BindGroupDescriptor descriptor;
63         descriptor.layout = layout;
64         descriptor.entryCount = bindings.size();
65         descriptor.entries = bindings.data();
66         fBindGroup = gpu->device().CreateBindGroup(&descriptor);
67         fUniformsDirty = false;
68     }
69     return fBindGroup;
70 }
71