summaryrefslogtreecommitdiff
path: root/src/gpu/texture_manager.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/gpu/texture_manager.cc')
-rw-r--r--src/gpu/texture_manager.cc487
1 files changed, 130 insertions, 357 deletions
diff --git a/src/gpu/texture_manager.cc b/src/gpu/texture_manager.cc
index 9a19957..2b83f63 100644
--- a/src/gpu/texture_manager.cc
+++ b/src/gpu/texture_manager.cc
@@ -21,9 +21,6 @@
void TextureManager::init(WGPUDevice device, WGPUQueue queue) {
device_ = device;
queue_ = queue;
- noise_compute_pipeline_ = nullptr;
- perlin_compute_pipeline_ = nullptr;
- grid_compute_pipeline_ = nullptr;
}
void TextureManager::shutdown() {
@@ -32,18 +29,13 @@ void TextureManager::shutdown() {
wgpuTextureRelease(pair.second.texture);
}
textures_.clear();
- if (noise_compute_pipeline_) {
- wgpuComputePipelineRelease(noise_compute_pipeline_);
- noise_compute_pipeline_ = nullptr;
- }
- if (perlin_compute_pipeline_) {
- wgpuComputePipelineRelease(perlin_compute_pipeline_);
- perlin_compute_pipeline_ = nullptr;
- }
- if (grid_compute_pipeline_) {
- wgpuComputePipelineRelease(grid_compute_pipeline_);
- grid_compute_pipeline_ = nullptr;
+
+ for (auto& pair : compute_pipelines_) {
+ if (pair.second.pipeline) {
+ wgpuComputePipelineRelease(pair.second.pipeline);
+ }
}
+ compute_pipelines_.clear();
}
void TextureManager::create_procedural_texture(
@@ -131,78 +123,90 @@ WGPUTextureView TextureManager::get_texture_view(const std::string& name) {
return nullptr;
}
-void TextureManager::dispatch_noise_compute(WGPUTexture target,
- const GpuProceduralParams& params) {
- // Lazy-init compute pipeline
- if (!noise_compute_pipeline_) {
- extern const char* gen_noise_compute_wgsl;
+WGPUComputePipeline TextureManager::get_or_create_compute_pipeline(
+ const std::string& func_name, const char* shader_code,
+ size_t uniform_size) {
+ auto it = compute_pipelines_.find(func_name);
+ if (it != compute_pipelines_.end()) {
+ return it->second.pipeline;
+ }
+
+ // Create new pipeline
+ ShaderComposer& composer = ShaderComposer::Get();
+ std::string resolved_shader = composer.Compose({}, shader_code);
+
+ WGPUShaderSourceWGSL wgsl_src = {};
+ wgsl_src.chain.sType = WGPUSType_ShaderSourceWGSL;
+ wgsl_src.code = str_view(resolved_shader.c_str());
+ WGPUShaderModuleDescriptor shader_desc = {};
+ shader_desc.nextInChain = &wgsl_src.chain;
+ WGPUShaderModule shader_module =
+ wgpuDeviceCreateShaderModule(device_, &shader_desc);
+
+ // Bind group layout (storage texture + uniform)
+ WGPUBindGroupLayoutEntry bgl_entries[2] = {};
+ bgl_entries[0].binding = 0;
+ bgl_entries[0].visibility = WGPUShaderStage_Compute;
+ bgl_entries[0].storageTexture.access = WGPUStorageTextureAccess_WriteOnly;
+ bgl_entries[0].storageTexture.format = WGPUTextureFormat_RGBA8Unorm;
+ bgl_entries[0].storageTexture.viewDimension = WGPUTextureViewDimension_2D;
- // Resolve #include directives using ShaderComposer
- ShaderComposer& composer = ShaderComposer::Get();
- std::string resolved_shader = composer.Compose({}, gen_noise_compute_wgsl);
+ bgl_entries[1].binding = 1;
+ bgl_entries[1].visibility = WGPUShaderStage_Compute;
+ bgl_entries[1].buffer.type = WGPUBufferBindingType_Uniform;
+ bgl_entries[1].buffer.minBindingSize = uniform_size;
- WGPUShaderSourceWGSL wgsl_src = {};
- wgsl_src.chain.sType = WGPUSType_ShaderSourceWGSL;
- wgsl_src.code = str_view(resolved_shader.c_str());
- WGPUShaderModuleDescriptor shader_desc = {};
- shader_desc.nextInChain = &wgsl_src.chain;
- WGPUShaderModule shader_module =
- wgpuDeviceCreateShaderModule(device_, &shader_desc);
+ WGPUBindGroupLayoutDescriptor bgl_desc = {};
+ bgl_desc.entryCount = 2;
+ bgl_desc.entries = bgl_entries;
+ WGPUBindGroupLayout bind_group_layout =
+ wgpuDeviceCreateBindGroupLayout(device_, &bgl_desc);
- // Bind group layout (storage texture + uniform)
- WGPUBindGroupLayoutEntry bgl_entries[2] = {};
- bgl_entries[0].binding = 0;
- bgl_entries[0].visibility = WGPUShaderStage_Compute;
- bgl_entries[0].storageTexture.access = WGPUStorageTextureAccess_WriteOnly;
- bgl_entries[0].storageTexture.format = WGPUTextureFormat_RGBA8Unorm;
- bgl_entries[0].storageTexture.viewDimension = WGPUTextureViewDimension_2D;
+ WGPUPipelineLayoutDescriptor pl_desc = {};
+ pl_desc.bindGroupLayoutCount = 1;
+ pl_desc.bindGroupLayouts = &bind_group_layout;
+ WGPUPipelineLayout pipeline_layout =
+ wgpuDeviceCreatePipelineLayout(device_, &pl_desc);
- bgl_entries[1].binding = 1;
- bgl_entries[1].visibility = WGPUShaderStage_Compute;
- bgl_entries[1].buffer.type = WGPUBufferBindingType_Uniform;
- bgl_entries[1].buffer.minBindingSize = 16; // sizeof(NoiseParams)
+ WGPUComputePipelineDescriptor pipeline_desc = {};
+ pipeline_desc.layout = pipeline_layout;
+ pipeline_desc.compute.module = shader_module;
+ pipeline_desc.compute.entryPoint = str_view("main");
- WGPUBindGroupLayoutDescriptor bgl_desc = {};
- bgl_desc.entryCount = 2;
- bgl_desc.entries = bgl_entries;
- WGPUBindGroupLayout bind_group_layout =
- wgpuDeviceCreateBindGroupLayout(device_, &bgl_desc);
+ WGPUComputePipeline pipeline =
+ wgpuDeviceCreateComputePipeline(device_, &pipeline_desc);
- WGPUPipelineLayoutDescriptor pl_desc = {};
- pl_desc.bindGroupLayoutCount = 1;
- pl_desc.bindGroupLayouts = &bind_group_layout;
- WGPUPipelineLayout pipeline_layout =
- wgpuDeviceCreatePipelineLayout(device_, &pl_desc);
+ wgpuPipelineLayoutRelease(pipeline_layout);
+ wgpuBindGroupLayoutRelease(bind_group_layout);
+ wgpuShaderModuleRelease(shader_module);
- WGPUComputePipelineDescriptor pipeline_desc = {};
- pipeline_desc.layout = pipeline_layout;
- pipeline_desc.compute.module = shader_module;
- pipeline_desc.compute.entryPoint = str_view("main");
+ // Cache pipeline
+ ComputePipelineInfo info = {pipeline, shader_code, uniform_size};
+ compute_pipelines_[func_name] = info;
- noise_compute_pipeline_ =
- wgpuDeviceCreateComputePipeline(device_, &pipeline_desc);
+ return pipeline;
+}
- wgpuPipelineLayoutRelease(pipeline_layout);
- wgpuBindGroupLayoutRelease(bind_group_layout);
- wgpuShaderModuleRelease(shader_module);
+void TextureManager::dispatch_compute(const std::string& func_name,
+ WGPUTexture target,
+ const GpuProceduralParams& params,
+ const void* uniform_data,
+ size_t uniform_size) {
+ auto it = compute_pipelines_.find(func_name);
+ if (it == compute_pipelines_.end()) {
+ return; // Pipeline not created yet
}
- // Create uniform buffer (width, height, seed, frequency)
- struct NoiseParams {
- uint32_t width;
- uint32_t height;
- float seed;
- float frequency;
- };
- NoiseParams uniform_data = {(uint32_t)params.width, (uint32_t)params.height,
- params.params[0], params.params[1]};
+ WGPUComputePipeline pipeline = it->second.pipeline;
+
+ // Create uniform buffer
WGPUBufferDescriptor buf_desc = {};
- buf_desc.size = sizeof(NoiseParams);
+ buf_desc.size = uniform_size;
buf_desc.usage = WGPUBufferUsage_Uniform | WGPUBufferUsage_CopyDst;
buf_desc.mappedAtCreation = WGPUOptionalBool_True;
WGPUBuffer uniform_buf = wgpuDeviceCreateBuffer(device_, &buf_desc);
- void* mapped = wgpuBufferGetMappedRange(uniform_buf, 0, sizeof(NoiseParams));
- memcpy(mapped, &uniform_data, sizeof(NoiseParams));
+ void* mapped = wgpuBufferGetMappedRange(uniform_buf, 0, uniform_size);
+ memcpy(mapped, uniform_data, uniform_size);
wgpuBufferUnmap(uniform_buf);
// Create storage texture view
@@ -223,7 +227,7 @@ void TextureManager::dispatch_noise_compute(WGPUTexture target,
bgl_entries[1].binding = 1;
bgl_entries[1].visibility = WGPUShaderStage_Compute;
bgl_entries[1].buffer.type = WGPUBufferBindingType_Uniform;
- bgl_entries[1].buffer.minBindingSize = 16;
+ bgl_entries[1].buffer.minBindingSize = uniform_size;
WGPUBindGroupLayoutDescriptor bgl_desc = {};
bgl_desc.entryCount = 2;
@@ -237,7 +241,7 @@ void TextureManager::dispatch_noise_compute(WGPUTexture target,
bg_entries[0].textureView = target_view;
bg_entries[1].binding = 1;
bg_entries[1].buffer = uniform_buf;
- bg_entries[1].size = sizeof(NoiseParams);
+ bg_entries[1].size = uniform_size;
WGPUBindGroupDescriptor bg_desc = {};
bg_desc.layout = bind_group_layout;
@@ -247,9 +251,11 @@ void TextureManager::dispatch_noise_compute(WGPUTexture target,
// Dispatch compute
WGPUCommandEncoderDescriptor enc_desc = {};
- WGPUCommandEncoder encoder = wgpuDeviceCreateCommandEncoder(device_, &enc_desc);
- WGPUComputePassEncoder pass = wgpuCommandEncoderBeginComputePass(encoder, nullptr);
- wgpuComputePassEncoderSetPipeline(pass, noise_compute_pipeline_);
+ WGPUCommandEncoder encoder =
+ wgpuDeviceCreateCommandEncoder(device_, &enc_desc);
+ WGPUComputePassEncoder pass =
+ wgpuCommandEncoderBeginComputePass(encoder, nullptr);
+ wgpuComputePassEncoderSetPipeline(pass, pipeline);
wgpuComputePassEncoderSetBindGroup(pass, 0, bind_group, 0, nullptr);
wgpuComputePassEncoderDispatchWorkgroups(pass, (params.width + 7) / 8,
(params.height + 7) / 8, 1);
@@ -271,7 +277,9 @@ void TextureManager::dispatch_noise_compute(WGPUTexture target,
void TextureManager::create_gpu_noise_texture(
const std::string& name, const GpuProceduralParams& params) {
- // Create storage texture
+ extern const char* gen_noise_compute_wgsl;
+ get_or_create_compute_pipeline("gen_noise", gen_noise_compute_wgsl, 16);
+
WGPUTextureDescriptor tex_desc = {};
tex_desc.usage =
WGPUTextureUsage_StorageBinding | WGPUTextureUsage_TextureBinding;
@@ -282,10 +290,16 @@ void TextureManager::create_gpu_noise_texture(
tex_desc.sampleCount = 1;
WGPUTexture texture = wgpuDeviceCreateTexture(device_, &tex_desc);
- // Generate via compute
- dispatch_noise_compute(texture, params);
+ struct NoiseParams {
+ uint32_t width;
+ uint32_t height;
+ float seed;
+ float frequency;
+ };
+ NoiseParams uniforms = {(uint32_t)params.width, (uint32_t)params.height,
+ params.params[0], params.params[1]};
+ dispatch_compute("gen_noise", texture, params, &uniforms, sizeof(NoiseParams));
- // Create view for sampling
WGPUTextureViewDescriptor view_desc = {};
view_desc.format = WGPUTextureFormat_RGBA8Unorm;
view_desc.dimension = WGPUTextureViewDimension_2D;
@@ -293,7 +307,6 @@ void TextureManager::create_gpu_noise_texture(
view_desc.arrayLayerCount = 1;
WGPUTextureView view = wgpuTextureCreateView(texture, &view_desc);
- // Store texture
GpuTexture gpu_tex;
gpu_tex.texture = texture;
gpu_tex.view = view;
@@ -307,59 +320,21 @@ void TextureManager::create_gpu_noise_texture(
#endif
}
-void TextureManager::dispatch_perlin_compute(WGPUTexture target,
- const GpuProceduralParams& params) {
- // Lazy-init compute pipeline
- if (!perlin_compute_pipeline_) {
- extern const char* gen_perlin_compute_wgsl;
- ShaderComposer& composer = ShaderComposer::Get();
- std::string resolved_shader = composer.Compose({}, gen_perlin_compute_wgsl);
-
- WGPUShaderSourceWGSL wgsl_src = {};
- wgsl_src.chain.sType = WGPUSType_ShaderSourceWGSL;
- wgsl_src.code = str_view(resolved_shader.c_str());
- WGPUShaderModuleDescriptor shader_desc = {};
- shader_desc.nextInChain = &wgsl_src.chain;
- WGPUShaderModule shader_module =
- wgpuDeviceCreateShaderModule(device_, &shader_desc);
-
- WGPUBindGroupLayoutEntry bgl_entries[2] = {};
- bgl_entries[0].binding = 0;
- bgl_entries[0].visibility = WGPUShaderStage_Compute;
- bgl_entries[0].storageTexture.access = WGPUStorageTextureAccess_WriteOnly;
- bgl_entries[0].storageTexture.format = WGPUTextureFormat_RGBA8Unorm;
- bgl_entries[0].storageTexture.viewDimension = WGPUTextureViewDimension_2D;
- bgl_entries[1].binding = 1;
- bgl_entries[1].visibility = WGPUShaderStage_Compute;
- bgl_entries[1].buffer.type = WGPUBufferBindingType_Uniform;
- bgl_entries[1].buffer.minBindingSize = 32; // sizeof(PerlinParams)
-
- WGPUBindGroupLayoutDescriptor bgl_desc = {};
- bgl_desc.entryCount = 2;
- bgl_desc.entries = bgl_entries;
- WGPUBindGroupLayout bind_group_layout =
- wgpuDeviceCreateBindGroupLayout(device_, &bgl_desc);
-
- WGPUPipelineLayoutDescriptor pl_desc = {};
- pl_desc.bindGroupLayoutCount = 1;
- pl_desc.bindGroupLayouts = &bind_group_layout;
- WGPUPipelineLayout pipeline_layout =
- wgpuDeviceCreatePipelineLayout(device_, &pl_desc);
-
- WGPUComputePipelineDescriptor pipeline_desc = {};
- pipeline_desc.layout = pipeline_layout;
- pipeline_desc.compute.module = shader_module;
- pipeline_desc.compute.entryPoint = str_view("main");
-
- perlin_compute_pipeline_ =
- wgpuDeviceCreateComputePipeline(device_, &pipeline_desc);
+void TextureManager::create_gpu_perlin_texture(
+ const std::string& name, const GpuProceduralParams& params) {
+ extern const char* gen_perlin_compute_wgsl;
+ get_or_create_compute_pipeline("gen_perlin", gen_perlin_compute_wgsl, 32);
- wgpuPipelineLayoutRelease(pipeline_layout);
- wgpuBindGroupLayoutRelease(bind_group_layout);
- wgpuShaderModuleRelease(shader_module);
- }
+ WGPUTextureDescriptor tex_desc = {};
+ tex_desc.usage =
+ WGPUTextureUsage_StorageBinding | WGPUTextureUsage_TextureBinding;
+ tex_desc.dimension = WGPUTextureDimension_2D;
+ tex_desc.size = {(uint32_t)params.width, (uint32_t)params.height, 1};
+ tex_desc.format = WGPUTextureFormat_RGBA8Unorm;
+ tex_desc.mipLevelCount = 1;
+ tex_desc.sampleCount = 1;
+ WGPUTexture texture = wgpuDeviceCreateTexture(device_, &tex_desc);
- // Create uniform buffer
struct PerlinParams {
uint32_t width;
uint32_t height;
@@ -370,98 +345,17 @@ void TextureManager::dispatch_perlin_compute(WGPUTexture target,
uint32_t octaves;
float _pad0;
};
- PerlinParams uniform_data = {
+ PerlinParams uniforms = {
(uint32_t)params.width,
(uint32_t)params.height,
- params.params[0], // seed
- params.params[1], // frequency
- params.num_params > 2 ? params.params[2] : 1.0f, // amplitude
- params.num_params > 3 ? params.params[3] : 0.5f, // amplitude_decay
- params.num_params > 4 ? (uint32_t)params.params[4] : 4u, // octaves
- 0.0f // padding
- };
-
- WGPUBufferDescriptor buf_desc = {};
- buf_desc.size = sizeof(PerlinParams);
- buf_desc.usage = WGPUBufferUsage_Uniform | WGPUBufferUsage_CopyDst;
- buf_desc.mappedAtCreation = WGPUOptionalBool_True;
- WGPUBuffer uniform_buf = wgpuDeviceCreateBuffer(device_, &buf_desc);
- void* mapped = wgpuBufferGetMappedRange(uniform_buf, 0, sizeof(PerlinParams));
- memcpy(mapped, &uniform_data, sizeof(PerlinParams));
- wgpuBufferUnmap(uniform_buf);
-
- WGPUTextureViewDescriptor view_desc = {};
- view_desc.format = WGPUTextureFormat_RGBA8Unorm;
- view_desc.dimension = WGPUTextureViewDimension_2D;
- view_desc.mipLevelCount = 1;
- view_desc.arrayLayerCount = 1;
- WGPUTextureView target_view = wgpuTextureCreateView(target, &view_desc);
-
- WGPUBindGroupLayoutEntry bgl_entries[2] = {};
- bgl_entries[0].binding = 0;
- bgl_entries[0].visibility = WGPUShaderStage_Compute;
- bgl_entries[0].storageTexture.access = WGPUStorageTextureAccess_WriteOnly;
- bgl_entries[0].storageTexture.format = WGPUTextureFormat_RGBA8Unorm;
- bgl_entries[0].storageTexture.viewDimension = WGPUTextureViewDimension_2D;
- bgl_entries[1].binding = 1;
- bgl_entries[1].visibility = WGPUShaderStage_Compute;
- bgl_entries[1].buffer.type = WGPUBufferBindingType_Uniform;
- bgl_entries[1].buffer.minBindingSize = 32;
-
- WGPUBindGroupLayoutDescriptor bgl_desc = {};
- bgl_desc.entryCount = 2;
- bgl_desc.entries = bgl_entries;
- WGPUBindGroupLayout bind_group_layout =
- wgpuDeviceCreateBindGroupLayout(device_, &bgl_desc);
-
- WGPUBindGroupEntry bg_entries[2] = {};
- bg_entries[0].binding = 0;
- bg_entries[0].textureView = target_view;
- bg_entries[1].binding = 1;
- bg_entries[1].buffer = uniform_buf;
- bg_entries[1].size = sizeof(PerlinParams);
-
- WGPUBindGroupDescriptor bg_desc = {};
- bg_desc.layout = bind_group_layout;
- bg_desc.entryCount = 2;
- bg_desc.entries = bg_entries;
- WGPUBindGroup bind_group = wgpuDeviceCreateBindGroup(device_, &bg_desc);
-
- WGPUCommandEncoderDescriptor enc_desc = {};
- WGPUCommandEncoder encoder = wgpuDeviceCreateCommandEncoder(device_, &enc_desc);
- WGPUComputePassEncoder pass = wgpuCommandEncoderBeginComputePass(encoder, nullptr);
- wgpuComputePassEncoderSetPipeline(pass, perlin_compute_pipeline_);
- wgpuComputePassEncoderSetBindGroup(pass, 0, bind_group, 0, nullptr);
- wgpuComputePassEncoderDispatchWorkgroups(pass, (params.width + 7) / 8,
- (params.height + 7) / 8, 1);
- wgpuComputePassEncoderEnd(pass);
-
- WGPUCommandBufferDescriptor cmd_desc = {};
- WGPUCommandBuffer cmd = wgpuCommandEncoderFinish(encoder, &cmd_desc);
- wgpuQueueSubmit(queue_, 1, &cmd);
-
- wgpuCommandBufferRelease(cmd);
- wgpuCommandEncoderRelease(encoder);
- wgpuComputePassEncoderRelease(pass);
- wgpuBindGroupRelease(bind_group);
- wgpuBindGroupLayoutRelease(bind_group_layout);
- wgpuBufferRelease(uniform_buf);
- wgpuTextureViewRelease(target_view);
-}
-
-void TextureManager::create_gpu_perlin_texture(
- const std::string& name, const GpuProceduralParams& params) {
- WGPUTextureDescriptor tex_desc = {};
- tex_desc.usage =
- WGPUTextureUsage_StorageBinding | WGPUTextureUsage_TextureBinding;
- tex_desc.dimension = WGPUTextureDimension_2D;
- tex_desc.size = {(uint32_t)params.width, (uint32_t)params.height, 1};
- tex_desc.format = WGPUTextureFormat_RGBA8Unorm;
- tex_desc.mipLevelCount = 1;
- tex_desc.sampleCount = 1;
- WGPUTexture texture = wgpuDeviceCreateTexture(device_, &tex_desc);
-
- dispatch_perlin_compute(texture, params);
+ params.params[0],
+ params.params[1],
+ params.num_params > 2 ? params.params[2] : 1.0f,
+ params.num_params > 3 ? params.params[3] : 0.5f,
+ params.num_params > 4 ? (uint32_t)params.params[4] : 4u,
+ 0.0f};
+ dispatch_compute("gen_perlin", texture, params, &uniforms,
+ sizeof(PerlinParams));
WGPUTextureViewDescriptor view_desc = {};
view_desc.format = WGPUTextureFormat_RGBA8Unorm;
@@ -483,142 +377,11 @@ void TextureManager::create_gpu_perlin_texture(
#endif
}
-void TextureManager::dispatch_grid_compute(WGPUTexture target,
- const GpuProceduralParams& params) {
- // Lazy-init compute pipeline
- if (!grid_compute_pipeline_) {
- extern const char* gen_grid_compute_wgsl;
- ShaderComposer& composer = ShaderComposer::Get();
- std::string resolved_shader = composer.Compose({}, gen_grid_compute_wgsl);
-
- WGPUShaderSourceWGSL wgsl_src = {};
- wgsl_src.chain.sType = WGPUSType_ShaderSourceWGSL;
- wgsl_src.code = str_view(resolved_shader.c_str());
- WGPUShaderModuleDescriptor shader_desc = {};
- shader_desc.nextInChain = &wgsl_src.chain;
- WGPUShaderModule shader_module =
- wgpuDeviceCreateShaderModule(device_, &shader_desc);
-
- WGPUBindGroupLayoutEntry bgl_entries[2] = {};
- bgl_entries[0].binding = 0;
- bgl_entries[0].visibility = WGPUShaderStage_Compute;
- bgl_entries[0].storageTexture.access = WGPUStorageTextureAccess_WriteOnly;
- bgl_entries[0].storageTexture.format = WGPUTextureFormat_RGBA8Unorm;
- bgl_entries[0].storageTexture.viewDimension = WGPUTextureViewDimension_2D;
- bgl_entries[1].binding = 1;
- bgl_entries[1].visibility = WGPUShaderStage_Compute;
- bgl_entries[1].buffer.type = WGPUBufferBindingType_Uniform;
- bgl_entries[1].buffer.minBindingSize = 16; // sizeof(GridParams)
-
- WGPUBindGroupLayoutDescriptor bgl_desc = {};
- bgl_desc.entryCount = 2;
- bgl_desc.entries = bgl_entries;
- WGPUBindGroupLayout bind_group_layout =
- wgpuDeviceCreateBindGroupLayout(device_, &bgl_desc);
-
- WGPUPipelineLayoutDescriptor pl_desc = {};
- pl_desc.bindGroupLayoutCount = 1;
- pl_desc.bindGroupLayouts = &bind_group_layout;
- WGPUPipelineLayout pipeline_layout =
- wgpuDeviceCreatePipelineLayout(device_, &pl_desc);
-
- WGPUComputePipelineDescriptor pipeline_desc = {};
- pipeline_desc.layout = pipeline_layout;
- pipeline_desc.compute.module = shader_module;
- pipeline_desc.compute.entryPoint = str_view("main");
-
- grid_compute_pipeline_ =
- wgpuDeviceCreateComputePipeline(device_, &pipeline_desc);
-
- wgpuPipelineLayoutRelease(pipeline_layout);
- wgpuBindGroupLayoutRelease(bind_group_layout);
- wgpuShaderModuleRelease(shader_module);
- }
-
- // Create uniform buffer
- struct GridParams {
- uint32_t width;
- uint32_t height;
- uint32_t grid_size;
- uint32_t thickness;
- };
- GridParams uniform_data = {
- (uint32_t)params.width,
- (uint32_t)params.height,
- params.num_params > 0 ? (uint32_t)params.params[0] : 32u, // grid_size
- params.num_params > 1 ? (uint32_t)params.params[1] : 2u // thickness
- };
-
- WGPUBufferDescriptor buf_desc = {};
- buf_desc.size = sizeof(GridParams);
- buf_desc.usage = WGPUBufferUsage_Uniform | WGPUBufferUsage_CopyDst;
- buf_desc.mappedAtCreation = WGPUOptionalBool_True;
- WGPUBuffer uniform_buf = wgpuDeviceCreateBuffer(device_, &buf_desc);
- void* mapped = wgpuBufferGetMappedRange(uniform_buf, 0, sizeof(GridParams));
- memcpy(mapped, &uniform_data, sizeof(GridParams));
- wgpuBufferUnmap(uniform_buf);
-
- WGPUTextureViewDescriptor view_desc = {};
- view_desc.format = WGPUTextureFormat_RGBA8Unorm;
- view_desc.dimension = WGPUTextureViewDimension_2D;
- view_desc.mipLevelCount = 1;
- view_desc.arrayLayerCount = 1;
- WGPUTextureView target_view = wgpuTextureCreateView(target, &view_desc);
-
- WGPUBindGroupLayoutEntry bgl_entries[2] = {};
- bgl_entries[0].binding = 0;
- bgl_entries[0].visibility = WGPUShaderStage_Compute;
- bgl_entries[0].storageTexture.access = WGPUStorageTextureAccess_WriteOnly;
- bgl_entries[0].storageTexture.format = WGPUTextureFormat_RGBA8Unorm;
- bgl_entries[0].storageTexture.viewDimension = WGPUTextureViewDimension_2D;
- bgl_entries[1].binding = 1;
- bgl_entries[1].visibility = WGPUShaderStage_Compute;
- bgl_entries[1].buffer.type = WGPUBufferBindingType_Uniform;
- bgl_entries[1].buffer.minBindingSize = 16;
-
- WGPUBindGroupLayoutDescriptor bgl_desc = {};
- bgl_desc.entryCount = 2;
- bgl_desc.entries = bgl_entries;
- WGPUBindGroupLayout bind_group_layout =
- wgpuDeviceCreateBindGroupLayout(device_, &bgl_desc);
-
- WGPUBindGroupEntry bg_entries[2] = {};
- bg_entries[0].binding = 0;
- bg_entries[0].textureView = target_view;
- bg_entries[1].binding = 1;
- bg_entries[1].buffer = uniform_buf;
- bg_entries[1].size = sizeof(GridParams);
-
- WGPUBindGroupDescriptor bg_desc = {};
- bg_desc.layout = bind_group_layout;
- bg_desc.entryCount = 2;
- bg_desc.entries = bg_entries;
- WGPUBindGroup bind_group = wgpuDeviceCreateBindGroup(device_, &bg_desc);
-
- WGPUCommandEncoderDescriptor enc_desc = {};
- WGPUCommandEncoder encoder = wgpuDeviceCreateCommandEncoder(device_, &enc_desc);
- WGPUComputePassEncoder pass = wgpuCommandEncoderBeginComputePass(encoder, nullptr);
- wgpuComputePassEncoderSetPipeline(pass, grid_compute_pipeline_);
- wgpuComputePassEncoderSetBindGroup(pass, 0, bind_group, 0, nullptr);
- wgpuComputePassEncoderDispatchWorkgroups(pass, (params.width + 7) / 8,
- (params.height + 7) / 8, 1);
- wgpuComputePassEncoderEnd(pass);
-
- WGPUCommandBufferDescriptor cmd_desc = {};
- WGPUCommandBuffer cmd = wgpuCommandEncoderFinish(encoder, &cmd_desc);
- wgpuQueueSubmit(queue_, 1, &cmd);
-
- wgpuCommandBufferRelease(cmd);
- wgpuCommandEncoderRelease(encoder);
- wgpuComputePassEncoderRelease(pass);
- wgpuBindGroupRelease(bind_group);
- wgpuBindGroupLayoutRelease(bind_group_layout);
- wgpuBufferRelease(uniform_buf);
- wgpuTextureViewRelease(target_view);
-}
-
void TextureManager::create_gpu_grid_texture(
const std::string& name, const GpuProceduralParams& params) {
+ extern const char* gen_grid_compute_wgsl;
+ get_or_create_compute_pipeline("gen_grid", gen_grid_compute_wgsl, 16);
+
WGPUTextureDescriptor tex_desc = {};
tex_desc.usage =
WGPUTextureUsage_StorageBinding | WGPUTextureUsage_TextureBinding;
@@ -629,7 +392,17 @@ void TextureManager::create_gpu_grid_texture(
tex_desc.sampleCount = 1;
WGPUTexture texture = wgpuDeviceCreateTexture(device_, &tex_desc);
- dispatch_grid_compute(texture, params);
+ struct GridParams {
+ uint32_t width;
+ uint32_t height;
+ uint32_t grid_size;
+ uint32_t thickness;
+ };
+ GridParams uniforms = {
+ (uint32_t)params.width, (uint32_t)params.height,
+ params.num_params > 0 ? (uint32_t)params.params[0] : 32u,
+ params.num_params > 1 ? (uint32_t)params.params[1] : 2u};
+ dispatch_compute("gen_grid", texture, params, &uniforms, sizeof(GridParams));
WGPUTextureViewDescriptor view_desc = {};
view_desc.format = WGPUTextureFormat_RGBA8Unorm;