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 ds.freeTextureHandle = true;
136 return ret;
137 }
138
140 {
141 DepthStencilViewDescription view_desc = {};
142 view_desc.texture = textureHandle;
143 view_desc.layerIndex = 0;
144 view_desc.numLayers = 1;
145 view_desc.levelIndex = 0;
146 return createDepthStencilTarget(handle, view_desc);
147 }
148
150 {
151 DepthStencilTargetWebGPU depth_stencil_target;
152
153 if(graphicsDevice->use_error_scope){
154 wgpuDevicePushErrorScope(graphicsDevice->device, graphicsDevice->filter);
155 }
156
157 {
158 ResourceCountersWebGPU &counters = graphicsDevice->counters;
159 const DepthStencilViewDescription &set = depthStencilView;
160 const TextureWebGPU &texture = graphicsDevice->textures.textures[set.texture];
161
162 WGPUTextureViewDescriptor desc = WGPU_TEXTURE_VIEW_DESCRIPTOR_INIT;
163 desc.format = texture.view_format;
164 desc.dimension = texture.view_dimension;
165 if(set.numLayers == 1){
166 switch(desc.dimension){
167 case WGPUTextureViewDimension_2DArray:
168 case WGPUTextureViewDimension_CubeArray:
169 case WGPUTextureViewDimension_Cube:
170 desc.dimension = WGPUTextureViewDimension_2D;
171 break;
172 default:
173 break;
174 }
175 }
176 desc.baseMipLevel = set.levelIndex;
177 desc.mipLevelCount = 1;
178 desc.baseArrayLayer = set.layerIndex;
179 desc.arrayLayerCount = set.numLayers;
180 desc.aspect = WGPUTextureAspect_All;
181 depth_stencil_target.view = wgpuTextureCreateView(texture.texture, &desc);
182 counters.texture_view++;
183 depth_stencil_target.format = texture.view_format;
184 depth_stencil_target.samples = texture.samples;
185 }
186
187 if(graphicsDevice->use_error_scope){
188 WGPUPopErrorScopeCallbackInfo info = WGPU_POP_ERROR_SCOPE_CALLBACK_INFO_INIT;
189 info.mode = WGPUCallbackMode_AllowSpontaneous;
190 info.callback = render_targets_error_callback;
191 info.userdata1 = this;
192 info.userdata2 = graphicsDevice;
193 WGPUFuture future = wgpuDevicePopErrorScope(graphicsDevice->device, info);
194 // WGPUWaitStatus wgpuInstanceWaitAny(WGPUInstance instance, size_t futureCount, WGPUFutureWaitInfo * futures, uint64_t timeoutNS);
195 }
196
197 return depth_stencil_targets.addResource(std::move(depth_stencil_target));
198 }
199
201 {
202 if(!HandleIsValid(handle)) return;
203 ResourceCountersWebGPU &counters = graphicsDevice->counters;
204 DepthStencilTargetWebGPU &target = depth_stencil_targets[handle];
205 wgpuTextureViewRelease(target.view);
206 counters.texture_view--;
207 if(target.freeTextureHandle){
208 graphicsDevice->textures.releaseTexture(target.textureHandle);
209 }
210 depth_stencil_targets.removeResource(handle);
211 }
212
214 {
215 {
216 std::vector<RenderTargetHandle> handles;
217 for (auto& resource : render_targets) {
218 handles.push_back(render_targets.getHandle(resource));
219 }
220 for (auto& handle : handles) {
221 releaseRenderTarget(handle);
222 }
223 }
224 {
225 std::vector<DepthStencilHandle> handles;
226 for (auto& resource : depth_stencil_targets) {
227 handles.push_back(depth_stencil_targets.getHandle(resource));
228 }
229 for (auto& handle : handles) {
231 }
232 }
233 }
234
235}
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 releaseResources() override
Release all allocated render target resources.
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 void releaseTexture(TextureHandle textureHandle) override
Release the texture with the given textureHandle.
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