@@ -649,13 +649,13 @@ static WGPUTextureUsageFlags SDLToWGPUTextureUsageFlags(SDL_GPUTextureUsageFlags
649
649
wgpuFlags |= WGPUTextureUsage_RenderAttachment ;
650
650
}
651
651
if (usageFlags & SDL_GPU_TEXTUREUSAGE_GRAPHICS_STORAGE_READ ) {
652
- wgpuFlags |= WGPUTextureUsage_StorageBinding ;
652
+ wgpuFlags |= WGPUTextureUsage_StorageBinding | WGPUTextureUsage_CopyDst ;
653
653
}
654
654
if (usageFlags & SDL_GPU_TEXTUREUSAGE_COMPUTE_STORAGE_READ ) {
655
- wgpuFlags |= WGPUTextureUsage_StorageBinding | WGPUTextureUsage_CopySrc ;
655
+ wgpuFlags |= WGPUTextureUsage_StorageBinding | WGPUTextureUsage_CopyDst ;
656
656
}
657
657
if (usageFlags & SDL_GPU_TEXTUREUSAGE_COMPUTE_STORAGE_WRITE ) {
658
- wgpuFlags |= WGPUTextureUsage_StorageBinding | WGPUTextureUsage_CopyDst ;
658
+ wgpuFlags |= WGPUTextureUsage_StorageBinding | WGPUTextureUsage_CopySrc ;
659
659
}
660
660
if (usageFlags & SDL_GPU_TEXTUREUSAGE_COMPUTE_STORAGE_SIMULTANEOUS_READ_WRITE ) {
661
661
wgpuFlags |= WGPUTextureUsage_StorageBinding | WGPUTextureUsage_CopySrc | WGPUTextureUsage_CopyDst ;
@@ -829,11 +829,9 @@ static Uint32 SDLToWGPUSampleCount(SDL_GPUSampleCount samples)
829
829
case SDL_GPU_SAMPLECOUNT_1 :
830
830
return 1 ;
831
831
case SDL_GPU_SAMPLECOUNT_2 :
832
- return 2 ;
833
832
case SDL_GPU_SAMPLECOUNT_4 :
834
- return 4 ;
835
833
case SDL_GPU_SAMPLECOUNT_8 :
836
- return 8 ;
834
+ return 4 ;
837
835
default :
838
836
return 1 ;
839
837
}
@@ -1278,7 +1276,6 @@ static void WebGPU_SetBufferName(SDL_GPURenderer *driverData,
1278
1276
wgpuBufferSetLabel (webgpuBuffer -> buffer , text );
1279
1277
}
1280
1278
1281
-
1282
1279
static SDL_GPUBuffer * WebGPU_CreateGPUBuffer (SDL_GPURenderer * driverData ,
1283
1280
SDL_GPUBufferUsageFlags usageFlags ,
1284
1281
Uint32 size ,
@@ -1311,7 +1308,7 @@ static SDL_GPUTransferBuffer *WebGPU_CreateTransferBuffer(
1311
1308
{
1312
1309
SDL_GPUBuffer * buffer = WebGPU_INTERNAL_CreateGPUBuffer (driverData , & usage , size , WEBGPU_BUFFER_TYPE_TRANSFER );
1313
1310
if (debugName ) {
1314
- WebGPU_SetBufferName (driverData , buffer , debugName );
1311
+ WebGPU_SetBufferName (driverData , buffer , debugName );
1315
1312
} else {
1316
1313
WebGPU_SetBufferName (driverData , buffer , "SDLGPU Transfer Buffer" );
1317
1314
}
@@ -2357,15 +2354,15 @@ static void WebGPU_CreateSwapchain(WebGPURenderer *renderer, WindowData *windowD
2357
2354
2358
2355
swapchainData -> format = wgpuSurfaceGetPreferredFormat (swapchainData -> surface , renderer -> adapter );
2359
2356
swapchainData -> presentMode = SDLToWGPUPresentMode (windowData -> presentMode );
2360
- wgpuSurfaceConfigure (swapchainData -> surface , & (WGPUSurfaceConfiguration ){
2361
- .usage = WGPUTextureUsage_RenderAttachment | WGPUTextureUsage_CopySrc | WGPUTextureUsage_CopyDst ,
2362
- .format = swapchainData -> format ,
2363
- .width = windowData -> window -> w ,
2364
- .height = windowData -> window -> h ,
2365
- .presentMode = swapchainData -> presentMode ,
2366
- .alphaMode = WGPUCompositeAlphaMode_Opaque ,
2367
- .device = renderer -> device ,
2368
- });
2357
+ wgpuSurfaceConfigure (swapchainData -> surface , & (WGPUSurfaceConfiguration ){
2358
+ .usage = WGPUTextureUsage_RenderAttachment | WGPUTextureUsage_CopySrc | WGPUTextureUsage_CopyDst ,
2359
+ .format = swapchainData -> format ,
2360
+ .width = windowData -> window -> w ,
2361
+ .height = windowData -> window -> h ,
2362
+ .presentMode = swapchainData -> presentMode ,
2363
+ .alphaMode = WGPUCompositeAlphaMode_Opaque ,
2364
+ .device = renderer -> device ,
2365
+ });
2369
2366
2370
2367
// Swapchain should be the size of whatever SDL_Window it is attached to
2371
2368
swapchainData -> width = windowData -> window -> w ;
@@ -2469,21 +2466,21 @@ static WGPUTexture WebGPU_INTERNAL_AcquireSurfaceTexture(WebGPURenderer *rendere
2469
2466
wgpuSurfaceGetCurrentTexture (windowData -> swapchainData .surface , & surfaceTexture );
2470
2467
2471
2468
switch (surfaceTexture .status ) {
2472
- case WGPUSurfaceGetCurrentTextureStatus_Success :
2473
- break ;
2474
- case WGPUSurfaceGetCurrentTextureStatus_DeviceLost :
2475
- SDL_LogError (SDL_LOG_CATEGORY_GPU , "GPU DEVICE LOST" );
2476
- SDL_SetError ("GPU DEVICE LOST" );
2477
- return NULL ;
2478
- case WGPUSurfaceGetCurrentTextureStatus_OutOfMemory :
2479
- SDL_OutOfMemory ();
2480
- return NULL ;
2481
- case WGPUSurfaceGetCurrentTextureStatus_Timeout :
2482
- case WGPUSurfaceGetCurrentTextureStatus_Outdated :
2483
- case WGPUSurfaceGetCurrentTextureStatus_Lost :
2484
- default :
2485
- WebGPU_RecreateSwapchain (renderer , windowData );
2486
- return NULL ;
2469
+ case WGPUSurfaceGetCurrentTextureStatus_Success :
2470
+ break ;
2471
+ case WGPUSurfaceGetCurrentTextureStatus_DeviceLost :
2472
+ SDL_LogError (SDL_LOG_CATEGORY_GPU , "GPU DEVICE LOST" );
2473
+ SDL_SetError ("GPU DEVICE LOST" );
2474
+ return NULL ;
2475
+ case WGPUSurfaceGetCurrentTextureStatus_OutOfMemory :
2476
+ SDL_OutOfMemory ();
2477
+ return NULL ;
2478
+ case WGPUSurfaceGetCurrentTextureStatus_Timeout :
2479
+ case WGPUSurfaceGetCurrentTextureStatus_Outdated :
2480
+ case WGPUSurfaceGetCurrentTextureStatus_Lost :
2481
+ default :
2482
+ WebGPU_RecreateSwapchain (renderer , windowData );
2483
+ return NULL ;
2487
2484
}
2488
2485
2489
2486
return surfaceTexture .texture ;
@@ -2610,18 +2607,20 @@ static bool WebGPU_SupportsSampleCount(SDL_GPURenderer *driverData,
2610
2607
{
2611
2608
(void )driverData ;
2612
2609
WGPUTextureFormat wgpuFormat = SDLToWGPUTextureFormat (format );
2613
- Uint32 wgpuSampleCount = SDLToWGPUSampleCount (desiredSampleCount );
2614
-
2615
2610
// Verify that the format and sample count are considered valid
2616
2611
if (wgpuFormat == WGPUTextureFormat_Undefined ) {
2617
2612
return false;
2618
2613
}
2619
2614
2615
+ SDL_Log ("Desired sample count %u" , desiredSampleCount );
2616
+
2620
2617
// WebGPU only supports 1 and 4.
2621
- if (wgpuSampleCount != 1 && wgpuSampleCount != 4 ) {
2618
+ if (desiredSampleCount != SDL_GPU_SAMPLECOUNT_1 && desiredSampleCount != SDL_GPU_SAMPLECOUNT_4 ) {
2622
2619
return false;
2623
2620
}
2624
2621
2622
+ /*Uint32 wgpuSampleCount = SDLToWGPUSampleCount(desiredSampleCount);*/
2623
+
2625
2624
// Sample count is valid.
2626
2625
return true;
2627
2626
}
@@ -3297,6 +3296,13 @@ static SDL_GPUGraphicsPipeline *WebGPU_CreateGraphicsPipeline(
3297
3296
SDL_Log ("TODO: Implement specific pipeline setup to emulate line fill mode." );
3298
3297
}
3299
3298
3299
+ Uint32 sampleCount = pipelineCreateInfo -> multisample_state .sample_count == 0 ? 1 : pipelineCreateInfo -> multisample_state .sample_count ;
3300
+ Uint32 sampleMask = pipelineCreateInfo -> multisample_state .sample_mask == 0 ? 0xFFFF : pipelineCreateInfo -> multisample_state .sample_mask ;
3301
+ if (sampleCount != SDL_GPU_SAMPLECOUNT_1 && sampleCount != SDL_GPU_SAMPLECOUNT_4 ) {
3302
+ SDL_Log ("Sample count not supported in WebGPU. Defaulting to 1." );
3303
+ sampleCount = SDL_GPU_SAMPLECOUNT_1 ;
3304
+ }
3305
+
3300
3306
// Create the render pipeline descriptor
3301
3307
WGPURenderPipelineDescriptor pipelineDesc = {
3302
3308
.nextInChain = NULL ,
@@ -3312,8 +3318,8 @@ static SDL_GPUGraphicsPipeline *WebGPU_CreateGraphicsPipeline(
3312
3318
// Needs to be set up
3313
3319
.depthStencil = pipelineCreateInfo -> target_info .has_depth_stencil_target ? & depthStencil : NULL ,
3314
3320
.multisample = {
3315
- .count = pipelineCreateInfo -> multisample_state . sample_count == 0 ? 1 : pipelineCreateInfo -> multisample_state . sample_count ,
3316
- .mask = pipelineCreateInfo -> multisample_state . sample_mask == 0 ? 0xFFFF : pipelineCreateInfo -> multisample_state . sample_mask ,
3321
+ .count = SDLToWGPUSampleCount ( sampleCount ) ,
3322
+ .mask = sampleMask ,
3317
3323
.alphaToCoverageEnabled = false,
3318
3324
},
3319
3325
.fragment = & fragmentState ,
@@ -3827,9 +3833,29 @@ void WebGPU_SetScissorRect(SDL_GPUCommandBuffer *renderPass, const SDL_Rect *sci
3827
3833
static void WebGPU_SetStencilReference (SDL_GPUCommandBuffer * commandBuffer ,
3828
3834
Uint8 reference )
3829
3835
{
3836
+ if (commandBuffer == NULL ) {
3837
+ return ;
3838
+ }
3839
+
3830
3840
wgpuRenderPassEncoderSetStencilReference (((WebGPUCommandBuffer * )commandBuffer )-> renderPassEncoder , reference );
3831
3841
}
3832
3842
3843
+ static void WebGPU_SetBlendConstants (
3844
+ SDL_GPUCommandBuffer * commandBuffer ,
3845
+ SDL_FColor blendConstants )
3846
+ {
3847
+ if (commandBuffer == NULL ) {
3848
+ return ;
3849
+ }
3850
+
3851
+ wgpuRenderPassEncoderSetBlendConstant (((WebGPUCommandBuffer * )commandBuffer )-> renderPassEncoder , & (WGPUColor ){
3852
+ .r = blendConstants .r ,
3853
+ .g = blendConstants .g ,
3854
+ .b = blendConstants .b ,
3855
+ .a = blendConstants .a ,
3856
+ });
3857
+ }
3858
+
3833
3859
static void WebGPU_BindGraphicsPipeline (
3834
3860
SDL_GPUCommandBuffer * commandBuffer ,
3835
3861
SDL_GPUGraphicsPipeline * graphicsPipeline )
@@ -3949,6 +3975,7 @@ static void WebGPU_DrawPrimitives(
3949
3975
wgpuRenderPassEncoderDraw (wgpu_cmd_buf -> renderPassEncoder , vertexCount , instanceCount , firstVertex , firstInstance );
3950
3976
}
3951
3977
3978
+
3952
3979
static void WebGPU_DrawIndexedPrimitives (
3953
3980
SDL_GPUCommandBuffer * commandBuffer ,
3954
3981
Uint32 numIndices ,
@@ -3957,11 +3984,50 @@ static void WebGPU_DrawIndexedPrimitives(
3957
3984
Sint32 vertexOffset ,
3958
3985
Uint32 firstInstance )
3959
3986
{
3987
+ if (commandBuffer == NULL ) {
3988
+ return ;
3989
+ }
3960
3990
WebGPUCommandBuffer * wgpu_cmd_buf = (WebGPUCommandBuffer * )commandBuffer ;
3961
3991
WebGPU_INTERNAL_SetBindGroups (commandBuffer );
3962
3992
wgpuRenderPassEncoderDrawIndexed (wgpu_cmd_buf -> renderPassEncoder , numIndices , numInstances , firstIndex , vertexOffset , firstInstance );
3963
3993
}
3964
3994
3995
+ static void WebGPU_DrawPrimitivesIndirect (
3996
+ SDL_GPUCommandBuffer * commandBuffer ,
3997
+ SDL_GPUBuffer * buffer ,
3998
+ Uint32 offset ,
3999
+ Uint32 drawCount )
4000
+ {
4001
+ if (commandBuffer == NULL ) {
4002
+ return ;
4003
+ }
4004
+ WebGPUCommandBuffer * wgpu_cmd_buf = (WebGPUCommandBuffer * )commandBuffer ;
4005
+ WebGPUBuffer * wgpuBuffer = (WebGPUBuffer * )buffer ;
4006
+ Uint32 pitch = sizeof (SDL_GPUIndirectDrawCommand );
4007
+ WebGPU_INTERNAL_SetBindGroups (commandBuffer );
4008
+ for (Uint32 i = 0 ; i < drawCount ; i += 1 ) {
4009
+ wgpuRenderPassEncoderDrawIndirect (wgpu_cmd_buf -> renderPassEncoder , wgpuBuffer -> buffer , offset + (i * pitch ));
4010
+ }
4011
+ }
4012
+
4013
+ static void WebGPU_DrawIndexedIndirect (
4014
+ SDL_GPUCommandBuffer * commandBuffer ,
4015
+ SDL_GPUBuffer * buffer ,
4016
+ Uint32 offset ,
4017
+ Uint32 drawCount )
4018
+ {
4019
+ if (commandBuffer == NULL ) {
4020
+ return ;
4021
+ }
4022
+ WebGPUCommandBuffer * wgpu_cmd_buf = (WebGPUCommandBuffer * )commandBuffer ;
4023
+ WebGPUBuffer * wgpuBuffer = (WebGPUBuffer * )buffer ;
4024
+ Uint32 pitch = sizeof (SDL_GPUIndexedIndirectDrawCommand );
4025
+ WebGPU_INTERNAL_SetBindGroups (commandBuffer );
4026
+ for (Uint32 i = 0 ; i < drawCount ; i += 1 ) {
4027
+ wgpuRenderPassEncoderDrawIndexedIndirect (wgpu_cmd_buf -> renderPassEncoder , wgpuBuffer -> buffer , offset + (i * pitch ));
4028
+ }
4029
+ }
4030
+
3965
4031
// Blit Functionality Workaround
3966
4032
// ---------------------------------------------------
3967
4033
@@ -4308,6 +4374,52 @@ static void WebGPU_Blit(SDL_GPUCommandBuffer *commandBuffer, const SDL_GPUBlitIn
4308
4374
4309
4375
// ---------------------------------------------------
4310
4376
4377
+ void WebGPU_GenerateMipmaps (SDL_GPUCommandBuffer * commandBuffer ,
4378
+ SDL_GPUTexture * texture )
4379
+ {
4380
+ // We will have to implement our own mipmapping pipeline here.
4381
+ // I suggest Elie Michel's guide on mipmapping: https://eliemichel.github.io/LearnWebGPU/basic-compute/image-processing/mipmap-generation.html
4382
+ SDL_LogError (SDL_LOG_CATEGORY_GPU , "WebGPU mipmapping is not yet implemented" );
4383
+ }
4384
+
4385
+ // ---------------------------------------------------
4386
+
4387
+ // Debugging Functionality
4388
+
4389
+ void WebGPU_InsertDebugLabel (
4390
+ SDL_GPUCommandBuffer * commandBuffer ,
4391
+ const char * text )
4392
+ {
4393
+ if (!commandBuffer || !text ) {
4394
+ return ;
4395
+ }
4396
+ WebGPUCommandBuffer * wgpu_cmd_buf = (WebGPUCommandBuffer * )commandBuffer ;
4397
+ wgpuCommandEncoderInsertDebugMarker (wgpu_cmd_buf -> commandEncoder , text );
4398
+ }
4399
+
4400
+ void WebGPU_PushDebugGroup (
4401
+ SDL_GPUCommandBuffer * commandBuffer ,
4402
+ const char * text )
4403
+ {
4404
+ if (!commandBuffer || !text ) {
4405
+ return ;
4406
+ }
4407
+ WebGPUCommandBuffer * wgpu_cmd_buf = (WebGPUCommandBuffer * )commandBuffer ;
4408
+ wgpuCommandEncoderPushDebugGroup (wgpu_cmd_buf -> commandEncoder , text );
4409
+ }
4410
+
4411
+ void WebGPU_PopDebugGroup (
4412
+ SDL_GPUCommandBuffer * commandBuffer )
4413
+ {
4414
+ if (!commandBuffer ) {
4415
+ return ;
4416
+ }
4417
+ WebGPUCommandBuffer * wgpu_cmd_buf = (WebGPUCommandBuffer * )commandBuffer ;
4418
+ wgpuCommandEncoderPopDebugGroup (wgpu_cmd_buf -> commandEncoder );
4419
+ }
4420
+
4421
+ // ---------------------------------------------------
4422
+
4311
4423
static bool WebGPU_PrepareDriver (SDL_VideoDevice * _this )
4312
4424
{
4313
4425
// Realistically, we should check if the browser supports WebGPU here and return false if it doesn't
@@ -4443,11 +4555,16 @@ static SDL_GPUDevice *WebGPU_CreateDevice(bool debug, bool preferLowPower, SDL_P
4443
4555
result -> BindGraphicsPipeline = WebGPU_BindGraphicsPipeline ;
4444
4556
result -> ReleaseGraphicsPipeline = WebGPU_ReleaseGraphicsPipeline ;
4445
4557
result -> DrawPrimitives = WebGPU_DrawPrimitives ;
4558
+ result -> DrawPrimitivesIndirect = WebGPU_DrawPrimitivesIndirect ;
4446
4559
result -> DrawIndexedPrimitives = WebGPU_DrawIndexedPrimitives ;
4560
+ result -> DrawIndexedPrimitivesIndirect = WebGPU_DrawIndexedIndirect ;
4447
4561
4448
4562
result -> SetScissor = WebGPU_SetScissorRect ;
4449
4563
result -> SetViewport = WebGPU_SetViewport ;
4450
4564
result -> SetStencilReference = WebGPU_SetStencilReference ;
4565
+ result -> SetBlendConstants = WebGPU_SetBlendConstants ;
4566
+
4567
+ result -> GenerateMipmaps = WebGPU_GenerateMipmaps ;
4451
4568
4452
4569
result -> Submit = WebGPU_Submit ;
4453
4570
result -> SubmitAndAcquireFence = WebGPU_SubmitAndAcquireFence ;
@@ -4461,6 +4578,8 @@ static SDL_GPUDevice *WebGPU_CreateDevice(bool debug, bool preferLowPower, SDL_P
4461
4578
result -> BeginCopyPass = WebGPU_BeginCopyPass ;
4462
4579
result -> EndCopyPass = WebGPU_EndCopyPass ;
4463
4580
4581
+ result -> InsertDebugLabel = WebGPU_InsertDebugLabel ;
4582
+
4464
4583
renderer -> sdlDevice = result ;
4465
4584
4466
4585
return result ;
0 commit comments