Skip to content

Commit

Permalink
Reland: WebGPU decoder: Add Associate/Dissociate mailbox
Browse files Browse the repository at this point in the history
Reland with a fix for missing immediate data storage in the decoder
unittests.

These WebGPU IPC commands allows wrapping a mailbox in a Dawn texture
and associate it to a given ID in dawn_wire. There is the respective
dissociate command too.

SharedImageRepresentationIOSurfaceDawn is changed to destroy() the Dawn
texture on EndAccess so it is an error to access the texture after the
mailbox has been dissociated. The class also gets some refcounting
improvements.

This also makes some GPU service objects able to be used when no GL
context is present, as is the case when running WebGPU unittests.

BUG=chromium:877147

Change-Id: Ib0c8f6251441c9dbe69252773279b53a1fec3736
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1577422
Reviewed-by: Antoine Labour <piman@chromium.org>
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
Cr-Commit-Position: refs/heads/master@{#653366}
  • Loading branch information
Kangz authored and Commit Bot committed Apr 23, 2019
1 parent cba24fa commit 7dab10e
Show file tree
Hide file tree
Showing 35 changed files with 924 additions and 39 deletions.
1 change: 1 addition & 0 deletions gpu/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,7 @@ test("gl_tests") {
if (use_dawn) {
sources += [
"command_buffer/tests/webgpu_fence_unittest.cc",
"command_buffer/tests/webgpu_mailbox_unittest.cc",
"command_buffer/tests/webgpu_test.cc",
"command_buffer/tests/webgpu_test.h",
]
Expand Down
9 changes: 8 additions & 1 deletion gpu/command_buffer/build_webgpu_cmd_buffer.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,16 @@
'commands': 'size * sizeof(char)',
},
},
'AssociateMailbox': {
'type': 'PUT',
'count': 16, # GL_MAILBOX_SIZE_CHROMIUM
'trace_level': 1,
},
'DissociateMailbox': {
'trace_level': 1,
},
}


def main(argv):
"""This is the main function."""
parser = OptionParser()
Expand Down
23 changes: 23 additions & 0 deletions gpu/command_buffer/client/webgpu_cmd_helper_autogen.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,27 @@ void DawnCommands(uint32_t commands_shm_id,
}
}

void AssociateMailboxImmediate(GLuint device_id,
GLuint device_generation,
GLuint id,
GLuint generation,
GLuint usage,
const GLbyte* mailbox) {
const uint32_t size = webgpu::cmds::AssociateMailboxImmediate::ComputeSize();
webgpu::cmds::AssociateMailboxImmediate* c =
GetImmediateCmdSpaceTotalSize<webgpu::cmds::AssociateMailboxImmediate>(
size);
if (c) {
c->Init(device_id, device_generation, id, generation, usage, mailbox);
}
}

void DissociateMailbox(GLuint texture_id, GLuint texture_generation) {
webgpu::cmds::DissociateMailbox* c =
GetCmdSpace<webgpu::cmds::DissociateMailbox>();
if (c) {
c->Init(texture_id, texture_generation);
}
}

#endif // GPU_COMMAND_BUFFER_CLIENT_WEBGPU_CMD_HELPER_AUTOGEN_H_
10 changes: 10 additions & 0 deletions gpu/command_buffer/client/webgpu_implementation.cc
Original file line number Diff line number Diff line change
Expand Up @@ -278,5 +278,15 @@ DawnDevice WebGPUImplementation::GetDefaultDevice() {
#endif
}

ReservedTexture WebGPUImplementation::ReserveTexture(DawnDevice device) {
#if BUILDFLAG(USE_DAWN)
dawn_wire::ReservedTexture reservation = wire_client_->ReserveTexture(device);
return {reservation.texture, reservation.id, reservation.generation};
#else
NOTREACHED();
return {};
#endif
}

} // namespace webgpu
} // namespace gpu
2 changes: 2 additions & 0 deletions gpu/command_buffer/client/webgpu_implementation.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,9 +114,11 @@ class WEBGPU_EXPORT WebGPUImplementation final
const DawnProcTable& GetProcs() const override;
void FlushCommands() override;
DawnDevice GetDefaultDevice() override;
ReservedTexture ReserveTexture(DawnDevice device) override;

private:
const char* GetLogPrefix() const { return "webgpu"; }
void CheckGLError() {}

WebGPUCmdHelper* helper_;
#if BUILDFLAG(USE_DAWN)
Expand Down
9 changes: 9 additions & 0 deletions gpu/command_buffer/client/webgpu_implementation_autogen.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,13 @@
#ifndef GPU_COMMAND_BUFFER_CLIENT_WEBGPU_IMPLEMENTATION_AUTOGEN_H_
#define GPU_COMMAND_BUFFER_CLIENT_WEBGPU_IMPLEMENTATION_AUTOGEN_H_

void AssociateMailbox(GLuint device_id,
GLuint device_generation,
GLuint id,
GLuint generation,
GLuint usage,
const GLbyte* mailbox) override;

void DissociateMailbox(GLuint texture_id, GLuint texture_generation) override;

#endif // GPU_COMMAND_BUFFER_CLIENT_WEBGPU_IMPLEMENTATION_AUTOGEN_H_
27 changes: 27 additions & 0 deletions gpu/command_buffer/client/webgpu_implementation_impl_autogen.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,31 @@
#ifndef GPU_COMMAND_BUFFER_CLIENT_WEBGPU_IMPLEMENTATION_IMPL_AUTOGEN_H_
#define GPU_COMMAND_BUFFER_CLIENT_WEBGPU_IMPLEMENTATION_IMPL_AUTOGEN_H_

void WebGPUImplementation::AssociateMailbox(GLuint device_id,
GLuint device_generation,
GLuint id,
GLuint generation,
GLuint usage,
const GLbyte* mailbox) {
GPU_CLIENT_SINGLE_THREAD_CHECK();
GPU_CLIENT_LOG("[" << GetLogPrefix() << "] wgAssociateMailbox(" << device_id
<< ", " << device_generation << ", " << id << ", "
<< generation << ", " << usage << ", "
<< static_cast<const void*>(mailbox) << ")");
uint32_t count = 16;
for (uint32_t ii = 0; ii < count; ++ii)
GPU_CLIENT_LOG("value[" << ii << "]: " << mailbox[ii]);
helper_->AssociateMailboxImmediate(device_id, device_generation, id,
generation, usage, mailbox);
CheckGLError();
}

void WebGPUImplementation::DissociateMailbox(GLuint texture_id,
GLuint texture_generation) {
GPU_CLIENT_SINGLE_THREAD_CHECK();
GPU_CLIENT_LOG("[" << GetLogPrefix() << "] wgDissociateMailbox(" << texture_id
<< ", " << texture_generation << ")");
helper_->DissociateMailbox(texture_id, texture_generation);
}

#endif // GPU_COMMAND_BUFFER_CLIENT_WEBGPU_IMPLEMENTATION_IMPL_AUTOGEN_H_
26 changes: 26 additions & 0 deletions gpu/command_buffer/client/webgpu_implementation_unittest_autogen.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,30 @@
#ifndef GPU_COMMAND_BUFFER_CLIENT_WEBGPU_IMPLEMENTATION_UNITTEST_AUTOGEN_H_
#define GPU_COMMAND_BUFFER_CLIENT_WEBGPU_IMPLEMENTATION_UNITTEST_AUTOGEN_H_

TEST_F(WebGPUImplementationTest, AssociateMailbox) {
GLbyte data[16] = {0};
struct Cmds {
cmds::AssociateMailboxImmediate cmd;
GLbyte data[16];
};

for (int jj = 0; jj < 16; ++jj) {
data[jj] = static_cast<GLbyte>(jj);
}
Cmds expected;
expected.cmd.Init(1, 2, 3, 4, 5, &data[0]);
gl_->AssociateMailbox(1, 2, 3, 4, 5, &data[0]);
EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
}

TEST_F(WebGPUImplementationTest, DissociateMailbox) {
struct Cmds {
cmds::DissociateMailbox cmd;
};
Cmds expected;
expected.cmd.Init(1, 2);

gl_->DissociateMailbox(1, 2);
EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
}
#endif // GPU_COMMAND_BUFFER_CLIENT_WEBGPU_IMPLEMENTATION_UNITTEST_AUTOGEN_H_
7 changes: 7 additions & 0 deletions gpu/command_buffer/client/webgpu_interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@ extern "C" typedef struct _GLColorSpace* GLColorSpace;
namespace gpu {
namespace webgpu {

struct ReservedTexture {
DawnTexture texture;
uint32_t id;
uint32_t generation;
};

class WebGPUInterface : public InterfaceBase {
public:
WebGPUInterface() {}
Expand All @@ -23,6 +29,7 @@ class WebGPUInterface : public InterfaceBase {
virtual const DawnProcTable& GetProcs() const = 0;
virtual void FlushCommands() = 0;
virtual DawnDevice GetDefaultDevice() = 0;
virtual ReservedTexture ReserveTexture(DawnDevice device) = 0;

// Include the auto-generated part of this class. We split this because
// it means we can easily edit the non-auto generated parts right here in
Expand Down
8 changes: 8 additions & 0 deletions gpu/command_buffer/client/webgpu_interface_autogen.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,12 @@
#ifndef GPU_COMMAND_BUFFER_CLIENT_WEBGPU_INTERFACE_AUTOGEN_H_
#define GPU_COMMAND_BUFFER_CLIENT_WEBGPU_INTERFACE_AUTOGEN_H_

virtual void AssociateMailbox(GLuint device_id,
GLuint device_generation,
GLuint id,
GLuint generation,
GLuint usage,
const GLbyte* mailbox) = 0;
virtual void DissociateMailbox(GLuint texture_id,
GLuint texture_generation) = 0;
#endif // GPU_COMMAND_BUFFER_CLIENT_WEBGPU_INTERFACE_AUTOGEN_H_
1 change: 1 addition & 0 deletions gpu/command_buffer/common/webgpu_cmd_format.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "base/logging.h"
#include "base/macros.h"
#include "gpu/command_buffer/common/common_cmd_format.h"
#include "gpu/command_buffer/common/gl2_types.h"
#include "gpu/command_buffer/common/webgpu_cmd_ids.h"
#include "ui/gfx/buffer_types.h"

Expand Down
105 changes: 105 additions & 0 deletions gpu/command_buffer/common/webgpu_cmd_format_autogen.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,109 @@ static_assert(offsetof(DawnCommands, commands_shm_offset) == 8,
static_assert(offsetof(DawnCommands, size) == 12,
"offset of DawnCommands size should be 12");

struct AssociateMailboxImmediate {
typedef AssociateMailboxImmediate ValueType;
static const CommandId kCmdId = kAssociateMailboxImmediate;
static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN;
static const uint8_t cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(1);

static uint32_t ComputeDataSize() {
return static_cast<uint32_t>(sizeof(GLbyte) * 16);
}

static uint32_t ComputeSize() {
return static_cast<uint32_t>(sizeof(ValueType) + ComputeDataSize());
}

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

void Init(GLuint _device_id,
GLuint _device_generation,
GLuint _id,
GLuint _generation,
GLuint _usage,
const GLbyte* _mailbox) {
SetHeader();
device_id = _device_id;
device_generation = _device_generation;
id = _id;
generation = _generation;
usage = _usage;
memcpy(ImmediateDataAddress(this), _mailbox, ComputeDataSize());
}

void* Set(void* cmd,
GLuint _device_id,
GLuint _device_generation,
GLuint _id,
GLuint _generation,
GLuint _usage,
const GLbyte* _mailbox) {
static_cast<ValueType*>(cmd)->Init(_device_id, _device_generation, _id,
_generation, _usage, _mailbox);
const uint32_t size = ComputeSize();
return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size);
}

gpu::CommandHeader header;
uint32_t device_id;
uint32_t device_generation;
uint32_t id;
uint32_t generation;
uint32_t usage;
};

static_assert(sizeof(AssociateMailboxImmediate) == 24,
"size of AssociateMailboxImmediate should be 24");
static_assert(offsetof(AssociateMailboxImmediate, header) == 0,
"offset of AssociateMailboxImmediate header should be 0");
static_assert(offsetof(AssociateMailboxImmediate, device_id) == 4,
"offset of AssociateMailboxImmediate device_id should be 4");
static_assert(
offsetof(AssociateMailboxImmediate, device_generation) == 8,
"offset of AssociateMailboxImmediate device_generation should be 8");
static_assert(offsetof(AssociateMailboxImmediate, id) == 12,
"offset of AssociateMailboxImmediate id should be 12");
static_assert(offsetof(AssociateMailboxImmediate, generation) == 16,
"offset of AssociateMailboxImmediate generation should be 16");
static_assert(offsetof(AssociateMailboxImmediate, usage) == 20,
"offset of AssociateMailboxImmediate usage should be 20");

struct DissociateMailbox {
typedef DissociateMailbox ValueType;
static const CommandId kCmdId = kDissociateMailbox;
static const cmd::ArgFlags kArgFlags = cmd::kFixed;
static const uint8_t cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(1);

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

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

void Init(GLuint _texture_id, GLuint _texture_generation) {
SetHeader();
texture_id = _texture_id;
texture_generation = _texture_generation;
}

void* Set(void* cmd, GLuint _texture_id, GLuint _texture_generation) {
static_cast<ValueType*>(cmd)->Init(_texture_id, _texture_generation);
return NextCmdAddress<ValueType>(cmd);
}

gpu::CommandHeader header;
uint32_t texture_id;
uint32_t texture_generation;
};

static_assert(sizeof(DissociateMailbox) == 12,
"size of DissociateMailbox should be 12");
static_assert(offsetof(DissociateMailbox, header) == 0,
"offset of DissociateMailbox header should be 0");
static_assert(offsetof(DissociateMailbox, texture_id) == 4,
"offset of DissociateMailbox texture_id should be 4");
static_assert(offsetof(DissociateMailbox, texture_generation) == 8,
"offset of DissociateMailbox texture_generation should be 8");

#endif // GPU_COMMAND_BUFFER_COMMON_WEBGPU_CMD_FORMAT_AUTOGEN_H_
51 changes: 51 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 @@ -28,4 +28,55 @@ TEST_F(WebGPUFormatTest, DawnCommands) {
CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
}

TEST_F(WebGPUFormatTest, AssociateMailboxImmediate) {
const int kSomeBaseValueToTestWith = 51;
static GLbyte data[] = {
static_cast<GLbyte>(kSomeBaseValueToTestWith + 0),
static_cast<GLbyte>(kSomeBaseValueToTestWith + 1),
static_cast<GLbyte>(kSomeBaseValueToTestWith + 2),
static_cast<GLbyte>(kSomeBaseValueToTestWith + 3),
static_cast<GLbyte>(kSomeBaseValueToTestWith + 4),
static_cast<GLbyte>(kSomeBaseValueToTestWith + 5),
static_cast<GLbyte>(kSomeBaseValueToTestWith + 6),
static_cast<GLbyte>(kSomeBaseValueToTestWith + 7),
static_cast<GLbyte>(kSomeBaseValueToTestWith + 8),
static_cast<GLbyte>(kSomeBaseValueToTestWith + 9),
static_cast<GLbyte>(kSomeBaseValueToTestWith + 10),
static_cast<GLbyte>(kSomeBaseValueToTestWith + 11),
static_cast<GLbyte>(kSomeBaseValueToTestWith + 12),
static_cast<GLbyte>(kSomeBaseValueToTestWith + 13),
static_cast<GLbyte>(kSomeBaseValueToTestWith + 14),
static_cast<GLbyte>(kSomeBaseValueToTestWith + 15),
};
cmds::AssociateMailboxImmediate& cmd =
*GetBufferAs<cmds::AssociateMailboxImmediate>();
void* next_cmd =
cmd.Set(&cmd, static_cast<GLuint>(11), static_cast<GLuint>(12),
static_cast<GLuint>(13), static_cast<GLuint>(14),
static_cast<GLuint>(15), data);
EXPECT_EQ(static_cast<uint32_t>(cmds::AssociateMailboxImmediate::kCmdId),
cmd.header.command);
EXPECT_EQ(sizeof(cmd) + RoundSizeToMultipleOfEntries(sizeof(data)),
cmd.header.size * 4u);
EXPECT_EQ(static_cast<GLuint>(11), cmd.device_id);
EXPECT_EQ(static_cast<GLuint>(12), cmd.device_generation);
EXPECT_EQ(static_cast<GLuint>(13), cmd.id);
EXPECT_EQ(static_cast<GLuint>(14), cmd.generation);
EXPECT_EQ(static_cast<GLuint>(15), cmd.usage);
CheckBytesWrittenMatchesExpectedSize(
next_cmd, sizeof(cmd) + RoundSizeToMultipleOfEntries(sizeof(data)));
}

TEST_F(WebGPUFormatTest, DissociateMailbox) {
cmds::DissociateMailbox& cmd = *GetBufferAs<cmds::DissociateMailbox>();
void* next_cmd =
cmd.Set(&cmd, static_cast<GLuint>(11), static_cast<GLuint>(12));
EXPECT_EQ(static_cast<uint32_t>(cmds::DissociateMailbox::kCmdId),
cmd.header.command);
EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
EXPECT_EQ(static_cast<GLuint>(11), cmd.texture_id);
EXPECT_EQ(static_cast<GLuint>(12), cmd.texture_generation);
CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
}

#endif // GPU_COMMAND_BUFFER_COMMON_WEBGPU_CMD_FORMAT_TEST_AUTOGEN_H_
5 changes: 4 additions & 1 deletion gpu/command_buffer/common/webgpu_cmd_ids_autogen.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@
#ifndef GPU_COMMAND_BUFFER_COMMON_WEBGPU_CMD_IDS_AUTOGEN_H_
#define GPU_COMMAND_BUFFER_COMMON_WEBGPU_CMD_IDS_AUTOGEN_H_

#define WEBGPU_COMMAND_LIST(OP) OP(DawnCommands) /* 256 */
#define WEBGPU_COMMAND_LIST(OP) \
OP(DawnCommands) /* 256 */ \
OP(AssociateMailboxImmediate) /* 257 */ \
OP(DissociateMailbox) /* 258 */

enum CommandId {
kOneBeforeStartPoint =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ class GPU_GLES2_EXPORT SharedImageBackingFactoryIOSurface
: public SharedImageBackingFactory {
public:
SharedImageBackingFactoryIOSurface(const GpuDriverBugWorkarounds& workarounds,
const GpuFeatureInfo& gpu_feature_info);
const GpuFeatureInfo& gpu_feature_info,
bool use_gl);
~SharedImageBackingFactoryIOSurface() override;

// SharedImageBackingFactory implementation.
Expand Down Expand Up @@ -59,7 +60,10 @@ class GPU_GLES2_EXPORT SharedImageBackingFactoryIOSurface
uint32_t usage) override;

private:
void CollectGLFormatInfo(const GpuDriverBugWorkarounds& workarounds,
const GpuFeatureInfo& gpu_feature_info);
bool format_supported_by_gl_[viz::RESOURCE_FORMAT_MAX + 1];
bool use_gl_ = false;

DISALLOW_COPY_AND_ASSIGN(SharedImageBackingFactoryIOSurface);
};
Expand Down
Loading

0 comments on commit 7dab10e

Please sign in to comment.