Skip to content

Commit

Permalink
Adds WebGPU command to pass execution context token from renderer->GPU.
Browse files Browse the repository at this point in the history
Note: Additional decoder unit tests are added in follow up CL since
      there isn't enough surface to test in this change (plus some
      autogen tests are also added).

Note: If we ever update build_webgpu_cmd_buffer.py to handle uint64_t
      we can remove the code used to break into uint32_ts.

- Adds SetExecutionContextToken command to build_webgpu_cmd_buffer.py
  and re-run it to generate autogen pieces.
- Plumb the token to the GPU process from the renderer process when
  creating an adapter for Dawn so that we can use the token to correlate
  back to the Browser process to get a unique isolation key for caching
  purposes.

Bug: dawn:549
Change-Id: Ifaa63233dcd9e09b6bdd0315de6f1a659fd62f05
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3733180
Reviewed-by: Sunny Sachanandani <sunnyps@chromium.org>
Reviewed-by: Daniel Cheng <dcheng@chromium.org>
Reviewed-by: Austin Eng <enga@chromium.org>
Commit-Queue: Loko Kung <lokokung@google.com>
Cr-Commit-Position: refs/heads/main@{#1046685}
  • Loading branch information
lokokung authored and Chromium LUCI CQ committed Sep 14, 2022
1 parent 871eb5f commit 45cf4a3
Show file tree
Hide file tree
Showing 17 changed files with 188 additions and 1 deletion.
1 change: 1 addition & 0 deletions gpu/DEPS
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ include_rules = [
"+net",
"+third_party/angle",
"+third_party/amd",
"+third_party/blink/public/common/tokens",
"+third_party/nvml",
"+third_party/re2",
"+third_party/smhasher",
Expand Down
4 changes: 4 additions & 0 deletions gpu/command_buffer/build_webgpu_cmd_buffer.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,10 @@
'impl_func': False,
'internal': True,
},
'SetExecutionContextToken': {
'impl_func': False,
'client_test': False,
},
}

def main(argv):
Expand Down
1 change: 1 addition & 0 deletions gpu/command_buffer/client/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,7 @@ source_set("webgpu_interface") {
":interface_base",
"//base",
"//gpu/command_buffer/common:webgpu",
"//third_party/blink/public/common/tokens:tokens_headers",
]
}

Expand Down
12 changes: 12 additions & 0 deletions gpu/command_buffer/client/webgpu_cmd_helper_autogen.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,16 @@ void DissociateMailboxForPresent(GLuint device_id,
}
}

void SetExecutionContextToken(uint32_t type,
uint32_t high_high,
uint32_t high_low,
uint32_t low_high,
uint32_t low_low) {
webgpu::cmds::SetExecutionContextToken* c =
GetCmdSpace<webgpu::cmds::SetExecutionContextToken>();
if (c) {
c->Init(type, high_high, high_low, low_high, low_low);
}
}

#endif // GPU_COMMAND_BUFFER_CLIENT_WEBGPU_CMD_HELPER_AUTOGEN_H_
11 changes: 11 additions & 0 deletions gpu/command_buffer/client/webgpu_implementation.cc
Original file line number Diff line number Diff line change
Expand Up @@ -452,5 +452,16 @@ void WebGPUImplementation::DissociateMailboxForPresent(
#endif
}

void WebGPUImplementation::SetExecutionContextToken(uint32_t type,
uint32_t high_high,
uint32_t high_low,
uint32_t low_high,
uint32_t low_low) {
#if BUILDFLAG(USE_DAWN)
helper_->SetExecutionContextToken(type, high_high, high_low, low_high,
low_low);
#endif
}

} // namespace webgpu
} // namespace gpu
6 changes: 6 additions & 0 deletions gpu/command_buffer/client/webgpu_implementation_autogen.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,10 @@ void DissociateMailboxForPresent(GLuint device_id,
GLuint texture_id,
GLuint texture_generation) override;

void SetExecutionContextToken(uint32_t type,
uint32_t high_high,
uint32_t high_low,
uint32_t low_high,
uint32_t low_low) override;

#endif // GPU_COMMAND_BUFFER_CLIENT_WEBGPU_IMPLEMENTATION_AUTOGEN_H_
8 changes: 8 additions & 0 deletions gpu/command_buffer/client/webgpu_interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "gpu/command_buffer/client/interface_base.h"
#include "gpu/command_buffer/common/webgpu_cmd_enums.h"
#include "gpu/command_buffer/common/webgpu_cmd_ids.h"
#include "third_party/blink/public/common/tokens/tokens.h"

namespace gpu {
namespace webgpu {
Expand Down Expand Up @@ -88,6 +89,13 @@ class WebGPUInterface : public InterfaceBase {
AssociateMailbox(device_id, device_generation, id, generation, usage,
WEBGPU_MAILBOX_NONE, mailbox);
}

void SetExecutionContextToken(const blink::ExecutionContextToken& token) {
uint64_t high = token.value().GetHighForSerialization();
uint64_t low = token.value().GetLowForSerialization();
SetExecutionContextToken(token.variant_index(), high >> 32,
high & 0xFFFFFFFF, low >> 32, low & 0xFFFFFFFF);
}
};

} // namespace webgpu
Expand Down
5 changes: 5 additions & 0 deletions gpu/command_buffer/client/webgpu_interface_autogen.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,9 @@ virtual void DissociateMailboxForPresent(GLuint device_id,
GLuint device_generation,
GLuint texture_id,
GLuint texture_generation) = 0;
virtual void SetExecutionContextToken(uint32_t type,
uint32_t high_high,
uint32_t high_low,
uint32_t low_high,
uint32_t low_low) = 0;
#endif // GPU_COMMAND_BUFFER_CLIENT_WEBGPU_INTERFACE_AUTOGEN_H_
5 changes: 5 additions & 0 deletions gpu/command_buffer/client/webgpu_interface_stub_autogen.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,9 @@ void DissociateMailboxForPresent(GLuint device_id,
GLuint device_generation,
GLuint texture_id,
GLuint texture_generation) override;
void SetExecutionContextToken(uint32_t type,
uint32_t high_high,
uint32_t high_low,
uint32_t low_high,
uint32_t low_low) override;
#endif // GPU_COMMAND_BUFFER_CLIENT_WEBGPU_INTERFACE_STUB_AUTOGEN_H_
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,9 @@ void WebGPUInterfaceStub::DissociateMailboxForPresent(
GLuint /* device_generation */,
GLuint /* texture_id */,
GLuint /* texture_generation */) {}
void WebGPUInterfaceStub::SetExecutionContextToken(uint32_t /* type */,
uint32_t /* high_high */,
uint32_t /* high_low */,
uint32_t /* low_high */,
uint32_t /* low_low */) {}
#endif // GPU_COMMAND_BUFFER_CLIENT_WEBGPU_INTERFACE_STUB_IMPL_AUTOGEN_H_
59 changes: 59 additions & 0 deletions gpu/command_buffer/common/webgpu_cmd_format_autogen.h
Original file line number Diff line number Diff line change
Expand Up @@ -223,4 +223,63 @@ static_assert(
offsetof(DissociateMailboxForPresent, texture_generation) == 16,
"offset of DissociateMailboxForPresent texture_generation should be 16");

struct SetExecutionContextToken {
typedef SetExecutionContextToken ValueType;
static const CommandId kCmdId = kSetExecutionContextToken;
static const cmd::ArgFlags kArgFlags = cmd::kFixed;
static const uint8_t cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);

static uint32_t ComputeSize() {
return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT
}

void SetHeader() { header.SetCmd<ValueType>(); }

void Init(uint32_t _type,
uint32_t _high_high,
uint32_t _high_low,
uint32_t _low_high,
uint32_t _low_low) {
SetHeader();
type = _type;
high_high = _high_high;
high_low = _high_low;
low_high = _low_high;
low_low = _low_low;
}

void* Set(void* cmd,
uint32_t _type,
uint32_t _high_high,
uint32_t _high_low,
uint32_t _low_high,
uint32_t _low_low) {
static_cast<ValueType*>(cmd)->Init(_type, _high_high, _high_low, _low_high,
_low_low);
return NextCmdAddress<ValueType>(cmd);
}

gpu::CommandHeader header;
uint32_t type;
uint32_t high_high;
uint32_t high_low;
uint32_t low_high;
uint32_t low_low;
};

static_assert(sizeof(SetExecutionContextToken) == 24,
"size of SetExecutionContextToken should be 24");
static_assert(offsetof(SetExecutionContextToken, header) == 0,
"offset of SetExecutionContextToken header should be 0");
static_assert(offsetof(SetExecutionContextToken, type) == 4,
"offset of SetExecutionContextToken type should be 4");
static_assert(offsetof(SetExecutionContextToken, high_high) == 8,
"offset of SetExecutionContextToken high_high should be 8");
static_assert(offsetof(SetExecutionContextToken, high_low) == 12,
"offset of SetExecutionContextToken high_low should be 12");
static_assert(offsetof(SetExecutionContextToken, low_high) == 16,
"offset of SetExecutionContextToken low_high should be 16");
static_assert(offsetof(SetExecutionContextToken, low_low) == 20,
"offset of SetExecutionContextToken low_low should be 20");

#endif // GPU_COMMAND_BUFFER_COMMON_WEBGPU_CMD_FORMAT_AUTOGEN_H_
18 changes: 18 additions & 0 deletions gpu/command_buffer/common/webgpu_cmd_format_test_autogen.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,4 +96,22 @@ TEST_F(WebGPUFormatTest, DissociateMailboxForPresent) {
CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
}

TEST_F(WebGPUFormatTest, SetExecutionContextToken) {
cmds::SetExecutionContextToken& cmd =
*GetBufferAs<cmds::SetExecutionContextToken>();
void* next_cmd =
cmd.Set(&cmd, static_cast<uint32_t>(11), static_cast<uint32_t>(12),
static_cast<uint32_t>(13), static_cast<uint32_t>(14),
static_cast<uint32_t>(15));
EXPECT_EQ(static_cast<uint32_t>(cmds::SetExecutionContextToken::kCmdId),
cmd.header.command);
EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
EXPECT_EQ(static_cast<uint32_t>(11), cmd.type);
EXPECT_EQ(static_cast<uint32_t>(12), cmd.high_high);
EXPECT_EQ(static_cast<uint32_t>(13), cmd.high_low);
EXPECT_EQ(static_cast<uint32_t>(14), cmd.low_high);
EXPECT_EQ(static_cast<uint32_t>(15), cmd.low_low);
CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
}

#endif // GPU_COMMAND_BUFFER_COMMON_WEBGPU_CMD_FORMAT_TEST_AUTOGEN_H_
3 changes: 2 additions & 1 deletion gpu/command_buffer/common/webgpu_cmd_ids_autogen.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
OP(DawnCommands) /* 256 */ \
OP(AssociateMailboxImmediate) /* 257 */ \
OP(DissociateMailbox) /* 258 */ \
OP(DissociateMailboxForPresent) /* 259 */
OP(DissociateMailboxForPresent) /* 259 */ \
OP(SetExecutionContextToken) /* 260 */

enum CommandId {
kOneBeforeStartPoint =
Expand Down
1 change: 1 addition & 0 deletions gpu/command_buffer/service/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,7 @@ target(link_target_type, "gles2_sources") {
"//gpu/command_buffer/common:raster_sources",
"//gpu/command_buffer/common:webgpu_sources",
"//skia",
"//third_party/blink/public/common/tokens:tokens_headers",
"//third_party/dawn/include/dawn:headers",
]
deps += [
Expand Down
39 changes: 39 additions & 0 deletions gpu/command_buffer/service/webgpu_decoder_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "base/memory/raw_ptr.h"
#include "base/numerics/checked_math.h"
#include "base/trace_event/trace_event.h"
#include "base/unguessable_token.h"
#include "build/build_config.h"
#include "components/viz/common/resources/resource_format_utils.h"
#include "gpu/command_buffer/common/mailbox.h"
Expand All @@ -38,6 +39,7 @@
#include "gpu/command_buffer/service/webgpu_decoder.h"
#include "gpu/config/gpu_preferences.h"
#include "gpu/webgpu/callback.h"
#include "third_party/blink/public/common/tokens/tokens.h"
#include "third_party/skia/include/core/SkPromiseImageTexture.h"
#include "third_party/skia/include/gpu/GrBackendSemaphore.h"
#include "ui/gl/gl_context_egl.h"
Expand Down Expand Up @@ -401,6 +403,7 @@ class WebGPUDecoderImpl final : public WebGPUDecoder {
std::vector<std::string> force_enabled_toggles_;
std::vector<std::string> force_disabled_toggles_;
bool allow_unsafe_apis_;
blink::ExecutionContextToken execution_context_token_;

std::unique_ptr<dawn::wire::WireServer> wire_server_;
std::unique_ptr<DawnServiceSerializer> wire_serializer_;
Expand Down Expand Up @@ -1740,5 +1743,41 @@ error::Error WebGPUDecoderImpl::HandleDissociateMailboxForPresent(
return error::kNoError;
}

error::Error WebGPUDecoderImpl::HandleSetExecutionContextToken(
uint32_t immediate_data_size,
const volatile void* cmd_data) {
const volatile webgpu::cmds::SetExecutionContextToken& c =
*static_cast<const volatile webgpu::cmds::SetExecutionContextToken*>(
cmd_data);
uint32_t type(c.type);
uint64_t high = uint64_t(c.high_high) << 32 | uint64_t(c.high_low);
uint64_t low = uint64_t(c.low_high) << 32 | uint64_t(c.low_low);
base::UnguessableToken token = base::UnguessableToken::Deserialize(high, low);
switch (type) {
// TODO(dawn:549) LocalFrameToken is a temp solution for initial testing.
// It will not be used in the final product because it can produce
// known races. The use of LocalFrameToken should only be enabled through
// --enable-unsafe-webgpu for now for testing. Once DocumentToken is ready,
// this should be migrated before enabling by default.
case blink::ExecutionContextToken::Base::template TypeIndex<
blink::LocalFrameToken>::kValue: {
DCHECK(enable_unsafe_webgpu_);
execution_context_token_ =
blink::ExecutionContextToken(blink::LocalFrameToken(token));
break;
}
case blink::ExecutionContextToken::Base::template TypeIndex<
blink::DedicatedWorkerToken>::kValue: {
execution_context_token_ =
blink::ExecutionContextToken(blink::DedicatedWorkerToken(token));
break;
}
default:
NOTREACHED();
return error::kInvalidArguments;
}
return error::kNoError;
}

} // namespace webgpu
} // namespace gpu
5 changes: 5 additions & 0 deletions gpu/command_buffer/webgpu_cmd_buffer_functions.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,8 @@ GL_APICALL void GL_APIENTRY wgDawnCommands (const char* commands, size_t size);
GL_APICALL void GL_APIENTRY wgAssociateMailbox (GLuint device_id, GLuint device_generation, GLuint id, GLuint generation, GLuint usage, MailboxFlags flags, const GLbyte* mailbox);
GL_APICALL void GL_APIENTRY wgDissociateMailbox (GLuint texture_id, GLuint texture_generation);
GL_APICALL void GL_APIENTRY wgDissociateMailboxForPresent (GLuint device_id, GLuint device_generation, GLuint texture_id, GLuint texture_generation);

// The ExecutionContext tokens are represented by two 64 bit uints, but the
// the generator currently only supports 32 bit members so we break the token
// into 4 parts.
GL_APICALL void GL_APIENTRY wgSetExecutionContextToken (uint32_t type, uint32_t high_high, uint32_t high_low, uint32_t low_high, uint32_t low_low);
6 changes: 6 additions & 0 deletions third_party/blink/renderer/modules/webgpu/gpu.cc
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,12 @@ ScriptPromise GPU::requestAdapter(ScriptState* script_state,
resolver->Resolve(v8::Null(script_state->GetIsolate()));
return promise;
} else {
// Get an identifying token from the execution context to be sent to the
// GPU process so that it can be cross-referenced against the browser
// process to get an isolation key for caching purposes.
context_provider->WebGPUInterface()->SetExecutionContextToken(
execution_context->GetExecutionContextToken());

// Make a new DawnControlClientHolder with the context provider we just
// made and set the lost context callback
dawn_control_client_ = DawnControlClientHolder::Create(
Expand Down

0 comments on commit 45cf4a3

Please sign in to comment.