xref: /aosp_15_r20/external/angle/src/libANGLE/renderer/wgpu/ProgramExecutableWgpu.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2024 The ANGLE Project Authors. All rights reserved.
3*8975f5c5SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
4*8975f5c5SAndroid Build Coastguard Worker // found in the LICENSE file.
5*8975f5c5SAndroid Build Coastguard Worker //
6*8975f5c5SAndroid Build Coastguard Worker // ProgramExecutableWgpu.cpp: Implementation of ProgramExecutableWgpu.
7*8975f5c5SAndroid Build Coastguard Worker 
8*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/wgpu/ProgramExecutableWgpu.h"
9*8975f5c5SAndroid Build Coastguard Worker 
10*8975f5c5SAndroid Build Coastguard Worker #include <iterator>
11*8975f5c5SAndroid Build Coastguard Worker 
12*8975f5c5SAndroid Build Coastguard Worker #include "angle_gl.h"
13*8975f5c5SAndroid Build Coastguard Worker #include "anglebase/numerics/safe_conversions.h"
14*8975f5c5SAndroid Build Coastguard Worker #include "common/PackedGLEnums_autogen.h"
15*8975f5c5SAndroid Build Coastguard Worker #include "compiler/translator/wgsl/OutputUniformBlocks.h"
16*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Error.h"
17*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Program.h"
18*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/renderer_utils.h"
19*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/wgpu/ContextWgpu.h"
20*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/wgpu/wgpu_helpers.h"
21*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/wgpu/wgpu_pipeline_state.h"
22*8975f5c5SAndroid Build Coastguard Worker 
23*8975f5c5SAndroid Build Coastguard Worker namespace rx
24*8975f5c5SAndroid Build Coastguard Worker {
25*8975f5c5SAndroid Build Coastguard Worker 
ProgramExecutableWgpu(const gl::ProgramExecutable * executable)26*8975f5c5SAndroid Build Coastguard Worker ProgramExecutableWgpu::ProgramExecutableWgpu(const gl::ProgramExecutable *executable)
27*8975f5c5SAndroid Build Coastguard Worker     : ProgramExecutableImpl(executable)
28*8975f5c5SAndroid Build Coastguard Worker {
29*8975f5c5SAndroid Build Coastguard Worker     for (std::shared_ptr<BufferAndLayout> &defaultBlock : mDefaultUniformBlocks)
30*8975f5c5SAndroid Build Coastguard Worker     {
31*8975f5c5SAndroid Build Coastguard Worker         defaultBlock = std::make_shared<BufferAndLayout>();
32*8975f5c5SAndroid Build Coastguard Worker     }
33*8975f5c5SAndroid Build Coastguard Worker }
34*8975f5c5SAndroid Build Coastguard Worker 
35*8975f5c5SAndroid Build Coastguard Worker ProgramExecutableWgpu::~ProgramExecutableWgpu() = default;
36*8975f5c5SAndroid Build Coastguard Worker 
destroy(const gl::Context * context)37*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableWgpu::destroy(const gl::Context *context) {}
38*8975f5c5SAndroid Build Coastguard Worker 
updateUniformsAndGetBindGroup(ContextWgpu * contextWgpu,wgpu::BindGroup * outBindGroup)39*8975f5c5SAndroid Build Coastguard Worker angle::Result ProgramExecutableWgpu::updateUniformsAndGetBindGroup(ContextWgpu *contextWgpu,
40*8975f5c5SAndroid Build Coastguard Worker                                                                    wgpu::BindGroup *outBindGroup)
41*8975f5c5SAndroid Build Coastguard Worker {
42*8975f5c5SAndroid Build Coastguard Worker     if (mDefaultUniformBlocksDirty.any())
43*8975f5c5SAndroid Build Coastguard Worker     {
44*8975f5c5SAndroid Build Coastguard Worker         // TODO(anglebug.com/376553328): this creates an entire new buffer every time a single
45*8975f5c5SAndroid Build Coastguard Worker         // uniform changes, and the old ones are just garbage collected. This should be optimized.
46*8975f5c5SAndroid Build Coastguard Worker         webgpu::BufferHelper defaultUniformBuffer;
47*8975f5c5SAndroid Build Coastguard Worker 
48*8975f5c5SAndroid Build Coastguard Worker         gl::ShaderMap<uint64_t> offsets =
49*8975f5c5SAndroid Build Coastguard Worker             {};  // offset in the GPU-side buffer of each shader stage's uniform data.
50*8975f5c5SAndroid Build Coastguard Worker         size_t requiredSpace;
51*8975f5c5SAndroid Build Coastguard Worker 
52*8975f5c5SAndroid Build Coastguard Worker         angle::CheckedNumeric<size_t> requiredSpaceChecked =
53*8975f5c5SAndroid Build Coastguard Worker             calcUniformUpdateRequiredSpace(contextWgpu, &offsets);
54*8975f5c5SAndroid Build Coastguard Worker         if (!requiredSpaceChecked.AssignIfValid(&requiredSpace))
55*8975f5c5SAndroid Build Coastguard Worker         {
56*8975f5c5SAndroid Build Coastguard Worker             return angle::Result::Stop;
57*8975f5c5SAndroid Build Coastguard Worker         }
58*8975f5c5SAndroid Build Coastguard Worker 
59*8975f5c5SAndroid Build Coastguard Worker         ANGLE_TRY(defaultUniformBuffer.initBuffer(
60*8975f5c5SAndroid Build Coastguard Worker             contextWgpu->getDevice(), requiredSpace,
61*8975f5c5SAndroid Build Coastguard Worker             wgpu::BufferUsage::Uniform | wgpu::BufferUsage::CopyDst, webgpu::MapAtCreation::Yes));
62*8975f5c5SAndroid Build Coastguard Worker 
63*8975f5c5SAndroid Build Coastguard Worker         ASSERT(defaultUniformBuffer.valid());
64*8975f5c5SAndroid Build Coastguard Worker 
65*8975f5c5SAndroid Build Coastguard Worker         // Copy all of the CPU-side data into this buffer which will be visible to the GPU after it
66*8975f5c5SAndroid Build Coastguard Worker         // is unmapped here on the CPU.
67*8975f5c5SAndroid Build Coastguard Worker         uint8_t *bufferData = defaultUniformBuffer.getMapWritePointer(0, requiredSpace);
68*8975f5c5SAndroid Build Coastguard Worker         for (gl::ShaderType shaderType : mExecutable->getLinkedShaderStages())
69*8975f5c5SAndroid Build Coastguard Worker         {
70*8975f5c5SAndroid Build Coastguard Worker             const angle::MemoryBuffer &uniformData = mDefaultUniformBlocks[shaderType]->uniformData;
71*8975f5c5SAndroid Build Coastguard Worker             memcpy(&bufferData[offsets[shaderType]], uniformData.data(), uniformData.size());
72*8975f5c5SAndroid Build Coastguard Worker             mDefaultUniformBlocksDirty.reset(shaderType);
73*8975f5c5SAndroid Build Coastguard Worker         }
74*8975f5c5SAndroid Build Coastguard Worker         ANGLE_TRY(defaultUniformBuffer.unmap());
75*8975f5c5SAndroid Build Coastguard Worker 
76*8975f5c5SAndroid Build Coastguard Worker         // Create the BindGroupEntries
77*8975f5c5SAndroid Build Coastguard Worker         std::vector<wgpu::BindGroupEntry> bindings;
78*8975f5c5SAndroid Build Coastguard Worker         auto addBindingToGroupIfNecessary = [&](uint32_t bindingIndex, gl::ShaderType shaderType) {
79*8975f5c5SAndroid Build Coastguard Worker             if (mDefaultUniformBlocks[shaderType]->uniformData.size() != 0)
80*8975f5c5SAndroid Build Coastguard Worker             {
81*8975f5c5SAndroid Build Coastguard Worker                 wgpu::BindGroupEntry bindGroupEntry;
82*8975f5c5SAndroid Build Coastguard Worker                 bindGroupEntry.binding = bindingIndex;
83*8975f5c5SAndroid Build Coastguard Worker                 bindGroupEntry.buffer  = defaultUniformBuffer.getBuffer();
84*8975f5c5SAndroid Build Coastguard Worker                 bindGroupEntry.offset  = offsets[shaderType];
85*8975f5c5SAndroid Build Coastguard Worker                 bindGroupEntry.size    = mDefaultUniformBlocks[shaderType]->uniformData.size();
86*8975f5c5SAndroid Build Coastguard Worker                 bindings.push_back(bindGroupEntry);
87*8975f5c5SAndroid Build Coastguard Worker             }
88*8975f5c5SAndroid Build Coastguard Worker         };
89*8975f5c5SAndroid Build Coastguard Worker 
90*8975f5c5SAndroid Build Coastguard Worker         // Add the BindGroupEntry for the default blocks of both the vertex and fragment shaders.
91*8975f5c5SAndroid Build Coastguard Worker         // They will use the same buffer with a different offset.
92*8975f5c5SAndroid Build Coastguard Worker         addBindingToGroupIfNecessary(sh::kDefaultVertexUniformBlockBinding, gl::ShaderType::Vertex);
93*8975f5c5SAndroid Build Coastguard Worker         addBindingToGroupIfNecessary(sh::kDefaultFragmentUniformBlockBinding,
94*8975f5c5SAndroid Build Coastguard Worker                                      gl::ShaderType::Fragment);
95*8975f5c5SAndroid Build Coastguard Worker 
96*8975f5c5SAndroid Build Coastguard Worker         // A bind group contains one or multiple bindings
97*8975f5c5SAndroid Build Coastguard Worker         wgpu::BindGroupDescriptor bindGroupDesc{};
98*8975f5c5SAndroid Build Coastguard Worker         bindGroupDesc.layout = mDefaultBindGroupLayout;
99*8975f5c5SAndroid Build Coastguard Worker         // There must be as many bindings as declared in the layout!
100*8975f5c5SAndroid Build Coastguard Worker         bindGroupDesc.entryCount = bindings.size();
101*8975f5c5SAndroid Build Coastguard Worker         bindGroupDesc.entries    = bindings.data();
102*8975f5c5SAndroid Build Coastguard Worker         mDefaultBindGroup        = contextWgpu->getDevice().CreateBindGroup(&bindGroupDesc);
103*8975f5c5SAndroid Build Coastguard Worker     }
104*8975f5c5SAndroid Build Coastguard Worker 
105*8975f5c5SAndroid Build Coastguard Worker     ASSERT(mDefaultBindGroup);
106*8975f5c5SAndroid Build Coastguard Worker     *outBindGroup = mDefaultBindGroup;
107*8975f5c5SAndroid Build Coastguard Worker 
108*8975f5c5SAndroid Build Coastguard Worker     return angle::Result::Continue;
109*8975f5c5SAndroid Build Coastguard Worker }
110*8975f5c5SAndroid Build Coastguard Worker 
getDefaultUniformAlignedSize(ContextWgpu * context,gl::ShaderType shaderType) const111*8975f5c5SAndroid Build Coastguard Worker angle::CheckedNumeric<size_t> ProgramExecutableWgpu::getDefaultUniformAlignedSize(
112*8975f5c5SAndroid Build Coastguard Worker     ContextWgpu *context,
113*8975f5c5SAndroid Build Coastguard Worker     gl::ShaderType shaderType) const
114*8975f5c5SAndroid Build Coastguard Worker {
115*8975f5c5SAndroid Build Coastguard Worker     size_t alignment = angle::base::checked_cast<size_t>(
116*8975f5c5SAndroid Build Coastguard Worker         context->getDisplay()->getLimitsWgpu().minUniformBufferOffsetAlignment);
117*8975f5c5SAndroid Build Coastguard Worker     return CheckedRoundUp(mDefaultUniformBlocks[shaderType]->uniformData.size(), alignment);
118*8975f5c5SAndroid Build Coastguard Worker }
119*8975f5c5SAndroid Build Coastguard Worker 
calcUniformUpdateRequiredSpace(ContextWgpu * context,gl::ShaderMap<uint64_t> * uniformOffsets) const120*8975f5c5SAndroid Build Coastguard Worker angle::CheckedNumeric<size_t> ProgramExecutableWgpu::calcUniformUpdateRequiredSpace(
121*8975f5c5SAndroid Build Coastguard Worker     ContextWgpu *context,
122*8975f5c5SAndroid Build Coastguard Worker     gl::ShaderMap<uint64_t> *uniformOffsets) const
123*8975f5c5SAndroid Build Coastguard Worker {
124*8975f5c5SAndroid Build Coastguard Worker     angle::CheckedNumeric<size_t> requiredSpace = 0;
125*8975f5c5SAndroid Build Coastguard Worker     for (gl::ShaderType shaderType : mExecutable->getLinkedShaderStages())
126*8975f5c5SAndroid Build Coastguard Worker     {
127*8975f5c5SAndroid Build Coastguard Worker         (*uniformOffsets)[shaderType] = requiredSpace.ValueOrDie();
128*8975f5c5SAndroid Build Coastguard Worker         requiredSpace += getDefaultUniformAlignedSize(context, shaderType);
129*8975f5c5SAndroid Build Coastguard Worker         if (!requiredSpace.IsValid())
130*8975f5c5SAndroid Build Coastguard Worker         {
131*8975f5c5SAndroid Build Coastguard Worker             break;
132*8975f5c5SAndroid Build Coastguard Worker         }
133*8975f5c5SAndroid Build Coastguard Worker     }
134*8975f5c5SAndroid Build Coastguard Worker     return requiredSpace;
135*8975f5c5SAndroid Build Coastguard Worker }
136*8975f5c5SAndroid Build Coastguard Worker 
resizeUniformBlockMemory(const gl::ShaderMap<size_t> & requiredBufferSize)137*8975f5c5SAndroid Build Coastguard Worker angle::Result ProgramExecutableWgpu::resizeUniformBlockMemory(
138*8975f5c5SAndroid Build Coastguard Worker     const gl::ShaderMap<size_t> &requiredBufferSize)
139*8975f5c5SAndroid Build Coastguard Worker {
140*8975f5c5SAndroid Build Coastguard Worker     for (gl::ShaderType shaderType : mExecutable->getLinkedShaderStages())
141*8975f5c5SAndroid Build Coastguard Worker     {
142*8975f5c5SAndroid Build Coastguard Worker         if (requiredBufferSize[shaderType] > 0)
143*8975f5c5SAndroid Build Coastguard Worker         {
144*8975f5c5SAndroid Build Coastguard Worker             if (!mDefaultUniformBlocks[shaderType]->uniformData.resize(
145*8975f5c5SAndroid Build Coastguard Worker                     requiredBufferSize[shaderType]))
146*8975f5c5SAndroid Build Coastguard Worker             {
147*8975f5c5SAndroid Build Coastguard Worker                 return angle::Result::Stop;
148*8975f5c5SAndroid Build Coastguard Worker             }
149*8975f5c5SAndroid Build Coastguard Worker 
150*8975f5c5SAndroid Build Coastguard Worker             // Initialize uniform buffer memory to zero by default.
151*8975f5c5SAndroid Build Coastguard Worker             mDefaultUniformBlocks[shaderType]->uniformData.fill(0);
152*8975f5c5SAndroid Build Coastguard Worker             mDefaultUniformBlocksDirty.set(shaderType);
153*8975f5c5SAndroid Build Coastguard Worker         }
154*8975f5c5SAndroid Build Coastguard Worker     }
155*8975f5c5SAndroid Build Coastguard Worker 
156*8975f5c5SAndroid Build Coastguard Worker     return angle::Result::Continue;
157*8975f5c5SAndroid Build Coastguard Worker }
158*8975f5c5SAndroid Build Coastguard Worker 
markDefaultUniformsDirty()159*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableWgpu::markDefaultUniformsDirty()
160*8975f5c5SAndroid Build Coastguard Worker {
161*8975f5c5SAndroid Build Coastguard Worker     // Mark all linked stages as having dirty default uniforms
162*8975f5c5SAndroid Build Coastguard Worker     mDefaultUniformBlocksDirty = getExecutable()->getLinkedShaderStages();
163*8975f5c5SAndroid Build Coastguard Worker }
164*8975f5c5SAndroid Build Coastguard Worker 
setUniform1fv(GLint location,GLsizei count,const GLfloat * v)165*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableWgpu::setUniform1fv(GLint location, GLsizei count, const GLfloat *v)
166*8975f5c5SAndroid Build Coastguard Worker {
167*8975f5c5SAndroid Build Coastguard Worker     SetUniform(mExecutable, location, count, v, GL_FLOAT, &mDefaultUniformBlocks,
168*8975f5c5SAndroid Build Coastguard Worker                &mDefaultUniformBlocksDirty);
169*8975f5c5SAndroid Build Coastguard Worker }
170*8975f5c5SAndroid Build Coastguard Worker 
setUniform2fv(GLint location,GLsizei count,const GLfloat * v)171*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableWgpu::setUniform2fv(GLint location, GLsizei count, const GLfloat *v)
172*8975f5c5SAndroid Build Coastguard Worker {
173*8975f5c5SAndroid Build Coastguard Worker     SetUniform(mExecutable, location, count, v, GL_FLOAT_VEC2, &mDefaultUniformBlocks,
174*8975f5c5SAndroid Build Coastguard Worker                &mDefaultUniformBlocksDirty);
175*8975f5c5SAndroid Build Coastguard Worker }
176*8975f5c5SAndroid Build Coastguard Worker 
setUniform3fv(GLint location,GLsizei count,const GLfloat * v)177*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableWgpu::setUniform3fv(GLint location, GLsizei count, const GLfloat *v)
178*8975f5c5SAndroid Build Coastguard Worker {
179*8975f5c5SAndroid Build Coastguard Worker     SetUniform(mExecutable, location, count, v, GL_FLOAT_VEC3, &mDefaultUniformBlocks,
180*8975f5c5SAndroid Build Coastguard Worker                &mDefaultUniformBlocksDirty);
181*8975f5c5SAndroid Build Coastguard Worker }
182*8975f5c5SAndroid Build Coastguard Worker 
setUniform4fv(GLint location,GLsizei count,const GLfloat * v)183*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableWgpu::setUniform4fv(GLint location, GLsizei count, const GLfloat *v)
184*8975f5c5SAndroid Build Coastguard Worker {
185*8975f5c5SAndroid Build Coastguard Worker     SetUniform(mExecutable, location, count, v, GL_FLOAT_VEC4, &mDefaultUniformBlocks,
186*8975f5c5SAndroid Build Coastguard Worker                &mDefaultUniformBlocksDirty);
187*8975f5c5SAndroid Build Coastguard Worker }
188*8975f5c5SAndroid Build Coastguard Worker 
setUniform1iv(GLint location,GLsizei count,const GLint * v)189*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableWgpu::setUniform1iv(GLint location, GLsizei count, const GLint *v)
190*8975f5c5SAndroid Build Coastguard Worker {
191*8975f5c5SAndroid Build Coastguard Worker     const gl::VariableLocation &locationInfo = mExecutable->getUniformLocations()[location];
192*8975f5c5SAndroid Build Coastguard Worker     const gl::LinkedUniform &linkedUniform   = mExecutable->getUniforms()[locationInfo.index];
193*8975f5c5SAndroid Build Coastguard Worker     if (linkedUniform.isSampler())
194*8975f5c5SAndroid Build Coastguard Worker     {
195*8975f5c5SAndroid Build Coastguard Worker         // TODO(anglebug.com/42267100): handle samplers.
196*8975f5c5SAndroid Build Coastguard Worker         return;
197*8975f5c5SAndroid Build Coastguard Worker     }
198*8975f5c5SAndroid Build Coastguard Worker 
199*8975f5c5SAndroid Build Coastguard Worker     SetUniform(mExecutable, location, count, v, GL_INT, &mDefaultUniformBlocks,
200*8975f5c5SAndroid Build Coastguard Worker                &mDefaultUniformBlocksDirty);
201*8975f5c5SAndroid Build Coastguard Worker }
202*8975f5c5SAndroid Build Coastguard Worker 
setUniform2iv(GLint location,GLsizei count,const GLint * v)203*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableWgpu::setUniform2iv(GLint location, GLsizei count, const GLint *v)
204*8975f5c5SAndroid Build Coastguard Worker {
205*8975f5c5SAndroid Build Coastguard Worker     SetUniform(mExecutable, location, count, v, GL_INT_VEC2, &mDefaultUniformBlocks,
206*8975f5c5SAndroid Build Coastguard Worker                &mDefaultUniformBlocksDirty);
207*8975f5c5SAndroid Build Coastguard Worker }
208*8975f5c5SAndroid Build Coastguard Worker 
setUniform3iv(GLint location,GLsizei count,const GLint * v)209*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableWgpu::setUniform3iv(GLint location, GLsizei count, const GLint *v)
210*8975f5c5SAndroid Build Coastguard Worker {
211*8975f5c5SAndroid Build Coastguard Worker     SetUniform(mExecutable, location, count, v, GL_INT_VEC3, &mDefaultUniformBlocks,
212*8975f5c5SAndroid Build Coastguard Worker                &mDefaultUniformBlocksDirty);
213*8975f5c5SAndroid Build Coastguard Worker }
214*8975f5c5SAndroid Build Coastguard Worker 
setUniform4iv(GLint location,GLsizei count,const GLint * v)215*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableWgpu::setUniform4iv(GLint location, GLsizei count, const GLint *v)
216*8975f5c5SAndroid Build Coastguard Worker {
217*8975f5c5SAndroid Build Coastguard Worker     SetUniform(mExecutable, location, count, v, GL_INT_VEC4, &mDefaultUniformBlocks,
218*8975f5c5SAndroid Build Coastguard Worker                &mDefaultUniformBlocksDirty);
219*8975f5c5SAndroid Build Coastguard Worker }
220*8975f5c5SAndroid Build Coastguard Worker 
setUniform1uiv(GLint location,GLsizei count,const GLuint * v)221*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableWgpu::setUniform1uiv(GLint location, GLsizei count, const GLuint *v)
222*8975f5c5SAndroid Build Coastguard Worker {
223*8975f5c5SAndroid Build Coastguard Worker     SetUniform(mExecutable, location, count, v, GL_UNSIGNED_INT, &mDefaultUniformBlocks,
224*8975f5c5SAndroid Build Coastguard Worker                &mDefaultUniformBlocksDirty);
225*8975f5c5SAndroid Build Coastguard Worker }
226*8975f5c5SAndroid Build Coastguard Worker 
setUniform2uiv(GLint location,GLsizei count,const GLuint * v)227*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableWgpu::setUniform2uiv(GLint location, GLsizei count, const GLuint *v)
228*8975f5c5SAndroid Build Coastguard Worker {
229*8975f5c5SAndroid Build Coastguard Worker     SetUniform(mExecutable, location, count, v, GL_UNSIGNED_INT_VEC2, &mDefaultUniformBlocks,
230*8975f5c5SAndroid Build Coastguard Worker                &mDefaultUniformBlocksDirty);
231*8975f5c5SAndroid Build Coastguard Worker }
232*8975f5c5SAndroid Build Coastguard Worker 
setUniform3uiv(GLint location,GLsizei count,const GLuint * v)233*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableWgpu::setUniform3uiv(GLint location, GLsizei count, const GLuint *v)
234*8975f5c5SAndroid Build Coastguard Worker {
235*8975f5c5SAndroid Build Coastguard Worker     SetUniform(mExecutable, location, count, v, GL_UNSIGNED_INT_VEC3, &mDefaultUniformBlocks,
236*8975f5c5SAndroid Build Coastguard Worker                &mDefaultUniformBlocksDirty);
237*8975f5c5SAndroid Build Coastguard Worker }
238*8975f5c5SAndroid Build Coastguard Worker 
setUniform4uiv(GLint location,GLsizei count,const GLuint * v)239*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableWgpu::setUniform4uiv(GLint location, GLsizei count, const GLuint *v)
240*8975f5c5SAndroid Build Coastguard Worker {
241*8975f5c5SAndroid Build Coastguard Worker     SetUniform(mExecutable, location, count, v, GL_UNSIGNED_INT_VEC4, &mDefaultUniformBlocks,
242*8975f5c5SAndroid Build Coastguard Worker                &mDefaultUniformBlocksDirty);
243*8975f5c5SAndroid Build Coastguard Worker }
244*8975f5c5SAndroid Build Coastguard Worker 
setUniformMatrix2fv(GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)245*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableWgpu::setUniformMatrix2fv(GLint location,
246*8975f5c5SAndroid Build Coastguard Worker                                                 GLsizei count,
247*8975f5c5SAndroid Build Coastguard Worker                                                 GLboolean transpose,
248*8975f5c5SAndroid Build Coastguard Worker                                                 const GLfloat *value)
249*8975f5c5SAndroid Build Coastguard Worker {
250*8975f5c5SAndroid Build Coastguard Worker     SetUniformMatrixfv<2, 2>(mExecutable, location, count, transpose, value, &mDefaultUniformBlocks,
251*8975f5c5SAndroid Build Coastguard Worker                              &mDefaultUniformBlocksDirty);
252*8975f5c5SAndroid Build Coastguard Worker }
253*8975f5c5SAndroid Build Coastguard Worker 
setUniformMatrix3fv(GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)254*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableWgpu::setUniformMatrix3fv(GLint location,
255*8975f5c5SAndroid Build Coastguard Worker                                                 GLsizei count,
256*8975f5c5SAndroid Build Coastguard Worker                                                 GLboolean transpose,
257*8975f5c5SAndroid Build Coastguard Worker                                                 const GLfloat *value)
258*8975f5c5SAndroid Build Coastguard Worker {
259*8975f5c5SAndroid Build Coastguard Worker     SetUniformMatrixfv<3, 3>(mExecutable, location, count, transpose, value, &mDefaultUniformBlocks,
260*8975f5c5SAndroid Build Coastguard Worker                              &mDefaultUniformBlocksDirty);
261*8975f5c5SAndroid Build Coastguard Worker }
262*8975f5c5SAndroid Build Coastguard Worker 
setUniformMatrix4fv(GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)263*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableWgpu::setUniformMatrix4fv(GLint location,
264*8975f5c5SAndroid Build Coastguard Worker                                                 GLsizei count,
265*8975f5c5SAndroid Build Coastguard Worker                                                 GLboolean transpose,
266*8975f5c5SAndroid Build Coastguard Worker                                                 const GLfloat *value)
267*8975f5c5SAndroid Build Coastguard Worker {
268*8975f5c5SAndroid Build Coastguard Worker     SetUniformMatrixfv<4, 4>(mExecutable, location, count, transpose, value, &mDefaultUniformBlocks,
269*8975f5c5SAndroid Build Coastguard Worker                              &mDefaultUniformBlocksDirty);
270*8975f5c5SAndroid Build Coastguard Worker }
271*8975f5c5SAndroid Build Coastguard Worker 
setUniformMatrix2x3fv(GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)272*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableWgpu::setUniformMatrix2x3fv(GLint location,
273*8975f5c5SAndroid Build Coastguard Worker                                                   GLsizei count,
274*8975f5c5SAndroid Build Coastguard Worker                                                   GLboolean transpose,
275*8975f5c5SAndroid Build Coastguard Worker                                                   const GLfloat *value)
276*8975f5c5SAndroid Build Coastguard Worker {
277*8975f5c5SAndroid Build Coastguard Worker     SetUniformMatrixfv<2, 3>(mExecutable, location, count, transpose, value, &mDefaultUniformBlocks,
278*8975f5c5SAndroid Build Coastguard Worker                              &mDefaultUniformBlocksDirty);
279*8975f5c5SAndroid Build Coastguard Worker }
280*8975f5c5SAndroid Build Coastguard Worker 
setUniformMatrix3x2fv(GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)281*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableWgpu::setUniformMatrix3x2fv(GLint location,
282*8975f5c5SAndroid Build Coastguard Worker                                                   GLsizei count,
283*8975f5c5SAndroid Build Coastguard Worker                                                   GLboolean transpose,
284*8975f5c5SAndroid Build Coastguard Worker                                                   const GLfloat *value)
285*8975f5c5SAndroid Build Coastguard Worker {
286*8975f5c5SAndroid Build Coastguard Worker     SetUniformMatrixfv<3, 2>(mExecutable, location, count, transpose, value, &mDefaultUniformBlocks,
287*8975f5c5SAndroid Build Coastguard Worker                              &mDefaultUniformBlocksDirty);
288*8975f5c5SAndroid Build Coastguard Worker }
289*8975f5c5SAndroid Build Coastguard Worker 
setUniformMatrix2x4fv(GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)290*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableWgpu::setUniformMatrix2x4fv(GLint location,
291*8975f5c5SAndroid Build Coastguard Worker                                                   GLsizei count,
292*8975f5c5SAndroid Build Coastguard Worker                                                   GLboolean transpose,
293*8975f5c5SAndroid Build Coastguard Worker                                                   const GLfloat *value)
294*8975f5c5SAndroid Build Coastguard Worker {
295*8975f5c5SAndroid Build Coastguard Worker     SetUniformMatrixfv<2, 4>(mExecutable, location, count, transpose, value, &mDefaultUniformBlocks,
296*8975f5c5SAndroid Build Coastguard Worker                              &mDefaultUniformBlocksDirty);
297*8975f5c5SAndroid Build Coastguard Worker }
298*8975f5c5SAndroid Build Coastguard Worker 
setUniformMatrix4x2fv(GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)299*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableWgpu::setUniformMatrix4x2fv(GLint location,
300*8975f5c5SAndroid Build Coastguard Worker                                                   GLsizei count,
301*8975f5c5SAndroid Build Coastguard Worker                                                   GLboolean transpose,
302*8975f5c5SAndroid Build Coastguard Worker                                                   const GLfloat *value)
303*8975f5c5SAndroid Build Coastguard Worker {
304*8975f5c5SAndroid Build Coastguard Worker     SetUniformMatrixfv<4, 2>(mExecutable, location, count, transpose, value, &mDefaultUniformBlocks,
305*8975f5c5SAndroid Build Coastguard Worker                              &mDefaultUniformBlocksDirty);
306*8975f5c5SAndroid Build Coastguard Worker }
307*8975f5c5SAndroid Build Coastguard Worker 
setUniformMatrix3x4fv(GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)308*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableWgpu::setUniformMatrix3x4fv(GLint location,
309*8975f5c5SAndroid Build Coastguard Worker                                                   GLsizei count,
310*8975f5c5SAndroid Build Coastguard Worker                                                   GLboolean transpose,
311*8975f5c5SAndroid Build Coastguard Worker                                                   const GLfloat *value)
312*8975f5c5SAndroid Build Coastguard Worker {
313*8975f5c5SAndroid Build Coastguard Worker     SetUniformMatrixfv<3, 4>(mExecutable, location, count, transpose, value, &mDefaultUniformBlocks,
314*8975f5c5SAndroid Build Coastguard Worker                              &mDefaultUniformBlocksDirty);
315*8975f5c5SAndroid Build Coastguard Worker }
316*8975f5c5SAndroid Build Coastguard Worker 
setUniformMatrix4x3fv(GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)317*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableWgpu::setUniformMatrix4x3fv(GLint location,
318*8975f5c5SAndroid Build Coastguard Worker                                                   GLsizei count,
319*8975f5c5SAndroid Build Coastguard Worker                                                   GLboolean transpose,
320*8975f5c5SAndroid Build Coastguard Worker                                                   const GLfloat *value)
321*8975f5c5SAndroid Build Coastguard Worker {
322*8975f5c5SAndroid Build Coastguard Worker     SetUniformMatrixfv<4, 3>(mExecutable, location, count, transpose, value, &mDefaultUniformBlocks,
323*8975f5c5SAndroid Build Coastguard Worker                              &mDefaultUniformBlocksDirty);
324*8975f5c5SAndroid Build Coastguard Worker }
325*8975f5c5SAndroid Build Coastguard Worker 
getUniformfv(const gl::Context * context,GLint location,GLfloat * params) const326*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableWgpu::getUniformfv(const gl::Context *context,
327*8975f5c5SAndroid Build Coastguard Worker                                          GLint location,
328*8975f5c5SAndroid Build Coastguard Worker                                          GLfloat *params) const
329*8975f5c5SAndroid Build Coastguard Worker {
330*8975f5c5SAndroid Build Coastguard Worker     GetUniform(mExecutable, location, params, GL_FLOAT, &mDefaultUniformBlocks);
331*8975f5c5SAndroid Build Coastguard Worker }
332*8975f5c5SAndroid Build Coastguard Worker 
getUniformiv(const gl::Context * context,GLint location,GLint * params) const333*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableWgpu::getUniformiv(const gl::Context *context,
334*8975f5c5SAndroid Build Coastguard Worker                                          GLint location,
335*8975f5c5SAndroid Build Coastguard Worker                                          GLint *params) const
336*8975f5c5SAndroid Build Coastguard Worker {
337*8975f5c5SAndroid Build Coastguard Worker     GetUniform(mExecutable, location, params, GL_INT, &mDefaultUniformBlocks);
338*8975f5c5SAndroid Build Coastguard Worker }
339*8975f5c5SAndroid Build Coastguard Worker 
getUniformuiv(const gl::Context * context,GLint location,GLuint * params) const340*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableWgpu::getUniformuiv(const gl::Context *context,
341*8975f5c5SAndroid Build Coastguard Worker                                           GLint location,
342*8975f5c5SAndroid Build Coastguard Worker                                           GLuint *params) const
343*8975f5c5SAndroid Build Coastguard Worker {
344*8975f5c5SAndroid Build Coastguard Worker     GetUniform(mExecutable, location, params, GL_UNSIGNED_INT, &mDefaultUniformBlocks);
345*8975f5c5SAndroid Build Coastguard Worker }
346*8975f5c5SAndroid Build Coastguard Worker 
getShaderModule(gl::ShaderType type)347*8975f5c5SAndroid Build Coastguard Worker TranslatedWGPUShaderModule &ProgramExecutableWgpu::getShaderModule(gl::ShaderType type)
348*8975f5c5SAndroid Build Coastguard Worker {
349*8975f5c5SAndroid Build Coastguard Worker     return mShaderModules[type];
350*8975f5c5SAndroid Build Coastguard Worker }
351*8975f5c5SAndroid Build Coastguard Worker 
getRenderPipeline(ContextWgpu * context,const webgpu::RenderPipelineDesc & desc,wgpu::RenderPipeline * pipelineOut)352*8975f5c5SAndroid Build Coastguard Worker angle::Result ProgramExecutableWgpu::getRenderPipeline(ContextWgpu *context,
353*8975f5c5SAndroid Build Coastguard Worker                                                        const webgpu::RenderPipelineDesc &desc,
354*8975f5c5SAndroid Build Coastguard Worker                                                        wgpu::RenderPipeline *pipelineOut)
355*8975f5c5SAndroid Build Coastguard Worker {
356*8975f5c5SAndroid Build Coastguard Worker     gl::ShaderMap<wgpu::ShaderModule> shaders;
357*8975f5c5SAndroid Build Coastguard Worker     for (gl::ShaderType shaderType : gl::AllShaderTypes())
358*8975f5c5SAndroid Build Coastguard Worker     {
359*8975f5c5SAndroid Build Coastguard Worker         shaders[shaderType] = mShaderModules[shaderType].module;
360*8975f5c5SAndroid Build Coastguard Worker     }
361*8975f5c5SAndroid Build Coastguard Worker 
362*8975f5c5SAndroid Build Coastguard Worker     genBindingLayoutIfNecessary(context);
363*8975f5c5SAndroid Build Coastguard Worker 
364*8975f5c5SAndroid Build Coastguard Worker     return mPipelineCache.getRenderPipeline(context, desc, mPipelineLayout, shaders, pipelineOut);
365*8975f5c5SAndroid Build Coastguard Worker }
366*8975f5c5SAndroid Build Coastguard Worker 
genBindingLayoutIfNecessary(ContextWgpu * context)367*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableWgpu::genBindingLayoutIfNecessary(ContextWgpu *context)
368*8975f5c5SAndroid Build Coastguard Worker {
369*8975f5c5SAndroid Build Coastguard Worker     if (mPipelineLayout)
370*8975f5c5SAndroid Build Coastguard Worker     {
371*8975f5c5SAndroid Build Coastguard Worker         return;
372*8975f5c5SAndroid Build Coastguard Worker     }
373*8975f5c5SAndroid Build Coastguard Worker     // TODO(anglebug.com/42267100): for now, only create a wgpu::PipelineLayout with the default
374*8975f5c5SAndroid Build Coastguard Worker     // uniform block. Will need to be extended for driver uniforms, UBOs, and textures/samplers.
375*8975f5c5SAndroid Build Coastguard Worker     // Also, possibly provide this layout as a compilation hint to createShaderModule().
376*8975f5c5SAndroid Build Coastguard Worker 
377*8975f5c5SAndroid Build Coastguard Worker     std::vector<wgpu::BindGroupLayoutEntry> bindGroupLayoutEntries;
378*8975f5c5SAndroid Build Coastguard Worker     auto addBindGroupLayoutEntryIfNecessary = [&](uint32_t bindingIndex, gl::ShaderType shaderType,
379*8975f5c5SAndroid Build Coastguard Worker                                                   wgpu::ShaderStage wgpuVisibility) {
380*8975f5c5SAndroid Build Coastguard Worker         if (mDefaultUniformBlocks[shaderType]->uniformData.size() != 0)
381*8975f5c5SAndroid Build Coastguard Worker         {
382*8975f5c5SAndroid Build Coastguard Worker             wgpu::BindGroupLayoutEntry bindGroupLayoutEntry;
383*8975f5c5SAndroid Build Coastguard Worker             bindGroupLayoutEntry.visibility  = wgpuVisibility;
384*8975f5c5SAndroid Build Coastguard Worker             bindGroupLayoutEntry.binding     = bindingIndex;
385*8975f5c5SAndroid Build Coastguard Worker             bindGroupLayoutEntry.buffer.type = wgpu::BufferBindingType::Uniform;
386*8975f5c5SAndroid Build Coastguard Worker             // By setting a `minBindingSize`, some validation is pushed from every draw call to
387*8975f5c5SAndroid Build Coastguard Worker             // pipeline creation time.
388*8975f5c5SAndroid Build Coastguard Worker             bindGroupLayoutEntry.buffer.minBindingSize =
389*8975f5c5SAndroid Build Coastguard Worker                 mDefaultUniformBlocks[shaderType]->uniformData.size();
390*8975f5c5SAndroid Build Coastguard Worker             bindGroupLayoutEntries.push_back(bindGroupLayoutEntry);
391*8975f5c5SAndroid Build Coastguard Worker         }
392*8975f5c5SAndroid Build Coastguard Worker     };
393*8975f5c5SAndroid Build Coastguard Worker     // Default uniform blocks for each of the vertex shader and the fragment shader.
394*8975f5c5SAndroid Build Coastguard Worker     addBindGroupLayoutEntryIfNecessary(sh::kDefaultVertexUniformBlockBinding,
395*8975f5c5SAndroid Build Coastguard Worker                                        gl::ShaderType::Vertex, wgpu::ShaderStage::Vertex);
396*8975f5c5SAndroid Build Coastguard Worker     addBindGroupLayoutEntryIfNecessary(sh::kDefaultFragmentUniformBlockBinding,
397*8975f5c5SAndroid Build Coastguard Worker                                        gl::ShaderType::Fragment, wgpu::ShaderStage::Fragment);
398*8975f5c5SAndroid Build Coastguard Worker 
399*8975f5c5SAndroid Build Coastguard Worker     // Create a bind group layout with these entries.
400*8975f5c5SAndroid Build Coastguard Worker     wgpu::BindGroupLayoutDescriptor bindGroupLayoutDesc{};
401*8975f5c5SAndroid Build Coastguard Worker     bindGroupLayoutDesc.entryCount = bindGroupLayoutEntries.size();
402*8975f5c5SAndroid Build Coastguard Worker     bindGroupLayoutDesc.entries    = bindGroupLayoutEntries.data();
403*8975f5c5SAndroid Build Coastguard Worker     mDefaultBindGroupLayout = context->getDevice().CreateBindGroupLayout(&bindGroupLayoutDesc);
404*8975f5c5SAndroid Build Coastguard Worker 
405*8975f5c5SAndroid Build Coastguard Worker     // Create the pipeline layout. This is a list where each element N corresponds to the @group(N)
406*8975f5c5SAndroid Build Coastguard Worker     // in the compiled shaders.
407*8975f5c5SAndroid Build Coastguard Worker     wgpu::PipelineLayoutDescriptor layoutDesc{};
408*8975f5c5SAndroid Build Coastguard Worker     layoutDesc.bindGroupLayoutCount = 1;
409*8975f5c5SAndroid Build Coastguard Worker     layoutDesc.bindGroupLayouts     = &mDefaultBindGroupLayout;
410*8975f5c5SAndroid Build Coastguard Worker     mPipelineLayout                 = context->getDevice().CreatePipelineLayout(&layoutDesc);
411*8975f5c5SAndroid Build Coastguard Worker }
412*8975f5c5SAndroid Build Coastguard Worker 
413*8975f5c5SAndroid Build Coastguard Worker }  // namespace rx
414