1#include "Foundation/Platform/WindowData.h"
3#include "GraphicsDeviceWebGPU.h"
6#include "dawn/webgpu_cpp_print.h"
7#include "dawn/dawn_proc.h"
8#include "dawn/native/DawnNative.h"
12#include <emscripten/version.h>
15#include "Foundation/Logging/Logger.h"
20 void request_adapter(WGPURequestAdapterStatus status, WGPUAdapter adapter, WGPUStringView message,
void * userdata,
void * )
23 char const *msg = message.data ? message.data :
"";
24 int siz = message.data ?
static_cast<int>(message.length) : 0;
25 char const *stat = status == WGPURequestAdapterStatus_Success ?
"success" :
"";
26 LOG_INFO(logger,
"request_adapter %p %.*s %s", adapter, siz, msg, stat);
27 ptr->initialize_adapter(adapter);
30 void request_device(WGPURequestDeviceStatus status, WGPUDevice device, WGPUStringView message,
void * userdata,
void * )
33 char const *msg = message.data ? message.data :
"";
34 int siz = message.data ?
static_cast<int>(message.length) : 0;
35 char const *stat = status == WGPURequestDeviceStatus_Success ?
"success" :
"";
36 LOG_INFO(logger,
"request_device %p %.*s %s", device, siz, msg, stat);
37 ptr->initialize_device(device);
40 void error_callback(
const WGPUDevice * , WGPUErrorType type, WGPUStringView message,
void * userdata1,
void * )
44 LOG_ERROR(logger,
"WebGPU err (%d) %.*s", type, WGPUStringViewFormat(message));
48 void logging_callback(WGPULoggingType type, WGPUStringView message,
void * userdata1,
void * )
52 LOG_INFO(logger,
"WebGPU log (%d) x%.*s", type, WGPUStringViewFormat(message));
63 void device_lost(
const WGPUDevice * , WGPUDeviceLostReason reason, WGPUStringView message,
void * userdata,
void * )
67 if(reason == WGPUDeviceLostReason_Destroyed)
68 LOG_INFO(logger,
"device_lost (%d) %.*s", reason, WGPUStringViewFormat(message));
69 else if(reason != WGPUDeviceLostReason_CallbackCancelled) {
70 LOG_FATAL(logger,
"device_lost (%d) %.*s", reason, WGPUStringViewFormat(message));
71 assert(reason == WGPUDeviceLostReason_Destroyed);
75 WGPULimits WebGPUDefaultLimits()
78 WGPULimits limits = WGPU_LIMITS_INIT;
79 limits.maxTextureDimension1D = 8192;
80 limits.maxTextureDimension2D = 8192;
81 limits.maxTextureDimension3D = 2048;
82 limits.maxTextureArrayLayers = 256;
83 limits.maxBindGroups = 4;
84 limits.maxBindGroupsPlusVertexBuffers = 24;
85 limits.maxBindingsPerBindGroup = 1000;
86 limits.maxDynamicUniformBuffersPerPipelineLayout = 8;
87 limits.maxDynamicStorageBuffersPerPipelineLayout = 4;
88 limits.maxSampledTexturesPerShaderStage = 16;
89 limits.maxSamplersPerShaderStage = 16;
90 limits.maxStorageBuffersPerShaderStage = 8;
91 limits.maxStorageTexturesPerShaderStage = 4;
92 limits.maxUniformBuffersPerShaderStage = 12;
93 limits.maxUniformBufferBindingSize = 65536;
94 limits.maxStorageBufferBindingSize = 134217728;
95 limits.minUniformBufferOffsetAlignment = 256;
96 limits.minStorageBufferOffsetAlignment = 256;
97 limits.maxVertexBuffers = 8;
98 limits.maxBufferSize = 268435456;
99 limits.maxVertexAttributes = 16;
100 limits.maxVertexBufferArrayStride = 2048;
101 limits.maxInterStageShaderVariables = 16;
102 limits.maxColorAttachments = 8;
103 limits.maxColorAttachmentBytesPerSample = 32;
104 limits.maxComputeWorkgroupStorageSize = 16384;
105 limits.maxComputeInvocationsPerWorkgroup = 256;
106 limits.maxComputeWorkgroupSizeX = 256;
107 limits.maxComputeWorkgroupSizeY = 256;
108 limits.maxComputeWorkgroupSizeZ = 64;
109 limits.maxComputeWorkgroupsPerDimension = 65535;
110 limits.maxImmediateSize = 64;
117 GraphicsDeviceWebGPU::GraphicsDeviceWebGPU(RenderingAllocatorInfo* )
119 buffers.initialize(
this);
120 effects.initialize(
this, &buffers);
121 pipeline_states.initialize(
this);
122 renderTargets.initialize(
this);
123 bindGroups.initialize(
this);
124 context.initialize(
this);
125 textures.initialize(
this);
128 GraphicsDeviceWebGPU::~GraphicsDeviceWebGPU()
139#ifndef __EMSCRIPTEN__
141 DawnProcTable procTable = dawn::native::GetProcs();
142 dawnProcSetProcs(&procTable);
146 WGPUInstanceDescriptor instance_desc = WGPU_INSTANCE_DESCRIPTOR_INIT;
147 instance = wgpuCreateInstance(&instance_desc);
153 if(wgpuHasInstanceFeature(WGPUInstanceFeatureName_TimedWaitAny) != 0){
154 LOG_INFO(logger,
"Has Instance Features: TimedWaitAny");
156 if(wgpuHasInstanceFeature(WGPUInstanceFeatureName_ShaderSourceSPIRV) != 0){
157 LOG_INFO(logger,
"Has Instance Features: ShaderSourceSPIRV");
159 if(wgpuHasInstanceFeature(WGPUInstanceFeatureName_MultipleDevicesPerAdapter) != 0){
160 LOG_INFO(logger,
"Has Instance Features: MultipleDevicesPerAdapter");
164 WGPUInstanceLimits instance_limits = WGPU_INSTANCE_LIMITS_INIT;
165 if(wgpuGetInstanceLimits(&instance_limits) == WGPUStatus_Success){
166 LOG_INFO(logger,
"Instance timedWaitAnyMaxCount %zu", instance_limits.timedWaitAnyMaxCount);
170 WGPUSurfaceDescriptor surface_desc = WGPU_SURFACE_DESCRIPTOR_INIT;
171 surface_desc.label = {
"WebGPU Surface", WGPU_STRLEN};
173 WGPUSurfaceSourceWindowsHWND hwnd_window = {};
174 hwnd_window.chain.sType = WGPUSType_SurfaceSourceWindowsHWND;
175 hwnd_window.hinstance = ::GetModuleHandle(
nullptr);
176 hwnd_window.hwnd = settings.
windowData->windowHandle;
177 surface_desc.nextInChain = (WGPUChainedStruct*)&hwnd_window;
184#elif defined(__EMSCRIPTEN__)
185 WGPUEmscriptenSurfaceSourceCanvasHTMLSelector html_canvas = WGPU_EMSCRIPTEN_SURFACE_SOURCE_CANVAS_HTML_SELECTOR_INIT;
186 html_canvas.chain.sType = WGPUSType_EmscriptenSurfaceSourceCanvasHTMLSelector;
187 html_canvas.selector = {
"canvas", WGPU_STRLEN};
188 surface_desc.nextInChain = (WGPUChainedStruct*)&html_canvas;
189#elif defined(__APPLE__)
193 static_assert(
false,
"Implement WebGPU Apple surface");
194#elif defined(__linux__)
195 WGPUSurfaceDescriptorFromXlibWindow x11_window = {};
196 x11_window.chain.sType = WGPUSType_SurfaceSourceXlibWindow;
197 x11_window.display = settings.
windowData->display;
198 x11_window.window = settings.
windowData->windowHandle;
199 surface_desc.nextInChain = (WGPUChainedStruct*)&x11_window;
204#elif defined(__ANDROID_API__)
208 static_assert(
false,
"Implement WebGPU Android surface");
210 surface = wgpuInstanceCreateSurface(instance, &surface_desc);
213 WGPURequestAdapterOptions adapter_options = WGPU_REQUEST_ADAPTER_OPTIONS_INIT;
214 adapter_options.featureLevel = WGPUFeatureLevel_Core;
215 adapter_options.powerPreference = WGPUPowerPreference_HighPerformance;
216 adapter_options.compatibleSurface = surface;
218 WGPURequestAdapterCallbackInfo callbackInfo = WGPU_REQUEST_ADAPTER_CALLBACK_INFO_INIT;
219 callbackInfo.nextInChain =
nullptr;
220 callbackInfo.callback = request_adapter;
221 callbackInfo.mode = WGPUCallbackMode_AllowSpontaneous;
222 callbackInfo.userdata1 =
this;
224 WGPUFuture future = wgpuInstanceRequestAdapter(instance, &adapter_options, callbackInfo);
226 WGPUFutureWaitInfo waitInfo = WGPU_FUTURE_WAIT_INFO_INIT;
227 waitInfo.future = future;
228 wgpuInstanceWaitAny(instance, 1, &waitInfo, 0);
233 const char *FeatureNameStr(WGPUFeatureName name)
236 case WGPUFeatureName_CoreFeaturesAndLimits:
237 return "CoreFeaturesAndLimits";
238 case WGPUFeatureName_DepthClipControl:
239 return "DepthClipControl";
240 case WGPUFeatureName_Depth32FloatStencil8:
241 return "Depth32FloatStencil8";
242 case WGPUFeatureName_TextureCompressionBC:
243 return "TextureCompressionBC";
244 case WGPUFeatureName_TextureCompressionBCSliced3D:
245 return "TextureCompressionBCSliced3D";
246 case WGPUFeatureName_TextureCompressionETC2:
247 return "TextureCompressionETC2";
248 case WGPUFeatureName_TextureCompressionASTC:
249 return "TextureCompressionASTC";
250 case WGPUFeatureName_TextureCompressionASTCSliced3D:
251 return "TextureCompressionASTCSliced3D";
252 case WGPUFeatureName_TimestampQuery:
253 return "TimestampQuery";
254 case WGPUFeatureName_IndirectFirstInstance:
255 return "IndirectFirstInstance";
256 case WGPUFeatureName_ShaderF16:
258 case WGPUFeatureName_RG11B10UfloatRenderable:
259 return "RG11B10UfloatRenderable";
260 case WGPUFeatureName_BGRA8UnormStorage:
261 return "BGRA8UnormStorage";
262 case WGPUFeatureName_Float32Filterable:
263 return "Float32Filterable";
264 case WGPUFeatureName_Float32Blendable:
265 return "Float32Blendable";
266 case WGPUFeatureName_ClipDistances:
267 return "ClipDistances";
268 case WGPUFeatureName_DualSourceBlending:
269 return "DualSourceBlending";
270 case WGPUFeatureName_Subgroups:
272 case WGPUFeatureName_TextureFormatsTier1:
273 return "TextureFormatsTier1";
274 case WGPUFeatureName_TextureFormatsTier2:
275 return "TextureFormatsTier2";
276 case WGPUFeatureName_PrimitiveIndex:
277 return "PrimitiveIndex";
278 case WGPUFeatureName_Unorm16TextureFormats:
279 return "Unorm16TextureFormats";
280 case WGPUFeatureName_Snorm16TextureFormats:
281 return "Snorm16TextureFormats";
282 case WGPUFeatureName_MultiDrawIndirect:
283 return "MultiDrawIndirect";
284 case WGPUFeatureName_Force32:
290 void GraphicsDeviceWebGPU::initialize_adapter(WGPUAdapter adapter_in)
292 adapter = adapter_in;
295 WGPUSupportedFeatures supportedFeatures = WGPU_SUPPORTED_FEATURES_INIT;
296 wgpuAdapterGetFeatures(adapter, &supportedFeatures);
297 for(
size_t i=0; i<supportedFeatures.featureCount; i++){
298 WGPUFeatureName name = supportedFeatures.features[i];
299 LOG_INFO(logger,
"Feature: %u %s", name, FeatureNameStr(name));
301 wgpuSupportedFeaturesFreeMembers(supportedFeatures);
303 WGPUAdapterInfo properties = WGPU_ADAPTER_INFO_INIT;
304 wgpuAdapterGetInfo(adapter, &properties);
305 LOG_INFO(logger,
"vendorID %u", properties.vendorID);
306 LOG_INFO(logger,
"vendor %.*s", WGPUStringViewFormat(properties.vendor));
307 LOG_INFO(logger,
"architecture %.*s", WGPUStringViewFormat(properties.architecture));
308 LOG_INFO(logger,
"deviceID %u", properties.deviceID);
309 LOG_INFO(logger,
"device %.*s", WGPUStringViewFormat(properties.device));
310 LOG_INFO(logger,
"description %.*s", WGPUStringViewFormat(properties.description));
311 LOG_INFO(logger,
"adapterType %d", properties.adapterType);
312 LOG_INFO(logger,
"backendType %d", properties.backendType);
313 LOG_INFO(logger,
"subgroupMinSize %u", properties.subgroupMinSize);
314 LOG_INFO(logger,
"subgroupMaxSize %u", properties.subgroupMaxSize);
316 if(properties.vendorID == 4130)
318 else if(properties.vendorID == 4318)
320 else if(properties.vendorID == 32902)
322 else if(properties.vendorID == 4203)
325 if(properties.vendorID == 4130){
326 if(strstr(properties.device.data,
"FireGL") !=
nullptr){
329 else if(strstr(properties.device.data,
"RadeonX") !=
nullptr){
332 else if(strstr(properties.device.data,
"RadeonHD") !=
nullptr){
336 else if(properties.vendorID == 4318){
337 if(strstr(properties.device.data,
"QuadroFX") !=
nullptr){
340 else if(strstr(properties.device.data,
"Quadro") !=
nullptr){
343 else if(strstr(properties.device.data,
"GeForce") !=
nullptr){
347 else if(properties.vendorID == 32902){
348 if(strstr(properties.device.data,
"IrisPro") !=
nullptr){
351 else if(strstr(properties.device.data,
"Iris") !=
nullptr){
354 else if(strstr(properties.device.data,
"HD") !=
nullptr){
359 capabilities.model = properties.deviceID;
361 wgpuAdapterInfoFreeMembers(properties);
363 WGPULimits adapter_limits = WGPU_LIMITS_INIT;
364 if(wgpuAdapterGetLimits(adapter, &adapter_limits)){
365 LOG_INFO(logger,
"adapter_limits ");
366 LOG_INFO(logger,
"maxTextureDimension1D %u", adapter_limits.maxTextureDimension1D);
367 LOG_INFO(logger,
"maxTextureDimension2D %u", adapter_limits.maxTextureDimension2D);
368 LOG_INFO(logger,
"maxTextureDimension3D %u", adapter_limits.maxTextureDimension3D);
369 LOG_INFO(logger,
"maxTextureArrayLayers %u", adapter_limits.maxTextureArrayLayers);
370 LOG_INFO(logger,
"maxBindGroups %u", adapter_limits.maxBindGroups);
371 LOG_INFO(logger,
"maxBindGroupsPlusVertexBuffers %u", adapter_limits.maxBindGroupsPlusVertexBuffers);
372 LOG_INFO(logger,
"maxBindingsPerBindGroup %u", adapter_limits.maxBindingsPerBindGroup);
373 LOG_INFO(logger,
"maxDynamicUniformBuffersPerPipelineLayout %u", adapter_limits.maxDynamicUniformBuffersPerPipelineLayout);
374 LOG_INFO(logger,
"maxDynamicStorageBuffersPerPipelineLayout %u", adapter_limits.maxDynamicStorageBuffersPerPipelineLayout);
375 LOG_INFO(logger,
"maxSampledTexturesPerShaderStage %u", adapter_limits.maxSampledTexturesPerShaderStage);
376 LOG_INFO(logger,
"maxSamplersPerShaderStage %u", adapter_limits.maxSamplersPerShaderStage);
377 LOG_INFO(logger,
"maxStorageBuffersPerShaderStage %u", adapter_limits.maxStorageBuffersPerShaderStage);
378 LOG_INFO(logger,
"maxStorageTexturesPerShaderStage %u", adapter_limits.maxStorageTexturesPerShaderStage);
379 LOG_INFO(logger,
"maxUniformBuffersPerShaderStage %u", adapter_limits.maxUniformBuffersPerShaderStage);
380 LOG_INFO(logger,
"maxUniformBufferBindingSize %llu", adapter_limits.maxUniformBufferBindingSize);
381 LOG_INFO(logger,
"maxStorageBufferBindingSize %llu", adapter_limits.maxStorageBufferBindingSize);
382 LOG_INFO(logger,
"minUniformBufferOffsetAlignment %u", adapter_limits.minUniformBufferOffsetAlignment);
383 LOG_INFO(logger,
"minStorageBufferOffsetAlignment %u", adapter_limits.minStorageBufferOffsetAlignment);
384 LOG_INFO(logger,
"maxVertexBuffers %u", adapter_limits.maxVertexBuffers);
385 LOG_INFO(logger,
"maxBufferSize %llu", adapter_limits.maxBufferSize);
386 LOG_INFO(logger,
"maxVertexAttributes %u", adapter_limits.maxVertexAttributes);
387 LOG_INFO(logger,
"maxVertexBufferArrayStride %u", adapter_limits.maxVertexBufferArrayStride);
388 LOG_INFO(logger,
"maxInterStageShaderVariables %u", adapter_limits.maxInterStageShaderVariables);
389 LOG_INFO(logger,
"maxColorAttachments %u", adapter_limits.maxColorAttachments);
390 LOG_INFO(logger,
"maxColorAttachmentBytesPerSample %u", adapter_limits.maxColorAttachmentBytesPerSample);
391 LOG_INFO(logger,
"maxComputeWorkgroupStorageSize %u", adapter_limits.maxComputeWorkgroupStorageSize);
392 LOG_INFO(logger,
"maxComputeInvocationsPerWorkgroup %u", adapter_limits.maxComputeInvocationsPerWorkgroup);
393 LOG_INFO(logger,
"maxComputeWorkgroupSizeX %u", adapter_limits.maxComputeWorkgroupSizeX);
394 LOG_INFO(logger,
"maxComputeWorkgroupSizeY %u", adapter_limits.maxComputeWorkgroupSizeY);
395 LOG_INFO(logger,
"maxComputeWorkgroupSizeZ %u", adapter_limits.maxComputeWorkgroupSizeZ);
396 LOG_INFO(logger,
"maxComputeWorkgroupsPerDimension %u", adapter_limits.maxComputeWorkgroupsPerDimension);
397 LOG_INFO(logger,
"maxImmediateSize %u", adapter_limits.maxImmediateSize);
436 WGPULimits required_limits = adapter_limits;
438 std::vector<WGPUFeatureName> features;
440 if(wgpuAdapterHasFeature(adapter, WGPUFeatureName_TextureCompressionBC)) {
441 features.push_back(WGPUFeatureName_TextureCompressionBC);
442 capabilities.capabilities.TextureCompressionBPTC =
true;
444 if(wgpuAdapterHasFeature(adapter, WGPUFeatureName_TextureCompressionASTC)) {
445 features.push_back(WGPUFeatureName_TextureCompressionASTC);
446 capabilities.capabilities.TextureCompressionASTC =
true;
448 if(wgpuAdapterHasFeature(adapter, WGPUFeatureName_TextureCompressionETC2)) {
449 features.push_back(WGPUFeatureName_TextureCompressionETC2);
450 capabilities.capabilities.TextureCompressionETC =
true;
452 if(wgpuAdapterHasFeature(adapter, WGPUFeatureName_Float32Filterable)) {
453 features.push_back(WGPUFeatureName_Float32Filterable);
457 WGPUDeviceDescriptor device_desc = WGPU_DEVICE_DESCRIPTOR_INIT;
458 device_desc.label = {
"WebGPU device", WGPU_STRLEN};
460 device_desc.requiredFeatureCount = features.size();
461 device_desc.requiredFeatures = features.data();
462 device_desc.requiredLimits = &required_limits;
463 device_desc.defaultQueue.label = {
"Default WebGPU queue", WGPU_STRLEN};
465 WGPUDeviceLostCallbackInfo deviceLostCallbackInfo = WGPU_DEVICE_LOST_CALLBACK_INFO_INIT;
466 deviceLostCallbackInfo.nextInChain =
nullptr;
467 deviceLostCallbackInfo.callback = device_lost;
468 deviceLostCallbackInfo.mode = WGPUCallbackMode_AllowSpontaneous;
469 deviceLostCallbackInfo.userdata1 =
this;
470 device_desc.deviceLostCallbackInfo = deviceLostCallbackInfo;
472 WGPUUncapturedErrorCallbackInfo uncapturedErrorCallbackInfo = WGPU_UNCAPTURED_ERROR_CALLBACK_INFO_INIT;
473 uncapturedErrorCallbackInfo.nextInChain =
nullptr;
474 uncapturedErrorCallbackInfo.callback = error_callback;
475 uncapturedErrorCallbackInfo.userdata1 =
this;
476 device_desc.uncapturedErrorCallbackInfo = uncapturedErrorCallbackInfo;
487 WGPURequestDeviceCallbackInfo requestDeviceCallbackInfo = WGPU_REQUEST_DEVICE_CALLBACK_INFO_INIT;
488 requestDeviceCallbackInfo.nextInChain =
nullptr;
489 requestDeviceCallbackInfo.mode = WGPUCallbackMode_AllowSpontaneous;
490 requestDeviceCallbackInfo.userdata1 =
this;
491 requestDeviceCallbackInfo.callback = request_device;
492 WGPUFuture future = wgpuAdapterRequestDevice(adapter, &device_desc, requestDeviceCallbackInfo);
494 WGPUFutureWaitInfo waitInfo = WGPU_FUTURE_WAIT_INFO_INIT;
495 waitInfo.future = future;
496 wgpuInstanceWaitAny(instance, 1, &waitInfo, 0);
499 void GraphicsDeviceWebGPU::maybeCreateUploadCommandEncoder()
501 if(commandEncoder)
return;
502 WGPUCommandEncoderDescriptor command_encoder_desc = WGPU_COMMAND_ENCODER_DESCRIPTOR_INIT;
503 command_encoder_desc.label = {
"Upload Command Encoder", WGPU_STRLEN};
504 commandEncoder = wgpuDeviceCreateCommandEncoder(device, &command_encoder_desc);
506 void GraphicsDeviceWebGPU::initialize_device(WGPUDevice device_in)
511#ifndef __EMSCRIPTEN__
512 WGPULoggingCallbackInfo loggingCallbackInfo = {};
513 loggingCallbackInfo.nextInChain =
nullptr;
514 loggingCallbackInfo.callback = logging_callback;
515 loggingCallbackInfo.userdata1 =
this;
516 wgpuDeviceSetLoggingCallback(device, loggingCallbackInfo);
519 WGPULimits device_limits = WGPU_LIMITS_INIT;
520 if(wgpuDeviceGetLimits(device, &device_limits)){
521 LOG_INFO(logger,
"device_limits ");
522 LOG_INFO(logger,
"maxTextureDimension1D %u", device_limits.maxTextureDimension1D);
523 LOG_INFO(logger,
"maxTextureDimension2D %u", device_limits.maxTextureDimension2D);
524 LOG_INFO(logger,
"maxTextureDimension3D %u", device_limits.maxTextureDimension3D);
525 LOG_INFO(logger,
"maxTextureArrayLayers %u", device_limits.maxTextureArrayLayers);
526 LOG_INFO(logger,
"maxBindGroups %u", device_limits.maxBindGroups);
527 LOG_INFO(logger,
"maxBindGroupsPlusVertexBuffers %u", device_limits.maxBindGroupsPlusVertexBuffers);
528 LOG_INFO(logger,
"maxBindingsPerBindGroup %u", device_limits.maxBindingsPerBindGroup);
529 LOG_INFO(logger,
"maxDynamicUniformBuffersPerPipelineLayout %u", device_limits.maxDynamicUniformBuffersPerPipelineLayout);
530 LOG_INFO(logger,
"maxDynamicStorageBuffersPerPipelineLayout %u", device_limits.maxDynamicStorageBuffersPerPipelineLayout);
531 LOG_INFO(logger,
"maxSampledTexturesPerShaderStage %u", device_limits.maxSampledTexturesPerShaderStage);
532 LOG_INFO(logger,
"maxSamplersPerShaderStage %u", device_limits.maxSamplersPerShaderStage);
533 LOG_INFO(logger,
"maxStorageBuffersPerShaderStage %u", device_limits.maxStorageBuffersPerShaderStage);
534 LOG_INFO(logger,
"maxStorageTexturesPerShaderStage %u", device_limits.maxStorageTexturesPerShaderStage);
535 LOG_INFO(logger,
"maxUniformBuffersPerShaderStage %u", device_limits.maxUniformBuffersPerShaderStage);
536 LOG_INFO(logger,
"maxUniformBufferBindingSize %llu", device_limits.maxUniformBufferBindingSize);
537 LOG_INFO(logger,
"maxStorageBufferBindingSize %llu", device_limits.maxStorageBufferBindingSize);
538 LOG_INFO(logger,
"minUniformBufferOffsetAlignment %u", device_limits.minUniformBufferOffsetAlignment);
539 LOG_INFO(logger,
"minStorageBufferOffsetAlignment %u", device_limits.minStorageBufferOffsetAlignment);
540 LOG_INFO(logger,
"maxVertexBuffers %u", device_limits.maxVertexBuffers);
541 LOG_INFO(logger,
"maxBufferSize %llu", device_limits.maxBufferSize);
542 LOG_INFO(logger,
"maxVertexAttributes %u", device_limits.maxVertexAttributes);
543 LOG_INFO(logger,
"maxVertexBufferArrayStride %u", device_limits.maxVertexBufferArrayStride);
544 LOG_INFO(logger,
"maxInterStageShaderVariables %u", device_limits.maxInterStageShaderVariables);
545 LOG_INFO(logger,
"maxColorAttachments %u", device_limits.maxColorAttachments);
546 LOG_INFO(logger,
"maxColorAttachmentBytesPerSample %u", device_limits.maxColorAttachmentBytesPerSample);
547 LOG_INFO(logger,
"maxComputeWorkgroupStorageSize %u", device_limits.maxComputeWorkgroupStorageSize);
548 LOG_INFO(logger,
"maxComputeInvocationsPerWorkgroup %u", device_limits.maxComputeInvocationsPerWorkgroup);
549 LOG_INFO(logger,
"maxComputeWorkgroupSizeX %u", device_limits.maxComputeWorkgroupSizeX);
550 LOG_INFO(logger,
"maxComputeWorkgroupSizeY %u", device_limits.maxComputeWorkgroupSizeY);
551 LOG_INFO(logger,
"maxComputeWorkgroupSizeZ %u", device_limits.maxComputeWorkgroupSizeZ);
552 LOG_INFO(logger,
"maxComputeWorkgroupsPerDimension %u", device_limits.maxComputeWorkgroupsPerDimension);
553 LOG_INFO(logger,
"maxImmediateSize %u", device_limits.maxImmediateSize);
557 capabilities.capabilities.RenderPass =
true;
559 capabilities.capabilities.GeometryShaders =
false;
560 capabilities.capabilities.TessellationShaders =
false;
561 capabilities.capabilities.ComputeShaders =
false;
562 capabilities.capabilities.SupportsHlsl =
false;
563 capabilities.capabilities.SupportsMultipleThreads =
false;
566 capabilities.capabilities.
MaxTexture2DSize = device_limits.maxTextureDimension2D;
567 capabilities.capabilities.
MaxTexture3DSize = device_limits.maxTextureDimension3D;
570 defaultSwapChain.initialize(device, surface);
572 queue = wgpuDeviceGetQueue(device);
574 LOG_INFO(logger,
"Has WebGPU Device");
578 void GraphicsDeviceWebGPU::destroy()
581 context.ClearBindGroups();
583 wgpuInstanceRelease(instance);
584 LOG_INFO(logger,
"WebGPU destroy");
586 wgpuCommandEncoderRelease(commandEncoder);
587 commandEncoder =
nullptr;
589 wgpuQueueRelease(queue);
590 defaultSwapChain.destroy();
591 wgpuSurfaceRelease(surface);
593 wgpuDeviceDestroy(device);
594 wgpuDeviceRelease(device);
596 wgpuAdapterRelease(adapter);
601 pipeline_states.releaseResources();
613 context.beginFrame();
616 WGPUCommandBufferDescriptor command_buffer_desc = WGPU_COMMAND_BUFFER_DESCRIPTOR_INIT;
617 command_buffer_desc.label = {
"Upload Command Buffer", WGPU_STRLEN};
618 WGPUCommandBuffer command_buffer = wgpuCommandEncoderFinish(commandEncoder, &command_buffer_desc);
619 wgpuCommandEncoderRelease(commandEncoder);
620 commandEncoder =
nullptr;
621 wgpuQueueSubmit(queue, 1, &command_buffer);
622 wgpuCommandBufferRelease(command_buffer);
623 buffers.resetInstances();
626#ifndef __EMSCRIPTEN__
628 wgpuInstanceProcessEvents(instance);
629 wgpuDeviceTick(device);
634 WGPUCommandEncoderDescriptor command_encoder_desc = WGPU_COMMAND_ENCODER_DESCRIPTOR_INIT;
635 command_encoder_desc.label = {
"Default Command Encoder", WGPU_STRLEN};
636 commandEncoder = wgpuDeviceCreateCommandEncoder(device, &command_encoder_desc);
637 context.setDefaults();
642 context.updateRenderPass();
643 context.endRenderPassInt();
645#ifndef __EMSCRIPTEN__
646 WGPUTexelCopyTextureInfo src = WGPU_TEXEL_COPY_TEXTURE_INFO_INIT;
647 src.texture = defaultSwapChain.resolveTexture;
649 src.origin = {0, 0, 0};
650 src.aspect = WGPUTextureAspect_All;
651 WGPUTexelCopyTextureInfo dst = WGPU_TEXEL_COPY_TEXTURE_INFO_INIT;
652 WGPUSurfaceTexture surfaceTexture = context.graphicsDevice->defaultSwapChain.getTextureData();
653 dst.texture = surfaceTexture.texture;
655 dst.origin = {0, 0, 0};
656 dst.aspect = WGPUTextureAspect_All;
657 WGPUExtent3D copy_size = {(uint32_t)defaultSwapChain.set_width, (uint32_t)defaultSwapChain.set_height, 1};
658 wgpuCommandEncoderCopyTextureToTexture(commandEncoder, &src, &dst, ©_size);
659 wgpuTextureRelease(surfaceTexture.texture);
662 WGPUCommandBufferDescriptor command_buffer_desc = WGPU_COMMAND_BUFFER_DESCRIPTOR_INIT;
663 command_buffer_desc.label = {
"Default Command Buffer", WGPU_STRLEN};
664 WGPUCommandBuffer command_buffer = wgpuCommandEncoderFinish(commandEncoder, &command_buffer_desc);
665 wgpuCommandEncoderRelease(commandEncoder);
666 commandEncoder =
nullptr;
667 wgpuQueueSubmit(queue, 1, &command_buffer);
668 wgpuCommandBufferRelease(command_buffer);
669 buffers.resetInstances();
673 defaultSwapChain.
endFrame(syncInterval, presentFlags);
680 buffers.updateResourceStatistics(stats);
681 stats.textureBytes = textures.textureMemoryConsumption;
682 stats.vertexArrayObjectCount = 0;
683 stats.inputLayoutCount =
static_cast<uint32_t
>(buffers.inputLayouts.size());
684 stats.textureCount =
static_cast<uint32_t
>(textures.textures.size());
685 stats.samplerStateCount =
static_cast<uint32_t
>(textures.samplerStates.size());
686 stats.effectCount =
static_cast<uint32_t
>(effects.effects.size());
687 stats.blendStateCount = 0;
688 stats.rasterizerStateCount = 0;
689 stats.depthStencilStateCount = 0;
690 stats.rendertargetsCount =
static_cast<uint32_t
>(renderTargets.render_targets.size());
691 stats.framebufferCount = 0;
virtual void releaseResources() override
Releases all allocated buffer resources.
virtual void releaseResources() override
Release all allocated effect resources.
virtual void beginFrame() override
Signal the beginning of a new frame to the graphics device.
uint32_t frame_descriptor_count
virtual void releaseResources() override
Release all resources allocated.
virtual bool initialize() override
Initializes the graphics device with the settings previous set through calling setSettings.
virtual void endFrame(uint32_t=0, PresentFlags=PresentFlags::None) override
Signal the end of a frame to the graphics device.
Log implementation class.
virtual void releaseResources() override
Release all allocated render target resources.
virtual void beginFrame() override
Signal the beginning of a new frame to the graphics device.
virtual void endFrame(uint32_t syncInterval=0, PresentFlags presentFlags=PresentFlags::None) override
Signal the end of a frame to the graphics device.
virtual void releaseResources() override
Release all allocated texture resources.
constexpr Log getLogger(const char(&name)[LEN]) noexcept
Contains all Cogs related functionality.
PresentFlags
Flags controlling presentation.
void setIOHandler(IIOHandler *handler) override
Sets an external I/O handler to use for I/O operations.
uint32_t MaxTexture3DSize
Using D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION as default.
uint32_t MaxTexture2DSize
Using D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION as default.
bool SyncObjects
Support for syncronization objects.
uint32_t MaxTextureArrayLayers
Using D3D11_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION as default.
unsigned ConstantBufferOffsetAlignment
Minimum offset alignment when binding constant buffers.
bool ConstantBufferRange
supports binding a range of a constant buffer.
struct WindowData * windowData
Native window handle used to initialize the graphics device.
IIOHandler * ioHandler
Optional pointer to an IO handler.
@ QuadroFX
nVidia Quadro FX professional graphics adapters.
@ FireGL
AMD FireGL series.
@ geForce
nVidia geForce consumer adapters.
@ RadeonX
AMD Radeon X series.
@ RadeonHD
AMD Radeon HD series.
@ Quadro
nVidia Quadro professional graphics adapters.
@ nVidia
nVidia Corporation.