#define UREG_MAX_SYSTEM_VALUE PIPE_MAX_ATTRIBS
#define UREG_MAX_OUTPUT (4 * PIPE_MAX_SHADER_OUTPUTS)
#define UREG_MAX_CONSTANT_RANGE 32
+#define UREG_MAX_HW_ATOMIC_RANGE 32
#define UREG_MAX_IMMEDIATE 4096
#define UREG_MAX_ADDR 3
#define UREG_MAX_ARRAY_TEMPS 256
unsigned nr_constant_ranges;
};
+struct hw_atomic_decl {
+ struct {
+ unsigned first;
+ unsigned last;
+ unsigned array_id;
+ } hw_atomic_range[UREG_MAX_HW_ATOMIC_RANGE];
+ unsigned nr_hw_atomic_ranges;
+};
+
#define DOMAIN_DECL 0
#define DOMAIN_INSN 1
struct const_decl const_decls[PIPE_MAX_CONSTANT_BUFFERS];
+ struct hw_atomic_decl hw_atomic_decls[PIPE_MAX_HW_ATOMIC_BUFFERS];
+
unsigned properties[TGSI_PROPERTY_COUNT];
unsigned nr_addrs;
return ureg_src_dimension(src, 0);
}
+
+/* Returns a new hw atomic register. Keep track of which have been
+ * referred to so that we can emit decls later.
+ */
+void
+ureg_DECL_hw_atomic(struct ureg_program *ureg,
+ unsigned first,
+ unsigned last,
+ unsigned buffer_id,
+ unsigned array_id)
+{
+ struct hw_atomic_decl *decl = &ureg->hw_atomic_decls[buffer_id];
+
+ if (decl->nr_hw_atomic_ranges < UREG_MAX_HW_ATOMIC_RANGE) {
+ uint i = decl->nr_hw_atomic_ranges++;
+
+ decl->hw_atomic_range[i].first = first;
+ decl->hw_atomic_range[i].last = last;
+ decl->hw_atomic_range[i].array_id = array_id;
+ } else {
+ set_bad(ureg);
+ }
+}
+
static struct ureg_dst alloc_temporary( struct ureg_program *ureg,
boolean local )
{
}
}
+static void
+emit_decl_atomic_2d(struct ureg_program *ureg,
+ unsigned first,
+ unsigned last,
+ unsigned index2D,
+ unsigned array_id)
+{
+ union tgsi_any_token *out = get_tokens(ureg, DOMAIN_DECL, array_id ? 4 : 3);
+
+ out[0].value = 0;
+ out[0].decl.Type = TGSI_TOKEN_TYPE_DECLARATION;
+ out[0].decl.NrTokens = 3;
+ out[0].decl.File = TGSI_FILE_HW_ATOMIC;
+ out[0].decl.UsageMask = TGSI_WRITEMASK_XYZW;
+ out[0].decl.Dimension = 1;
+ out[0].decl.Array = array_id != 0;
+
+ out[1].value = 0;
+ out[1].decl_range.First = first;
+ out[1].decl_range.Last = last;
+
+ out[2].value = 0;
+ out[2].decl_dim.Index2D = index2D;
+
+ if (array_id) {
+ out[3].value = 0;
+ out[3].array.ArrayID = array_id;
+ }
+}
static void
emit_decl_fs(struct ureg_program *ureg,
}
}
+ for (i = 0; i < PIPE_MAX_HW_ATOMIC_BUFFERS; i++) {
+ struct hw_atomic_decl *decl = &ureg->hw_atomic_decls[i];
+
+ if (decl->nr_hw_atomic_ranges) {
+ uint j;
+
+ for (j = 0; j < decl->nr_hw_atomic_ranges; j++) {
+ emit_decl_atomic_2d(ureg,
+ decl->hw_atomic_range[j].first,
+ decl->hw_atomic_range[j].last,
+ i,
+ decl->hw_atomic_range[j].array_id);
+ }
+ }
+ }
+
if (ureg->nr_temps) {
unsigned array = 0;
for (i = 0; i < ureg->nr_temps;) {
concurrent memory access operation that affects the same memory
location is guaranteed to be performed strictly before or after the
entire execution of the atomic operation. The resource may be a BUFFER,
-IMAGE, or MEMORY. In the case of an image, the offset works the same as for
-``LOAD`` and ``STORE``, specified above. These atomic operations may
-only be used with 32-bit integer image formats.
+IMAGE, HWATOMIC, or MEMORY. In the case of an image, the offset works
+the same as for ``LOAD`` and ``STORE``, specified above. For atomic
+counters, the offset is an immediate index to the base hw atomic
+counter for this operation.
+These atomic operations may only be used with 32-bit integer image formats.
.. opcode:: ATOMUADD - Atomic integer addition
Usage of the STORE opcode is only allowed if the WR (writable) flag
is set.
+Hardware Atomic Register File
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Hardware atomics are declared as a 2D array with an optional array id.
+
+The first member of the dimension is the buffer resource the atomic
+is located in.
+The second member is a range into the buffer resource, either for
+one or multiple counters. If this is an array, the declaration will have
+an unique array id.
+
+Each counter is 4 bytes in size, and index and ranges are in counters not bytes.
+DCL HWATOMIC[0][0]
+DCL HWATOMIC[0][1]
+
+This declares two atomics, one at the start of the buffer and one in the
+second 4 bytes.
+
+DCL HWATOMIC[0][0]
+DCL HWATOMIC[1][0]
+DCL HWATOMIC[1][1..3], ARRAY(1)
+
+This declares 5 atomics, one in buffer 0 at 0,
+one in buffer 1 at 0, and an array of 3 atomics in
+the buffer 1, starting at 1.
Properties
^^^^^^^^^^^^^^^^^^^^^^^^