1/*
2 * Copyright © 2018 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 * DEALINGS IN THE SOFTWARE.
21 */
22
23#ifndef GENX_BOILERPLATE_H
24#define GENX_BOILERPLATE_H
25
26#include <assert.h>
27
28#include "genxml/gen_macros.h"
29
30#include "brw_context.h"
31#include "brw_batch.h"
32
33UNUSED static void *
34emit_dwords(struct brw_context *brw, unsigned n)
35{
36   brw_batch_begin(brw, n);
37   uint32_t *map = brw->batch.map_next;
38   brw->batch.map_next += n;
39   brw_batch_advance(brw);
40   return map;
41}
42
43struct brw_address {
44   struct brw_bo *bo;
45   unsigned reloc_flags;
46   uint32_t offset;
47};
48
49#define __gen_address_type struct brw_address
50#define __gen_user_data struct brw_context
51
52static uint64_t
53__gen_combine_address(struct brw_context *brw, void *location,
54                      struct brw_address address, uint32_t delta)
55{
56   struct brw_batch *batch = &brw->batch;
57   uint32_t offset;
58
59   if (address.bo == NULL) {
60      return address.offset + delta;
61   } else {
62      if (GFX_VER < 6 && brw_ptr_in_state_buffer(batch, location)) {
63         offset = (char *) location - (char *) brw->batch.state.map;
64         return brw_state_reloc(batch, offset, address.bo,
65                                address.offset + delta,
66                                address.reloc_flags);
67      }
68
69      assert(!brw_ptr_in_state_buffer(batch, location));
70
71      offset = (char *) location - (char *) brw->batch.batch.map;
72      return brw_batch_reloc(batch, offset, address.bo,
73                             address.offset + delta,
74                             address.reloc_flags);
75   }
76}
77
78UNUSED static struct brw_address
79rw_bo(struct brw_bo *bo, uint32_t offset)
80{
81   return (struct brw_address) {
82            .bo = bo,
83            .offset = offset,
84            .reloc_flags = RELOC_WRITE,
85   };
86}
87
88UNUSED static struct brw_address
89ro_bo(struct brw_bo *bo, uint32_t offset)
90{
91   return (struct brw_address) {
92            .bo = bo,
93            .offset = offset,
94   };
95}
96
97UNUSED static struct brw_address
98rw_32_bo(struct brw_bo *bo, uint32_t offset)
99{
100   return (struct brw_address) {
101            .bo = bo,
102            .offset = offset,
103            .reloc_flags = RELOC_WRITE | RELOC_32BIT,
104   };
105}
106
107UNUSED static struct brw_address
108ro_32_bo(struct brw_bo *bo, uint32_t offset)
109{
110   return (struct brw_address) {
111            .bo = bo,
112            .offset = offset,
113            .reloc_flags = RELOC_32BIT,
114   };
115}
116
117UNUSED static struct brw_address
118ggtt_bo(struct brw_bo *bo, uint32_t offset)
119{
120   return (struct brw_address) {
121            .bo = bo,
122            .offset = offset,
123            .reloc_flags = RELOC_WRITE | RELOC_NEEDS_GGTT,
124   };
125}
126
127#include "genxml/genX_pack.h"
128
129#define _brw_cmd_length(cmd) cmd ## _length
130#define _brw_cmd_length_bias(cmd) cmd ## _length_bias
131#define _brw_cmd_header(cmd) cmd ## _header
132#define _brw_cmd_pack(cmd) cmd ## _pack
133
134#define brw_batch_emit(brw, cmd, name)                  \
135   for (struct cmd name = { _brw_cmd_header(cmd) },     \
136        *_dst = emit_dwords(brw, _brw_cmd_length(cmd)); \
137        __builtin_expect(_dst != NULL, 1);              \
138        _brw_cmd_pack(cmd)(brw, (void *)_dst, &name),   \
139        _dst = NULL)
140
141#define brw_batch_emitn(brw, cmd, n, ...) ({           \
142      uint32_t *_dw = emit_dwords(brw, n);             \
143      struct cmd template = {                          \
144         _brw_cmd_header(cmd),                         \
145         .DWordLength = n - _brw_cmd_length_bias(cmd), \
146         __VA_ARGS__                                   \
147      };                                               \
148      _brw_cmd_pack(cmd)(brw, _dw, &template);         \
149      _dw + 1; /* Array starts at dw[1] */             \
150   })
151
152#define brw_state_emit(brw, cmd, align, offset, name)              \
153   for (struct cmd name = {},                                      \
154        *_dst = brw_state_batch(brw, _brw_cmd_length(cmd) * 4,     \
155                                align, offset);                    \
156        __builtin_expect(_dst != NULL, 1);                         \
157        _brw_cmd_pack(cmd)(brw, (void *)_dst, &name),              \
158        _dst = NULL)
159
160#endif
161