1#include "ContextWebGPU.h"
3#include "GraphicsDeviceWebGPU.h"
4#include "PipelineStatesWebGPU.h"
5#include "Foundation/Logging/Logger.h"
10 WGPULoadOp ConvWebGPULoadOp(Cogs::LoadOp load_op)
13 case Cogs::LoadOp::Undefined:
return WGPULoadOp_Undefined;
14 case Cogs::LoadOp::Clear:
return WGPULoadOp_Clear;
15 case Cogs::LoadOp::Load:
return WGPULoadOp_Load;
17 return WGPULoadOp_Undefined;
19 WGPUStoreOp ConvWebGPUStoreOp(Cogs::StoreOp store_op)
22 case Cogs::StoreOp::Undefined:
return WGPUStoreOp_Undefined;
23 case Cogs::StoreOp::Store:
return WGPUStoreOp_Store;
24 case Cogs::StoreOp::Discard:
return WGPUStoreOp_Discard;
26 return WGPUStoreOp_Undefined;
32 void ContextWebGPU::initialize(GraphicsDeviceWebGPU *graphicsDeviceIn)
34 graphicsDevice = graphicsDeviceIn;
37 void ContextWebGPU::frameStatisticsConfigure(
bool )
49 assert(!inRenderPass);
50 for(
size_t i=0; i<
sizeof(clearColor)/
sizeof(clearColor[0]); i++){
51 clearColor[i].r = value[0];
52 clearColor[i].g = value[1];
53 clearColor[i].b = value[2];
54 clearColor[i].a = value[3];
56 do_clear_render_target =
true;
57 update_render_target =
true;
62 assert(!inRenderPass);
63 for(
int i=0; i<numvalues; i++){
64 clearColor[i].r = values[i][0];
65 clearColor[i].g = values[i][1];
66 clearColor[i].b = values[i][2];
67 clearColor[i].a = values[i][3];
69 for(
size_t i=numvalues; i<
sizeof(clearColor)/
sizeof(clearColor[0]); i++){
72 do_clear_render_target =
true;
73 update_render_target =
true;
78 assert(!inRenderPass);
79 clearDepthVal = depth;
80 do_clear_depth =
true;
81 update_render_target =
true;
86 assert(renderPassEncoder == 0);
87 assert(computePassEncoder == 0);
88 assert(!inRenderPass);
90 update_render_target =
false;
92 renderTargetHandle = info.renderTargetHandle;
93 depthStencilHandle = info.depthStencilHandle;
95 WGPURenderPassColorAttachment color_attachment[8] = {};
96 WGPURenderPassDepthStencilAttachment ds_attachment = {};
97 uint32_t color_attachment_count = 0;
98 uint32_t ds_attachment_count = 0;
100 const char *name =
nullptr;
101 if (HandleIsValid(info.renderTargetHandle) || HandleIsValid(info.depthStencilHandle)) {
102 name =
"Custom Render Pass";
103 if(HandleIsValid(info.renderTargetHandle)){
104 RenderTargetWebGPU &target = graphicsDevice->renderTargets.render_targets[info.renderTargetHandle];
105 for(
size_t i=0; i<target.count; i++){
106 WGPURenderPassColorAttachment &att = color_attachment[i];
107 att.view = target.view[i];
109 att.depthSlice = WGPU_DEPTH_SLICE_UNDEFINED;
111 if(info.resolveHandle[i]){
112 att.resolveTarget = graphicsDevice->textures.textureViews[info.resolveHandle[i]].texture_view;
115 att.resolveTarget =
nullptr;
117 att.loadOp = ConvWebGPULoadOp(info.loadOp[i]);
118 att.storeOp = ConvWebGPUStoreOp(info.storeOp[i]);
119 att.clearValue.r = info.clearValue[i][0];
120 att.clearValue.g = info.clearValue[i][1];
121 att.clearValue.b = info.clearValue[i][2];
122 att.clearValue.a = info.clearValue[i][3];
124 color_attachment_count = target.count;
126 if(HandleIsValid(info.depthStencilHandle)){
128 WGPURenderPassDepthStencilAttachment &att = ds_attachment;
129 att.view = target.view;
130 att.depthLoadOp = ConvWebGPULoadOp(info.depthLoadOp);
131 att.depthStoreOp = ConvWebGPUStoreOp(info.depthStoreOp);
132 att.depthClearValue = info.depthClearValue;
133 att.depthReadOnly = info.depthReadOnly;
134 att.stencilLoadOp = WGPULoadOp_Undefined;
135 att.stencilStoreOp = WGPUStoreOp_Undefined;
136 att.stencilClearValue = 0;
137 att.stencilReadOnly =
false;
138 ds_attachment_count = 1;
142 name =
"Default Render Pass";
144 if(defaultSwapChain.samples > 1){
145 color_attachment[0].view = defaultSwapChain.colorBufferView;
146 color_attachment[0].resolveTarget = defaultSwapChain.resolveView;
149 color_attachment[0].view = defaultSwapChain.resolveView;
152 color_attachment[0].depthSlice = WGPU_DEPTH_SLICE_UNDEFINED;
154 color_attachment[0].loadOp = ConvWebGPULoadOp(info.loadOp[0]);
155 color_attachment[0].storeOp = ConvWebGPUStoreOp(info.storeOp[0]);
156 color_attachment[0].clearValue.r = info.clearValue[0][0];
157 color_attachment[0].clearValue.g = info.clearValue[0][1];
158 color_attachment[0].clearValue.b = info.clearValue[0][2];
159 color_attachment[0].clearValue.a = info.clearValue[0][3];
160 color_attachment_count = 1;
162 ds_attachment.view = defaultSwapChain.depthBufferView;
163 ds_attachment.depthLoadOp = ConvWebGPULoadOp(info.depthLoadOp);
164 ds_attachment.depthStoreOp = ConvWebGPUStoreOp(info.depthStoreOp);
165 ds_attachment.depthClearValue = info.depthClearValue;
166 ds_attachment.depthReadOnly = info.depthReadOnly;
167 ds_attachment.stencilLoadOp = WGPULoadOp_Undefined;
168 ds_attachment.stencilStoreOp = WGPUStoreOp_Undefined;
169 ds_attachment.stencilClearValue = 0;
170 ds_attachment.stencilReadOnly =
false;
171 ds_attachment_count = 1;
174 WGPURenderPassDescriptor render_pass_desc = {};
175 render_pass_desc.label = name;
176 if(color_attachment_count){
177 render_pass_desc.colorAttachmentCount = color_attachment_count;
178 render_pass_desc.colorAttachments = color_attachment;
180 if(ds_attachment_count){
181 render_pass_desc.depthStencilAttachment = &ds_attachment;
183 render_pass_desc.occlusionQuerySet =
nullptr;
185 render_pass_desc.timestampWrites =
nullptr;
186 renderPassEncoder = wgpuCommandEncoderBeginRenderPass(graphicsDevice->commandEncoder, &render_pass_desc);
190 assert(renderPassEncoder);
191 assert(inRenderPass);
192 inRenderPass =
false;
193 wgpuRenderPassEncoderEnd(renderPassEncoder);
194 renderPassEncoder = 0;
195 update_render_target =
true;
200 if(HandleIsValid(rt_handle))
201 renderTargetHandle = rt_handle;
203 renderTargetHandle = {};
204 if(HandleIsValid(ds_handle))
205 depthStencilHandle = ds_handle;
207 depthStencilHandle = {};
208 rasterizeStateHandle = {};
209 blendStateHandle = {};
210 assert(do_clear_render_target ==
false);
211 assert(do_clear_depth ==
false);
212 do_clear_render_target =
false;
213 do_clear_depth =
false;
214 update_render_target =
true;
220 float minDepth = 0.0f;
221 float maxDepth = 1.0f;
222 wgpuRenderPassEncoderSetViewport(renderPassEncoder, x, y, width, height, minDepth, maxDepth);
230 int xx = glm::clamp(x, 0, w);
231 int yy = glm::clamp(y, 0, h);
232 int ww = glm::clamp(width, 0, w-xx);
233 int hh = glm::clamp(height, 0, h-yy);
234 wgpuRenderPassEncoderSetScissorRect(renderPassEncoder, xx, yy, ww, hh);
239 if(HandleIsValid(handle))
240 depthStencilStateHandle = handle;
242 depthStencilStateHandle = {};
248 if(HandleIsValid(handle))
249 blendStateHandle = handle;
251 blendStateHandle = {};
254 color.r = constants[0];
255 color.g = constants[1];
256 color.b = constants[2];
257 color.a = constants[3];
265 wgpuRenderPassEncoderSetBlendConstant(renderPassEncoder, &color);
270 if(HandleIsValid(handle))
271 rasterizeStateHandle = handle;
273 rasterizeStateHandle = {};
276 void ContextWebGPU::setDefaults() {
277 rasterizeStateHandle = {};
278 depthStencilStateHandle = {};
279 blendStateHandle = {};
284 if(HandleIsValid(handle))
288 inputLayoutHandle = {};
290 update_descriptors =
true;
314 setTexture(getEffects()->getTextureBinding(getCurrentEffect(), name, unit), textureHandle);
321 if (!HandleIsValid(handle)) {
322 descriptors.erase((uint32_t)binding.
handle);
325 TextureWebGPU texture = graphicsDevice->textures.textures[handle];
326 WGPUBindGroupEntry bg_ent = {};
327 bg_ent.binding = (uint32_t)binding.
handle;
328 bg_ent.buffer =
nullptr;
331 bg_ent.sampler =
nullptr;
332 bg_ent.textureView = texture.texture_view;
333 descriptors[bg_ent.binding] = bg_ent;
334 update_descriptors =
true;
339 setTexture(getEffects()->getTextureBinding(getCurrentEffect(), name, 1), textureViewHandle);
346 if (!HandleIsValid(handle)) {
347 descriptors.erase((uint32_t)binding.handle);
350 TextureViewWebGPU texture_view = graphicsDevice->textures.textureViews[handle];
351 WGPUBindGroupEntry bg_ent = {};
352 bg_ent.binding = (uint32_t)binding.handle;
353 bg_ent.buffer =
nullptr;
356 bg_ent.sampler =
nullptr;
357 bg_ent.textureView = texture_view.texture_view;
358 descriptors[bg_ent.binding] = bg_ent;
359 update_descriptors =
true;
364 setSamplerState(getEffects()->getSamplerStateBinding(getCurrentEffect(), name, unit), handle);
371 if (!HandleIsValid(handle)) {
372 descriptors.erase((uint32_t)binding.
handle);
375 if (!HandleIsValid(binding)) {
379 WGPUBindGroupEntry bg_ent = {};
380 bg_ent.binding = (uint32_t)binding.
handle;
381 bg_ent.buffer =
nullptr;
384 bg_ent.sampler = sampler.sampler;
385 bg_ent.textureView =
nullptr;
386 descriptors[bg_ent.binding] = bg_ent;
393 update_descriptors =
true;
398 if(HandleIsValid(handle))
399 inputLayoutHandle = handle;
401 inputLayoutHandle = {};
407 for(
size_t i=0; i<count; i++){
409 uint32_t slot = (uint32_t)i;
411 uint32_t offset = offsets ? offsets[i] : 0;
412 wgpuRenderPassEncoderSetVertexBuffer(renderPassEncoder, slot, buffer.buffer, offset, buffer.size-offset);
427 WGPUIndexFormat format = (stride == 2) ? WGPUIndexFormat_Uint16 : WGPUIndexFormat_Uint32;
428 uint64_t offset = offset_in;
430 wgpuRenderPassEncoderSetIndexBuffer(renderPassEncoder, buffer.buffer, format, offset, buffer.size);
440 setConstantBuffer(getEffects()->getConstantBufferBinding(getCurrentEffect(), name), bufferHandle, offset, size);
447 if (!HandleIsValid(handle)) {
448 descriptors.erase((uint32_t)binding.
handle);
451 if (!HandleIsValid(binding)) {
455 BufferWebGPU &buffer = graphicsDevice->buffers.buffers[handle];
456 WGPUBindGroupEntry bg_ent = {};
457 bg_ent.binding = (uint32_t)binding.
handle;
458 bg_ent.buffer = buffer.buffer;
459 bg_ent.offset = offset;
460 bg_ent.size = (size == ~0u) ? WGPU_WHOLE_SIZE : size;
461 bg_ent.sampler =
nullptr;
462 bg_ent.textureView =
nullptr;
463 descriptors[bg_ent.binding] = bg_ent;
464 update_descriptors =
true;
497 if (updateRenderPipeline(primitiveType)) {
498 drawInstanced(primitiveType, startVertex, numVertexes, 0, 1);
505 if (updateRenderPipeline(primitiveType)) {
506 wgpuRenderPassEncoderDrawIndexed(renderPassEncoder, (uint32_t)numIndexes, 1, (uint32_t)startIndex, (int32_t)startVertex, 0);
513 if (updateRenderPipeline(primitiveType)) {
514 wgpuRenderPassEncoderDraw(renderPassEncoder, (uint32_t)numVertexes, (uint32_t)numInstances, (uint32_t)startVertex, (uint32_t)startInstance);
521 if (updateRenderPipeline(primitiveType)) {
522 wgpuRenderPassEncoderDrawIndexed(renderPassEncoder, (uint32_t)numIndexes, (uint32_t)numInstances, (uint32_t)startIndex, 0, (uint32_t)startInstance);
526 void ContextWebGPU::beginRenderPassInt()
528 assert(renderPassEncoder == 0);
529 assert(computePassEncoder == 0);
530 WGPURenderPassColorAttachment color_attachment[8] = {};
531 WGPURenderPassDepthStencilAttachment ds_attachment = {};
532 uint32_t color_attachment_count = 0;
533 uint32_t ds_attachment_count = 0;
535 WGPULoadOp loadOp = do_clear_render_target ? WGPULoadOp_Clear : WGPULoadOp_Load;
536 do_clear_render_target =
false;
537 WGPULoadOp depthLoadOp = do_clear_depth ? WGPULoadOp_Clear : WGPULoadOp_Load;
538 do_clear_depth =
false;
539 const char *name =
nullptr;
541 name =
"Custom Render Pass";
543 RenderTargetWebGPU &target = graphicsDevice->renderTargets.render_targets[renderTargetHandle];
544 for(
size_t i=0; i<target.count; i++){
545 WGPURenderPassColorAttachment &att = color_attachment[i];
546 att.view = target.view[i];
548 att.depthSlice = WGPU_DEPTH_SLICE_UNDEFINED;
550 att.resolveTarget =
nullptr;
552 att.storeOp = WGPUStoreOp_Store;
553 att.clearValue = clearColor[i];
555 color_attachment_count = target.count;
558 DepthStencilTargetWebGPU &target = graphicsDevice->renderTargets.depth_stencil_targets[depthStencilHandle];
559 WGPURenderPassDepthStencilAttachment &att = ds_attachment;
560 att.view = target.view;
561 att.depthLoadOp = depthLoadOp;
562 att.depthStoreOp = WGPUStoreOp_Store;
563 att.depthClearValue = clearDepthVal;
564 att.depthReadOnly =
false;
565 att.stencilLoadOp = WGPULoadOp_Undefined;
566 att.stencilStoreOp = WGPUStoreOp_Undefined;
567 att.stencilClearValue = 0;
568 att.stencilReadOnly =
false;
569 ds_attachment_count = 1;
573 name =
"Default Render Pass";
574 SwapChainWebGPU &defaultSwapChain = graphicsDevice->defaultSwapChain;
575 if(defaultSwapChain.samples > 1){
576 color_attachment[0].view = defaultSwapChain.colorBufferView;
577 color_attachment[0].resolveTarget = defaultSwapChain.resolveView;
580 color_attachment[0].view = defaultSwapChain.resolveView;
583 color_attachment[0].depthSlice = WGPU_DEPTH_SLICE_UNDEFINED;
585 color_attachment[0].loadOp = loadOp;
586 color_attachment[0].storeOp = WGPUStoreOp_Store;
587 color_attachment[0].clearValue = clearColor[0];
588 color_attachment_count = 1;
590 ds_attachment.view = defaultSwapChain.depthBufferView;
591 ds_attachment.depthLoadOp = depthLoadOp;
592 ds_attachment.depthStoreOp = WGPUStoreOp_Store;
593 ds_attachment.depthClearValue = clearDepthVal;
594 ds_attachment.depthReadOnly =
false;
595 ds_attachment.stencilLoadOp = WGPULoadOp_Undefined;
596 ds_attachment.stencilStoreOp = WGPUStoreOp_Undefined;
597 ds_attachment.stencilClearValue = 0;
598 ds_attachment.stencilReadOnly =
false;
599 ds_attachment_count = 1;
602 WGPURenderPassDescriptor render_pass_desc = {};
603 render_pass_desc.label = name;
604 if(color_attachment_count){
605 render_pass_desc.colorAttachmentCount = color_attachment_count;
606 render_pass_desc.colorAttachments = color_attachment;
608 if(ds_attachment_count){
609 render_pass_desc.depthStencilAttachment = &ds_attachment;
611 render_pass_desc.occlusionQuerySet =
nullptr;
613 render_pass_desc.timestampWrites =
nullptr;
614 renderPassEncoder = wgpuCommandEncoderBeginRenderPass(graphicsDevice->commandEncoder, &render_pass_desc);
617 void ContextWebGPU::endRenderPassInt()
619 assert(!inRenderPass);
620 if(!renderPassEncoder)
return;
621 wgpuRenderPassEncoderEnd(renderPassEncoder);
622 renderPassEncoder = 0;
623 update_render_target =
true;
626 void ContextWebGPU::updateRenderPass()
628 if(update_render_target){
631 beginRenderPassInt();
632 update_render_target =
false;
638 assert(renderPassEncoder);
639 PipelineStatesWebGPU &pipeline_states = graphicsDevice->pipeline_states;
642 RenderPipelineWebGPU pipelineState = pipeline_states.renderPipeline[currentRenderPipeline];
643 if(pipelineState.effect != effect) reload =
true;
644 if(pipelineState.inputLayoutHandle != inputLayoutHandle) reload =
true;
645 if(pipelineState.primitiveType != primitiveType) reload =
true;
646 if(pipelineState.rasterizeStateHandle != rasterizeStateHandle) reload =
true;
647 if(pipelineState.depthStencilStateHandle != depthStencilStateHandle) reload =
true;
648 if(pipelineState.blendStateHandle != blendStateHandle) reload =
true;
649 if(pipelineState.renderTargetHandle != renderTargetHandle) reload =
true;
650 if(pipelineState.depthStencilHandle != depthStencilHandle) reload =
true;
656 RenderPipelineHandle pipelineStateHandle = pipeline_states.loadRenderPipeline
661 rasterizeStateHandle,
662 depthStencilStateHandle,
667 RenderPipelineWebGPU pipelineState = pipeline_states.renderPipeline[pipelineStateHandle];
668 currentRenderPipeline = pipelineStateHandle;
671 RenderPipelineWebGPU &pipelineState = pipeline_states.renderPipeline[currentRenderPipeline];
672 wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelineState.pipeline);
674 if(update_descriptors){
675 RenderPipelineWebGPU &pipelineState = pipeline_states.renderPipeline[currentRenderPipeline];
677 std::vector<WGPUBindGroupEntry> entries;
678 entries.resize(descriptors.size());
680 for(
auto &tmp : descriptors){
681 entries[i++] = tmp.second;
685 auto bindings = getEffects()->getConstantBufferBindings(effect, num_bindings);
687 for (
size_t ii = 0; ii < num_bindings; ii++) {
689 for (
size_t j = 0; j < entries.size(); j++) {
690 if (bindings[ii].bg_ent.binding == entries[j].binding) {
695 LOG_ERROR_ONCE(logger,
"binding %d in layout but not set", bindings[ii].bg_ent.binding);
700 WGPUBindGroupDescriptor bg_desc = {};
702 bg_desc.layout = pipelineState.layout;
703 bg_desc.entryCount = (uint32_t)entries.size();
704 bg_desc.entries = entries.data();
705 current_bind_group = wgpuDeviceCreateBindGroup(graphicsDevice->device, &bg_desc);
707 if(current_bind_group){
708 uint32_t groupIndex = 0;
709 wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, groupIndex, current_bind_group, 0,
nullptr);
717 updateComputePipeline();
718 wgpuComputePassEncoderDispatchWorkgroups(computePassEncoder, threadGroupsX, threadGroupsY, threadGroupsZ);
721 void ContextWebGPU::beginComputePass()
723 assert(renderPassEncoder == 0);
724 assert(computePassEncoder == 0);
725 WGPUComputePassDescriptor compute_pass_desc = {};
726 compute_pass_desc.label =
"Compute Pass";
728 compute_pass_desc.timestampWrites =
nullptr;
729 computePassEncoder = wgpuCommandEncoderBeginComputePass(graphicsDevice->commandEncoder, &compute_pass_desc);
732 void ContextWebGPU::endComputePass()
734 if(!computePassEncoder)
return;
735 wgpuComputePassEncoderEnd(computePassEncoder);
736 computePassEncoder = 0;
739 void ContextWebGPU::updateComputePass()
741 if(!computePassEncoder){
745 update_render_target =
true;
749 void ContextWebGPU::updateComputePipeline()
751 assert(computePassEncoder);
752 PipelineStatesWebGPU &pipeline_states = graphicsDevice->pipeline_states;
755 ComputePipelineWebGPU pipelineState = pipeline_states.computePipeline[currentComputePipeline];
756 if(pipelineState.effect != effect) reload =
true;
762 ComputePipelineHandle pipelineStateHandle = pipeline_states.loadComputePipeline(effect);
763 ComputePipelineWebGPU pipelineState = pipeline_states.computePipeline[pipelineStateHandle];
764 currentComputePipeline = pipelineStateHandle;
767 ComputePipelineWebGPU &pipelineState = pipeline_states.computePipeline[currentComputePipeline];
768 wgpuComputePassEncoderSetPipeline(computePassEncoder, pipelineState.pipeline);
770 if(update_descriptors){
771 ComputePipelineWebGPU &pipelineState = pipeline_states.computePipeline[currentComputePipeline];
773 std::vector<WGPUBindGroupEntry> entries;
774 entries.resize(descriptors.size());
776 for(
auto &tmp : descriptors){
777 entries[i++] = tmp.second;
780 WGPUBindGroupDescriptor bg_desc = {};
782 bg_desc.layout = pipelineState.layout;
783 bg_desc.entryCount = (uint32_t)entries.size();
784 bg_desc.entries = entries.data();
785 current_bind_group = wgpuDeviceCreateBindGroup(graphicsDevice->device, &bg_desc);
787 if(current_bind_group){
788 uint32_t groupIndex = 0;
789 wgpuComputePassEncoderSetBindGroup(computePassEncoder, groupIndex, current_bind_group, 0,
nullptr);
795 const WGPUCommandEncoder &commandEncoder = graphicsDevice->commandEncoder;
797 BufferWebGPU buffer = graphicsDevice->buffers.buffers[bufferHandle];
801 WGPUImageCopyTexture src = {};
802 if (HandleIsValid(renderTargetHandle) || HandleIsValid(depthStencilHandle)) {
803 if(!HandleIsValid(depthStencilHandle))
return;
805 TextureWebGPU &src_tex = textures.textures[target.textureHandle];
806 src.texture = src_tex.texture;
810 src.texture = defaultSwapChain.depthBufferTexture;
813 src.origin = {(uint32_t)x, (uint32_t)y, 0};
814 src.aspect = WGPUTextureAspect_DepthOnly;
815 WGPUImageCopyBuffer dst = {};
816 dst.layout.offset = 0;
817 dst.layout.bytesPerRow = (uint32_t)buffer.size;
818 dst.layout.rowsPerImage = 1;
819 dst.buffer = buffer.buffer;
820 WGPUExtent3D size = {};
822 size.height = height;
823 size.depthOrArrayLayers = 1;
824 wgpuCommandEncoderCopyTextureToBuffer(commandEncoder, &src, &dst, &size);
829 const WGPUCommandEncoder &commandEncoder = graphicsDevice->commandEncoder;
831 BufferWebGPU buffer = graphicsDevice->buffers.buffers[bufferHandle];
835 WGPUImageCopyTexture src = {};
836 if (HandleIsValid(renderTargetHandle) || HandleIsValid(depthStencilHandle)) {
837 if(!HandleIsValid(renderTargetHandle))
return;
838 RenderTargetWebGPU target = graphicsDevice->renderTargets.render_targets[renderTargetHandle];
839 TextureWebGPU &src_tex = textures.textures[target.textureHandle[0]];
840 src.texture = src_tex.texture;
846 src.texture = defaultSwapChain.colorBufferTexture;
848 src.texture = defaultSwapChain.resolveTexture;
852 src.origin = {(uint32_t)x, (uint32_t)y, 0};
853 src.aspect = WGPUTextureAspect_All;
854 WGPUImageCopyBuffer dst = {};
855 dst.layout.offset = 0;
856 dst.layout.bytesPerRow = (uint32_t)buffer.size;
857 dst.layout.rowsPerImage = 1;
858 dst.buffer = buffer.buffer;
859 WGPUExtent3D size = {};
861 size.height = height;
862 size.depthOrArrayLayers = 1;
863 wgpuCommandEncoderCopyTextureToBuffer(commandEncoder, &src, &dst, &size);
868 assert(stride ==
nullptr || stride[0] == 0);
869 BufferWebGPU &buffer = graphicsDevice->buffers.buffers[handle];
870 if(buffer.is_read_buffer){
871 assert(mapMode == MapMode::Read);
873 WGPUBufferMapCallback callback =
nullptr;
874 void * userdata =
nullptr;
875 wgpuBufferMapAsync(buffer.buffer, WGPUMapMode_Read, offset, buffer.size, callback, userdata);
877 WGPUBufferMapState state = wgpuBufferGetMapState(buffer.buffer);
878 while(state != WGPUBufferMapState_Mapped){
880 assert(state == WGPUBufferMapState_Pending);
881 wgpuInstanceProcessEvents(graphicsDevice->instance);
882 wgpuDeviceTick(graphicsDevice->device);
883 state = wgpuBufferGetMapState(buffer.buffer);
889 return (
void*)wgpuBufferGetConstMappedRange(buffer.buffer, 0, buffer.size);
892 assert(mapMode == MapMode::WriteDiscard);
893 buffer.NextInstance(graphicsDevice);
894 buffer.map =
new char[buffer.size];
907 BufferWebGPU &buffer = graphicsDevice->buffers.buffers[handle];
908 if(buffer.is_read_buffer){
911 wgpuBufferUnmap(buffer.buffer);
916 wgpuQueueWriteBuffer(graphicsDevice->queue, buffer.buffer, 0, buffer.map, buffer.size);
917 delete [] (
char*)buffer.map;
918 buffer.map =
nullptr;
927 void ContextWebGPU::updateBuffer(
BufferHandle handle,
const void* data,
const size_t size)
929 BufferWebGPU &buffer = graphicsDevice->buffers.buffers[handle];
930 buffer.NextInstance(graphicsDevice);
931 wgpuQueueWriteBuffer(graphicsDevice->queue, buffer.buffer, 0, data, size);
934 void ContextWebGPU::updateSubTexture(
TextureHandle ,
const size_t ,
const void* )
939 void ContextWebGPU::updateSubBuffer(
BufferHandle handle,
const size_t offset,
const size_t size,
const void* data)
941 BufferWebGPU &buffer = graphicsDevice->buffers.buffers[handle];
942 assert(buffer.alias_idx == 0);
944 wgpuQueueWriteBuffer(graphicsDevice->queue, buffer.buffer, offset, data, size);
957 void ContextWebGPU::copyResource(TextureHandle , TextureHandle )
962 void ContextWebGPU::copyTexture(TextureHandle dstHandle,
unsigned dstSub,
unsigned dstX,
unsigned dstY,
unsigned dstZ, TextureHandle srcHandle,
unsigned srcSub)
964 const WGPUCommandEncoder &commandEncoder = graphicsDevice->commandEncoder;
965 TexturesWebGPU &textures = graphicsDevice->textures;
967 TextureWebGPU &src = textures.textures[srcHandle];
968 TextureWebGPU &dst = textures.textures[dstHandle];
970 uint32_t srcLevel = 0;
971 uint32_t srcLayer = srcSub;
973 WGPUImageCopyTexture copy_src = {};
974 copy_src.texture = src.texture;
975 copy_src.mipLevel = srcLevel;
976 copy_src.origin = {0, 0, srcLayer};
977 copy_src.aspect = WGPUTextureAspect_All;
979 uint32_t dstLevel = 0;
980 uint32_t dstLayer = dstSub;
982 WGPUImageCopyTexture copy_dst = {};
983 copy_dst.texture = dst.texture;
984 copy_dst.mipLevel = dstLevel;
985 copy_dst.origin = {dstX, dstY, dstZ+dstLayer};
986 copy_dst.aspect = WGPUTextureAspect_All;
988 WGPUExtent3D size = {};
989 size.width = src.width;
990 size.height = src.height;
991 size.depthOrArrayLayers = 1;
992 wgpuCommandEncoderCopyTextureToTexture(commandEncoder, ©_src, ©_dst, &size);
995 void ContextWebGPU::clearResource(BufferHandle , uint32_t* )
1000 void ContextWebGPU::clearResource(BufferHandle ,
float* )
1005 EffectHandle ContextWebGPU::getCurrentEffect()
1010 EffectsWebGPU *ContextWebGPU::getEffects()
1012 return &graphicsDevice->effects;
virtual void setMatrixVariable(const StringView &, const float *) override
Sets the matrix variable with the given name in the current effect to value.
virtual void setSamplerState(const StringView &, unsigned int, SamplerStateHandle) override
Sets the sampler slot given by unit with the given name to contain the given sampler state.
virtual void getBufferCounter(BufferHandle, BufferHandle) override
Get the associated counter of a buffer.
virtual void setScalarVariable(const StringView &, const float) override
Sets the scalar floating point variable with the given name to the given value.
virtual void setVector2Variable(const StringView &, const float *) override
Sets the vector variable with the given name to the given two-component value.
virtual void setEffect(EffectHandle) override
Set the current effect.
virtual void setVector4Variable(const StringView &, const float *) override
Sets the vector variable with the given name to the given four-component value.
virtual void clearDepth(const float=1.0f) override
Clear the currently set depth/stencil target to the given depth.
virtual void setBlendState(const BlendStateHandle, const float *) override
Set the current blend state.
virtual void draw(PrimitiveType::EPrimitiveType, const size_t, const size_t) override
Draws non-indexed, non-instanced primitives.
virtual void setVertexBuffers(const VertexBufferHandle *, const size_t, const uint32_t *, const uint32_t *) override
Sets the current vertex buffers.
virtual void setBuffer(const StringView &, BufferHandle) override
Sets the given buffer to the buffer binding slot with the given name.
virtual void setVariable(const EffectVariableHandle, const uint8_t *, size_t) override
Sets the variable with the given name and size.
virtual void dispatchCompute(const unsigned int, const unsigned int, const unsigned int) override
Dispatch computing work on the graphics device using the desired thread group count.
virtual void drawIndexed(PrimitiveType::EPrimitiveType, const size_t, const size_t, const size_t=0) override
Draws indexed, non-instanced primitives.
virtual void setConstantBuffer(const StringView &, const BufferHandle, const uint32_t=0, const uint32_t=~0u) override
Sets a constant buffer to be bound to the given name and slot.
virtual void setBufferCounter(BufferHandle, uint32_t) override
Set the associated counter of a buffer.
virtual void setDepthStencilState(const DepthStencilStateHandle) override
Set the current depth stencil state.
virtual void setScissor(const int, const int, const int, const int) override
Sets the current scissor rectangle.
virtual void setRasterizerState(const RasterizerStateHandle) override
Set the current rasterizer state.
virtual void drawInstanced(PrimitiveType::EPrimitiveType, const size_t, const size_t, const size_t, const size_t) override
Draws non-indexed, instanced primitives.
virtual void endRenderPass() override
End a render pass.
virtual void beginRenderPass(const RenderPassInfo &info) override
Begin a render pass.
virtual void setVector3Variable(const StringView &, const float *) override
Sets the vector variable with the given name to the given three-component value.
virtual void setVertexArrayObject(VertexArrayObjectHandle) override
Sets vertexBuffers and index buffers using a prevalidated vertex array object.
virtual void signal(FenceHandle) override
Insert a fence in the command stream that will signal when all commands before the fence are complete...
virtual void setIndexBuffer(IndexBufferHandle, uint32_t=4, uint32_t=0) override
Sets the current index buffer.
virtual void clearRenderTarget(const float *) override
Clear the currently set render target to the given value (4 component floating point RGBA).
virtual void setTexture(const StringView &, unsigned int, TextureHandle) override
Sets the texture slot given by unit with the given name to contain the given texture.
virtual void setInputLayout(const InputLayoutHandle) override
Sets the current input layout.
virtual void setRenderTarget(const RenderTargetHandle handle, const DepthStencilHandle depthStencilHandle) override
Sets the current render target and an associated depth stencil target.
virtual void setViewport(const float, const float, const float, const float) override
Sets the current viewport to the given location and dimensions.
virtual void drawInstancedIndexed(PrimitiveType::EPrimitiveType, const size_t, const size_t, const size_t, const size_t) override
Draws indexed, instanced primitives.
virtual void readDepthBuffer(BufferHandle, int, int, int, int, Framebuffer::EFrameBuffer) override
Reads data from the current depth target into the given bufferHandle.
void releaseBufferBinding(BufferBindingHandle) override
Release a handle to a buffer binding.
BufferBindingHandle getBufferBinding(EffectHandle effectHandle, const StringView &name) override
Get a handle to a buffer binding.
virtual bool getSize(int &w, int &h) const override
Retrieve the size previously set by setSize.
Log implementation class.
Provides a weakly referenced view over the contents of a string.
bool HandleIsValid(const ResourceHandle_t< T > &handle)
Check if the given resource is valid, that is not equal to NoHandle or InvalidHandle.
constexpr Log getLogger(const char(&name)[LEN]) noexcept
Contains all Cogs related functionality.
Handle template class used to provide opaque, non-converting handles.
static const Handle_t NoHandle
Represents a handle to nothing.
handle_type handle
Internal resource handle.
EMapMode
Mapping mode enumeration.
EPrimitiveType
Primitive type enumeration.