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