Skip to content

Commit 36ea331

Browse files
committed
Main menu can render
1 parent ba1856e commit 36ea331

File tree

7 files changed

+175
-63
lines changed

7 files changed

+175
-63
lines changed

drivers/webgpu/rendering_context_driver_webgpu.cpp

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,8 @@ Error RenderingContextDriverWebGpu::initialize() {
6060

6161
adapter_options.powerPreference = WGPUPowerPreference::WGPUPowerPreference_LowPower;
6262
wgpuInstanceRequestAdapter(instance,
63-
&adapter_options,
64-
adapter_callback_info);
63+
&adapter_options,
64+
adapter_callback_info);
6565

6666
// NOTE: Currently unimplemented in wgpu.
6767
// wgpuInstanceProcessEvents(instance);
@@ -166,23 +166,36 @@ void RenderingContextDriverWebGpu::adapter_push_back(WGPUAdapter p_adapter, Devi
166166
}
167167

168168
void RenderingContextDriverWebGpu::Surface::configure(WGPUAdapter p_adapter, WGPUDevice p_device) {
169-
// NOTE: This is not the best way of getting the format of the surface.
170169
WGPUSurfaceCapabilities capabilities;
171170
wgpuSurfaceGetCapabilities(surface, p_adapter, &capabilities);
172-
WGPUTextureFormat surface_format = capabilities.formats[0];
173-
this->format = surface_format;
171+
172+
// Godot only supports these swapchain formats.
173+
for (uint32_t i = 0; i < capabilities.formatCount; i++) {
174+
WGPUTextureFormat format = capabilities.formats[i];
175+
switch (format) {
176+
case WGPUTextureFormat_BGRA8Unorm:
177+
this->format = format;
178+
this->rd_format = RDD::DATA_FORMAT_B8G8R8A8_UNORM;
179+
break;
180+
case WGPUTextureFormat_RGBA8Unorm:
181+
this->format = format;
182+
this->rd_format = RDD::DATA_FORMAT_R8G8B8A8_UNORM;
183+
break;
184+
default:
185+
DEV_ASSERT(false && "No supported surface formats.");
186+
}
187+
}
174188

175189
// TODO: Complete full surface config.
176190
WGPUSurfaceConfiguration surface_config = (WGPUSurfaceConfiguration){
177191
.device = p_device,
178-
.format = surface_format,
192+
.format = this->format,
179193
.usage = WGPUTextureUsage_RenderAttachment,
180194
.width = this->width,
181195
.height = this->height,
182196
};
183197

184198
wgpuSurfaceConfigure(this->surface, &surface_config);
185-
186199
}
187200

188201
#endif // WEBGPU_ENABLED

drivers/webgpu/rendering_context_driver_webgpu.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ class RenderingContextDriverWebGpu : public RenderingContextDriver {
3737
public:
3838
WGPUSurface surface = nullptr;
3939
WGPUTextureFormat format = WGPUTextureFormat_Undefined;
40+
RDD::DataFormat rd_format = RDD::DataFormat::DATA_FORMAT_MAX;
4041
uint32_t width = 0;
4142
uint32_t height = 0;
4243
DisplayServer::VSyncMode vsync_mode = DisplayServer::VSYNC_ENABLED;

drivers/webgpu/rendering_device_driver_webgpu.cpp

Lines changed: 98 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,21 @@ RenderingDeviceDriver::TextureID RenderingDeviceDriverWebGpu::texture_create(con
291291
WGPUTexture texture = wgpuDeviceCreateTexture(device, &texture_desc);
292292
WGPUTextureFormat format = webgpu_texture_format_from_rd(p_view.format);
293293

294+
WGPUTextureViewDescriptorExtras texture_view_desc_extras = (WGPUTextureViewDescriptorExtras){
295+
.chain = (WGPUChainedStruct){
296+
.next = nullptr,
297+
.sType = (WGPUSType)WGPUSType_TextureViewDescriptorExtras,
298+
},
299+
.swizzle = (WGPUTextureViewSwizzle){
300+
.r = webgpu_component_swizzle_from_rd(p_view.swizzle_r),
301+
.g = webgpu_component_swizzle_from_rd(p_view.swizzle_g),
302+
.b = webgpu_component_swizzle_from_rd(p_view.swizzle_b),
303+
.a = webgpu_component_swizzle_from_rd(p_view.swizzle_a),
304+
},
305+
};
306+
294307
WGPUTextureViewDescriptor texture_view_desc = (WGPUTextureViewDescriptor){
308+
.nextInChain = (WGPUChainedStruct *)&texture_view_desc_extras,
295309
.format = format,
296310
.dimension = webgpu_texture_view_dimension_from_rd(p_format.texture_type),
297311
.mipLevelCount = texture_desc.mipLevelCount,
@@ -333,7 +347,21 @@ RenderingDeviceDriver::TextureID RenderingDeviceDriverWebGpu::texture_create_sha
333347
}
334348
}
335349

350+
WGPUTextureViewDescriptorExtras texture_view_desc_extras = (WGPUTextureViewDescriptorExtras){
351+
.chain = (WGPUChainedStruct){
352+
.next = nullptr,
353+
.sType = (WGPUSType)WGPUSType_TextureViewDescriptorExtras,
354+
},
355+
.swizzle = (WGPUTextureViewSwizzle){
356+
.r = webgpu_component_swizzle_from_rd(p_view.swizzle_r),
357+
.g = webgpu_component_swizzle_from_rd(p_view.swizzle_g),
358+
.b = webgpu_component_swizzle_from_rd(p_view.swizzle_b),
359+
.a = webgpu_component_swizzle_from_rd(p_view.swizzle_a),
360+
},
361+
};
362+
336363
WGPUTextureViewDescriptor texture_view_desc = (WGPUTextureViewDescriptor){
364+
.nextInChain = (WGPUChainedStruct *)&texture_view_desc_extras,
337365
.format = webgpu_texture_format_from_rd(p_view.format),
338366
.mipLevelCount = texture_info->mip_level_count,
339367
.arrayLayerCount = texture_info->is_using_depth ? 1 : texture_info->depth_or_array,
@@ -353,7 +381,21 @@ RenderingDeviceDriver::TextureID RenderingDeviceDriverWebGpu::texture_create_sha
353381
RenderingDeviceDriver::TextureID RenderingDeviceDriverWebGpu::texture_create_shared_from_slice(TextureID p_original_texture, const TextureView &p_view, TextureSliceType p_slice_type, uint32_t p_layer, uint32_t p_layers, uint32_t p_mipmap, uint32_t p_mipmaps) {
354382
TextureInfo *texture_info = (TextureInfo *)p_original_texture.id;
355383

384+
WGPUTextureViewDescriptorExtras texture_view_desc_extras = (WGPUTextureViewDescriptorExtras){
385+
.chain = (WGPUChainedStruct){
386+
.next = nullptr,
387+
.sType = (WGPUSType)WGPUSType_TextureViewDescriptorExtras,
388+
},
389+
.swizzle = (WGPUTextureViewSwizzle){
390+
.r = webgpu_component_swizzle_from_rd(p_view.swizzle_r),
391+
.g = webgpu_component_swizzle_from_rd(p_view.swizzle_g),
392+
.b = webgpu_component_swizzle_from_rd(p_view.swizzle_b),
393+
.a = webgpu_component_swizzle_from_rd(p_view.swizzle_a),
394+
},
395+
};
396+
356397
WGPUTextureViewDescriptor texture_view_desc = (WGPUTextureViewDescriptor){
398+
.nextInChain = (WGPUChainedStruct *)&texture_view_desc_extras,
357399
.format = webgpu_texture_format_from_rd(p_view.format),
358400
.baseMipLevel = p_mipmap,
359401
.mipLevelCount = p_mipmaps,
@@ -462,32 +504,37 @@ bool RenderingDeviceDriverWebGpu::sampler_is_format_supported_for_filter(DataFor
462504

463505
// NOTE: The attributes in `p_vertex_attribs` must be in order.
464506
RenderingDeviceDriver::VertexFormatID RenderingDeviceDriverWebGpu::vertex_format_create(VectorView<VertexAttribute> p_vertex_attribs) {
465-
WGPUVertexAttribute *vertex_attributes = memnew_arr(WGPUVertexAttribute, p_vertex_attribs.size());
466-
uint64_t array_stride = 0;
467-
for (int i = 0; i < p_vertex_attribs.size(); i++) {
507+
VertexFormatInfo *vertex_format_info = memnew(VertexFormatInfo);
508+
vertex_format_info->layouts.resize_zeroed(p_vertex_attribs.size());
509+
vertex_format_info->vertex_attributes.resize_zeroed(p_vertex_attribs.size());
510+
511+
for (uint32_t i = 0; i < p_vertex_attribs.size(); i++) {
468512
VertexAttribute attrib = p_vertex_attribs[i];
469-
vertex_attributes[i] = (WGPUVertexAttribute){
470-
.format = webgpu_vertex_format_from_rd(attrib.format),
471-
.offset = attrib.offset,
472-
.shaderLocation = attrib.location,
513+
514+
vertex_format_info->vertex_attributes.set(i,
515+
(WGPUVertexAttribute){
516+
.format = webgpu_vertex_format_from_rd(attrib.format),
517+
.offset = attrib.offset,
518+
.shaderLocation = attrib.location,
519+
});
520+
521+
WGPUVertexStepMode step_mode = attrib.frequency == VertexFrequency::VERTEX_FREQUENCY_VERTEX ? WGPUVertexStepMode_Vertex : WGPUVertexStepMode_Instance;
522+
523+
WGPUVertexBufferLayout layout = (WGPUVertexBufferLayout){
524+
.stepMode = step_mode,
525+
.arrayStride = attrib.stride,
526+
.attributeCount = 1,
527+
.attributes = vertex_format_info->vertex_attributes.ptr() + i,
473528
};
474-
array_stride += attrib.stride;
529+
vertex_format_info->layouts.set(i, layout);
475530
}
476531

477-
WGPUVertexStepMode step_mode = p_vertex_attribs[0].frequency == VertexFrequency::VERTEX_FREQUENCY_VERTEX ? WGPUVertexStepMode_Vertex : WGPUVertexStepMode_Instance;
478-
479-
WGPUVertexBufferLayout *layout = memnew(WGPUVertexBufferLayout);
480-
layout->attributes = vertex_attributes;
481-
layout->attributeCount = p_vertex_attribs.size();
482-
layout->stepMode = step_mode;
483-
layout->arrayStride = array_stride;
484-
return VertexFormatID(layout);
532+
return VertexFormatID(vertex_format_info);
485533
}
486534

487535
void RenderingDeviceDriverWebGpu::vertex_format_free(VertexFormatID p_vertex_format) {
488-
WGPUVertexBufferLayout *layout = (WGPUVertexBufferLayout *)p_vertex_format.id;
489-
memdelete_arr(layout->attributes);
490-
memdelete(layout);
536+
VertexFormatInfo *vertex_format_info = (VertexFormatInfo *)p_vertex_format.id;
537+
memdelete(vertex_format_info);
491538
}
492539

493540
/******************/
@@ -556,7 +603,7 @@ Error RenderingDeviceDriverWebGpu::command_queue_execute_and_present(CommandQueu
556603
Vector<WGPUCommandBuffer> commands = Vector<WGPUCommandBuffer>();
557604

558605
for (uint32_t i = 0; i < p_cmd_buffers.size(); i++) {
559-
CommandBufferInfo* command_buffer_info = (CommandBufferInfo*)p_cmd_buffers[i].id;
606+
CommandBufferInfo *command_buffer_info = (CommandBufferInfo *)p_cmd_buffers[i].id;
560607

561608
DEV_ASSERT(command_buffer_info != nullptr);
562609
DEV_ASSERT(command_buffer_info->encoder != nullptr);
@@ -698,16 +745,10 @@ RenderingDeviceDriver::SwapChainID RenderingDeviceDriverWebGpu::swap_chain_creat
698745

699746
RenderPassInfo *render_pass_info = memnew(RenderPassInfo);
700747

701-
// NOTE: This is not the best way of getting the format of the surface.
702-
WGPUSurfaceCapabilities capabilities;
703-
wgpuSurfaceGetCapabilities(surface->surface, this->adapter, &capabilities);
704-
WGPUTextureFormat surface_format = capabilities.formats[0];
705-
surface->format = surface_format;
706-
707748
surface->configure(this->adapter, this->device);
708749

709750
render_pass_info->attachments = Vector<RenderPassAttachmentInfo>({ (RenderPassAttachmentInfo){
710-
.format = surface_format,
751+
.format = surface->format,
711752
.sample_count = 1,
712753
.load_op = WGPULoadOp_Clear,
713754
.store_op = WGPUStoreOp_Store,
@@ -746,13 +787,11 @@ RenderingDeviceDriver::RenderPassID RenderingDeviceDriverWebGpu::swap_chain_get_
746787
return swapchain_info->render_pass;
747788
}
748789

749-
// NOTE: In theory, this function's result doesn't matter.
750-
// We take this to create a framebuffer attachment that we never end up using since WebGpu does not support framebuffers.
751790
RenderingDeviceDriver::DataFormat RenderingDeviceDriverWebGpu::swap_chain_get_format(SwapChainID p_swap_chain) {
752791
SwapChainInfo *swapchain_info = (SwapChainInfo *)p_swap_chain.id;
753-
RenderingContextDriverWebGpu::Surface *_ = (RenderingContextDriverWebGpu::Surface *)swapchain_info->surface;
754-
// TODO: impl Replace this with a proper conversion
755-
return DATA_FORMAT_B8G8R8A8_SRGB;
792+
RenderingContextDriverWebGpu::Surface *surface = (RenderingContextDriverWebGpu::Surface *)swapchain_info->surface;
793+
794+
return surface->rd_format;
756795
}
757796

758797
void RenderingDeviceDriverWebGpu::swap_chain_free(SwapChainID p_swap_chain) {
@@ -1879,17 +1918,19 @@ void RenderingDeviceDriverWebGpu::command_render_set_viewport(CommandBufferID p_
18791918

18801919
ERR_FAIL_COND_MSG(p_viewports.size() != 1, "WebGpu cannot set multiple viewports.");
18811920

1882-
command_buffer_info->active_render_pass_info.commands.push_back(((RenderPassEncoderCommand){
1883-
.type = RenderPassEncoderCommand::CommandType::SET_VIEWPORT,
1884-
.set_viewport = (RenderPassEncoderCommand::SetViewport){
1885-
.x = (float)p_viewports[0].position.x,
1886-
.y = (float)p_viewports[0].position.y,
1887-
.width = (float)p_viewports[0].size.x,
1888-
.height = (float)p_viewports[0].size.y,
1889-
.min_depth = 0.0,
1890-
.max_depth = 1.0,
1891-
},
1892-
}));
1921+
for (int i = 0; i < p_viewports.size(); i++) {
1922+
command_buffer_info->active_render_pass_info.commands.push_back(((RenderPassEncoderCommand){
1923+
.type = RenderPassEncoderCommand::CommandType::SET_VIEWPORT,
1924+
.set_viewport = (RenderPassEncoderCommand::SetViewport){
1925+
.x = (float)p_viewports[i].position.x,
1926+
.y = (float)p_viewports[i].position.y,
1927+
.width = (float)p_viewports[i].size.x,
1928+
.height = (float)p_viewports[i].size.y,
1929+
.min_depth = 0.0,
1930+
.max_depth = 1.0,
1931+
},
1932+
}));
1933+
}
18931934
}
18941935

18951936
void RenderingDeviceDriverWebGpu::command_render_set_scissor(CommandBufferID p_cmd_buffer, VectorView<Rect2i> p_scissors) {
@@ -1900,15 +1941,17 @@ void RenderingDeviceDriverWebGpu::command_render_set_scissor(CommandBufferID p_c
19001941

19011942
ERR_FAIL_COND_MSG(p_scissors.size() != 1, "WebGpu cannot set multiple scissors.");
19021943

1903-
command_buffer_info->active_render_pass_info.commands.push_back(((RenderPassEncoderCommand){
1904-
.type = RenderPassEncoderCommand::CommandType::SET_SCISSOR_RECT,
1905-
.set_scissor_rect = (RenderPassEncoderCommand::SetScissorRect){
1906-
.x = (uint32_t)p_scissors[0].position.x,
1907-
.y = (uint32_t)p_scissors[0].position.y,
1908-
.width = (uint32_t)p_scissors[0].position.width,
1909-
.height = (uint32_t)p_scissors[0].position.height,
1910-
},
1911-
}));
1944+
for (int i = 0; i < p_scissors.size(); i++) {
1945+
command_buffer_info->active_render_pass_info.commands.push_back(((RenderPassEncoderCommand){
1946+
.type = RenderPassEncoderCommand::CommandType::SET_SCISSOR_RECT,
1947+
.set_scissor_rect = (RenderPassEncoderCommand::SetScissorRect){
1948+
.x = (uint32_t)p_scissors[i].position.x,
1949+
.y = (uint32_t)p_scissors[i].position.y,
1950+
.width = (uint32_t)p_scissors[i].size.width,
1951+
.height = (uint32_t)p_scissors[i].size.height,
1952+
},
1953+
}));
1954+
}
19121955
}
19131956

19141957
void RenderingDeviceDriverWebGpu::command_render_clear_attachments(CommandBufferID _p_cmd_buffer, VectorView<AttachmentClear> p_attachment_clears, VectorView<Rect2i> p_rects) {
@@ -2185,9 +2228,9 @@ RenderingDeviceDriver::PipelineID RenderingDeviceDriverWebGpu::render_pipeline_c
21852228

21862229
// NOTE: I'm not sure dynamic vertex state is supported.
21872230
if (p_vertex_format) {
2188-
WGPUVertexBufferLayout *vertex_buffer_layout = (WGPUVertexBufferLayout *)p_vertex_format.id;
2189-
vertex_state.buffers = vertex_buffer_layout;
2190-
vertex_state.bufferCount = 1;
2231+
VertexFormatInfo *format_info = (VertexFormatInfo *)p_vertex_format.id;
2232+
vertex_state.buffers = format_info->layouts.ptr();
2233+
vertex_state.bufferCount = format_info->layouts.size();
21912234
}
21922235

21932236
pipeline_descriptor.vertex = vertex_state;

drivers/webgpu/rendering_device_driver_webgpu.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
#define RENDERING_DEVICE_DRIVER_WEBGPU_H
33

44
#include "core/templates/hash_map.h"
5-
#include "core/templates/local_vector.h"
65
#include "drivers/webgpu/rendering_context_driver_webgpu.h"
76

87
#include "servers/rendering/rendering_context_driver.h"
@@ -48,6 +47,7 @@ class RenderingDeviceDriverWebGpu : public RenderingDeviceDriver {
4847

4948
private:
5049
struct TextureInfo {
50+
public:
5151
WGPUTexture texture;
5252
WGPUTextureFormat format;
5353
WGPUTextureUsage usage;
@@ -60,6 +60,9 @@ class RenderingDeviceDriverWebGpu : public RenderingDeviceDriver {
6060
uint32_t mip_level_count;
6161
};
6262

63+
// Keep track of existing mirror textures to ensure we don't write to a deleted texture.
64+
HashSet<TextureID> mirror_textures;
65+
6366
public:
6467
virtual TextureID texture_create(const TextureFormat &p_format, const TextureView &p_view) override final;
6568
virtual TextureID texture_create_from_extension(uint64_t p_native_texture, TextureType p_type, DataFormat p_format, uint32_t p_array_layers, bool p_depth_stencil) override final;
@@ -85,6 +88,12 @@ class RenderingDeviceDriverWebGpu : public RenderingDeviceDriver {
8588
/**** VERTEX ARRAY ****/
8689
/**********************/
8790

91+
private:
92+
struct VertexFormatInfo {
93+
Vector<WGPUVertexBufferLayout> layouts;
94+
Vector<WGPUVertexAttribute> vertex_attributes;
95+
};
96+
8897
public:
8998
virtual VertexFormatID vertex_format_create(VectorView<VertexAttribute> p_vertex_attribs) override final;
9099
virtual void vertex_format_free(VertexFormatID p_vertex_format) override final;

drivers/webgpu/webgpu_conv.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -576,6 +576,25 @@ uint64_t rd_limit_from_webgpu(RDD::Limit p_selected_limit, WGPULimits p_limits)
576576
}
577577
}
578578

579+
WGPUTextureComponentSwizzle webgpu_component_swizzle_from_rd(RDD::TextureSwizzle p_texture_swizzle) {
580+
switch (p_texture_swizzle) {
581+
case RDD::TextureSwizzle::TEXTURE_SWIZZLE_ZERO:
582+
return WGPUTextureComponentSwizzle_Zero;
583+
case RDD::TextureSwizzle::TEXTURE_SWIZZLE_ONE:
584+
return WGPUTextureComponentSwizzle_One;
585+
case RDD::TextureSwizzle::TEXTURE_SWIZZLE_R:
586+
return WGPUTextureComponentSwizzle_R;
587+
case RDD::TextureSwizzle::TEXTURE_SWIZZLE_G:
588+
return WGPUTextureComponentSwizzle_G;
589+
case RDD::TextureSwizzle::TEXTURE_SWIZZLE_B:
590+
return WGPUTextureComponentSwizzle_B;
591+
case RDD::TextureSwizzle::TEXTURE_SWIZZLE_A:
592+
return WGPUTextureComponentSwizzle_A;
593+
default:
594+
return WGPUTextureComponentSwizzle_Identity;
595+
}
596+
}
597+
579598
ImageBufferLayoutInfo webgpu_image_buffer_layout_from_format(WGPUTextureFormat p_format) {
580599
// NOTE: Please also update `webgpu_texture_format_from_rd` alongside this.
581600
switch ((uint32_t)p_format) {

drivers/webgpu/webgpu_conv.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
#include "servers/rendering/rendering_device.h"
55
#include <webgpu.h>
66

7+
// NOTE: Used only for swizzle feature.
8+
#include <wgpu.h>
9+
710
WGPUBufferUsage webgpu_buffer_usage_from_rd(BitField<RDD::BufferUsageBits> p_buffer_usage);
811
WGPUTextureFormat webgpu_texture_format_from_rd(RDD::DataFormat p_data_format);
912
WGPUFilterMode webgpu_filter_mode_from_rd(RDD::SamplerFilter p_sampler_filter);
@@ -19,6 +22,7 @@ WGPUTextureAspect webgpu_texture_aspect_from_rd(BitField<RDD::TextureAspectBits>
1922
WGPUBlendOperation webgpu_blend_operation_from_rd(RDD::BlendOperation p_blend_operation);
2023
WGPUBlendFactor webgpu_blend_factor_from_rd(RDD::BlendFactor p_blend_factor);
2124
WGPUStencilOperation webgpu_stencil_operation_from_rd(RDD::StencilOperation p_stencil_operation);
25+
WGPUTextureComponentSwizzle webgpu_component_swizzle_from_rd(RDD::TextureSwizzle p_texture_swizzle);
2226

2327
uint64_t rd_limit_from_webgpu(RDD::Limit p_selected_limit, WGPULimits p_limits);
2428

0 commit comments

Comments
 (0)