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 context.initialize(
this);
124 textures.initialize(
this);
127 GraphicsDeviceWebGPU::~GraphicsDeviceWebGPU()
138#ifndef __EMSCRIPTEN__
140 DawnProcTable procTable = dawn::native::GetProcs();
141 dawnProcSetProcs(&procTable);
145 WGPUInstanceDescriptor instance_desc = WGPU_INSTANCE_DESCRIPTOR_INIT;
146 instance = wgpuCreateInstance(&instance_desc);
152 if(wgpuHasInstanceFeature(WGPUInstanceFeatureName_TimedWaitAny) != 0){
153 LOG_INFO(logger,
"Has Instance Features: TimedWaitAny");
155 if(wgpuHasInstanceFeature(WGPUInstanceFeatureName_ShaderSourceSPIRV) != 0){
156 LOG_INFO(logger,
"Has Instance Features: ShaderSourceSPIRV");
158 if(wgpuHasInstanceFeature(WGPUInstanceFeatureName_MultipleDevicesPerAdapter) != 0){
159 LOG_INFO(logger,
"Has Instance Features: MultipleDevicesPerAdapter");
163 WGPUInstanceLimits instance_limits = WGPU_INSTANCE_LIMITS_INIT;
164 if(wgpuGetInstanceLimits(&instance_limits) == WGPUStatus_Success){
165 LOG_INFO(logger,
"Instance timedWaitAnyMaxCount %zu", instance_limits.timedWaitAnyMaxCount);
169 WGPUSurfaceDescriptor surface_desc = WGPU_SURFACE_DESCRIPTOR_INIT;
170 surface_desc.label = {
"WebGPU Surface", WGPU_STRLEN};
172 WGPUSurfaceSourceWindowsHWND hwnd_window = {};
173 hwnd_window.chain.sType = WGPUSType_SurfaceSourceWindowsHWND;
174 hwnd_window.hinstance = ::GetModuleHandle(
nullptr);
175 hwnd_window.hwnd = settings.
windowData->windowHandle;
176 surface_desc.nextInChain = (WGPUChainedStruct*)&hwnd_window;
183#elif defined(__EMSCRIPTEN__)
184 WGPUEmscriptenSurfaceSourceCanvasHTMLSelector html_canvas = WGPU_EMSCRIPTEN_SURFACE_SOURCE_CANVAS_HTML_SELECTOR_INIT;
185 html_canvas.chain.sType = WGPUSType_EmscriptenSurfaceSourceCanvasHTMLSelector;
186 html_canvas.selector = {
"canvas", WGPU_STRLEN};
187 surface_desc.nextInChain = (WGPUChainedStruct*)&html_canvas;
188#elif defined(__APPLE__)
192 static_assert(
false,
"Implement WebGPU Apple surface");
193#elif defined(__linux__)
194 WGPUSurfaceDescriptorFromXlibWindow x11_window = {};
195 x11_window.chain.sType = WGPUSType_SurfaceSourceXlibWindow;
196 x11_window.display = settings.
windowData->display;
197 x11_window.window = settings.
windowData->windowHandle;
198 surface_desc.nextInChain = (WGPUChainedStruct*)&x11_window;
203#elif defined(__ANDROID_API__)
207 static_assert(
false,
"Implement WebGPU Android surface");
209 surface = wgpuInstanceCreateSurface(instance, &surface_desc);
212 WGPURequestAdapterOptions adapter_options = WGPU_REQUEST_ADAPTER_OPTIONS_INIT;
213 adapter_options.featureLevel = WGPUFeatureLevel_Core;
214 adapter_options.powerPreference = WGPUPowerPreference_HighPerformance;
215 adapter_options.compatibleSurface = surface;
217 WGPURequestAdapterCallbackInfo callbackInfo = WGPU_REQUEST_ADAPTER_CALLBACK_INFO_INIT;
218 callbackInfo.nextInChain =
nullptr;
219 callbackInfo.callback = request_adapter;
220 callbackInfo.mode = WGPUCallbackMode_AllowSpontaneous;
221 callbackInfo.userdata1 =
this;
223 WGPUFuture future = wgpuInstanceRequestAdapter(instance, &adapter_options, callbackInfo);
225 WGPUFutureWaitInfo waitInfo = WGPU_FUTURE_WAIT_INFO_INIT;
226 waitInfo.future = future;
227 wgpuInstanceWaitAny(instance, 1, &waitInfo, 0);
232 const char *FeatureNameStr(WGPUFeatureName name)
235 case WGPUFeatureName_CoreFeaturesAndLimits:
236 return "CoreFeaturesAndLimits";
237 case WGPUFeatureName_DepthClipControl:
238 return "DepthClipControl";
239 case WGPUFeatureName_Depth32FloatStencil8:
240 return "Depth32FloatStencil8";
241 case WGPUFeatureName_TextureCompressionBC:
242 return "TextureCompressionBC";
243 case WGPUFeatureName_TextureCompressionBCSliced3D:
244 return "TextureCompressionBCSliced3D";
245 case WGPUFeatureName_TextureCompressionETC2:
246 return "TextureCompressionETC2";
247 case WGPUFeatureName_TextureCompressionASTC:
248 return "TextureCompressionASTC";
249 case WGPUFeatureName_TextureCompressionASTCSliced3D:
250 return "TextureCompressionASTCSliced3D";
251 case WGPUFeatureName_TimestampQuery:
252 return "TimestampQuery";
253 case WGPUFeatureName_IndirectFirstInstance:
254 return "IndirectFirstInstance";
255 case WGPUFeatureName_ShaderF16:
257 case WGPUFeatureName_RG11B10UfloatRenderable:
258 return "RG11B10UfloatRenderable";
259 case WGPUFeatureName_BGRA8UnormStorage:
260 return "BGRA8UnormStorage";
261 case WGPUFeatureName_Float32Filterable:
262 return "Float32Filterable";
263 case WGPUFeatureName_Float32Blendable:
264 return "Float32Blendable";
265 case WGPUFeatureName_ClipDistances:
266 return "ClipDistances";
267 case WGPUFeatureName_DualSourceBlending:
268 return "DualSourceBlending";
269 case WGPUFeatureName_Subgroups:
271 case WGPUFeatureName_TextureFormatsTier1:
272 return "TextureFormatsTier1";
273 case WGPUFeatureName_TextureFormatsTier2:
274 return "TextureFormatsTier2";
275 case WGPUFeatureName_PrimitiveIndex:
276 return "PrimitiveIndex";
277 case WGPUFeatureName_Unorm16TextureFormats:
278 return "Unorm16TextureFormats";
279 case WGPUFeatureName_Snorm16TextureFormats:
280 return "Snorm16TextureFormats";
281 case WGPUFeatureName_MultiDrawIndirect:
282 return "MultiDrawIndirect";
283 case WGPUFeatureName_Force32:
289 void GraphicsDeviceWebGPU::initialize_adapter(WGPUAdapter adapter_in)
291 adapter = adapter_in;
294 WGPUSupportedFeatures supportedFeatures = WGPU_SUPPORTED_FEATURES_INIT;
295 wgpuAdapterGetFeatures(adapter, &supportedFeatures);
296 for(
size_t i=0; i<supportedFeatures.featureCount; i++){
297 WGPUFeatureName name = supportedFeatures.features[i];
298 LOG_INFO(logger,
"Feature: %u %s", name, FeatureNameStr(name));
300 wgpuSupportedFeaturesFreeMembers(supportedFeatures);
302 WGPUAdapterInfo properties = WGPU_ADAPTER_INFO_INIT;
303 wgpuAdapterGetInfo(adapter, &properties);
304 LOG_INFO(logger,
"vendorID %u", properties.vendorID);
305 LOG_INFO(logger,
"vendor %.*s", WGPUStringViewFormat(properties.vendor));
306 LOG_INFO(logger,
"architecture %.*s", WGPUStringViewFormat(properties.architecture));
307 LOG_INFO(logger,
"deviceID %u", properties.deviceID);
308 LOG_INFO(logger,
"device %.*s", WGPUStringViewFormat(properties.device));
309 LOG_INFO(logger,
"description %.*s", WGPUStringViewFormat(properties.description));
310 LOG_INFO(logger,
"adapterType %d", properties.adapterType);
311 LOG_INFO(logger,
"backendType %d", properties.backendType);
312 LOG_INFO(logger,
"subgroupMinSize %u", properties.subgroupMinSize);
313 LOG_INFO(logger,
"subgroupMaxSize %u", properties.subgroupMaxSize);
315 if(properties.vendorID == 4130)
317 else if(properties.vendorID == 4318)
319 else if(properties.vendorID == 32902)
321 else if(properties.vendorID == 4203)
324 if(properties.vendorID == 4130){
325 if(strstr(properties.device.data,
"FireGL") !=
nullptr){
328 else if(strstr(properties.device.data,
"RadeonX") !=
nullptr){
331 else if(strstr(properties.device.data,
"RadeonHD") !=
nullptr){
335 else if(properties.vendorID == 4318){
336 if(strstr(properties.device.data,
"QuadroFX") !=
nullptr){
339 else if(strstr(properties.device.data,
"Quadro") !=
nullptr){
342 else if(strstr(properties.device.data,
"GeForce") !=
nullptr){
346 else if(properties.vendorID == 32902){
347 if(strstr(properties.device.data,
"IrisPro") !=
nullptr){
350 else if(strstr(properties.device.data,
"Iris") !=
nullptr){
353 else if(strstr(properties.device.data,
"HD") !=
nullptr){
358 capabilities.model = properties.deviceID;
360 wgpuAdapterInfoFreeMembers(properties);
362 WGPULimits adapter_limits = WGPU_LIMITS_INIT;
363 if(wgpuAdapterGetLimits(adapter, &adapter_limits)){
364 LOG_INFO(logger,
"adapter_limits ");
365 LOG_INFO(logger,
"maxTextureDimension1D %u", adapter_limits.maxTextureDimension1D);
366 LOG_INFO(logger,
"maxTextureDimension2D %u", adapter_limits.maxTextureDimension2D);
367 LOG_INFO(logger,
"maxTextureDimension3D %u", adapter_limits.maxTextureDimension3D);
368 LOG_INFO(logger,
"maxTextureArrayLayers %u", adapter_limits.maxTextureArrayLayers);
369 LOG_INFO(logger,
"maxBindGroups %u", adapter_limits.maxBindGroups);
370 LOG_INFO(logger,
"maxBindGroupsPlusVertexBuffers %u", adapter_limits.maxBindGroupsPlusVertexBuffers);
371 LOG_INFO(logger,
"maxBindingsPerBindGroup %u", adapter_limits.maxBindingsPerBindGroup);
372 LOG_INFO(logger,
"maxDynamicUniformBuffersPerPipelineLayout %u", adapter_limits.maxDynamicUniformBuffersPerPipelineLayout);
373 LOG_INFO(logger,
"maxDynamicStorageBuffersPerPipelineLayout %u", adapter_limits.maxDynamicStorageBuffersPerPipelineLayout);
374 LOG_INFO(logger,
"maxSampledTexturesPerShaderStage %u", adapter_limits.maxSampledTexturesPerShaderStage);
375 LOG_INFO(logger,
"maxSamplersPerShaderStage %u", adapter_limits.maxSamplersPerShaderStage);
376 LOG_INFO(logger,
"maxStorageBuffersPerShaderStage %u", adapter_limits.maxStorageBuffersPerShaderStage);
377 LOG_INFO(logger,
"maxStorageTexturesPerShaderStage %u", adapter_limits.maxStorageTexturesPerShaderStage);
378 LOG_INFO(logger,
"maxUniformBuffersPerShaderStage %u", adapter_limits.maxUniformBuffersPerShaderStage);
379 LOG_INFO(logger,
"maxUniformBufferBindingSize %llu", adapter_limits.maxUniformBufferBindingSize);
380 LOG_INFO(logger,
"maxStorageBufferBindingSize %llu", adapter_limits.maxStorageBufferBindingSize);
381 LOG_INFO(logger,
"minUniformBufferOffsetAlignment %u", adapter_limits.minUniformBufferOffsetAlignment);
382 LOG_INFO(logger,
"minStorageBufferOffsetAlignment %u", adapter_limits.minStorageBufferOffsetAlignment);
383 LOG_INFO(logger,
"maxVertexBuffers %u", adapter_limits.maxVertexBuffers);
384 LOG_INFO(logger,
"maxBufferSize %llu", adapter_limits.maxBufferSize);
385 LOG_INFO(logger,
"maxVertexAttributes %u", adapter_limits.maxVertexAttributes);
386 LOG_INFO(logger,
"maxVertexBufferArrayStride %u", adapter_limits.maxVertexBufferArrayStride);
387 LOG_INFO(logger,
"maxInterStageShaderVariables %u", adapter_limits.maxInterStageShaderVariables);
388 LOG_INFO(logger,
"maxColorAttachments %u", adapter_limits.maxColorAttachments);
389 LOG_INFO(logger,
"maxColorAttachmentBytesPerSample %u", adapter_limits.maxColorAttachmentBytesPerSample);
390 LOG_INFO(logger,
"maxComputeWorkgroupStorageSize %u", adapter_limits.maxComputeWorkgroupStorageSize);
391 LOG_INFO(logger,
"maxComputeInvocationsPerWorkgroup %u", adapter_limits.maxComputeInvocationsPerWorkgroup);
392 LOG_INFO(logger,
"maxComputeWorkgroupSizeX %u", adapter_limits.maxComputeWorkgroupSizeX);
393 LOG_INFO(logger,
"maxComputeWorkgroupSizeY %u", adapter_limits.maxComputeWorkgroupSizeY);
394 LOG_INFO(logger,
"maxComputeWorkgroupSizeZ %u", adapter_limits.maxComputeWorkgroupSizeZ);
395 LOG_INFO(logger,
"maxComputeWorkgroupsPerDimension %u", adapter_limits.maxComputeWorkgroupsPerDimension);
396 LOG_INFO(logger,
"maxImmediateSize %u", adapter_limits.maxImmediateSize);
435 WGPULimits required_limits = adapter_limits;
437 std::vector<WGPUFeatureName> features;
439 if(wgpuAdapterHasFeature(adapter, WGPUFeatureName_TextureCompressionBC)) {
440 features.push_back(WGPUFeatureName_TextureCompressionBC);
441 capabilities.capabilities.TextureCompressionBPTC =
true;
443 if(wgpuAdapterHasFeature(adapter, WGPUFeatureName_TextureCompressionASTC)) {
444 features.push_back(WGPUFeatureName_TextureCompressionASTC);
445 capabilities.capabilities.TextureCompressionASTC =
true;
447 if(wgpuAdapterHasFeature(adapter, WGPUFeatureName_TextureCompressionETC2)) {
448 features.push_back(WGPUFeatureName_TextureCompressionETC2);
449 capabilities.capabilities.TextureCompressionETC =
true;
451 if(wgpuAdapterHasFeature(adapter, WGPUFeatureName_Float32Filterable)) {
452 features.push_back(WGPUFeatureName_Float32Filterable);
456 WGPUDeviceDescriptor device_desc = WGPU_DEVICE_DESCRIPTOR_INIT;
457 device_desc.label = {
"WebGPU device", WGPU_STRLEN};
459 device_desc.requiredFeatureCount = features.size();
460 device_desc.requiredFeatures = features.data();
461 device_desc.requiredLimits = &required_limits;
462 device_desc.defaultQueue.label = {
"Default WebGPU queue", WGPU_STRLEN};
464 WGPUDeviceLostCallbackInfo deviceLostCallbackInfo = WGPU_DEVICE_LOST_CALLBACK_INFO_INIT;
465 deviceLostCallbackInfo.nextInChain =
nullptr;
466 deviceLostCallbackInfo.callback = device_lost;
467 deviceLostCallbackInfo.mode = WGPUCallbackMode_AllowSpontaneous;
468 deviceLostCallbackInfo.userdata1 =
this;
469 device_desc.deviceLostCallbackInfo = deviceLostCallbackInfo;
471 WGPUUncapturedErrorCallbackInfo uncapturedErrorCallbackInfo = WGPU_UNCAPTURED_ERROR_CALLBACK_INFO_INIT;
472 uncapturedErrorCallbackInfo.nextInChain =
nullptr;
473 uncapturedErrorCallbackInfo.callback = error_callback;
474 uncapturedErrorCallbackInfo.userdata1 =
this;
475 device_desc.uncapturedErrorCallbackInfo = uncapturedErrorCallbackInfo;
486 WGPURequestDeviceCallbackInfo requestDeviceCallbackInfo = WGPU_REQUEST_DEVICE_CALLBACK_INFO_INIT;
487 requestDeviceCallbackInfo.nextInChain =
nullptr;
488 requestDeviceCallbackInfo.mode = WGPUCallbackMode_AllowSpontaneous;
489 requestDeviceCallbackInfo.userdata1 =
this;
490 requestDeviceCallbackInfo.callback = request_device;
491 WGPUFuture future = wgpuAdapterRequestDevice(adapter, &device_desc, requestDeviceCallbackInfo);
493 WGPUFutureWaitInfo waitInfo = WGPU_FUTURE_WAIT_INFO_INIT;
494 waitInfo.future = future;
495 wgpuInstanceWaitAny(instance, 1, &waitInfo, 0);
498 void GraphicsDeviceWebGPU::maybeCreateUploadCommandEncoder()
500 if(commandEncoder)
return;
501 WGPUCommandEncoderDescriptor command_encoder_desc = WGPU_COMMAND_ENCODER_DESCRIPTOR_INIT;
502 command_encoder_desc.label = {
"Upload Command Encoder", WGPU_STRLEN};
503 commandEncoder = wgpuDeviceCreateCommandEncoder(device, &command_encoder_desc);
505 void GraphicsDeviceWebGPU::initialize_device(WGPUDevice device_in)
510#ifndef __EMSCRIPTEN__
511 WGPULoggingCallbackInfo loggingCallbackInfo = {};
512 loggingCallbackInfo.nextInChain =
nullptr;
513 loggingCallbackInfo.callback = logging_callback;
514 loggingCallbackInfo.userdata1 =
this;
515 wgpuDeviceSetLoggingCallback(device, loggingCallbackInfo);
518 WGPULimits device_limits = WGPU_LIMITS_INIT;
519 if(wgpuDeviceGetLimits(device, &device_limits)){
520 LOG_INFO(logger,
"device_limits ");
521 LOG_INFO(logger,
"maxTextureDimension1D %u", device_limits.maxTextureDimension1D);
522 LOG_INFO(logger,
"maxTextureDimension2D %u", device_limits.maxTextureDimension2D);
523 LOG_INFO(logger,
"maxTextureDimension3D %u", device_limits.maxTextureDimension3D);
524 LOG_INFO(logger,
"maxTextureArrayLayers %u", device_limits.maxTextureArrayLayers);
525 LOG_INFO(logger,
"maxBindGroups %u", device_limits.maxBindGroups);
526 LOG_INFO(logger,
"maxBindGroupsPlusVertexBuffers %u", device_limits.maxBindGroupsPlusVertexBuffers);
527 LOG_INFO(logger,
"maxBindingsPerBindGroup %u", device_limits.maxBindingsPerBindGroup);
528 LOG_INFO(logger,
"maxDynamicUniformBuffersPerPipelineLayout %u", device_limits.maxDynamicUniformBuffersPerPipelineLayout);
529 LOG_INFO(logger,
"maxDynamicStorageBuffersPerPipelineLayout %u", device_limits.maxDynamicStorageBuffersPerPipelineLayout);
530 LOG_INFO(logger,
"maxSampledTexturesPerShaderStage %u", device_limits.maxSampledTexturesPerShaderStage);
531 LOG_INFO(logger,
"maxSamplersPerShaderStage %u", device_limits.maxSamplersPerShaderStage);
532 LOG_INFO(logger,
"maxStorageBuffersPerShaderStage %u", device_limits.maxStorageBuffersPerShaderStage);
533 LOG_INFO(logger,
"maxStorageTexturesPerShaderStage %u", device_limits.maxStorageTexturesPerShaderStage);
534 LOG_INFO(logger,
"maxUniformBuffersPerShaderStage %u", device_limits.maxUniformBuffersPerShaderStage);
535 LOG_INFO(logger,
"maxUniformBufferBindingSize %llu", device_limits.maxUniformBufferBindingSize);
536 LOG_INFO(logger,
"maxStorageBufferBindingSize %llu", device_limits.maxStorageBufferBindingSize);
537 LOG_INFO(logger,
"minUniformBufferOffsetAlignment %u", device_limits.minUniformBufferOffsetAlignment);
538 LOG_INFO(logger,
"minStorageBufferOffsetAlignment %u", device_limits.minStorageBufferOffsetAlignment);
539 LOG_INFO(logger,
"maxVertexBuffers %u", device_limits.maxVertexBuffers);
540 LOG_INFO(logger,
"maxBufferSize %llu", device_limits.maxBufferSize);
541 LOG_INFO(logger,
"maxVertexAttributes %u", device_limits.maxVertexAttributes);
542 LOG_INFO(logger,
"maxVertexBufferArrayStride %u", device_limits.maxVertexBufferArrayStride);
543 LOG_INFO(logger,
"maxInterStageShaderVariables %u", device_limits.maxInterStageShaderVariables);
544 LOG_INFO(logger,
"maxColorAttachments %u", device_limits.maxColorAttachments);
545 LOG_INFO(logger,
"maxColorAttachmentBytesPerSample %u", device_limits.maxColorAttachmentBytesPerSample);
546 LOG_INFO(logger,
"maxComputeWorkgroupStorageSize %u", device_limits.maxComputeWorkgroupStorageSize);
547 LOG_INFO(logger,
"maxComputeInvocationsPerWorkgroup %u", device_limits.maxComputeInvocationsPerWorkgroup);
548 LOG_INFO(logger,
"maxComputeWorkgroupSizeX %u", device_limits.maxComputeWorkgroupSizeX);
549 LOG_INFO(logger,
"maxComputeWorkgroupSizeY %u", device_limits.maxComputeWorkgroupSizeY);
550 LOG_INFO(logger,
"maxComputeWorkgroupSizeZ %u", device_limits.maxComputeWorkgroupSizeZ);
551 LOG_INFO(logger,
"maxComputeWorkgroupsPerDimension %u", device_limits.maxComputeWorkgroupsPerDimension);
552 LOG_INFO(logger,
"maxImmediateSize %u", device_limits.maxImmediateSize);
556 capabilities.capabilities.RenderPass =
true;
558 capabilities.capabilities.GeometryShaders =
false;
559 capabilities.capabilities.TessellationShaders =
false;
560 capabilities.capabilities.ComputeShaders =
false;
561 capabilities.capabilities.SupportsHlsl =
false;
562 capabilities.capabilities.SupportsMultipleThreads =
false;
565 capabilities.capabilities.
MaxTexture2DSize = device_limits.maxTextureDimension2D;
566 capabilities.capabilities.
MaxTexture3DSize = device_limits.maxTextureDimension3D;
569 defaultSwapChain.initialize(device, surface);
571 queue = wgpuDeviceGetQueue(device);
573 LOG_INFO(logger,
"Has WebGPU Device");
577 void GraphicsDeviceWebGPU::destroy()
581 context.ClearBindGroups();
582 context.SwapBindGroups();
583 context.ClearBindGroups();
585 wgpuInstanceRelease(instance);
586 LOG_INFO(logger,
"WebGPU destroy");
588 wgpuCommandEncoderRelease(commandEncoder);
589 commandEncoder =
nullptr;
591 wgpuQueueRelease(queue);
592 defaultSwapChain.destroy();
593 wgpuSurfaceRelease(surface);
595 wgpuDeviceDestroy(device);
596 wgpuDeviceRelease(device);
598 wgpuAdapterRelease(adapter);
603 pipeline_states.releaseResources();
612 context.beginFrame();
615 WGPUCommandBufferDescriptor command_buffer_desc = WGPU_COMMAND_BUFFER_DESCRIPTOR_INIT;
616 command_buffer_desc.label = {
"Upload Command Buffer", WGPU_STRLEN};
617 WGPUCommandBuffer command_buffer = wgpuCommandEncoderFinish(commandEncoder, &command_buffer_desc);
618 wgpuCommandEncoderRelease(commandEncoder);
619 commandEncoder =
nullptr;
620 wgpuQueueSubmit(queue, 1, &command_buffer);
621 wgpuCommandBufferRelease(command_buffer);
622 buffers.resetInstances();
625 context.ClearBindGroups();
627#ifndef __EMSCRIPTEN__
629 wgpuInstanceProcessEvents(instance);
630 wgpuDeviceTick(device);
635 WGPUCommandEncoderDescriptor command_encoder_desc = WGPU_COMMAND_ENCODER_DESCRIPTOR_INIT;
636 command_encoder_desc.label = {
"Default Command Encoder", WGPU_STRLEN};
637 commandEncoder = wgpuDeviceCreateCommandEncoder(device, &command_encoder_desc);
638 context.setDefaults();
643 context.updateRenderPass();
644 context.endRenderPassInt();
646#ifndef __EMSCRIPTEN__
647 WGPUTexelCopyTextureInfo src = WGPU_TEXEL_COPY_TEXTURE_INFO_INIT;
648 src.texture = defaultSwapChain.resolveTexture;
650 src.origin = {0, 0, 0};
651 src.aspect = WGPUTextureAspect_All;
652 WGPUTexelCopyTextureInfo dst = WGPU_TEXEL_COPY_TEXTURE_INFO_INIT;
653 WGPUSurfaceTexture surfaceTexture = context.graphicsDevice->defaultSwapChain.getTextureData();
654 dst.texture = surfaceTexture.texture;
656 dst.origin = {0, 0, 0};
657 dst.aspect = WGPUTextureAspect_All;
658 WGPUExtent3D copy_size = {(uint32_t)defaultSwapChain.set_width, (uint32_t)defaultSwapChain.set_height, 1};
659 wgpuCommandEncoderCopyTextureToTexture(commandEncoder, &src, &dst, ©_size);
660 wgpuTextureRelease(surfaceTexture.texture);
663 WGPUCommandBufferDescriptor command_buffer_desc = WGPU_COMMAND_BUFFER_DESCRIPTOR_INIT;
664 command_buffer_desc.label = {
"Default Command Buffer", WGPU_STRLEN};
665 WGPUCommandBuffer command_buffer = wgpuCommandEncoderFinish(commandEncoder, &command_buffer_desc);
666 wgpuCommandEncoderRelease(commandEncoder);
667 commandEncoder =
nullptr;
668 wgpuQueueSubmit(queue, 1, &command_buffer);
669 wgpuCommandBufferRelease(command_buffer);
670 buffers.resetInstances();
674 defaultSwapChain.
endFrame(syncInterval, presentFlags);
676 context.SwapBindGroups();
683 stats.bufferMemoryConsumption = buffers.bufferMemoryConsumption;
684 stats.textureMemoryConsumption = textures.textureMemoryConsumption;
685 stats.bufferCount =
static_cast<uint32_t
>(buffers.buffers.size());
686 stats.vertexArrayObjectCount = 0;
687 stats.inputLayoutCount =
static_cast<uint32_t
>(buffers.inputLayouts.size());
688 stats.textureCount =
static_cast<uint32_t
>(textures.textures.size());
689 stats.samplerStateCount =
static_cast<uint32_t
>(textures.samplerStates.size());
690 stats.effectCount =
static_cast<uint32_t
>(effects.effects.size());
691 stats.blendStateCount = 0;
692 stats.rasterizerStateCount = 0;
693 stats.depthStencilStateCount = 0;
694 stats.rendertargetsCount =
static_cast<uint32_t
>(renderTargets.render_targets.size());
695 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.
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.