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