Hash :
4b69ba93
Author :
Date :
2025-04-28T16:45:56
WGPU: upload texture bind groups and configured samplers
GLSL samplers are split into separate sampler/texture variables
in WGSL. Before this CL, the WGSL translator generated shaders
that look like:
@group(1) @binding(@@@@@@) var ANGLE_sampler_samp2D :
sampler;
@group(1) @binding(@@@@@@) var ANGLE_texture_samp2D :
texture_2d<f32>;
@group(1) @binding(@@@@@@) var ANGLE_sampler_sampCube :
sampler;
@group(1) @binding(@@@@@@) var ANGLE_texture_sampCube :
texture_cube<f32>;
This CL replaces those with actual binding numbers
@group(1) @binding(0) var ANGLE_sampler_samp2D :
sampler;
@group(1) @binding(1) var ANGLE_texture_samp2D :
texture_2d<f32>;
...
Such that @binding(n*2) is the WGSL sampler variable corresponding
to the n-th GLSL sampler and @binding(n*2+1) is the WGSL texture
variable corresponding to the n-th GLSL sampler.
This CL then generates binding group layouts matching the above,
and uploads textures and configured samplers in bind groups.
This makes some of the deqp_gles2 tests 2d texture tests pass,
though some fail because they need a flipped y coordinate.
Not yet supported:
1. arrays of samplers
2. shadow samplers
3. cube textures
Bug: angleproject:389145696
Change-Id: I2ab18ae5ebb4d1289101266bd9451576aa04ce2a
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/6382272
Reviewed-by: Liza Burakova <liza@chromium.org>
Auto-Submit: Matthew Denton <mpdenton@chromium.org>
Commit-Queue: Geoff Lang <geofflang@chromium.org>
Reviewed-by: Geoff Lang <geofflang@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 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
//
// 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.
//
// ProgramExecutableWgpu.h: Implementation of ProgramExecutableImpl.
#ifndef LIBANGLE_RENDERER_WGPU_PROGRAMEXECUTABLEWGPU_H_
#define LIBANGLE_RENDERER_WGPU_PROGRAMEXECUTABLEWGPU_H_
#include "libANGLE/ProgramExecutable.h"
#include "libANGLE/renderer/ProgramExecutableImpl.h"
#include "libANGLE/renderer/renderer_utils.h"
#include "libANGLE/renderer/wgpu/wgpu_pipeline_state.h"
#include <dawn/webgpu_cpp.h>
namespace rx
{
struct TranslatedWGPUShaderModule
{
wgpu::ShaderModule module;
};
class ProgramExecutableWgpu : public ProgramExecutableImpl
{
public:
ProgramExecutableWgpu(const gl::ProgramExecutable *executable);
~ProgramExecutableWgpu() override;
void destroy(const gl::Context *context) override;
angle::Result updateUniformsAndGetBindGroup(ContextWgpu *context,
wgpu::BindGroup *outBindGroup);
angle::Result getSamplerAndTextureBindGroup(ContextWgpu *contextWgpu,
wgpu::BindGroup *outBindGroup);
angle::Result resizeUniformBlockMemory(const gl::ShaderMap<size_t> &requiredBufferSize);
std::shared_ptr<BufferAndLayout> &getSharedDefaultUniformBlock(gl::ShaderType shaderType)
{
return mDefaultUniformBlocks[shaderType];
}
void markDefaultUniformsDirty();
bool checkDirtyUniforms() { return mDefaultUniformBlocksDirty.any(); }
void markSamplerBindingsDirty() { mSamplerBindingsDirty = true; }
bool hasDirtySamplerBindings() { return mSamplerBindingsDirty; }
void setUniform1fv(GLint location, GLsizei count, const GLfloat *v) override;
void setUniform2fv(GLint location, GLsizei count, const GLfloat *v) override;
void setUniform3fv(GLint location, GLsizei count, const GLfloat *v) override;
void setUniform4fv(GLint location, GLsizei count, const GLfloat *v) override;
void setUniform1iv(GLint location, GLsizei count, const GLint *v) override;
void setUniform2iv(GLint location, GLsizei count, const GLint *v) override;
void setUniform3iv(GLint location, GLsizei count, const GLint *v) override;
void setUniform4iv(GLint location, GLsizei count, const GLint *v) override;
void setUniform1uiv(GLint location, GLsizei count, const GLuint *v) override;
void setUniform2uiv(GLint location, GLsizei count, const GLuint *v) override;
void setUniform3uiv(GLint location, GLsizei count, const GLuint *v) override;
void setUniform4uiv(GLint location, GLsizei count, const GLuint *v) override;
void setUniformMatrix2fv(GLint location,
GLsizei count,
GLboolean transpose,
const GLfloat *value) override;
void setUniformMatrix3fv(GLint location,
GLsizei count,
GLboolean transpose,
const GLfloat *value) override;
void setUniformMatrix4fv(GLint location,
GLsizei count,
GLboolean transpose,
const GLfloat *value) override;
void setUniformMatrix2x3fv(GLint location,
GLsizei count,
GLboolean transpose,
const GLfloat *value) override;
void setUniformMatrix3x2fv(GLint location,
GLsizei count,
GLboolean transpose,
const GLfloat *value) override;
void setUniformMatrix2x4fv(GLint location,
GLsizei count,
GLboolean transpose,
const GLfloat *value) override;
void setUniformMatrix4x2fv(GLint location,
GLsizei count,
GLboolean transpose,
const GLfloat *value) override;
void setUniformMatrix3x4fv(GLint location,
GLsizei count,
GLboolean transpose,
const GLfloat *value) override;
void setUniformMatrix4x3fv(GLint location,
GLsizei count,
GLboolean transpose,
const GLfloat *value) override;
void getUniformfv(const gl::Context *context, GLint location, GLfloat *params) const override;
void getUniformiv(const gl::Context *context, GLint location, GLint *params) const override;
void getUniformuiv(const gl::Context *context, GLint location, GLuint *params) const override;
TranslatedWGPUShaderModule &getShaderModule(gl::ShaderType type);
angle::Result getRenderPipeline(ContextWgpu *context,
const webgpu::RenderPipelineDesc &desc,
wgpu::RenderPipeline *pipelineOut);
private:
angle::CheckedNumeric<size_t> getDefaultUniformAlignedSize(ContextWgpu *context,
gl::ShaderType shaderType) const;
angle::CheckedNumeric<size_t> calcUniformUpdateRequiredSpace(
ContextWgpu *context,
gl::ShaderMap<uint64_t> *uniformOffsets) const;
// The layout of the resource bind groups (numbering for buffers, textures, samplers) can be
// determined once the program is linked, and should be passed in pipeline creation. Fills in
// `mPipelineLayout` and `mDefaultBindGroupLayout` if they haven't been already.
void genBindingLayoutIfNecessary(ContextWgpu *context);
gl::ShaderMap<TranslatedWGPUShaderModule> mShaderModules;
webgpu::PipelineCache mPipelineCache;
// Holds the binding layout of resources (buffers, textures, samplers) required by the linked
// shaders.
wgpu::PipelineLayout mPipelineLayout;
// Holds the binding group layout for the default bind group.
wgpu::BindGroupLayout mDefaultBindGroupLayout;
// Holds the most recent BindGroup. Note there may be others in the command buffer.
wgpu::BindGroup mDefaultBindGroup;
// Holds layout info for basic GL uniforms, which needs to be laid out in a buffer for WGSL
// similarly to a UBO.
DefaultUniformBlockMap mDefaultUniformBlocks;
gl::ShaderBitSet mDefaultUniformBlocksDirty;
// Tracks when a sampler binding has been changed with glUniform1i(). Starts true to ensure the
// bind group is created the first time around.
bool mSamplerBindingsDirty = true;
// Holds the binding group layout for the samplers and textures.
wgpu::BindGroupLayout mSamplersAndTexturesBindGroupLayout;
// Holds the most recent samplers and textures BindGroup. Note there may be others in the
// command buffer.
wgpu::BindGroup mSamplersAndTexturesBindGroup;
};
} // namespace rx
#endif // LIBANGLE_RENDERER_WGPU_PROGRAMEXECUTABLEWGPU_H_