blob: 3a51035d09a1bc8c42eec4414f9509b11a0af57c [file] [log] [blame]
Ryan Harrisondbc13af2022-02-21 15:19:07 +00001// Copyright 2021 The Tint Authors.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#ifndef SRC_TINT_TRANSFORM_DECOMPOSE_MEMORY_ACCESS_H_
16#define SRC_TINT_TRANSFORM_DECOMPOSE_MEMORY_ACCESS_H_
17
18#include <string>
19
20#include "src/tint/ast/internal_attribute.h"
21#include "src/tint/transform/transform.h"
22
Ryan Harrisondbc13af2022-02-21 15:19:07 +000023// Forward declarations
dan sinclairb5599d32022-04-07 16:55:14 +000024namespace tint {
Ryan Harrisondbc13af2022-02-21 15:19:07 +000025class CloneContext;
Ben Claytona7230f02022-04-11 14:37:21 +000026} // namespace tint
Ryan Harrisondbc13af2022-02-21 15:19:07 +000027
dan sinclairb5599d32022-04-07 16:55:14 +000028namespace tint::transform {
Ryan Harrisondbc13af2022-02-21 15:19:07 +000029
30/// DecomposeMemoryAccess is a transform used to replace storage and uniform
31/// buffer accesses with a combination of load, store or atomic functions on
32/// primitive types.
dan sinclair41e4d9a2022-05-01 14:40:55 +000033class DecomposeMemoryAccess final : public Castable<DecomposeMemoryAccess, Transform> {
34 public:
35 /// Intrinsic is an InternalAttribute that's used to decorate a stub function
36 /// so that the HLSL transforms this into calls to
37 /// `[RW]ByteAddressBuffer.Load[N]()` or `[RW]ByteAddressBuffer.Store[N]()`,
38 /// with a possible cast.
39 class Intrinsic final : public Castable<Intrinsic, ast::InternalAttribute> {
40 public:
41 /// Intrinsic op
42 enum class Op {
43 kLoad,
44 kStore,
45 kAtomicLoad,
46 kAtomicStore,
47 kAtomicAdd,
48 kAtomicSub,
49 kAtomicMax,
50 kAtomicMin,
51 kAtomicAnd,
52 kAtomicOr,
53 kAtomicXor,
54 kAtomicExchange,
55 kAtomicCompareExchangeWeak,
56 };
Ryan Harrisondbc13af2022-02-21 15:19:07 +000057
dan sinclair41e4d9a2022-05-01 14:40:55 +000058 /// Intrinsic data type
59 enum class DataType {
60 kU32,
61 kF32,
62 kI32,
Zhaoming Jiangab9b5f32022-11-24 05:25:35 +000063 kF16,
dan sinclair41e4d9a2022-05-01 14:40:55 +000064 kVec2U32,
65 kVec2F32,
66 kVec2I32,
Zhaoming Jiangab9b5f32022-11-24 05:25:35 +000067 kVec2F16,
dan sinclair41e4d9a2022-05-01 14:40:55 +000068 kVec3U32,
69 kVec3F32,
70 kVec3I32,
Zhaoming Jiangab9b5f32022-11-24 05:25:35 +000071 kVec3F16,
dan sinclair41e4d9a2022-05-01 14:40:55 +000072 kVec4U32,
73 kVec4F32,
74 kVec4I32,
Zhaoming Jiangab9b5f32022-11-24 05:25:35 +000075 kVec4F16,
dan sinclair41e4d9a2022-05-01 14:40:55 +000076 };
77
78 /// Constructor
Ben Clayton4a92a3c2022-07-18 20:50:02 +000079 /// @param pid the identifier of the program that owns this node
80 /// @param nid the unique node identifier
dan sinclair41e4d9a2022-05-01 14:40:55 +000081 /// @param o the op of the intrinsic
dan sinclairff7cf212022-10-03 14:05:23 +000082 /// @param sc the address space of the buffer
dan sinclair41e4d9a2022-05-01 14:40:55 +000083 /// @param ty the data type of the intrinsic
dan sinclair18b21582023-01-21 19:56:49 +000084 Intrinsic(ProgramID pid, ast::NodeID nid, Op o, type::AddressSpace sc, DataType ty);
dan sinclair41e4d9a2022-05-01 14:40:55 +000085 /// Destructor
86 ~Intrinsic() override;
87
88 /// @return a short description of the internal attribute which will be
89 /// displayed as `@internal(<name>)`
90 std::string InternalName() const override;
91
92 /// Performs a deep clone of this object using the CloneContext `ctx`.
93 /// @param ctx the clone context
94 /// @return the newly cloned object
95 const Intrinsic* Clone(CloneContext* ctx) const override;
96
Antonio Maiorano08f4b552022-05-31 13:20:28 +000097 /// @return true if op is atomic
98 bool IsAtomic() const;
99
dan sinclair41e4d9a2022-05-01 14:40:55 +0000100 /// The op of the intrinsic
101 const Op op;
102
dan sinclairff7cf212022-10-03 14:05:23 +0000103 /// The address space of the buffer this intrinsic operates on
dan sinclair18b21582023-01-21 19:56:49 +0000104 type::AddressSpace const address_space;
dan sinclair41e4d9a2022-05-01 14:40:55 +0000105
106 /// The type of the intrinsic
107 const DataType type;
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000108 };
109
110 /// Constructor
dan sinclair41e4d9a2022-05-01 14:40:55 +0000111 DecomposeMemoryAccess();
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000112 /// Destructor
dan sinclair41e4d9a2022-05-01 14:40:55 +0000113 ~DecomposeMemoryAccess() override;
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000114
Ben Claytonc6b38142022-11-03 08:41:19 +0000115 /// @copydoc Transform::Apply
116 ApplyResult Apply(const Program* program,
117 const DataMap& inputs,
118 DataMap& outputs) const override;
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000119
Ben Claytonc6b38142022-11-03 08:41:19 +0000120 private:
dan sinclair41e4d9a2022-05-01 14:40:55 +0000121 struct State;
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000122};
123
dan sinclairb5599d32022-04-07 16:55:14 +0000124} // namespace tint::transform
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000125
126#endif // SRC_TINT_TRANSFORM_DECOMPOSE_MEMORY_ACCESS_H_