mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-12-09 21:47:47 +00:00
dawn_wire: Support chunked commands
This CL adds support for chunking large commands by first serializing large commands first into a separate buffer, and then sending the buffer data chunk by chunk. This code path is used for large writeBuffer and writeTexture, as well as the inline memory transfer service for buffer mapping. The transfer for writeBuffer and writeTexture will be optimized further in Chrome, and the inline memory transfer service is currently used only in tests. Bug: chromium:1123861, chromium:951558 Change-Id: I02491a44e653e2383174958d9c3d4a4db6fd7bde Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/28882 Commit-Queue: Austin Eng <enga@chromium.org> Reviewed-by: Stephen White <senorblanco@chromium.org>
This commit is contained in:
committed by
Commit Bot service account
parent
ccaef85257
commit
cac0442277
@@ -99,11 +99,12 @@ namespace {
|
||||
{% macro write_record_serialization_helpers(record, name, members, is_cmd=False, is_return_command=False) %}
|
||||
{% set Return = "Return" if is_return_command else "" %}
|
||||
{% set Cmd = "Cmd" if is_cmd else "" %}
|
||||
{% set Inherits = " : CmdHeader" if is_cmd else "" %}
|
||||
|
||||
//* Structure for the wire format of each of the records. Members that are values
|
||||
//* are embedded directly in the structure. Other members are assumed to be in the
|
||||
//* memory directly following the structure in the buffer.
|
||||
struct {{Return}}{{name}}Transfer {
|
||||
struct {{Return}}{{name}}Transfer{{Inherits}} {
|
||||
static_assert({{[is_cmd, record.extensible, record.chained].count(True)}} <= 1,
|
||||
"Record must be at most one of is_cmd, extensible, and chained.");
|
||||
{% if is_cmd %}
|
||||
@@ -130,6 +131,11 @@ namespace {
|
||||
{% endfor %}
|
||||
};
|
||||
|
||||
{% if is_cmd %}
|
||||
static_assert(offsetof({{Return}}{{name}}Transfer, commandSize) == 0, "");
|
||||
static_assert(offsetof({{Return}}{{name}}Transfer, commandId) == sizeof(CmdHeader), "");
|
||||
{% endif %}
|
||||
|
||||
{% if record.chained %}
|
||||
static_assert(offsetof({{Return}}{{name}}Transfer, chain) == 0, "");
|
||||
{% endif %}
|
||||
@@ -379,12 +385,13 @@ namespace {
|
||||
return size;
|
||||
}
|
||||
|
||||
void {{Cmd}}::Serialize(char* buffer
|
||||
void {{Cmd}}::Serialize(size_t commandSize, char* buffer
|
||||
{%- if not is_return -%}
|
||||
, const ObjectIdProvider& objectIdProvider
|
||||
{%- endif -%}
|
||||
) const {
|
||||
auto transfer = reinterpret_cast<{{Name}}Transfer*>(buffer);
|
||||
transfer->commandSize = commandSize;
|
||||
buffer += sizeof({{Name}}Transfer);
|
||||
|
||||
{{Name}}Serialize(*this, transfer, &buffer
|
||||
|
||||
@@ -92,6 +92,10 @@ namespace dawn_wire {
|
||||
{% endfor %}
|
||||
};
|
||||
|
||||
struct CmdHeader {
|
||||
uint64_t commandSize;
|
||||
};
|
||||
|
||||
{% macro write_command_struct(command, is_return_command) %}
|
||||
{% set Return = "Return" if is_return_command else "" %}
|
||||
{% set Cmd = command.name.CamelCase() + "Cmd" %}
|
||||
@@ -101,7 +105,7 @@ namespace dawn_wire {
|
||||
|
||||
//* Serialize the structure and everything it points to into serializeBuffer which must be
|
||||
//* big enough to contain all the data (as queried from GetRequiredSize).
|
||||
void Serialize(char* serializeBuffer
|
||||
void Serialize(size_t commandSize, char* serializeBuffer
|
||||
{%- if not is_return_command -%}
|
||||
, const ObjectIdProvider& objectIdProvider
|
||||
{%- endif -%}
|
||||
|
||||
@@ -15,13 +15,14 @@
|
||||
#ifndef DAWNWIRE_CLIENT_CLIENTBASE_AUTOGEN_H_
|
||||
#define DAWNWIRE_CLIENT_CLIENTBASE_AUTOGEN_H_
|
||||
|
||||
#include "dawn_wire/ChunkedCommandHandler.h"
|
||||
#include "dawn_wire/WireCmd_autogen.h"
|
||||
#include "dawn_wire/client/ApiObjects.h"
|
||||
#include "dawn_wire/client/ObjectAllocator.h"
|
||||
|
||||
namespace dawn_wire { namespace client {
|
||||
|
||||
class ClientBase : public ObjectIdProvider {
|
||||
class ClientBase : public ChunkedCommandHandler, public ObjectIdProvider {
|
||||
public:
|
||||
ClientBase() {
|
||||
}
|
||||
|
||||
@@ -53,10 +53,20 @@ namespace dawn_wire { namespace client {
|
||||
}
|
||||
{% endfor %}
|
||||
|
||||
const volatile char* Client::HandleCommands(const volatile char* commands, size_t size) {
|
||||
while (size >= sizeof(ReturnWireCmd)) {
|
||||
ReturnWireCmd cmdId = *reinterpret_cast<const volatile ReturnWireCmd*>(commands);
|
||||
const volatile char* Client::HandleCommandsImpl(const volatile char* commands, size_t size) {
|
||||
while (size >= sizeof(CmdHeader) + sizeof(ReturnWireCmd)) {
|
||||
// Start by chunked command handling, if it is done, then it means the whole buffer
|
||||
// was consumed by it, so we return a pointer to the end of the commands.
|
||||
switch (HandleChunkedCommands(commands, size)) {
|
||||
case ChunkedCommandsResult::Consumed:
|
||||
return commands + size;
|
||||
case ChunkedCommandsResult::Error:
|
||||
return nullptr;
|
||||
case ChunkedCommandsResult::Passthrough:
|
||||
break;
|
||||
}
|
||||
|
||||
ReturnWireCmd cmdId = *reinterpret_cast<const volatile ReturnWireCmd*>(commands + sizeof(CmdHeader));
|
||||
bool success = false;
|
||||
switch (cmdId) {
|
||||
{% for command in cmd_records["return command"] %}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#define DAWNWIRE_SERVER_SERVERBASE_H_
|
||||
|
||||
#include "dawn/dawn_proc_table.h"
|
||||
#include "dawn_wire/ChunkedCommandHandler.h"
|
||||
#include "dawn_wire/Wire.h"
|
||||
#include "dawn_wire/WireCmd_autogen.h"
|
||||
#include "dawn_wire/WireDeserializeAllocator.h"
|
||||
@@ -23,7 +24,7 @@
|
||||
|
||||
namespace dawn_wire { namespace server {
|
||||
|
||||
class ServerBase : public ObjectIdResolver {
|
||||
class ServerBase : public ChunkedCommandHandler, public ObjectIdResolver {
|
||||
public:
|
||||
ServerBase() = default;
|
||||
virtual ~ServerBase() = default;
|
||||
|
||||
@@ -89,12 +89,22 @@ namespace dawn_wire { namespace server {
|
||||
}
|
||||
{% endfor %}
|
||||
|
||||
const volatile char* Server::HandleCommands(const volatile char* commands, size_t size) {
|
||||
const volatile char* Server::HandleCommandsImpl(const volatile char* commands, size_t size) {
|
||||
mProcs.deviceTick(DeviceObjects().Get(1)->handle);
|
||||
|
||||
while (size >= sizeof(WireCmd)) {
|
||||
WireCmd cmdId = *reinterpret_cast<const volatile WireCmd*>(commands);
|
||||
while (size >= sizeof(CmdHeader) + sizeof(WireCmd)) {
|
||||
// Start by chunked command handling, if it is done, then it means the whole buffer
|
||||
// was consumed by it, so we return a pointer to the end of the commands.
|
||||
switch (HandleChunkedCommands(commands, size)) {
|
||||
case ChunkedCommandsResult::Consumed:
|
||||
return commands + size;
|
||||
case ChunkedCommandsResult::Error:
|
||||
return nullptr;
|
||||
case ChunkedCommandsResult::Passthrough:
|
||||
break;
|
||||
}
|
||||
|
||||
WireCmd cmdId = *reinterpret_cast<const volatile WireCmd*>(commands + sizeof(CmdHeader));
|
||||
bool success = false;
|
||||
switch (cmdId) {
|
||||
{% for command in cmd_records["command"] %}
|
||||
|
||||
Reference in New Issue
Block a user