1#include "TexturesWebGPU.h"
3#include "FormatsWebGPU.h"
4#include "GraphicsDeviceWebGPU.h"
5#include "Foundation/Logging/Logger.h"
7#include "Foundation/StringView.h"
14 case Cogs::SamplerState::ComparisonFunction::Never:
15 return WGPUCompareFunction_Never;
16 case Cogs::SamplerState::ComparisonFunction::Less:
17 return WGPUCompareFunction_Less;
18 case Cogs::SamplerState::ComparisonFunction::Equal:
19 return WGPUCompareFunction_Equal;
20 case Cogs::SamplerState::ComparisonFunction::LessEqual:
21 return WGPUCompareFunction_LessEqual;
22 case Cogs::SamplerState::ComparisonFunction::Greater:
23 return WGPUCompareFunction_Greater;
24 case Cogs::SamplerState::ComparisonFunction::NotEqual:
25 return WGPUCompareFunction_NotEqual;
26 case Cogs::SamplerState::ComparisonFunction::GreaterEqual:
27 return WGPUCompareFunction_GreaterEqual;
28 case Cogs::SamplerState::ComparisonFunction::Always:
29 return WGPUCompareFunction_Always;
30 case Cogs::SamplerState::ComparisonFunction::ComparisonFunction_Size:
34 return WGPUCompareFunction_Undefined;
41 return WGPUAddressMode_ClampToEdge;
43 return WGPUAddressMode_Repeat;
45 return WGPUAddressMode_MirrorRepeat;
48 return WGPUAddressMode_ClampToEdge;
49 case Cogs::SamplerState::AddressMode::AddressMode_Size:
53 return WGPUAddressMode_Repeat;
59 void TexturesWebGPU::initialize(
class GraphicsDeviceWebGPU *device)
61 graphicsDevice = device;
67 wgpuTextureSetLabel(texture.texture, name.
data());
72 WGPUDevice device = graphicsDevice->device;
76 WGPUTextureFormat format = TextureFormatsWebGPU[(size_t)td.format];
77 WGPUTextureFormat view_formats[] = {format};
80 WGPUTextureDescriptor desc = {};
81 desc.usage = WGPUTextureUsage_CopyDst | WGPUTextureUsage_TextureBinding;
82 desc.usage |= WGPUTextureUsage_CopySrc;
85 desc.usage = WGPUTextureUsage_RenderAttachment | WGPUTextureUsage_TextureBinding;
88 desc.usage |= WGPUTextureUsage_StorageBinding;
90 if(td.target == ResourceDimensions::Texture1D ||
91 td.target == ResourceDimensions::Texture1DArray){
92 desc.dimension = WGPUTextureDimension_1D;
94 else if(td.target == ResourceDimensions::Texture3D ||
95 td.target == ResourceDimensions::Texture3DArray){
96 desc.dimension = WGPUTextureDimension_3D;
99 desc.dimension = WGPUTextureDimension_2D;
102 desc.size = {td.width, td.height, td.depth*td.faces*td.layers };
103 desc.format = format;
104 desc.mipLevelCount = td.levels;
105 desc.sampleCount = td.samples;
106 desc.viewFormatCount =
sizeof(view_formats)/
sizeof(view_formats[0]);
107 desc.viewFormats = view_formats;
110 wgpuDeviceValidateTextureDescriptor(device, &desc);
112 texture.texture = wgpuDeviceCreateTexture(device, &desc);
115 texture.view_format = desc.format;
116 if(td.target == ResourceDimensions::Texture1D ||
117 td.target == ResourceDimensions::Texture1DArray){
118 texture.view_dimension = WGPUTextureViewDimension_1D;
120 else if(td.target == ResourceDimensions::Texture2D ||
121 td.target == ResourceDimensions::Texture2DMS){
122 texture.view_dimension = WGPUTextureViewDimension_2D;
124 else if(td.target == ResourceDimensions::Texture2DArray ||
125 td.target == ResourceDimensions::Texture2DMSArray){
126 texture.view_dimension = WGPUTextureViewDimension_2DArray;
128 else if(td.target == ResourceDimensions::Texture3D ||
129 td.target == ResourceDimensions::Texture3DArray){
130 texture.view_dimension = WGPUTextureViewDimension_3D;
132 else if(td.target == ResourceDimensions::TextureCube){
133 texture.view_dimension = WGPUTextureViewDimension_Cube;
135 else if(td.target == ResourceDimensions::TextureCubeArray){
136 texture.view_dimension = WGPUTextureViewDimension_CubeArray;
141 WGPUTextureViewDescriptor view_desc = {};
142 view_desc.label =
"DefaultTextureView";
143 view_desc.format = texture.view_format;
144 view_desc.dimension = texture.view_dimension;
145 view_desc.baseMipLevel = 0;
146 view_desc.mipLevelCount = td.levels;
147 view_desc.baseArrayLayer = 0;
148 view_desc.arrayLayerCount = td.faces*td.layers;
149 view_desc.aspect = WGPUTextureAspect_All;
150 texture.texture_view = wgpuTextureCreateView(texture.texture, &view_desc);
152 texture.width = td.width;
153 texture.height = td.height;
154 texture.samples = td.samples;
158 for (
size_t f = 0; f < std::min(
size_t(td.faces), data->faces); ++f) {
159 for (
size_t a = 0; a < std::min(
size_t(td.layers), data->layers); ++a) {
160 for (
size_t j = 0; j < std::min(
size_t(td.levels), data->levels); ++j) {
162 const void *ptr = data->getData(a, f, j);
163 const size_t ptr_size = data->getLevelSize(j);
165 if ((extent.width % data->blockExtent.width) != 0) {
166 extent.width = (extent.width / data->blockExtent.width + 1) * data->blockExtent.width;
168 if ((extent.height % data->blockExtent.height) != 0) {
169 extent.height = (extent.height / data->blockExtent.height + 1) * data->blockExtent.height;
172 WGPUImageCopyTexture dst = {};
173 dst.texture = texture.texture;
174 dst.mipLevel = (uint32_t)j;
175 dst.origin = {0, 0, (uint32_t)(a+f)};
176 dst.aspect = WGPUTextureAspect_All;
178 WGPUTextureDataLayout layout = {};
180 layout.bytesPerRow = (uint32_t)data->getPitch(j);
181 layout.rowsPerImage = extent.height;
182 WGPUExtent3D size = {extent.width, extent.height, extent.depth};
183 wgpuQueueWriteTexture(graphicsDevice->queue, &dst, ptr, ptr_size, &layout, &size);
189 return textures.addResource(std::move(texture));
194 if(!HandleIsValid(handle))
return;
197 wgpuTextureDestroy(texture.texture);
198 wgpuTextureRelease(texture.texture);
200 textures.removeResource(handle);
209 WGPUTextureViewDescriptor desc = {};
210 desc.format = texture.view_format;
211 desc.dimension = texture.view_dimension;
213 switch(desc.dimension){
214 case WGPUTextureViewDimension_2DArray:
215 desc.dimension = WGPUTextureViewDimension_2D;
217 case WGPUTextureViewDimension_CubeArray:
218 desc.dimension = WGPUTextureViewDimension_Cube;
228 desc.aspect = WGPUTextureAspect_All;
229 texture_view.texture_view = wgpuTextureCreateView(texture.texture, &desc);
231 return textureViews.addResource(std::move(texture_view));
236 if(!HandleIsValid(handle))
return;
239 wgpuTextureViewRelease(texture_view.texture_view);
241 textureViews.removeResource(handle);
246 WGPUDevice device = graphicsDevice->device;
250 WGPUSamplerDescriptor desc = {};
255 case SamplerState::FilterMode::MinMagMipPoint:
256 desc.magFilter = WGPUFilterMode_Nearest;
257 desc.minFilter = WGPUFilterMode_Nearest;
258 desc.mipmapFilter = WGPUMipmapFilterMode_Nearest;
259 desc.compare = WGPUCompareFunction_Undefined;
261 case SamplerState::FilterMode::MinMagMipLinear:
262 desc.magFilter = WGPUFilterMode_Linear;
263 desc.minFilter = WGPUFilterMode_Linear;
264 desc.mipmapFilter = WGPUMipmapFilterMode_Linear;
265 desc.compare = WGPUCompareFunction_Undefined;
267 case SamplerState::FilterMode::ComparisonMinMagMipPoint:
268 desc.magFilter = WGPUFilterMode_Nearest;
269 desc.minFilter = WGPUFilterMode_Nearest;
270 desc.mipmapFilter = WGPUMipmapFilterMode_Nearest;
273 case SamplerState::FilterMode::ComparisonMinMagMipLinear:
274 desc.magFilter = WGPUFilterMode_Linear;
275 desc.minFilter = WGPUFilterMode_Linear;
276 desc.mipmapFilter = WGPUMipmapFilterMode_Linear;
283 desc.lodMinClamp = 0;
284 desc.lodMaxClamp = 32;
286 desc.maxAnisotropy = 1;
289 if ((desc.minFilter == WGPUFilterMode_Nearest || desc.magFilter == WGPUFilterMode_Nearest) && desc.maxAnisotropy > 1) {
290 LOG_WARNING(logger,
"Sampler with nearest filter must set maxAnisotropy = 1");
291 desc.maxAnisotropy = 1;
293 sampler.sampler = wgpuDeviceCreateSampler(device, &desc);
295 return samplerStates.addResource(std::move(sampler));
300 if(!HandleIsValid(handle))
return;
303 wgpuSamplerRelease(sampler.sampler);
305 samplerStates.removeResource(handle);
313 void TexturesWebGPU::releaseResources()
Log implementation class.
Provides a weakly referenced view over the contents of a string.
constexpr const char * data() const noexcept
Get the sequence of characters referenced by the string view.
virtual void annotate(TextureHandle handle, const StringView &name) override
Associate a name with an object for use in graphics debugging.
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
Contains all Cogs related functionality.
Encapsulates state for texture sampling in a state object.
ComparisonFunction comparisonFunction
Specifies the comparison function to use when applying a comparison sampler.
unsigned int maxAnisotropy
Specifies the maximum number of anisotropic samples to use when sampling a texture.
AddressMode addressModeW
Specifies the addressing mode along the W axis in texture coordinate space.
ComparisonFunction
Comparison functions applied when sampling depth buffers using comparison filters.
AddressMode addressModeS
Specifies the addressing mode along the S axis in texture coordinate space.
AddressMode
Addressing modes to use when sampling textures.
@ Clamp
Texture coordinates are clamped to the [0, 1] range.
@ Border
Texture color is set to the border color when outside [0, 1] range.
@ Wrap
Texture coordinates automatically wrap around to [0, 1] range.
@ Mirror
Texture coordinates are mirrored when outside [0, 1] range.
FilterMode filter
Specifies the filter to use for texture sampling.
AddressMode addressModeT
Specifies the addressing mode along the T axis in texture coordinate space.
@ DepthBuffer
The texture can be used as a depth target and have depth buffer values written into.
@ RenderTarget
The texture can be used as a render target and drawn into.
@ ReadWriteTexture
The texture can be used as a read/write texture. Can be used to output data from compute shaders.
Describes how to fetch data from a texture in shaders.
uint32_t layerIndex
Index of the first layer (if array) to fetch from.
uint32_t numLayers
Number of array layers available.
uint32_t numLevels
Number of mipmap levels available.
uint32_t levelIndex
First mipmap level to fetch data from.
TextureHandle texture
Texture.