diff options
Diffstat (limited to 'src/gpu')
| -rw-r--r-- | src/gpu/gpu.cc | 8 | ||||
| -rw-r--r-- | src/gpu/gpu.h | 10 | ||||
| -rw-r--r-- | src/gpu/texture_manager.cc | 107 | ||||
| -rw-r--r-- | src/gpu/texture_manager.h | 48 |
4 files changed, 165 insertions, 8 deletions
diff --git a/src/gpu/gpu.cc b/src/gpu/gpu.cc index a097efa..3cdf9aa 100644 --- a/src/gpu/gpu.cc +++ b/src/gpu/gpu.cc @@ -131,14 +131,6 @@ RenderPass gpu_create_render_pass(WGPUDevice device, WGPUTextureFormat format, color_target.blend = nullptr; // Add additive blending for particles - WGPUBlendState blend = {}; - blend.color.srcFactor = WGPUBlendFactor_SrcAlpha; - blend.color.dstFactor = WGPUBlendFactor_One; - blend.color.operation = WGPUBlendOperation_Add; - blend.alpha.srcFactor = WGPUBlendFactor_SrcAlpha; - blend.alpha.dstFactor = WGPUBlendFactor_One; - blend.alpha.operation = WGPUBlendOperation_Add; - color_target.blend = &blend; WGPUFragmentState fragment_state = {}; fragment_state.module = shader_module; diff --git a/src/gpu/gpu.h b/src/gpu/gpu.h index 8814cbc..b71e144 100644 --- a/src/gpu/gpu.h +++ b/src/gpu/gpu.h @@ -110,6 +110,16 @@ struct ResourceBinding { // WGPUBufferBindingType_Storage }; +// Cross-platform helper for color attachment initialization +inline void gpu_init_color_attachment(WGPURenderPassColorAttachment& attachment, WGPUTextureView view) { + attachment.view = view; + attachment.loadOp = WGPULoadOp_Clear; + attachment.storeOp = WGPUStoreOp_Store; +#if !defined(DEMO_CROSS_COMPILE_WIN32) + attachment.depthSlice = WGPU_DEPTH_SLICE_UNDEFINED; +#endif +} + GpuBuffer gpu_create_buffer(WGPUDevice device, size_t size, uint32_t usage, const void* data = nullptr); ComputePass gpu_create_compute_pass(WGPUDevice device, const char* shader_code, diff --git a/src/gpu/texture_manager.cc b/src/gpu/texture_manager.cc new file mode 100644 index 0000000..7c314d2 --- /dev/null +++ b/src/gpu/texture_manager.cc @@ -0,0 +1,107 @@ +// This file is part of the 64k demo project. +// It implements the TextureManager. + +#include "gpu/texture_manager.h" +#include <iostream> +#include <vector> + +#if defined(DEMO_CROSS_COMPILE_WIN32) +// Old API +#define WGPU_TEX_COPY_INFO WGPUImageCopyTexture +#define WGPU_TEX_DATA_LAYOUT WGPUTextureDataLayout +#else +// New API +#define WGPU_TEX_COPY_INFO WGPUTexelCopyTextureInfo +#define WGPU_TEX_DATA_LAYOUT WGPUTexelCopyBufferLayout +#endif + +void TextureManager::init(WGPUDevice device, WGPUQueue queue) { + device_ = device; + queue_ = queue; +} + +void TextureManager::shutdown() { + for (auto& pair : textures_) { + wgpuTextureViewRelease(pair.second.view); + wgpuTextureRelease(pair.second.texture); + } + textures_.clear(); +} + +void TextureManager::create_procedural_texture( + const std::string& name, const ProceduralTextureDef& def) { + // 1. Generate Data on CPU + std::vector<uint8_t> pixel_data; + pixel_data.resize(def.width * def.height * 4); + def.gen_func(pixel_data.data(), def.width, def.height, def.params.data(), + (int)def.params.size()); + + WGPUExtent3D tex_size = {(uint32_t)def.width, (uint32_t)def.height, 1}; + + // 2. Create GPU Texture + WGPUTextureDescriptor tex_desc = {}; + tex_desc.usage = + WGPUTextureUsage_TextureBinding | WGPUTextureUsage_CopyDst; + tex_desc.dimension = WGPUTextureDimension_2D; + tex_desc.size = tex_size; + tex_desc.format = WGPUTextureFormat_RGBA8Unorm; + tex_desc.mipLevelCount = 1; + tex_desc.sampleCount = 1; +#if defined(DEMO_CROSS_COMPILE_WIN32) + tex_desc.label = nullptr; +#else + tex_desc.label = {nullptr, 0}; +#endif + + WGPUTexture texture = wgpuDeviceCreateTexture(device_, &tex_desc); + + // 3. Upload Data + WGPU_TEX_COPY_INFO destination = {}; + destination.texture = texture; + destination.mipLevel = 0; + destination.origin = {0, 0, 0}; + destination.aspect = WGPUTextureAspect_All; + + WGPU_TEX_DATA_LAYOUT source_layout = {}; + source_layout.offset = 0; + source_layout.bytesPerRow = def.width * 4; + source_layout.rowsPerImage = def.height; + + wgpuQueueWriteTexture(queue_, &destination, pixel_data.data(), + pixel_data.size(), &source_layout, &tex_size); + + + // 4. Create View + WGPUTextureViewDescriptor view_desc = {}; + view_desc.format = WGPUTextureFormat_RGBA8Unorm; + view_desc.dimension = WGPUTextureViewDimension_2D; + view_desc.baseMipLevel = 0; + view_desc.mipLevelCount = 1; + view_desc.baseArrayLayer = 0; + view_desc.arrayLayerCount = 1; + view_desc.aspect = WGPUTextureAspect_All; + + WGPUTextureView view = wgpuTextureCreateView(texture, &view_desc); + + // 5. Store + GpuTexture gpu_tex; + gpu_tex.texture = texture; + gpu_tex.view = view; + gpu_tex.width = def.width; + gpu_tex.height = def.height; + + textures_[name] = gpu_tex; + +#if !defined(STRIP_ALL) + std::cout << "Generated procedural texture: " << name << " (" << def.width + << "x" << def.height << ")" << std::endl; +#endif +} + +WGPUTextureView TextureManager::get_texture_view(const std::string& name) { + auto it = textures_.find(name); + if (it != textures_.end()) { + return it->second.view; + } + return nullptr; +} diff --git a/src/gpu/texture_manager.h b/src/gpu/texture_manager.h new file mode 100644 index 0000000..3faf74c --- /dev/null +++ b/src/gpu/texture_manager.h @@ -0,0 +1,48 @@ +// This file is part of the 64k demo project. +// It defines the TextureManager for procedural assets. +// Handles generation and GPU upload of procedural textures. + +#pragma once + +#include "gpu/gpu.h" +#include <map> +#include <string> +#include <vector> + +#if defined(DEMO_CROSS_COMPILE_WIN32) +#include <webgpu/webgpu.h> +#else +#include <webgpu.h> +#endif + +struct ProceduralTextureDef { + int width; + int height; + void (*gen_func)(uint8_t*, int, int, const float*, int); + std::vector<float> params; +}; + +struct GpuTexture { + WGPUTexture texture; + WGPUTextureView view; + int width; + int height; +}; + +class TextureManager { + public: + void init(WGPUDevice device, WGPUQueue queue); + void shutdown(); + + // Registers and generates a texture immediately + void create_procedural_texture(const std::string& name, + const ProceduralTextureDef& def); + + // Retrieves a texture view by name (returns nullptr if not found) + WGPUTextureView get_texture_view(const std::string& name); + + private: + WGPUDevice device_; + WGPUQueue queue_; + std::map<std::string, GpuTexture> textures_; +}; |
