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 "intel_batchbuffer.h"
32
33 UNUSED static void *
emit_dwords(struct brw_context * brw,unsigned n)34 emit_dwords(struct brw_context *brw, unsigned n)
35 {
36 intel_batchbuffer_begin(brw, n);
37 uint32_t *map = brw->batch.map_next;
38 brw->batch.map_next += n;
39 intel_batchbuffer_advance(brw);
40 return map;
41 }
42
43 struct 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
52 static uint64_t
__gen_combine_address(struct brw_context * brw,void * location,struct brw_address address,uint32_t delta)53 __gen_combine_address(struct brw_context *brw, void *location,
54 struct brw_address address, uint32_t delta)
55 {
56 struct intel_batchbuffer *batch = &brw->batch;
57 uint32_t offset;
58
59 if (address.bo == NULL) {
60 return address.offset + delta;
61 } else {
62 if (GEN_GEN < 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
78 UNUSED static struct brw_address
rw_bo(struct brw_bo * bo,uint32_t offset)79 rw_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
88 UNUSED static struct brw_address
ro_bo(struct brw_bo * bo,uint32_t offset)89 ro_bo(struct brw_bo *bo, uint32_t offset)
90 {
91 return (struct brw_address) {
92 .bo = bo,
93 .offset = offset,
94 };
95 }
96
97 UNUSED static struct brw_address
rw_32_bo(struct brw_bo * bo,uint32_t offset)98 rw_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
107 UNUSED static struct brw_address
ro_32_bo(struct brw_bo * bo,uint32_t offset)108 ro_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
117 UNUSED static struct brw_address
ggtt_bo(struct brw_bo * bo,uint32_t offset)118 ggtt_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