From 267f035721bb5a769945e6bd6be5c97cc0b4223e Mon Sep 17 00:00:00 2001 From: John Zulauf Date: Thu, 15 Jun 2023 16:43:48 -0600 Subject: [PATCH] docs: rewrite alias section to use opaque --- docs/images/sync_alias_example1_ops.svg | 118 +++--------------------- docs/images/sync_alias_example_1.svg | 18 ++-- docs/synchronization.md | 66 ++++++------- 3 files changed, 47 insertions(+), 155 deletions(-) diff --git a/docs/images/sync_alias_example1_ops.svg b/docs/images/sync_alias_example1_ops.svg index dfacae73996..21f6d170e9e 100644 --- a/docs/images/sync_alias_example1_ops.svg +++ b/docs/images/sync_alias_example1_ops.svg @@ -36,13 +36,13 @@ fit-margin-bottom="0" inkscape:zoom="3.3068182" inkscape:cx="194.29553" - inkscape:cy="144.70103" + inkscape:cy="144.85223" inkscape:window-width="2348" - inkscape:window-height="2000" - inkscape:window-x="988" - inkscape:window-y="73" + inkscape:window-height="1851" + inkscape:window-x="593" + inkscape:window-y="182" inkscape:window-maximized="0" - inkscape:current-layer="layer4" /> + inkscape:current-layer="id10" /> @@ -365,23 +365,7 @@ fill="none" stroke="#3465a4" d="M 7350,6396 H 2270 v -317 h 10160 v 317 z" - id="path2021" />BI0I1I2I0I1 + inkscape:current-layer="g797" /> @@ -380,7 +380,6 @@ height="6580.3901" x="1094.2671" y="635.85791" />Idealized BindingOpaque RangeLinear BindingLinear Range @@ -1494,11 +1488,11 @@ These three representations are needed to model the read (r) and write (w) acces sync_alias_example1_ops -The effect of each operation is shown above. Accesses to linear resources (wc and rd) are tracked in a byte accurate way within ***M***. Likewise, accesses to non-linear, tiled resources (wa and rb) are tracked in a bytewise *consistent* way within ***A0***. Since the actual organization of tiled images is arbitrary, any arbitrary, consistent representation can be used within ***A0*** for accurate synchronization validation, even though it may not reflect any implementation. Because the memory organization is arbitrary for tiled images, any pixel could exists at any address within the linear bound range. Accesses to any portion of a non-linear image must be treated (for purposes of validation) as accesses to all bytes within the bound range -- "any access affects all locations". The linear representation of a set of accesses is the union of accesses found within the idealized representation. The Idealized representation allows for byte accurate hazard detection between consistent aliases of the same memory range. The linear representation allows for byte accurate hazard detection between linear resources (buffers and non-tiled images), a between non-linear resources and/or between linear and non-linear resources. +The effect of each operation is shown above. Accesses to linear resources (wc and rd) are tracked in a byte accurate way within ***M***. Likewise, accesses to non-linear, tiled resources (wa and rb) are tracked in a bytewise *consistent* way within ***A0***. Since the actual organization of tiled images is arbitrary, any arbitrary, consistent representation can be used within ***A0*** for accurate synchronization validation, even though it may not reflect any implementation. Because the memory organization is arbitrary for tiled images, any pixel could exists at any address within the linear bound range. Accesses to any portion of a non-linear image must be treated (for purposes of validation) as accesses to all bytes within the bound range -- "any access affects all locations". The linear representation of a set of accesses is the union of accesses found within the opaque representation. The Synchronization Validation internal representation allows for byte accurate hazard detection between consistent aliases of the same memory range. The linear representation allows for byte accurate hazard detection between linear resources (buffers and non-tiled images), a between non-linear resources and/or between linear and non-linear resources. We can see the usage of the various representation for hazard detection between the above operations. -| Access pair
(before, after) | Idealized | Linear | Comments | +| Access pair
(before, after) | Opaque | Linear | Comments | | -------- | ---- | -------- | -------- | | wa, rb | No hazard | N/A | Since a consistent interpretation is possible (***A0***), only that representation need be tested. | | wa, wc | N/A | WAW | wa must be considered to affect the entire bound range, thus the portion of wc overlapping I1 constitutes a hazard | @@ -1513,15 +1507,9 @@ Were ***I2*** to be tiled instead of linear, an additional representation ***A1* #### Access tagging -The Consistent Alias Group represents any number of images which satisfy the aliasing criteria for non-linear (tiled) images. The are denoted by a unique id (`AliasID`), likely represented by strictly increasing integer. New `AliasID` values are created each time a novel Consistent Alias Group is created, regardless of memory aliasing or reuse. When an `AliasID` is created, a range of ValidationStateTracker::fake_memory is allocated to represent the Idealized binding. This allows for a unified access map, obviating the need for separate Linear and Idealized address spaces. The second base address (the `idealized_base_address`) would be stored on a per image (see `SyncValImageState` below).There is a 1-1 mapping of `AliasID` to Idealized binding base address. Non-aliased images are also assigned a `AliasID`, as they represent a "group" of one, which can be use in the integrated `ResourceAccessState`. Each read and write access in the integrated state (see below) must be tagged with the `AliasID`. - -The `AliasID` of `AliasID::kLinear` is reserved for all resources that are linearly mapped (buffers, non-tiled images). - -***Note:*** *One could make the `AliasID` and `idealized_base_address` synonymous, at the cost of require the `AliasID` to be the size of `VkDeviceMemory`. (doubling the impact on the `ResourceAccessState` size).* - -#### `AliasID`Creation +The Consistent Alias Group represents any number of images which satisfy the aliasing criteria for non-linear (tiled) images (or other opaque resources). The are denoted by a unique id (`AliasID`), which is the starting address of the opaque range. As the opaque base address and range are already created at BindImageMemory and GetSwapchainImages time, the needed unique `AliasID` is known. Each read and write access in the integrated state (see below) must be tagged with the `AliasID`. -`AliasID` values are allocated during `BindImageMemory` and `CreateSwapchain` calls. The `AliasID` is assign to an Image at `BindImageMemory` and`CreatImage` calls depending on whether the image is bound to a`VkDeviceMemory` or `VkSwapchain` respectively. +The `AliasID` of `AliasID::kLinear` (with a value of 0, as 0 is reserved in the "fake" memory space) is reserved for all resources that are linearly mapped (buffers, non-tiled images). #### Optimization @@ -1529,13 +1517,13 @@ The most common scenario for memory usage is non-aliased. As memory aliasing ca #### Layer Derived Classes -To facilitate storage of `AliasID`, `has_inconsistent_alias`, and `idealized_base_address` information for a given image, the IMAGE_STATE needs to be derived with a child `SyncValImageState` class. +To facilitate storage of `AliasID`, `has_inconsistent_alias`, and `opaque_base_address` information for a given image, the IMAGE_STATE needs to be derived with a child `SyncValImageState` class. ### Integrated State -The contents of the bound range of a tiled (non-linear) resource reflects an integration of all access/barrier operation found with the Idealized binding. This integrated state updates the entire Linear binding for the resource. It reflects all read, write, and synchronization operations. The integration is lossy, as the specific subresource and pixel information of a given access is not retained, only it's existence *somewhere* within the Idealized binding. As such, the Linear binding update for tiled image resource cannot be incremental. The integration operation must be repeated for the whole of the Idealized binding, and applied to the entire Linear binding. +The contents of the Linear range of a tiled (opaque) resource reflects an integration of all access/barrier operation found with the opaque range for the resource. This integrated state updates the entire Linear range for the resource. It reflects all read and write operations, but not opaquely apply synchronization operations. The integration is lossy, as the specific subresource and pixel information of a given access is not retained, only it's existence *somewhere* within the opaque range. As such, the Linear range update for tiled image resources cannot be incremental. The integration operation must be repeated for the whole of the opaque range, and applied to the entire Linear range. -The integrated state is constructed by traversing all `ResourceAccessState` object within the Idealized binding. All unique read and write operations (stage/access/tag) are retained in the integrated state (both for current and first access information). To preserve the WAW detection logic ignoring WAW testing when intervening reads are present, as a "has_reads" flag read which is `true` IFF all references to a write/tag pair in the integrated range have intervening reads. For each unique read or write operation (stage/access/tag) the effective barrier and ordering rules are the intersection of the barriers and ordering rules (see **Note:**) of all references to the unique operation within the integrated range. +The integrated state is constructed by traversing all `ResourceAccessState` objects within the opaque range. Any access within the opaque range must be assumed to have happened at all locations within the Linear range. However, all image synchronization operations done within the opaque range must be assumed to *not* be applied at some location within the Linear range, and thus treated as if they were *not* applied at any location within the Linear range. All unique read and write operations (stage/access/tag) are retained in the integrated state (both for current and first access information). To preserve the WAW detection logic ignoring WAW testing when intervening reads are present, as a "has_reads" flag read which is `true` IFF all references to a write/tag pair in the integrated range have intervening reads. For each unique read or write operation (stage/access/tag) the effective barrier and ordering rules are the intersection of the barriers and ordering rules (see **Note:**) of all references to the unique operation within the integrated range. **Note:** `enum class SyncOrdering` is already (incidentally) a bit mask for `kColorAttachment`, `kDepthStencilAttachment`, and `kRaster`. This allows easy intersection of the ordering rules bitwise. This needs to be documented in the definition of of the `SyncOrdering`. @@ -1543,9 +1531,9 @@ The integrated state is constructed by traversing all `ResourceAccessState` obje ### Hazard Detection -For buffers and linear images, hazard detection is unchanged relative to pre-aliasing support. Accesses are validated against the Linear address `VkDeviceMemory` range affected. The effect of inconsistent memory alias access, if any, is recorded in the Linear binding by the update mechanism noted below. +For buffers and linear images, hazard detection is unchanged relative to pre-aliasing support. Accesses are validated against the Linear address `VkDeviceMemory` range affected. The effect of inconsistent memory alias access, if any, is recorded in the Linear range by the update mechanism noted below. -For tiled images every hazard detection and update operation now must be performed in against both Linear and Idealized bindings. Hazard detection is first performed against the image itself (including the consistent aliases). The hazard check is done on the exact Idealized memory location of the access or barrier operation. The second hazard check applies the same access or barrier, but against the entire Linear binding. Since the mapping of tiled image to Linear addresses is unknown, every access is considered to conflict with the entire bound Linear range. During this check the Linear `ResourceAccessState` information reflecting accesses *consistent* with the tiled image must be ignored. This requirement means that accesses must be tagged with an the `AliasID`. (Each read and write state.) +For tiled images every hazard detection and update operation now must be performed in against both Linear and opaque ranges. Hazard detection is first performed against the opaque range. The hazard check is done on the exact byte accurate location within the Synchronization Validation internal representation of the access or barrier operation. The second hazard check applies the same access or barrier, but against the entire Linear range. Since the mapping of tiled image to Linear addresses is unknown, every access is considered to conflict with the entire bound Linear range. During this check the Linear `ResourceAccessState` information reflecting accesses *consistent* with the tiled image must be ignored. This requirement means that accesses must be tagged with an `AliasID` for each read and write state. Any access within the Linear range tagged with the `AliasID` of the accessing resource is skipped during hazard checking. For all resource accesses, hazard detection must change to reflect the possibility of more than a single write operation or more than a single read operation per stage, in a given `ResourceAccessState` (resulting from Integration above). @@ -1570,9 +1558,9 @@ Updates of `ResourceAccessState` needs to be modified to include the `AliasID` o #### Update (from Integrated `ResourceAccessState`) -When updating the Linear binding associated with an Idealized binding update, the integrated access state is applied to the entire binding range. This operation differs for read and write operations. +When updating the Linear range associated with an opaque range update, the integrated access state is applied to the entire Linear range. This operation differs for read and write operations. - For updates associated with read operations, only the read stages of the Linear binding entry matching the `AliasID` are updated from the the integrated state. If the last write operation of the Linear binding entry has the same `AliasID` as the integrated access state, all of the integrated access state matching the `AliasID` of the access are updated, with new read entries added. However, if the last write `AliasID` of the Linear binding entry does not match the `AliasID` of the integrated access state, then only read elements with tags greater than the last write tag are updated, and/or added. (most recent access logic). +For updates associated with read operations, only the read stages of the Linear range entry matching the `AliasID` are updated from the the integrated state. If the last write operation of the Linear range entry has the same `AliasID` as the integrated access state, all of the integrated access state matching the `AliasID` of the access are updated, with new read entries added. However, if the last write `AliasID` of the Linear range entry does not match the `AliasID` of the integrated access state, then only read elements with tags greater than the last write tag are updated, and/or added. (most recent access logic). If the update is associate with a write operation, the integrated state *replaces* all state information in the linear address range. This implies that even when more than one write operation is present, all write operations always have the same `AliasID` . We could save storage by not including an `AliasID` in the per write state. @@ -1582,10 +1570,10 @@ Barriers are applied regardless of `AliasID`. Barrier treatment varies by type o | Barrier Type | Barrier Application | | ------------------ | ------------------------------------------------------------ | -| **Memory** | Applied to all ranges, regardless of binding type (Linear vs. Idealized). No integration/update from the Idealized bindings to Linear bindings are required. | -| **Buffer** | Applied to Linear binding of buffer. Applied to any Idealized binding which is fully covered by the buffer region. No integration/update from the Idealized binding is required. | -| **Image (linear)** | Applied to Linear binding of image. Applied to any Idealized binding which is fully covered by any contiguous range affected. No integration/update from Idealized binding is required. | -| **Image (tiled)** | Applied to Idealized Binding. Integration/update from Idealized *is* required. Barrier hazard detection needs to be performed against Linear binding in the case of Image Layout Transitions. Since the source stage/access scope is only known to apply to the image, (and the image may not occupy every byte of the binding), the barrier hazard check is against all accesses not matching the `AliasID` of the image barrier without apply the source stage/access barrier. (i.e. only not a hazard if no accesses not matching `AliasID` are present in the Linear binding) | +| **Memory** | Applied to all ranges, regardless of range type (Linear vs. opaque). No integration/update from the opaque ranges to Linear ranges are required. | +| **Buffer** | Applied to Linear range of the buffer. Applied to any opaque resource with a Linear range that is fully covered by the buffer region. No integration/update from the opaque range is required. | +| **Image (linear)** | Applied to Linear range of image at byte accuracy. Applied to any opaque resource with a Linear range which is fully covered by any contiguous range affected. No integration/update from opaque range is required. | +| **Image (tiled)** | Applied to opaque range. Integration/update from opaque range*is* required. Barrier hazard detection needs to be performed against Linear range in the case of Image Layout Transitions. Since the source stage/access scope is only known to apply to the image, (and the image may not occupy every byte of the Linear range), the barrier hazard check is against all accesses not matching the `AliasID` of the image barrier without apply the source stage/access barrier. (i.e. only not a hazard if no accesses not matching `AliasID` are present in the Linear range for the image) | #### Resolve @@ -1603,9 +1591,9 @@ The updated resolve logic (for used combining parallel `AccessContext` graphs) ##### Current Usage -As hazard detection of the Linear binding requires additional scoping to avoid false positives against the `AliasID` corresponding to the updated tiled image. `ResourceAccessContext::DetectHazard` member functions will require addition of an `AliasID` argument when they are performed on Linear bindings. +As hazard detection of the Linear range requires additional scoping to avoid false positives against the `AliasID` corresponding to the updated tiled image. `ResourceAccessContext::DetectHazard` member functions will require addition of an `AliasID` argument when they are performed on Linear ranges. -As only accesses consistent with the recorded `AliasID` are present in the Idealized binding, no additional scope test is needed for hazard detection on Idealized bindings. However, when detecting hazard conditions from accesses to non-tiled resources, no accesses within the Linear binding are ignored. +As only accesses consistent with the recorded `AliasID` are present in the opaque ranges, no additional scope test is needed for hazard detection on opaque ranges. However, when detecting hazard conditions from accesses to non-tiled resources, no accesses within the Linear resources are ignored. ***Implementation Idea:*** As opposed to having a flag controlling "ignore" behavior, simply passing an `AliasID ignore_id` argument, with a `AliasID::kInvalid` defined that is never used (effective disabling the `AliasID` masking). @@ -1615,7 +1603,7 @@ As only accesses consistent with the recorded `AliasID` are present in the Ideal The `DetectHazard` taking recorded usage (in the `DetectFirstUseHazard` path) will also need modification to -* Accept argument to specific the scope rule used for Idealized or Linear binding (***Note:*** *likely need to tag all `ResourceAccessStates` with Linear/Idealized boolean*) +* Accept argument to specific the scope rule used for Linear or opaque ranges (***Note:*** *likely need to tag all `ResourceAccessStates` with Linear/opaque boolean*) * Pass extracted recorded `AliasID` and scope rule information from first use information to underlying `DetectHazard` overrides. ### AccessContext Updates