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 
33 UNUSED static void *
emit_dwords(struct brw_context * brw,unsigned n)34 emit_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 
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 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 
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