1 // 2 // Copyright 2024 The ANGLE Project Authors. All rights reserved. 3 // Use of this source code is governed by a BSD-style license that can be 4 // found in the LICENSE file. 5 // 6 // ContextWgpu.h: 7 // Defines the class interface for ContextWgpu, implementing ContextImpl. 8 // 9 10 #ifndef LIBANGLE_RENDERER_WGPU_CONTEXTWGPU_H_ 11 #define LIBANGLE_RENDERER_WGPU_CONTEXTWGPU_H_ 12 13 #include <dawn/webgpu_cpp.h> 14 15 #include "image_util/loadimage.h" 16 #include "libANGLE/renderer/ContextImpl.h" 17 #include "libANGLE/renderer/wgpu/DisplayWgpu.h" 18 #include "libANGLE/renderer/wgpu/wgpu_command_buffer.h" 19 #include "libANGLE/renderer/wgpu/wgpu_format_utils.h" 20 #include "libANGLE/renderer/wgpu/wgpu_helpers.h" 21 #include "libANGLE/renderer/wgpu/wgpu_pipeline_state.h" 22 #include "libANGLE/renderer/wgpu/wgpu_utils.h" 23 24 namespace rx 25 { 26 27 class ContextWgpu : public ContextImpl 28 { 29 public: 30 ContextWgpu(const gl::State &state, gl::ErrorSet *errorSet, DisplayWgpu *display); 31 ~ContextWgpu() override; 32 33 angle::Result initialize(const angle::ImageLoadContext &imageLoadContext) override; 34 35 void onDestroy(const gl::Context *context) override; 36 37 // Flush and finish. 38 angle::Result flush(const gl::Context *context) override; 39 angle::Result finish(const gl::Context *context) override; 40 41 // Drawing methods. 42 angle::Result drawArrays(const gl::Context *context, 43 gl::PrimitiveMode mode, 44 GLint first, 45 GLsizei count) override; 46 angle::Result drawArraysInstanced(const gl::Context *context, 47 gl::PrimitiveMode mode, 48 GLint first, 49 GLsizei count, 50 GLsizei instanceCount) override; 51 angle::Result drawArraysInstancedBaseInstance(const gl::Context *context, 52 gl::PrimitiveMode mode, 53 GLint first, 54 GLsizei count, 55 GLsizei instanceCount, 56 GLuint baseInstance) override; 57 58 angle::Result drawElements(const gl::Context *context, 59 gl::PrimitiveMode mode, 60 GLsizei count, 61 gl::DrawElementsType type, 62 const void *indices) override; 63 angle::Result drawElementsBaseVertex(const gl::Context *context, 64 gl::PrimitiveMode mode, 65 GLsizei count, 66 gl::DrawElementsType type, 67 const void *indices, 68 GLint baseVertex) override; 69 angle::Result drawElementsInstanced(const gl::Context *context, 70 gl::PrimitiveMode mode, 71 GLsizei count, 72 gl::DrawElementsType type, 73 const void *indices, 74 GLsizei instances) override; 75 angle::Result drawElementsInstancedBaseVertex(const gl::Context *context, 76 gl::PrimitiveMode mode, 77 GLsizei count, 78 gl::DrawElementsType type, 79 const void *indices, 80 GLsizei instances, 81 GLint baseVertex) override; 82 angle::Result drawElementsInstancedBaseVertexBaseInstance(const gl::Context *context, 83 gl::PrimitiveMode mode, 84 GLsizei count, 85 gl::DrawElementsType type, 86 const void *indices, 87 GLsizei instances, 88 GLint baseVertex, 89 GLuint baseInstance) override; 90 angle::Result drawRangeElements(const gl::Context *context, 91 gl::PrimitiveMode mode, 92 GLuint start, 93 GLuint end, 94 GLsizei count, 95 gl::DrawElementsType type, 96 const void *indices) override; 97 angle::Result drawRangeElementsBaseVertex(const gl::Context *context, 98 gl::PrimitiveMode mode, 99 GLuint start, 100 GLuint end, 101 GLsizei count, 102 gl::DrawElementsType type, 103 const void *indices, 104 GLint baseVertex) override; 105 angle::Result drawArraysIndirect(const gl::Context *context, 106 gl::PrimitiveMode mode, 107 const void *indirect) override; 108 angle::Result drawElementsIndirect(const gl::Context *context, 109 gl::PrimitiveMode mode, 110 gl::DrawElementsType type, 111 const void *indirect) override; 112 113 angle::Result multiDrawArrays(const gl::Context *context, 114 gl::PrimitiveMode mode, 115 const GLint *firsts, 116 const GLsizei *counts, 117 GLsizei drawcount) override; 118 angle::Result multiDrawArraysInstanced(const gl::Context *context, 119 gl::PrimitiveMode mode, 120 const GLint *firsts, 121 const GLsizei *counts, 122 const GLsizei *instanceCounts, 123 GLsizei drawcount) override; 124 angle::Result multiDrawArraysIndirect(const gl::Context *context, 125 gl::PrimitiveMode mode, 126 const void *indirect, 127 GLsizei drawcount, 128 GLsizei stride) override; 129 angle::Result multiDrawElements(const gl::Context *context, 130 gl::PrimitiveMode mode, 131 const GLsizei *counts, 132 gl::DrawElementsType type, 133 const GLvoid *const *indices, 134 GLsizei drawcount) override; 135 angle::Result multiDrawElementsInstanced(const gl::Context *context, 136 gl::PrimitiveMode mode, 137 const GLsizei *counts, 138 gl::DrawElementsType type, 139 const GLvoid *const *indices, 140 const GLsizei *instanceCounts, 141 GLsizei drawcount) override; 142 angle::Result multiDrawElementsIndirect(const gl::Context *context, 143 gl::PrimitiveMode mode, 144 gl::DrawElementsType type, 145 const void *indirect, 146 GLsizei drawcount, 147 GLsizei stride) override; 148 angle::Result multiDrawArraysInstancedBaseInstance(const gl::Context *context, 149 gl::PrimitiveMode mode, 150 const GLint *firsts, 151 const GLsizei *counts, 152 const GLsizei *instanceCounts, 153 const GLuint *baseInstances, 154 GLsizei drawcount) override; 155 angle::Result multiDrawElementsInstancedBaseVertexBaseInstance(const gl::Context *context, 156 gl::PrimitiveMode mode, 157 const GLsizei *counts, 158 gl::DrawElementsType type, 159 const GLvoid *const *indices, 160 const GLsizei *instanceCounts, 161 const GLint *baseVertices, 162 const GLuint *baseInstances, 163 GLsizei drawcount) override; 164 165 // Device loss 166 gl::GraphicsResetStatus getResetStatus() override; 167 168 // EXT_debug_marker 169 angle::Result insertEventMarker(GLsizei length, const char *marker) override; 170 angle::Result pushGroupMarker(GLsizei length, const char *marker) override; 171 angle::Result popGroupMarker() override; 172 173 // KHR_debug 174 angle::Result pushDebugGroup(const gl::Context *context, 175 GLenum source, 176 GLuint id, 177 const std::string &message) override; 178 angle::Result popDebugGroup(const gl::Context *context) override; 179 180 // State sync with dirty bits. 181 angle::Result syncState(const gl::Context *context, 182 const gl::state::DirtyBits dirtyBits, 183 const gl::state::DirtyBits bitMask, 184 const gl::state::ExtendedDirtyBits extendedDirtyBits, 185 const gl::state::ExtendedDirtyBits extendedBitMask, 186 gl::Command command) override; 187 188 // Disjoint timer queries 189 GLint getGPUDisjoint() override; 190 GLint64 getTimestamp() override; 191 192 // Context switching 193 angle::Result onMakeCurrent(const gl::Context *context) override; 194 195 // Native capabilities, unmodified by gl::Context. 196 gl::Caps getNativeCaps() const override; 197 const gl::TextureCapsMap &getNativeTextureCaps() const override; 198 const gl::Extensions &getNativeExtensions() const override; 199 const gl::Limitations &getNativeLimitations() const override; 200 const ShPixelLocalStorageOptions &getNativePixelLocalStorageOptions() const override; 201 202 // Shader creation 203 CompilerImpl *createCompiler() override; 204 ShaderImpl *createShader(const gl::ShaderState &data) override; 205 ProgramImpl *createProgram(const gl::ProgramState &data) override; 206 ProgramExecutableImpl *createProgramExecutable( 207 const gl::ProgramExecutable *executable) override; 208 209 // Framebuffer creation 210 FramebufferImpl *createFramebuffer(const gl::FramebufferState &data) override; 211 212 // Texture creation 213 TextureImpl *createTexture(const gl::TextureState &state) override; 214 215 // Renderbuffer creation 216 RenderbufferImpl *createRenderbuffer(const gl::RenderbufferState &state) override; 217 218 // Buffer creation 219 BufferImpl *createBuffer(const gl::BufferState &state) override; 220 221 // Vertex Array creation 222 VertexArrayImpl *createVertexArray(const gl::VertexArrayState &data) override; 223 224 // Query and Fence creation 225 QueryImpl *createQuery(gl::QueryType type) override; 226 FenceNVImpl *createFenceNV() override; 227 SyncImpl *createSync() override; 228 229 // Transform Feedback creation 230 TransformFeedbackImpl *createTransformFeedback( 231 const gl::TransformFeedbackState &state) override; 232 233 // Sampler object creation 234 SamplerImpl *createSampler(const gl::SamplerState &state) override; 235 236 // Program Pipeline object creation 237 ProgramPipelineImpl *createProgramPipeline(const gl::ProgramPipelineState &data) override; 238 239 // Memory object creation. 240 MemoryObjectImpl *createMemoryObject() override; 241 242 // Semaphore creation. 243 SemaphoreImpl *createSemaphore() override; 244 245 // Overlay creation. 246 OverlayImpl *createOverlay(const gl::OverlayState &state) override; 247 248 angle::Result dispatchCompute(const gl::Context *context, 249 GLuint numGroupsX, 250 GLuint numGroupsY, 251 GLuint numGroupsZ) override; 252 angle::Result dispatchComputeIndirect(const gl::Context *context, GLintptr indirect) override; 253 254 angle::Result memoryBarrier(const gl::Context *context, GLbitfield barriers) override; 255 angle::Result memoryBarrierByRegion(const gl::Context *context, GLbitfield barriers) override; 256 257 void handleError(GLenum errorCode, 258 const char *message, 259 const char *file, 260 const char *function, 261 unsigned int line); 262 getImageLoadContext()263 const angle::ImageLoadContext &getImageLoadContext() const { return mImageLoadContext; } 264 getDisplay()265 DisplayWgpu *getDisplay() { return mDisplay; } getDevice()266 wgpu::Device &getDevice() { return mDisplay->getDevice(); } getQueue()267 wgpu::Queue &getQueue() { return mDisplay->getQueue(); } getInstance()268 wgpu::Instance &getInstance() { return mDisplay->getInstance(); } getImageLoadContext()269 angle::ImageLoadContext &getImageLoadContext() { return mImageLoadContext; } getFormat(GLenum internalFormat)270 const webgpu::Format &getFormat(GLenum internalFormat) const 271 { 272 return mDisplay->getFormat(internalFormat); 273 } 274 angle::Result startRenderPass(const wgpu::RenderPassDescriptor &desc); 275 angle::Result endRenderPass(webgpu::RenderPassClosureReason closureReason); 276 hasActiveRenderPass()277 bool hasActiveRenderPass() { return mCurrentRenderPass != nullptr; } 278 279 angle::Result onFramebufferChange(FramebufferWgpu *framebufferWgpu, gl::Command command); 280 281 angle::Result flush(webgpu::RenderPassClosureReason); 282 283 void setColorAttachmentFormat(size_t colorIndex, wgpu::TextureFormat format); 284 void setColorAttachmentFormats(const gl::DrawBuffersArray<wgpu::TextureFormat> &formats); 285 void setDepthStencilFormat(wgpu::TextureFormat format); 286 void setVertexAttribute(size_t attribIndex, webgpu::PackedVertexAttribute newAttrib); 287 288 void invalidateVertexBuffer(size_t slot); 289 void invalidateVertexBuffers(); 290 void invalidateIndexBuffer(); 291 292 void ensureCommandEncoderCreated(); 293 wgpu::CommandEncoder &getCurrentCommandEncoder(); 294 295 private: 296 // Dirty bits. 297 enum DirtyBitType : size_t 298 { 299 // The pipeline has changed and needs to be recreated. 300 DIRTY_BIT_RENDER_PIPELINE_DESC, 301 302 DIRTY_BIT_RENDER_PASS, 303 304 DIRTY_BIT_RENDER_PIPELINE_BINDING, 305 DIRTY_BIT_VIEWPORT, 306 DIRTY_BIT_SCISSOR, 307 308 DIRTY_BIT_VERTEX_BUFFERS, 309 DIRTY_BIT_INDEX_BUFFER, 310 311 DIRTY_BIT_BIND_GROUPS, 312 313 DIRTY_BIT_MAX, 314 }; 315 316 static_assert(DIRTY_BIT_RENDER_PIPELINE_BINDING > DIRTY_BIT_RENDER_PIPELINE_DESC, 317 "Pipeline binding must be handled after the pipeline desc dirty bit"); 318 319 // Dirty bit handlers that record commands or otherwise expect to manipulate the render pass 320 // that will be used for the draw call must be specified after DIRTY_BIT_RENDER_PASS. 321 static_assert(DIRTY_BIT_RENDER_PIPELINE_BINDING > DIRTY_BIT_RENDER_PASS, 322 "Render pass using dirty bit must be handled after the render pass dirty bit"); 323 324 using DirtyBits = angle::BitSet<DIRTY_BIT_MAX>; 325 326 DirtyBits mDirtyBits; 327 gl::AttributesMask mDirtyVertexBuffers; 328 329 DirtyBits mNewRenderPassDirtyBits; 330 invalidateCurrentRenderPipeline()331 ANGLE_INLINE void invalidateCurrentRenderPipeline() 332 { 333 mDirtyBits.set(DIRTY_BIT_RENDER_PIPELINE_DESC); 334 } 335 336 angle::Result setupDraw(const gl::Context *context, 337 gl::PrimitiveMode mode, 338 GLint firstVertexOrInvalid, 339 GLsizei vertexOrIndexCount, 340 GLsizei instanceCount, 341 gl::DrawElementsType indexTypeOrInvalid, 342 const void *indices, 343 GLint baseVertex, 344 uint32_t *outFirstIndex); 345 346 angle::Result handleDirtyRenderPipelineDesc(DirtyBits::Iterator *dirtyBitsIterator); 347 angle::Result handleDirtyRenderPipelineBinding(DirtyBits::Iterator *dirtyBitsIterator); 348 angle::Result handleDirtyViewport(DirtyBits::Iterator *dirtyBitsIterator); 349 angle::Result handleDirtyScissor(DirtyBits::Iterator *dirtyBitsIterator); 350 angle::Result handleDirtyVertexBuffers(const gl::AttributesMask &slots, 351 DirtyBits::Iterator *dirtyBitsIterator); 352 angle::Result handleDirtyIndexBuffer(gl::DrawElementsType indexType, 353 DirtyBits::Iterator *dirtyBitsIterator); 354 angle::Result handleDirtyBindGroups(DirtyBits::Iterator *dirtyBitsIterator); 355 356 angle::Result handleDirtyRenderPass(DirtyBits::Iterator *dirtyBitsIterator); 357 358 angle::ImageLoadContext mImageLoadContext; 359 360 DisplayWgpu *mDisplay; 361 362 wgpu::CommandEncoder mCurrentCommandEncoder; 363 wgpu::RenderPassEncoder mCurrentRenderPass; 364 365 webgpu::CommandBuffer mCommandBuffer; 366 367 webgpu::RenderPipelineDesc mRenderPipelineDesc; 368 wgpu::RenderPipeline mCurrentGraphicsPipeline; 369 gl::AttributesMask mCurrentRenderPipelineAllAttributes; 370 371 gl::DrawElementsType mCurrentIndexBufferType = gl::DrawElementsType::InvalidEnum; 372 }; 373 374 } // namespace rx 375 376 #endif // LIBANGLE_RENDERER_WGPU_CONTEXTWGPU_H_ 377