Hash :
4a835cf2
Author :
Date :
2024-11-01T13:31:00
WebGPU: send uniforms to GPU for use in shader Basic uniforms should now be accessible in the shader during a draw call, rather than just via glGetUniform*(). This is unoptimized and creates a new GPU-side copy of all the uniforms, every time any uniform changes. This sets up the bind group layout for a pipeline and sets the bind groups in the renderer pass. Right now these bind groups only contain the default uniform blocks, but in the future will need to contain textures, samplers, and non-default uniform blocks (UBOs). Bug: angleproject:376553328 Change-Id: I50891b81ab2ee374d674213257f76319c0222120 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/5980972 Reviewed-by: Geoff Lang <geofflang@chromium.org> Reviewed-by: Liza Burakova <liza@chromium.org> Commit-Queue: Matthew Denton <mpdenton@chromium.org>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
//
// Copyright 2024 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
#include "compiler/translator/wgsl/OutputUniformBlocks.h"
#include "angle_gl.h"
#include "common/utilities.h"
#include "compiler/translator/Compiler.h"
#include "compiler/translator/InfoSink.h"
#include "compiler/translator/IntermNode.h"
#include "compiler/translator/util.h"
#include "compiler/translator/wgsl/Utils.h"
namespace sh
{
bool OutputUniformBlocks(TCompiler *compiler, TIntermBlock *root)
{
// TODO(anglebug.com/42267100): This should eventually just be handled the same way as a regular
// UBO, like in Vulkan which create a block out of the default uniforms with a traverser:
// https://source.chromium.org/chromium/chromium/src/+/main:third_party/angle/src/compiler/translator/spirv/TranslatorSPIRV.cpp;l=70;drc=451093bbaf7fe812bf67d27d760f3bb64c92830b
const std::vector<ShaderVariable> &basicUniforms = compiler->getUniforms();
TInfoSinkBase &output = compiler->getInfoSink().obj;
GlobalVars globalVars = FindGlobalVars(root);
// Only output a struct at all if there are going to be members.
bool outputStructHeader = false;
for (const ShaderVariable &shaderVar : basicUniforms)
{
if (gl::IsOpaqueType(shaderVar.type))
{
continue;
}
if (shaderVar.isBuiltIn())
{
// gl_DepthRange and also the GLSL 4.2 gl_NumSamples are uniforms.
// TODO(anglebug.com/42267100): put gl_DepthRange into default uniform block.
continue;
}
if (!outputStructHeader)
{
output << "struct ANGLE_DefaultUniformBlock {\n";
outputStructHeader = true;
}
output << " ";
// TODO(anglebug.com/42267100): some types will NOT match std140 layout here, namely matCx2,
// bool, and arrays with stride less than 16.
// (this check does not cover the unsupported case where there is an array of structs of
// size < 16).
if (gl::VariableRowCount(shaderVar.type) == 2 || shaderVar.type == GL_BOOL ||
(shaderVar.isArray() && !shaderVar.isStruct() &&
gl::VariableComponentCount(shaderVar.type) < 3))
{
return false;
}
output << shaderVar.name << " : ";
TIntermDeclaration *declNode = globalVars.find(shaderVar.name)->second;
const TVariable *astVar = &ViewDeclaration(*declNode).symbol.variable();
WriteWgslType(output, astVar->getType());
output << ",\n";
}
// TODO(anglebug.com/42267100): might need string replacement for @group(0) and @binding(0)
// annotations. All WGSL resources available to shaders share the same (group, binding) ID
// space.
if (outputStructHeader)
{
ASSERT(compiler->getShaderType() == GL_VERTEX_SHADER ||
compiler->getShaderType() == GL_FRAGMENT_SHADER);
const uint32_t bindingIndex = compiler->getShaderType() == GL_VERTEX_SHADER
? kDefaultVertexUniformBlockBinding
: kDefaultFragmentUniformBlockBinding;
output << "};\n\n"
<< "@group(" << kDefaultUniformBlockBindGroup << ") @binding(" << bindingIndex
<< ") var<uniform> " << kDefaultUniformBlockVarName << " : "
<< kDefaultUniformBlockVarType << ";\n";
}
return true;
}
} // namespace sh