Hash :
bb14aa4d
Author :
Date :
2024-09-19T11:17:05
WebGPU: set vertex buffers. This change actually sets the vertex attributes that are added to the render pipeline description owned by the context, as well as sets the vertex buffer in the pipeline. Bug: angleproject:359823692 Change-Id: I5e94b357a4e6eadc1bbba54965cef94f90113b4e Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/5789155 Reviewed-by: Geoff Lang <geofflang@chromium.org> Commit-Queue: Geoff Lang <geofflang@chromium.org> Reviewed-by: Liza Burakova <liza@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 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220
//
// 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.
//
#ifndef LIBANGLE_RENDERER_WGPU_PIPELINE_STATE_H_
#define LIBANGLE_RENDERER_WGPU_PIPELINE_STATE_H_
#include <dawn/webgpu_cpp.h>
#include <stdint.h>
#include <limits>
#include "libANGLE/Constants.h"
#include "libANGLE/Error.h"
#include "libANGLE/angletypes.h"
#include "common/PackedEnums.h"
namespace rx
{
class ContextWgpu;
namespace webgpu
{
ANGLE_ENABLE_STRUCT_PADDING_WARNINGS
constexpr uint32_t kPrimitiveTopologyBitCount = 3;
constexpr uint32_t kIndexFormatBitCount = 1;
constexpr uint32_t kFrontFaceBitCount = 1;
constexpr uint32_t kCullModeBitCount = 2;
struct PackedPrimitiveState final
{
uint8_t topology : kPrimitiveTopologyBitCount;
uint8_t stripIndexFormat : kIndexFormatBitCount;
uint8_t frontFace : kFrontFaceBitCount;
uint8_t cullMode : kCullModeBitCount;
uint8_t pad0 : 1;
};
constexpr size_t kPackedPrimitiveStateSize = sizeof(PackedPrimitiveState);
static_assert(kPackedPrimitiveStateSize == 1, "Size mismatch");
constexpr uint32_t kTextureFormatBitCount = 19;
constexpr uint32_t kColorWriteMaskBitCount = 4;
constexpr uint32_t kBlendFactorBitCount = 5;
constexpr uint32_t kBlendOperationBitCount = 3;
struct PackedColorTargetState final
{
uint32_t format : kTextureFormatBitCount;
uint32_t blendEnabled : 1;
uint32_t colorBlendSrcFactor : kBlendFactorBitCount;
uint32_t colorBlendDstFactor : kBlendFactorBitCount;
uint32_t pad0 : 2;
uint32_t colorBlendOp : kBlendOperationBitCount;
uint32_t alphaBlendSrcFactor : kBlendFactorBitCount;
uint32_t alphaBlendDstFactor : kBlendFactorBitCount;
uint32_t alphaBlendOp : kBlendOperationBitCount;
uint32_t writeMask : kColorWriteMaskBitCount;
uint32_t pad1 : 12;
};
constexpr size_t kPackedColorTargetStateSize = sizeof(PackedColorTargetState);
static_assert(kPackedColorTargetStateSize == 8, "Size mismatch");
constexpr uint32_t kCompareFunctionBitCount = 4;
constexpr uint32_t kStencilOperationBitCount = 4;
struct PackedDepthStencilState final
{
uint32_t format : kTextureFormatBitCount;
uint32_t depthWriteEnabled : 1;
uint32_t depthCompare : kCompareFunctionBitCount;
uint32_t stencilFrontCompare : kCompareFunctionBitCount;
uint32_t stencilFrontFailOp : kStencilOperationBitCount;
uint32_t stencilFrontDepthFailOp : kStencilOperationBitCount;
uint32_t stencilFrontPassOp : kStencilOperationBitCount;
uint32_t stencilBackCompare : kCompareFunctionBitCount;
uint32_t stencilBackFailOp : kStencilOperationBitCount;
uint32_t stencilBackDepthFailOp : kStencilOperationBitCount;
uint32_t stencilBackPassOp : kStencilOperationBitCount;
uint32_t pad0 : 8;
uint8_t stencilReadMask;
uint8_t stencilWriteMask;
uint8_t pad1[2];
int32_t depthBias;
float depthBiasSlopeScalef;
float depthBiasClamp;
};
constexpr size_t kPackedDepthStencilStateSize = sizeof(PackedDepthStencilState);
static_assert(kPackedDepthStencilStateSize == 24, "Size mismatch");
constexpr uint32_t kVertexFormatBitCount = 5;
// A maximum offset of 4096 covers almost every Vulkan driver on desktop (80%) and mobile (99%). The
// next highest values to meet native drivers are 16 bits or 32 bits.
constexpr uint32_t kAttributeOffsetMaxBits = 15;
// In WebGPU, the maxVertexBufferArrayStride will be at least 2048.
constexpr uint32_t kVertexAttributeStrideBits = 16;
struct PackedVertexAttribute final
{
PackedVertexAttribute();
uint16_t offset : kAttributeOffsetMaxBits;
uint16_t enabled : 1;
uint8_t format : kVertexFormatBitCount;
uint8_t pad1 : 3;
uint8_t shaderLocation;
uint16_t stride : kVertexAttributeStrideBits;
};
constexpr size_t kPackedVertexAttributeSize = sizeof(PackedVertexAttribute);
static_assert(kPackedVertexAttributeSize == 6, "Size mismatch");
class RenderPipelineDesc final
{
public:
RenderPipelineDesc();
~RenderPipelineDesc();
RenderPipelineDesc(const RenderPipelineDesc &other);
RenderPipelineDesc &operator=(const RenderPipelineDesc &other);
// Returns true if the pipeline description has changed
bool setPrimitiveMode(gl::PrimitiveMode primitiveMode, gl::DrawElementsType indexTypeOrInvalid);
void setFrontFace(GLenum frontFace);
void setCullMode(gl::CullFaceMode cullMode, bool cullFaceEnabled);
void setColorWriteMask(size_t colorIndex, bool r, bool g, bool b, bool a);
bool setVertexAttribute(size_t attribIndex, PackedVertexAttribute &newAttrib);
bool setColorAttachmentFormat(size_t colorIndex, wgpu::TextureFormat format);
bool setDepthStencilAttachmentFormat(wgpu::TextureFormat format);
bool setDepthFunc(wgpu::CompareFunction compareFunc);
bool setStencilFrontFunc(wgpu::CompareFunction compareFunc);
bool setStencilFrontOps(wgpu::StencilOperation failOp,
wgpu::StencilOperation depthFailOp,
wgpu::StencilOperation passOp);
bool setStencilBackFunc(wgpu::CompareFunction compareFunc);
bool setStencilBackOps(wgpu::StencilOperation failOp,
wgpu::StencilOperation depthFailOp,
wgpu::StencilOperation passOp);
bool setStencilReadMask(uint8_t readeMask);
bool setStencilWriteMask(uint8_t writeMask);
size_t hash() const;
angle::Result createPipeline(ContextWgpu *context,
const wgpu::PipelineLayout &pipelineLayout,
const gl::ShaderMap<wgpu::ShaderModule> &shaders,
wgpu::RenderPipeline *pipelineOut) const;
private:
PackedVertexAttribute mVertexAttributes[gl::MAX_VERTEX_ATTRIBS];
PackedColorTargetState mColorTargetStates[gl::IMPLEMENTATION_MAX_DRAW_BUFFERS];
PackedDepthStencilState mDepthStencilState;
PackedPrimitiveState mPrimitiveState;
uint8_t mPad0[3];
};
constexpr size_t kRenderPipelineDescSize = sizeof(RenderPipelineDesc);
static_assert(kRenderPipelineDescSize % 4 == 0,
"RenderPipelineDesc size must be a multiple of 4 bytes.");
bool operator==(const RenderPipelineDesc &lhs, const RenderPipelineDesc &rhs);
ANGLE_DISABLE_STRUCT_PADDING_WARNINGS
} // namespace webgpu
} // namespace rx
// Introduce std::hash for the above classes.
namespace std
{
template <>
struct hash<rx::webgpu::RenderPipelineDesc>
{
size_t operator()(const rx::webgpu::RenderPipelineDesc &key) const { return key.hash(); }
};
} // namespace std
namespace rx
{
namespace webgpu
{
class PipelineCache final
{
public:
PipelineCache();
~PipelineCache();
angle::Result getRenderPipeline(ContextWgpu *context,
const RenderPipelineDesc &desc,
const wgpu::PipelineLayout &pipelineLayout,
const gl::ShaderMap<wgpu::ShaderModule> &shaders,
wgpu::RenderPipeline *pipelineOut);
private:
std::unordered_map<RenderPipelineDesc, wgpu::RenderPipeline> mRenderPipelines;
};
} // namespace webgpu
} // namespace rx
#endif // LIBANGLE_RENDERER_WGPU_PIPELINE_STATE_H_