Cogs.Core
RenderTargetsWebGPU.cpp
1#include "RenderTargetsWebGPU.h"
2
3#include "GraphicsDeviceWebGPU.h"
4#include "Foundation/Logging/Logger.h"
5
6#include <cassert>
7
8namespace{
9 Cogs::Logging::Log logger = Cogs::Logging::getLogger("RenderTargetsWebGPU");
10
11 void render_targets_error_callback(WGPUPopErrorScopeStatus status, WGPUErrorType type, WGPUStringView message, void* userdata1, void* userdata2)
12 {
13 Cogs::RenderTargetsWebGPU *render_targets = (Cogs::RenderTargetsWebGPU*)userdata1;
14 (void)render_targets;
16 (void)ptr;
17 if(status == WGPUPopErrorScopeStatus_CallbackCancelled){
18 LOG_ERROR(logger, "WebGPU render targets err status: Cancelled");
19 }
20 if(status == WGPUPopErrorScopeStatus_Error){
21 LOG_ERROR(logger, "WebGPU render targets err status: Error");
22 }
23 if(message.data && message.length){
24 LOG_ERROR(logger, "WebGPU render targets err (%d) %.*s", type, WGPUStringViewFormat(message));
25 }
26 }
27}
28
29namespace Cogs{
30
31 void RenderTargetsWebGPU::initialize(GraphicsDeviceWebGPU *graphicsDeviceIn)
32 {
33 graphicsDevice = graphicsDeviceIn;
34 }
35
37 {
38 ResourceCountersWebGPU &counters = graphicsDevice->counters;
39 RenderTargetWebGPU render_target = {};
40
41 if(graphicsDevice->use_error_scope){
42 wgpuDevicePushErrorScope(graphicsDevice->device, graphicsDevice->filter);
43 }
44
45 for(size_t i=0; i<numViews; i++){
46 const RenderTargetViewDescription &set = renderTargetViews[i];
47 assert(HandleIsValid(set.texture));
48 const TextureWebGPU &texture = graphicsDevice->textures.textures[set.texture];
49
50 WGPUTextureViewDescriptor desc = WGPU_TEXTURE_VIEW_DESCRIPTOR_INIT;
51 desc.format = texture.view_format;
52 desc.dimension = texture.view_dimension;
53 if(set.numLayers == 1){
54 switch(desc.dimension){
55 case WGPUTextureViewDimension_2DArray:
56 case WGPUTextureViewDimension_Cube:
57 case WGPUTextureViewDimension_CubeArray:
58 desc.dimension = WGPUTextureViewDimension_2D;
59 break;
60 default:
61 break;
62 }
63 }
64 desc.baseMipLevel = set.levelIndex;
65 desc.mipLevelCount = 1;
66 desc.baseArrayLayer = set.layerIndex;
67 desc.arrayLayerCount = set.numLayers;
68 desc.aspect = WGPUTextureAspect_All;
69 render_target.view[i] = wgpuTextureCreateView(texture.texture, &desc);
70 counters.texture_view++;
71 render_target.textureHandle[i] = set.texture;
72 render_target.format[i] = texture.view_format;
73 }
74 render_target.count = (uint32_t)numViews;
75
76 if(numViews){
77 const RenderTargetViewDescription &set = renderTargetViews[0];
78 const TextureWebGPU &texture = graphicsDevice->textures.textures[set.texture];
79 render_target.width = texture.width;
80 render_target.height = texture.height;
81 render_target.samples = texture.samples;
82 }
83
84 if(graphicsDevice->use_error_scope){
85 WGPUPopErrorScopeCallbackInfo info = WGPU_POP_ERROR_SCOPE_CALLBACK_INFO_INIT;
86 info.mode = WGPUCallbackMode_AllowSpontaneous;
87 info.callback = render_targets_error_callback;
88 info.userdata1 = this;
89 info.userdata2 = graphicsDevice;
90 WGPUFuture future = wgpuDevicePopErrorScope(graphicsDevice->device, info);
91 // WGPUWaitStatus wgpuInstanceWaitAny(WGPUInstance instance, size_t futureCount, WGPUFutureWaitInfo * futures, uint64_t timeoutNS);
92 }
93
94 return render_targets.addResource(std::move(render_target));
95 }
96
98 {
99 if(!HandleIsValid(handle)) return;
100 ResourceCountersWebGPU &counters = graphicsDevice->counters;
101 RenderTargetWebGPU &target = render_targets[handle];
102 for(size_t i=0; i<target.count; i++){
103 wgpuTextureViewRelease(target.view[i]);
104 counters.texture_view--;
105 }
106 render_targets.removeResource(handle);
107 }
108
110 {
111 RenderTargetWebGPU &target = render_targets[handle];
112 assert(target.width);
113 assert(target.height);
114 assert(target.samples);
115 TextureDescription tex_desc = {};
116 tex_desc.target = ResourceDimensions::Texture2D;
117 tex_desc.width = target.width;
118 tex_desc.height = target.height;
119 tex_desc.depth = 1;
120 tex_desc.layers = 1;
121 tex_desc.faces = 1;
122 tex_desc.levels = 1;
123 tex_desc.samples = target.samples;
124 tex_desc.format = TextureFormat::D32_FLOAT;
125 tex_desc.flags = TextureFlags::DepthBuffer;
126 TextureHandle textureHandle = graphicsDevice->textures.loadTexture(tex_desc, nullptr);
127 DepthStencilViewDescription view_desc = {};
128 view_desc.texture = textureHandle;
129 view_desc.layerIndex = 0;
130 view_desc.numLayers = 1;
131 view_desc.levelIndex = 0;
132 DepthStencilHandle ret = createDepthStencilTarget(handle, view_desc);
133 DepthStencilTargetWebGPU &ds = depth_stencil_targets[ret];
134 ds.textureHandle = textureHandle;
135 return ret;
136 }
137
139 {
140 DepthStencilViewDescription view_desc = {};
141 view_desc.texture = textureHandle;
142 view_desc.layerIndex = 0;
143 view_desc.numLayers = 1;
144 view_desc.levelIndex = 0;
145 return createDepthStencilTarget(handle, view_desc);
146 }
147
149 {
150 DepthStencilTargetWebGPU depth_stencil_target;
151
152 if(graphicsDevice->use_error_scope){
153 wgpuDevicePushErrorScope(graphicsDevice->device, graphicsDevice->filter);
154 }
155
156 {
157 ResourceCountersWebGPU &counters = graphicsDevice->counters;
158 const DepthStencilViewDescription &set = depthStencilView;
159 const TextureWebGPU &texture = graphicsDevice->textures.textures[set.texture];
160
161 WGPUTextureViewDescriptor desc = WGPU_TEXTURE_VIEW_DESCRIPTOR_INIT;
162 desc.format = texture.view_format;
163 desc.dimension = texture.view_dimension;
164 if(set.numLayers == 1){
165 switch(desc.dimension){
166 case WGPUTextureViewDimension_2DArray:
167 case WGPUTextureViewDimension_CubeArray:
168 case WGPUTextureViewDimension_Cube:
169 desc.dimension = WGPUTextureViewDimension_2D;
170 break;
171 default:
172 break;
173 }
174 }
175 desc.baseMipLevel = set.levelIndex;
176 desc.mipLevelCount = 1;
177 desc.baseArrayLayer = set.layerIndex;
178 desc.arrayLayerCount = set.numLayers;
179 desc.aspect = WGPUTextureAspect_All;
180 depth_stencil_target.view = wgpuTextureCreateView(texture.texture, &desc);
181 counters.texture_view++;
182 depth_stencil_target.format = texture.view_format;
183 depth_stencil_target.samples = texture.samples;
184 }
185
186 if(graphicsDevice->use_error_scope){
187 WGPUPopErrorScopeCallbackInfo info = WGPU_POP_ERROR_SCOPE_CALLBACK_INFO_INIT;
188 info.mode = WGPUCallbackMode_AllowSpontaneous;
189 info.callback = render_targets_error_callback;
190 info.userdata1 = this;
191 info.userdata2 = graphicsDevice;
192 WGPUFuture future = wgpuDevicePopErrorScope(graphicsDevice->device, info);
193 // WGPUWaitStatus wgpuInstanceWaitAny(WGPUInstance instance, size_t futureCount, WGPUFutureWaitInfo * futures, uint64_t timeoutNS);
194 }
195
196 return depth_stencil_targets.addResource(std::move(depth_stencil_target));
197 }
198
200 {
201 if(!HandleIsValid(handle)) return;
202 ResourceCountersWebGPU &counters = graphicsDevice->counters;
203 DepthStencilTargetWebGPU &target = depth_stencil_targets[handle];
204 wgpuTextureViewRelease(target.view);
205 counters.texture_view--;
206 depth_stencil_targets.removeResource(handle);
207 }
208
209}
Log implementation class.
Definition: LogManager.h:140
virtual void releaseRenderTarget(RenderTargetHandle handle) override
Release the render target with the given renderTargetHandle.
virtual DepthStencilHandle createDepthStencilTarget(const RenderTargetHandle handle) override
Creates a depth/stencil target to back the render target with the given handle.
virtual void releaseDepthStencilTarget(DepthStencilHandle handle) override
Release the depth target with the given depthStencilHandle.
virtual RenderTargetHandle createRenderTarget(const RenderTargetViewDescription *renderTargetViews, const size_t numViews) override
Create a render target using the given view descriptions.
virtual TextureHandle loadTexture(const TextureDescription &desc, const TextureData *data) override
Load a texture from the given description.
constexpr Log getLogger(const char(&name)[LEN]) noexcept
Definition: LogManager.h:181
Contains all Cogs related functionality.
Definition: FieldSetter.h:23
Describes a single depth stencil view and which resources to use from the underlying texture.
TextureHandle texture
Texture handle.
uint16_t numLayers
Number of available layers to write to.
uint8_t levelIndex
Index of the mipmap level to render to.
uint16_t layerIndex
Index of the first layer (if array) to write depth to.
Describes a single render target view and which resources to use from the underlying texture.
uint16_t layerIndex
Index of the first layer (if array) to render to.
uint16_t numLayers
Number of available layers to render to.
TextureHandle texture
Texture handle.
uint8_t levelIndex
Index of the mipmap level to render to.
@ DepthBuffer
The texture can be used as a depth target and have depth buffer values written into.
Definition: Flags.h:122