Commit a269bc04 authored by Austin Eng's avatar Austin Eng Committed by Commit Bot

Allow WebGPU command allocation up to transfer buffer size

This patch allows WebGPU to allocate command space up to the
transfer buffer size instead of being limited to the initial
starting transfer buffer size.

This patch also creates SharedMemoryLimits::ForWebGPUContext(). Because
WebGPU sends the majority of its commands via the transfer buffer, it is
preferrable to have a larger minimum transfer buffer size and smaller
command buffer.

Change-Id: I31bb74dfb1075a2b6f159985b297695d57e71ed3
Bug: 877147
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1559455
Commit-Queue: Austin Eng <enga@chromium.org>
Reviewed-by: default avatarAntoine Labour <piman@chromium.org>
Cr-Commit-Position: refs/heads/master@{#649744}
parent 3e80ed4d
...@@ -1018,7 +1018,7 @@ RendererBlinkPlatformImpl::CreateWebGPUGraphicsContext3DProvider( ...@@ -1018,7 +1018,7 @@ RendererBlinkPlatformImpl::CreateWebGPUGraphicsContext3DProvider(
kGpuStreamIdDefault, kGpuStreamPriorityDefault, kGpuStreamIdDefault, kGpuStreamPriorityDefault,
gpu::kNullSurfaceHandle, GURL(top_document_web_url), gpu::kNullSurfaceHandle, GURL(top_document_web_url),
automatic_flushes, support_locking, support_grcontext, automatic_flushes, support_locking, support_grcontext,
gpu::SharedMemoryLimits(), attributes, gpu::SharedMemoryLimits::ForWebGPUContext(), attributes,
ws::command_buffer_metrics::ContextType::WEBGPU)); ws::command_buffer_metrics::ContextType::WEBGPU));
return std::make_unique<WebGraphicsContext3DProviderImpl>( return std::make_unique<WebGraphicsContext3DProviderImpl>(
std::move(provider)); std::move(provider));
......
...@@ -66,6 +66,15 @@ struct SharedMemoryLimits { ...@@ -66,6 +66,15 @@ struct SharedMemoryLimits {
return limits; return limits;
} }
static SharedMemoryLimits ForWebGPUContext() {
// Most WebGPU commands are sent via transfer buffer, so we use a smaller
// command buffer.
SharedMemoryLimits limits;
limits.command_buffer_size = 64 * 1024;
return limits;
}
#if defined(OS_ANDROID) #if defined(OS_ANDROID)
static SharedMemoryLimits ForDisplayCompositor(const gfx::Size& screen_size) { static SharedMemoryLimits ForDisplayCompositor(const gfx::Size& screen_size) {
DCHECK(!screen_size.IsEmpty()); DCHECK(!screen_size.IsEmpty());
......
...@@ -4,8 +4,10 @@ ...@@ -4,8 +4,10 @@
#include "gpu/command_buffer/client/webgpu_implementation.h" #include "gpu/command_buffer/client/webgpu_implementation.h"
#include <algorithm>
#include <vector> #include <vector>
#include "base/numerics/checked_math.h"
#include "gpu/command_buffer/client/gpu_control.h" #include "gpu/command_buffer/client/gpu_control.h"
#include "gpu/command_buffer/client/shared_memory_limits.h" #include "gpu/command_buffer/client/shared_memory_limits.h"
...@@ -42,12 +44,8 @@ gpu::ContextResult WebGPUImplementation::Initialize( ...@@ -42,12 +44,8 @@ gpu::ContextResult WebGPUImplementation::Initialize(
return result; return result;
} }
// TODO(enga): Keep track of how much command space the application is using c2s_buffer_default_size_ = limits.start_transfer_buffer_size;
// and adjust c2s_buffer_size_ accordingly. DCHECK_GT(c2s_buffer_default_size_, 0u);
c2s_buffer_size_ = limits.start_transfer_buffer_size;
DCHECK_GT(c2s_buffer_size_, 0u);
DCHECK(
base::CheckAdd(c2s_buffer_size_, c2s_buffer_size_).IsValid<uint32_t>());
return gpu::ContextResult::kSuccess; return gpu::ContextResult::kSuccess;
} }
...@@ -214,36 +212,37 @@ void WebGPUImplementation::Dummy() { ...@@ -214,36 +212,37 @@ void WebGPUImplementation::Dummy() {
void* WebGPUImplementation::GetCmdSpace(size_t size) { void* WebGPUImplementation::GetCmdSpace(size_t size) {
// The buffer size must be initialized before any commands are serialized. // The buffer size must be initialized before any commands are serialized.
if (c2s_buffer_size_ == 0u) { if (c2s_buffer_default_size_ == 0u) {
NOTREACHED(); NOTREACHED();
return nullptr; return nullptr;
} }
// TODO(enga): Handle chunking commands if size > c2s_buffer_size_. base::CheckedNumeric<uint32_t> checked_next_offset(c2s_put_offset_);
if (size > c2s_buffer_size_) { checked_next_offset += size;
NOTREACHED();
return nullptr;
}
// This should never be more than 2 * c2s_buffer_size_ which is checked in uint32_t next_offset;
// WebGPUImplementation::Initialize. bool next_offset_valid = checked_next_offset.AssignIfValid(&next_offset);
DCHECK_LE(c2s_put_offset_, c2s_buffer_size_);
DCHECK_LE(size, c2s_buffer_size_);
uint32_t next_offset = c2s_put_offset_ + static_cast<uint32_t>(size);
// If the buffer does not have enough space, or if the buffer is not // If the buffer does not have enough space, or if the buffer is not
// initialized, flush and reset the command stream. // initialized, flush and reset the command stream.
if (next_offset > c2s_buffer_.size() || !c2s_buffer_.valid()) { if (!next_offset_valid || next_offset > c2s_buffer_.size() ||
!c2s_buffer_.valid()) {
Flush(); Flush();
c2s_buffer_.Reset(c2s_buffer_size_); uint32_t max_allocation = transfer_buffer_->GetMaxSize();
// TODO(crbug.com/951558): Handle command chunking or ensure commands aren't
// this large.
CHECK_LE(size, max_allocation);
uint32_t allocation_size =
std::max(c2s_buffer_default_size_, static_cast<uint32_t>(size));
c2s_buffer_.Reset(allocation_size);
c2s_put_offset_ = 0; c2s_put_offset_ = 0;
next_offset = size; next_offset = size;
if (size > c2s_buffer_.size() || !c2s_buffer_.valid()) { // TODO(crbug.com/951558): Handle OOM.
// TODO(enga): Handle OOM. CHECK(c2s_buffer_.valid());
return nullptr; CHECK_LE(size, c2s_buffer_.size());
}
} }
DCHECK(c2s_buffer_.valid()); DCHECK(c2s_buffer_.valid());
...@@ -256,6 +255,7 @@ void* WebGPUImplementation::GetCmdSpace(size_t size) { ...@@ -256,6 +255,7 @@ void* WebGPUImplementation::GetCmdSpace(size_t size) {
bool WebGPUImplementation::Flush() { bool WebGPUImplementation::Flush() {
if (c2s_buffer_.valid()) { if (c2s_buffer_.valid()) {
c2s_buffer_.Shrink(c2s_put_offset_);
helper_->DawnCommands(c2s_buffer_.shm_id(), c2s_buffer_.offset(), helper_->DawnCommands(c2s_buffer_.shm_id(), c2s_buffer_.offset(),
c2s_put_offset_); c2s_put_offset_);
c2s_put_offset_ = 0; c2s_put_offset_ = 0;
......
...@@ -124,7 +124,7 @@ class WEBGPU_EXPORT WebGPUImplementation final ...@@ -124,7 +124,7 @@ class WEBGPU_EXPORT WebGPUImplementation final
#endif #endif
DawnProcTable procs_ = {}; DawnProcTable procs_ = {};
uint32_t c2s_buffer_size_ = 0; uint32_t c2s_buffer_default_size_ = 0;
uint32_t c2s_put_offset_ = 0; uint32_t c2s_put_offset_ = 0;
ScopedTransferBufferPtr c2s_buffer_; ScopedTransferBufferPtr c2s_buffer_;
......
...@@ -27,7 +27,8 @@ class WebGPUTest : public testing::Test { ...@@ -27,7 +27,8 @@ class WebGPUTest : public testing::Test {
Options(); Options();
// Shared memory limits // Shared memory limits
SharedMemoryLimits shared_memory_limits = {}; SharedMemoryLimits shared_memory_limits =
SharedMemoryLimits::ForWebGPUContext();
}; };
WebGPUTest(); WebGPUTest();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment