Sitelet https://github.com/gpuweb/gpuweb/pull/419/files
Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 84 additions & 12 deletions spec/index.bs
Original file line number Diff line number Diff line change
Expand Up @@ -192,22 +192,45 @@ dictionary GPULimits {
</script>


Buffers {#buffers}
==================
# {{GPUBuffer}} # {#GPUBuffer}

## GPUBuffer ## {#buffer}
A {{GPUBuffer}} represents a block of memory that can be used in GPU operations.
Data is stored in linear layout, meaning that each byte of the allocation can be
addressed by its offset from the start of the {{GPUBuffer}}, subject to alignment
restrictions depending on the operation.

<script type=idl>
interface GPUBuffer : GPUObjectBase {
Promise<ArrayBuffer> mapReadAsync();
Promise<ArrayBuffer> mapWriteAsync();
void unmap();
{{GPUBuffer}} has the following internal slots:
Comment thread
Kangz marked this conversation as resolved.

void destroy();
};
</script>
<dl dfn-type=attribute dfn-for="GPUBuffer">
: <dfn>\[[size]]</dfn> of type {{GPUBufferSize}}.
::
The length of the {{GPUBuffer}} allocation in bytes.

### Creation ### {#buffer-creation}
: <dfn>\[[usage]]</dfn> of type {{GPUBufferUsageFlags}}.
::
The allowed usages for this {{GPUBuffer}}.

: <dfn>\[[state]]</dfn> of type [=buffer state=].
::
The current state of the {{GPUBuffer}}.
</dl>

Each {{GPUBuffer}} has a current <dfn dfn>buffer state</dfn> which is one of the following:

- "<dfn dfn for="buffer state">mapped</dfn>" where the {{GPUBuffer}} is available for CPU operations.
- "<dfn dfn for="buffer state">unmapped</dfn>" where the {{GPUBuffer}} is available for GPU operations.
- "<dfn dfn for="buffer state">destroyed</dfn>" where the {{GPUBuffer}} is no longer available for any operations except {{GPUBuffer/destroy}}.

Note:
{{GPUBuffer/[[size]]}} and {{GPUBuffer/[[usage]]}} are immutable once the {{GPUBuffer}} has been created.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO would no longer be needed with "readonly" above.


## Creation ## {#buffer-creation}

A {{GPUBuffer}} can be created in the "[=buffer state/unmapped=]" state using the {{GPUDevice}}.{{GPUDevice/createBuffer(descriptor)}} method.

### {{GPUBufferDescriptor}} ### {#GPUBufferDescriptor}

This specifies the options to use in creating a {{GPUBuffer}}.

<script type=idl>
dictionary GPUBufferDescriptor : GPUObjectDescriptorBase {
Expand All @@ -216,6 +239,40 @@ dictionary GPUBufferDescriptor : GPUObjectDescriptorBase {
};
</script>

<!-- TODO(kangz): Describe what are the {{device}} [[allowed buffer usages]] -->

<dl dfn-type="abstract-op">
: <dfn>validating GPUBufferDescriptor</dfn>(device, descriptor)
::
<div algorithm="validation GPUBufferDescriptor(device, descriptor)">

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some other specs seem to use present progressive tense, "validating GPUBufferDescriptor". Also I don't think the args are needed inside the algorithm name.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thinking about it more, it would make sense to make this be part of the "creating a GPUBuffer" algorithm. May or may not be useful to keep it separate from that.

1. If device is lost return false.
1. If any of the bits of |descriptor|'s {{GPUBufferDescriptor/usage}} aren't present in this device's [[allowed buffer usages]] return false.
Comment thread
Kangz marked this conversation as resolved.
1. If both the {{GPUBufferUsage/MAP_READ}} and {{GPUBufferUsage/MAP_WRITE}} bits of |descriptor|'s {{GPUBufferDescriptor/usage}} attribute are set, return false.
1. Return true.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, this appears to be written for the implementors
Would it be simpler if we describe it as:

Buffer creation fails if one of the conditions is true:

  1. Device is lost
  2. Any of the bits ...
  3. Usage contains both MAP_READ and MAP_WRITE ...

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an "algorithm" which means it's the procedure to do when "validating GPUBufferDescriptor". Other specs do this too. However since this has no return value it seems fine to flip it.

I think it's also that web specs are written more for browsers than for users. I'm personally ok with deviating from this because I see the tests as being the source of truth for browser implementers whenever possible.

</div>
</dl>

### {{GPUDevice/createBuffer(descriptor)|GPUDevice.createBuffer(descriptor)}} ### {#GPUDevice-createBuffer}

<dl dfn-type="method" dfn-for="GPUDevice">
: <dfn>createBuffer(descriptor)</dfn>
::
<div algorithm="GPUDevice.createBuffer(descriptor)">
1. If the result of [$validating GPUBufferDescriptor$](this, descriptor) is false:

1. Record a validation error in the current scope.
<!-- TODO(kangz): Once we have a description of the error monad, explain what the error buffer is. -->
1. Create an error buffer and return the result.
Comment thread
Kangz marked this conversation as resolved.

1. Let |b| be a new {{GPUBuffer}} object.
1. Set the {{GPUBuffer/[[size]]}} slot of |b| to the value of the {{GPUBufferDescriptor/size}} attribute of |descriptor|.
1. Set the {{GPUBuffer/[[usage]]}} slot of |b| to the value of the {{GPUBufferDescriptor/usage}} attribute of |descriptor|.
1. Set the {{GPUBuffer/[[state]]}} internal slot of |b| to `"unmapped"`.
1. Set each byte of |b|'s allocation to zero.
1. Return |b|.
</div>
</dl>

## Buffer Usage ## {#buffer-usage}

<script type=idl>
Expand All @@ -236,7 +293,16 @@ interface GPUBufferUsage {

## Buffer Mapping ## {#buffer-mapping}


<script type=idl>
interface GPUBuffer : GPUObjectBase {
Promise<ArrayBuffer> mapReadAsync();
Promise<ArrayBuffer> mapWriteAsync();
void unmap();

void destroy();
};

typedef sequence<any> GPUMappedBuffer;
</script>

Expand Down Expand Up @@ -1331,3 +1397,9 @@ partial interface GPUDevice {
attribute EventHandler onuncapturederror;
};
</script>

# Temporary usages of non-exported dfns ## {#temp-dfn-usages}

Eventually all of these should disappear but they are useful to avoid warning while building the specification.

[=buffer state/mapped=] [=buffer state/destroyed=]