1/* 2 * Copyright © 2013 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 (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 * IN THE SOFTWARE. 22 */ 23 24/** 25 * \file brw_binding_tables.c 26 * 27 * State atoms which upload the "binding table" for each shader stage. 28 * 29 * Binding tables map a numeric "surface index" to the SURFACE_STATE structure 30 * for a currently bound surface. This allows SEND messages (such as sampler 31 * or data port messages) to refer to a particular surface by number, rather 32 * than by pointer. 33 * 34 * The binding table is stored as a (sparse) array of SURFACE_STATE entries; 35 * surface indexes are simply indexes into the array. The ordering of the 36 * entries is entirely left up to software; see the SURF_INDEX_* macros in 37 * brw_context.h to see our current layout. 38 */ 39 40#include "main/mtypes.h" 41 42#include "brw_context.h" 43#include "brw_defines.h" 44#include "brw_state.h" 45#include "brw_batch.h" 46 47/** 48 * Upload a shader stage's binding table as indirect state. 49 * 50 * This copies brw_stage_state::surf_offset[] into the indirect state section 51 * of the batchbuffer (allocated by brw_state_batch()). 52 */ 53void 54brw_upload_binding_table(struct brw_context *brw, 55 uint32_t packet_name, 56 const struct brw_stage_prog_data *prog_data, 57 struct brw_stage_state *stage_state) 58{ 59 const struct intel_device_info *devinfo = &brw->screen->devinfo; 60 61 if (prog_data->binding_table.size_bytes == 0) { 62 /* There are no surfaces; skip making the binding table altogether. */ 63 if (stage_state->bind_bo_offset == 0 && devinfo->ver < 9) 64 return; 65 66 stage_state->bind_bo_offset = 0; 67 } else { 68 /* Upload a new binding table. */ 69 if (INTEL_DEBUG(DEBUG_SHADER_TIME)) { 70 brw_emit_buffer_surface_state( 71 brw, &stage_state->surf_offset[ 72 prog_data->binding_table.shader_time_start], 73 brw->shader_time.bo, 0, ISL_FORMAT_RAW, 74 brw->shader_time.bo->size, 1, RELOC_WRITE); 75 } 76 uint32_t *bind = 77 brw_state_batch(brw, prog_data->binding_table.size_bytes, 78 32, &stage_state->bind_bo_offset); 79 80 /* BRW_NEW_SURFACES and BRW_NEW_*_CONSTBUF */ 81 memcpy(bind, stage_state->surf_offset, 82 prog_data->binding_table.size_bytes); 83 } 84 85 brw->ctx.NewDriverState |= BRW_NEW_BINDING_TABLE_POINTERS; 86 87 if (devinfo->ver >= 7) { 88 BEGIN_BATCH(2); 89 OUT_BATCH(packet_name << 16 | (2 - 2)); 90 /* Align SurfaceStateOffset[16:6] format to [15:5] PS Binding Table field 91 * when hw-generated binding table is enabled. 92 */ 93 OUT_BATCH(stage_state->bind_bo_offset); 94 ADVANCE_BATCH(); 95 } 96} 97 98/** 99 * State atoms which upload the binding table for a particular shader stage. 100 * @{ 101 */ 102 103/** Upload the VS binding table. */ 104static void 105brw_vs_upload_binding_table(struct brw_context *brw) 106{ 107 /* BRW_NEW_VS_PROG_DATA */ 108 const struct brw_stage_prog_data *prog_data = brw->vs.base.prog_data; 109 brw_upload_binding_table(brw, 110 _3DSTATE_BINDING_TABLE_POINTERS_VS, 111 prog_data, 112 &brw->vs.base); 113} 114 115const struct brw_tracked_state brw_vs_binding_table = { 116 .dirty = { 117 .mesa = 0, 118 .brw = BRW_NEW_BATCH | 119 BRW_NEW_BLORP | 120 BRW_NEW_VS_CONSTBUF | 121 BRW_NEW_VS_PROG_DATA | 122 BRW_NEW_SURFACES, 123 }, 124 .emit = brw_vs_upload_binding_table, 125}; 126 127 128/** Upload the PS binding table. */ 129static void 130brw_upload_wm_binding_table(struct brw_context *brw) 131{ 132 /* BRW_NEW_FS_PROG_DATA */ 133 const struct brw_stage_prog_data *prog_data = brw->wm.base.prog_data; 134 brw_upload_binding_table(brw, 135 _3DSTATE_BINDING_TABLE_POINTERS_PS, 136 prog_data, 137 &brw->wm.base); 138} 139 140const struct brw_tracked_state brw_wm_binding_table = { 141 .dirty = { 142 .mesa = 0, 143 .brw = BRW_NEW_BATCH | 144 BRW_NEW_BLORP | 145 BRW_NEW_FS_PROG_DATA | 146 BRW_NEW_SURFACES, 147 }, 148 .emit = brw_upload_wm_binding_table, 149}; 150 151/** Upload the TCS binding table (if tessellation stages are active). */ 152static void 153brw_tcs_upload_binding_table(struct brw_context *brw) 154{ 155 /* Skip if the tessellation stages are disabled. */ 156 if (brw->programs[MESA_SHADER_TESS_EVAL] == NULL) 157 return; 158 159 /* BRW_NEW_TCS_PROG_DATA */ 160 const struct brw_stage_prog_data *prog_data = brw->tcs.base.prog_data; 161 brw_upload_binding_table(brw, 162 _3DSTATE_BINDING_TABLE_POINTERS_HS, 163 prog_data, 164 &brw->tcs.base); 165} 166 167const struct brw_tracked_state brw_tcs_binding_table = { 168 .dirty = { 169 .mesa = 0, 170 .brw = BRW_NEW_BATCH | 171 BRW_NEW_BLORP | 172 BRW_NEW_DEFAULT_TESS_LEVELS | 173 BRW_NEW_SURFACES | 174 BRW_NEW_TCS_CONSTBUF | 175 BRW_NEW_TCS_PROG_DATA, 176 }, 177 .emit = brw_tcs_upload_binding_table, 178}; 179 180/** Upload the TES binding table (if TES is active). */ 181static void 182brw_tes_upload_binding_table(struct brw_context *brw) 183{ 184 /* If there's no TES, skip changing anything. */ 185 if (brw->programs[MESA_SHADER_TESS_EVAL] == NULL) 186 return; 187 188 /* BRW_NEW_TES_PROG_DATA */ 189 const struct brw_stage_prog_data *prog_data = brw->tes.base.prog_data; 190 brw_upload_binding_table(brw, 191 _3DSTATE_BINDING_TABLE_POINTERS_DS, 192 prog_data, 193 &brw->tes.base); 194} 195 196const struct brw_tracked_state brw_tes_binding_table = { 197 .dirty = { 198 .mesa = 0, 199 .brw = BRW_NEW_BATCH | 200 BRW_NEW_BLORP | 201 BRW_NEW_SURFACES | 202 BRW_NEW_TES_CONSTBUF | 203 BRW_NEW_TES_PROG_DATA, 204 }, 205 .emit = brw_tes_upload_binding_table, 206}; 207 208/** Upload the GS binding table (if GS is active). */ 209static void 210brw_gs_upload_binding_table(struct brw_context *brw) 211{ 212 /* If there's no GS, skip changing anything. */ 213 if (brw->programs[MESA_SHADER_GEOMETRY] == NULL) 214 return; 215 216 /* BRW_NEW_GS_PROG_DATA */ 217 const struct brw_stage_prog_data *prog_data = brw->gs.base.prog_data; 218 brw_upload_binding_table(brw, 219 _3DSTATE_BINDING_TABLE_POINTERS_GS, 220 prog_data, 221 &brw->gs.base); 222} 223 224const struct brw_tracked_state brw_gs_binding_table = { 225 .dirty = { 226 .mesa = 0, 227 .brw = BRW_NEW_BATCH | 228 BRW_NEW_BLORP | 229 BRW_NEW_GS_CONSTBUF | 230 BRW_NEW_GS_PROG_DATA | 231 BRW_NEW_SURFACES, 232 }, 233 .emit = brw_gs_upload_binding_table, 234}; 235/** @} */ 236 237/** 238 * State atoms which emit 3DSTATE packets to update the binding table pointers. 239 * @{ 240 */ 241 242/** 243 * (Gfx4-5) Upload the binding table pointers for all shader stages. 244 * 245 * The binding table pointers are relative to the surface state base address, 246 * which points at the batchbuffer containing the streamed batch state. 247 */ 248static void 249gfx4_upload_binding_table_pointers(struct brw_context *brw) 250{ 251 BEGIN_BATCH(6); 252 OUT_BATCH(_3DSTATE_BINDING_TABLE_POINTERS << 16 | (6 - 2)); 253 OUT_BATCH(brw->vs.base.bind_bo_offset); 254 OUT_BATCH(0); /* gs */ 255 OUT_BATCH(0); /* clip */ 256 OUT_BATCH(0); /* sf */ 257 OUT_BATCH(brw->wm.base.bind_bo_offset); 258 ADVANCE_BATCH(); 259} 260 261const struct brw_tracked_state brw_binding_table_pointers = { 262 .dirty = { 263 .mesa = 0, 264 .brw = BRW_NEW_BATCH | 265 BRW_NEW_BLORP | 266 BRW_NEW_BINDING_TABLE_POINTERS | 267 BRW_NEW_STATE_BASE_ADDRESS, 268 }, 269 .emit = gfx4_upload_binding_table_pointers, 270}; 271 272/** 273 * (Sandybridge Only) Upload the binding table pointers for all shader stages. 274 * 275 * The binding table pointers are relative to the surface state base address, 276 * which points at the batchbuffer containing the streamed batch state. 277 */ 278static void 279gfx6_upload_binding_table_pointers(struct brw_context *brw) 280{ 281 BEGIN_BATCH(4); 282 OUT_BATCH(_3DSTATE_BINDING_TABLE_POINTERS << 16 | 283 GFX6_BINDING_TABLE_MODIFY_VS | 284 GFX6_BINDING_TABLE_MODIFY_GS | 285 GFX6_BINDING_TABLE_MODIFY_PS | 286 (4 - 2)); 287 OUT_BATCH(brw->vs.base.bind_bo_offset); /* vs */ 288 if (brw->ff_gs.prog_active) 289 OUT_BATCH(brw->ff_gs.bind_bo_offset); /* gs */ 290 else 291 OUT_BATCH(brw->gs.base.bind_bo_offset); /* gs */ 292 OUT_BATCH(brw->wm.base.bind_bo_offset); /* wm/ps */ 293 ADVANCE_BATCH(); 294} 295 296const struct brw_tracked_state gfx6_binding_table_pointers = { 297 .dirty = { 298 .mesa = 0, 299 .brw = BRW_NEW_BATCH | 300 BRW_NEW_BLORP | 301 BRW_NEW_BINDING_TABLE_POINTERS | 302 BRW_NEW_STATE_BASE_ADDRESS, 303 }, 304 .emit = gfx6_upload_binding_table_pointers, 305}; 306 307/** @} */ 308