Skip to content

Commit

Permalink
Increase GPU limits to unconstrain size of resources that can be used
Browse files Browse the repository at this point in the history
  • Loading branch information
Nelarius committed Apr 7, 2024
1 parent 4389072 commit 221884f
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 44 deletions.
8 changes: 8 additions & 0 deletions notes/storage_buffer_binding_size.md
@@ -1,5 +1,13 @@
# `.maxStorageBufferBindingSize`

_Amended: 2024-04-07_

> Dawn's internal storage buffer limit is 256 MiB, or `1 << 28` bytes.
The default max buffer size is 256 MiB. Increasing the max storage buffer binding size alone has not effect, as it is constrained by the max buffer size. Setting `maxBufferSize` > $2^{28}$ bytes unconstrains the storage buffer limit again. At the time of writing, the `maxBufferSize` was 10 GiB on both macOS and Windows.

The storage buffer binding size limit is the one which validation triggers when creating buffers larger than the limit, hence the initial focus on this particular value.

_Written: 2023-11-10_

_Context: when doing texture lookup on the GPU for the first time, it was observed that a single texture buffer can exceed Dawn's internal storage buffer size limit._
Expand Down
39 changes: 39 additions & 0 deletions src/pt/gpu_limits.hpp
@@ -0,0 +1,39 @@
#pragma once

namespace nlrs
{
constexpr WGPULimits REQUIRED_LIMITS{
.maxTextureDimension1D = 0,
.maxTextureDimension2D = 0,
.maxTextureDimension3D = 0,
.maxTextureArrayLayers = 0,
.maxBindGroups = 4,
.maxBindGroupsPlusVertexBuffers = 0,
.maxBindingsPerBindGroup = 8,
.maxDynamicUniformBuffersPerPipelineLayout = 0,
.maxDynamicStorageBuffersPerPipelineLayout = 0,
.maxSampledTexturesPerShaderStage = 0,
.maxSamplersPerShaderStage = 0,
.maxStorageBuffersPerShaderStage = 8,
.maxStorageTexturesPerShaderStage = 0,
.maxUniformBuffersPerShaderStage = 1,
.maxUniformBufferBindingSize = 1 << 10,
.maxStorageBufferBindingSize = 1 << 30,
.minUniformBufferOffsetAlignment = 256,
.minStorageBufferOffsetAlignment = 256,
.maxVertexBuffers = 4,
.maxBufferSize = 1 << 30,
.maxVertexAttributes = 8,
.maxVertexBufferArrayStride = sizeof(float[4]),
.maxInterStageShaderComponents = 0,
.maxInterStageShaderVariables = 0,
.maxColorAttachments = 4,
.maxColorAttachmentBytesPerSample = 0,
.maxComputeWorkgroupStorageSize = 0,
.maxComputeInvocationsPerWorkgroup = 0,
.maxComputeWorkgroupSizeX = 0,
.maxComputeWorkgroupSizeY = 0,
.maxComputeWorkgroupSizeZ = 0,
.maxComputeWorkgroupsPerDimension = 0,
};
}
10 changes: 6 additions & 4 deletions src/pt/main.cpp
@@ -1,5 +1,6 @@
#include "fly_camera_controller.hpp"
#include "gpu_context.hpp"
#include "gpu_limits.hpp"
#include "gui.hpp"
#include "deferred_renderer.hpp"
#include "reference_path_tracer.hpp"
Expand Down Expand Up @@ -112,11 +113,12 @@ try
return 0;
}

nlrs::GpuContext gpuContext{nlrs::ReferencePathTracer::wgpuRequiredLimits};
nlrs::Window window = [&gpuContext]() -> nlrs::Window {
nlrs::GpuContext gpuContext{
WGPURequiredLimits{.nextInChain = nullptr, .limits = nlrs::REQUIRED_LIMITS}};
nlrs::Window window = [&gpuContext]() -> nlrs::Window {
const nlrs::WindowDescriptor windowDesc{
.windowSize = nlrs::Extent2i{defaultWindowWidth, defaultWindowHeight},
.title = "pt-playground 🛝",
.windowSize = nlrs::Extent2i{defaultWindowWidth, defaultWindowHeight},
.title = "pt-playground 🛝",
};
return nlrs::Window{windowDesc, gpuContext};
}();
Expand Down
3 changes: 2 additions & 1 deletion src/pt/reference_path_tracer.cpp
@@ -1,5 +1,6 @@
#include "gpu_bind_group_layout.hpp"
#include "gpu_context.hpp"
#include "gpu_limits.hpp"
#include "reference_path_tracer.hpp"
#include "shader_source.hpp"
#include "webgpu_utils.hpp"
Expand Down Expand Up @@ -231,7 +232,7 @@ ReferencePathTracer::ReferencePathTracer(

const std::size_t textureDataNumBytes = textureData.size() * sizeof(Texture::BgraPixel);
const std::size_t maxStorageBufferBindingSize =
static_cast<std::size_t>(wgpuRequiredLimits.limits.maxStorageBufferBindingSize);
static_cast<std::size_t>(REQUIRED_LIMITS.maxStorageBufferBindingSize);
if (textureDataNumBytes > maxStorageBufferBindingSize)
{
throw std::runtime_error(fmt::format(
Expand Down
39 changes: 0 additions & 39 deletions src/pt/reference_path_tracer.hpp
Expand Up @@ -74,45 +74,6 @@ class ReferencePathTracer
float averageRenderpassDurationMs() const;
float renderProgressPercentage() const;

static constexpr WGPURequiredLimits wgpuRequiredLimits{
.nextInChain = nullptr,
.limits =
WGPULimits{
.maxTextureDimension1D = 0,
.maxTextureDimension2D = 0,
.maxTextureDimension3D = 0,
.maxTextureArrayLayers = 0,
.maxBindGroups = 2,
.maxBindGroupsPlusVertexBuffers = 0,
.maxBindingsPerBindGroup = 7,
.maxDynamicUniformBuffersPerPipelineLayout = 0,
.maxDynamicStorageBuffersPerPipelineLayout = 0,
.maxSampledTexturesPerShaderStage = 0,
.maxSamplersPerShaderStage = 0,
.maxStorageBuffersPerShaderStage = 6,
.maxStorageTexturesPerShaderStage = 0,
.maxUniformBuffersPerShaderStage = 1,
.maxUniformBufferBindingSize = 80,
.maxStorageBufferBindingSize = 1 << 28, // 256 MiB
.minUniformBufferOffsetAlignment = 256,
.minStorageBufferOffsetAlignment = 256,
.maxVertexBuffers = 1,
.maxBufferSize = 0,
.maxVertexAttributes = 2,
.maxVertexBufferArrayStride = 2 * sizeof(float),
.maxInterStageShaderComponents = 0,
.maxInterStageShaderVariables = 0,
.maxColorAttachments = 0,
.maxColorAttachmentBytesPerSample = 0,
.maxComputeWorkgroupStorageSize = 0,
.maxComputeInvocationsPerWorkgroup = 0,
.maxComputeWorkgroupSizeX = 0,
.maxComputeWorkgroupSizeY = 0,
.maxComputeWorkgroupSizeZ = 0,
.maxComputeWorkgroupsPerDimension = 0,
},
};

private:
GpuBuffer mVertexBuffer;
GpuBuffer mRenderParamsBuffer;
Expand Down

0 comments on commit 221884f

Please sign in to comment.