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/** 24 * @file iris_binder.c 25 * 26 * Shader programs refer to most resources via integer handles. These are 27 * indexes (BTIs) into a "Binding Table", which is simply a list of pointers 28 * to SURFACE_STATE entries. Each shader stage has its own binding table, 29 * set by the 3DSTATE_BINDING_TABLE_POINTERS_* commands. We stream out 30 * binding tables dynamically, storing them in special BOs we call "binders." 31 * 32 * Unfortunately, the hardware designers made 3DSTATE_BINDING_TABLE_POINTERS 33 * only accept a 16-bit pointer. This means that all binding tables have to 34 * live within the 64kB range starting at Surface State Base Address. (The 35 * actual SURFACE_STATE entries can live anywhere in the 4GB zone, as the 36 * binding table entries are full 32-bit pointers.) 37 * 38 * To handle this, we split a 4GB region of VMA into two memory zones. 39 * IRIS_MEMZONE_BINDER is a 1GB region at the bottom able to hold a few 40 * binder BOs. IRIS_MEMZONE_SURFACE contains the rest of the 4GB, and is 41 * always at a higher address than the binders. This allows us to program 42 * Surface State Base Address to the binder BO's address, and offset the 43 * values in the binding table to account for the base not starting at the 44 * beginning of the 4GB region. 45 * 46 * This does mean that we have to emit STATE_BASE_ADDRESS and stall when 47 * we run out of space in the binder, which hopefully won't happen too often. 48 */ 49 50#include <stdlib.h> 51#include "util/u_math.h" 52#include "iris_binder.h" 53#include "iris_bufmgr.h" 54#include "iris_context.h" 55 56static bool 57binder_has_space(struct iris_binder *binder, unsigned size) 58{ 59 return binder->insert_point + size <= binder->size; 60} 61 62static void 63binder_realloc(struct iris_context *ice) 64{ 65 struct iris_screen *screen = (void *) ice->ctx.screen; 66 struct iris_bufmgr *bufmgr = screen->bufmgr; 67 struct iris_binder *binder = &ice->state.binder; 68 69 if (binder->bo) 70 iris_bo_unreference(binder->bo); 71 72 binder->bo = iris_bo_alloc(bufmgr, "binder", binder->size, binder->alignment, 73 IRIS_MEMZONE_BINDER, 4096); 74 binder->map = iris_bo_map(NULL, binder->bo, MAP_WRITE); 75 76 /* Avoid using offset 0 - tools consider it NULL. */ 77 binder->insert_point = binder->alignment; 78 79 /* Allocating a new binder requires changing Surface State Base Address, 80 * which also invalidates all our previous binding tables - each entry 81 * in those tables is an offset from the old base. 82 * 83 * We do this here so that iris_binder_reserve_3d correctly gets a new 84 * larger total_size when making the updated reservation. 85 * 86 * Gfx11+ simply updates the binding table pool address instead, which 87 * means the old binding table's contents are still valid. Nevertheless, 88 * it still lives in the old BO, so we'd at least need to copy it to the 89 * new one. Instead, we just flag it dirty and re-emit it anyway. 90 */ 91 ice->state.dirty |= IRIS_DIRTY_RENDER_BUFFER; 92 ice->state.stage_dirty |= IRIS_ALL_STAGE_DIRTY_BINDINGS; 93} 94 95static uint32_t 96binder_insert(struct iris_binder *binder, unsigned size) 97{ 98 uint32_t offset = binder->insert_point; 99 100 binder->insert_point = 101 align(binder->insert_point + size, binder->alignment); 102 103 return offset; 104} 105 106/** 107 * Reserve a block of space in the binder, given the raw size in bytes. 108 */ 109uint32_t 110iris_binder_reserve(struct iris_context *ice, 111 unsigned size) 112{ 113 struct iris_binder *binder = &ice->state.binder; 114 115 if (!binder_has_space(binder, size)) 116 binder_realloc(ice); 117 118 assert(size > 0); 119 return binder_insert(binder, size); 120} 121 122/** 123 * Reserve and record binder space for 3D pipeline shader stages. 124 * 125 * Note that you must actually populate the new binding tables after 126 * calling this command - the new area is uninitialized. 127 */ 128void 129iris_binder_reserve_3d(struct iris_context *ice) 130{ 131 struct iris_compiled_shader **shaders = ice->shaders.prog; 132 struct iris_binder *binder = &ice->state.binder; 133 unsigned sizes[MESA_SHADER_STAGES] = {}; 134 unsigned total_size; 135 136 /* If nothing is dirty, skip all this. */ 137 if (!(ice->state.dirty & IRIS_DIRTY_RENDER_BUFFER) && 138 !(ice->state.stage_dirty & IRIS_ALL_STAGE_DIRTY_BINDINGS_FOR_RENDER)) 139 return; 140 141 /* Get the binding table sizes for each stage */ 142 for (int stage = 0; stage <= MESA_SHADER_FRAGMENT; stage++) { 143 if (!shaders[stage]) 144 continue; 145 146 /* Round up the size so our next table has an aligned starting offset */ 147 sizes[stage] = align(shaders[stage]->bt.size_bytes, binder->alignment); 148 } 149 150 /* Make space for the new binding tables...this may take two tries. */ 151 while (true) { 152 total_size = 0; 153 for (int stage = 0; stage <= MESA_SHADER_FRAGMENT; stage++) { 154 if (ice->state.stage_dirty & (IRIS_STAGE_DIRTY_BINDINGS_VS << stage)) 155 total_size += sizes[stage]; 156 } 157 158 assert(total_size < binder->size); 159 160 if (total_size == 0) 161 return; 162 163 if (binder_has_space(binder, total_size)) 164 break; 165 166 /* It didn't fit. Allocate a new buffer and try again. Note that 167 * this will flag all bindings dirty, which may increase total_size 168 * on the next iteration. 169 */ 170 binder_realloc(ice); 171 } 172 173 /* Assign space and record the new binding table offsets. */ 174 uint32_t offset = binder_insert(binder, total_size); 175 176 for (int stage = 0; stage <= MESA_SHADER_FRAGMENT; stage++) { 177 if (ice->state.stage_dirty & (IRIS_STAGE_DIRTY_BINDINGS_VS << stage)) { 178 binder->bt_offset[stage] = sizes[stage] > 0 ? offset : 0; 179 iris_record_state_size(ice->state.sizes, 180 binder->bo->address + offset, sizes[stage]); 181 offset += sizes[stage]; 182 } 183 } 184} 185 186void 187iris_binder_reserve_compute(struct iris_context *ice) 188{ 189 if (!(ice->state.stage_dirty & IRIS_STAGE_DIRTY_BINDINGS_CS)) 190 return; 191 192 struct iris_binder *binder = &ice->state.binder; 193 struct iris_compiled_shader *shader = 194 ice->shaders.prog[MESA_SHADER_COMPUTE]; 195 196 unsigned size = shader->bt.size_bytes; 197 198 if (size == 0) 199 return; 200 201 binder->bt_offset[MESA_SHADER_COMPUTE] = iris_binder_reserve(ice, size); 202} 203 204void 205iris_init_binder(struct iris_context *ice) 206{ 207 struct iris_screen *screen = (void *) ice->ctx.screen; 208 const struct intel_device_info *devinfo = &screen->devinfo; 209 210 memset(&ice->state.binder, 0, sizeof(struct iris_binder)); 211 212 /* We use different binding table pointer formats on various generations. 213 * 214 * - The 20:5 format gives us an alignment of 32B and max size of 1024kB. 215 * - The 18:8 format gives us an alignment of 256B and max size of 512kB. 216 * - The 15:5 format gives us an alignment of 32B and max size of 64kB. 217 * 218 * XeHP and later use the 20:5 format. Icelake and Tigerlake use 18:8 219 * in iris, but can use 15:5 if desired, Older platforms require 15:5. 220 */ 221 if (devinfo->verx10 >= 125) { 222 ice->state.binder.alignment = 32; 223 ice->state.binder.size = 1024 * 1024; 224 } else if (devinfo->ver >= 11) { 225 ice->state.binder.alignment = 256; 226 ice->state.binder.size = 512 * 1024; 227 } else { 228 ice->state.binder.alignment = 32; 229 ice->state.binder.size = 64 * 1024; 230 } 231 232 binder_realloc(ice); 233} 234 235void 236iris_destroy_binder(struct iris_binder *binder) 237{ 238 iris_bo_unreference(binder->bo); 239} 240