1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright © 2017 Intel Corporation 3bf215546Sopenharmony_ci * 4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 5bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 6bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation 7bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 9bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 10bf215546Sopenharmony_ci * 11bf215546Sopenharmony_ci * The above copyright notice and this permission notice shall be included 12bf215546Sopenharmony_ci * in all copies or substantial portions of the Software. 13bf215546Sopenharmony_ci * 14bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15bf215546Sopenharmony_ci * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19bf215546Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20bf215546Sopenharmony_ci * DEALINGS IN THE SOFTWARE. 21bf215546Sopenharmony_ci */ 22bf215546Sopenharmony_ci 23bf215546Sopenharmony_ci/** 24bf215546Sopenharmony_ci * @file crocus_pipe_control.c 25bf215546Sopenharmony_ci * 26bf215546Sopenharmony_ci * PIPE_CONTROL is the main flushing and synchronization primitive on Intel 27bf215546Sopenharmony_ci * GPUs. It can invalidate caches, stall until rendering reaches various 28bf215546Sopenharmony_ci * stages of completion, write to memory, and other things. In a way, it's 29bf215546Sopenharmony_ci * a swiss army knife command - it has all kinds of capabilities, but some 30bf215546Sopenharmony_ci * significant limitations as well. 31bf215546Sopenharmony_ci * 32bf215546Sopenharmony_ci * Unfortunately, it's notoriously complicated and difficult to use. Many 33bf215546Sopenharmony_ci * sub-commands can't be used together. Some are meant to be used at the 34bf215546Sopenharmony_ci * top of the pipeline (invalidating caches before drawing), while some are 35bf215546Sopenharmony_ci * meant to be used at the end (stalling or flushing after drawing). 36bf215546Sopenharmony_ci * 37bf215546Sopenharmony_ci * Also, there's a list of restrictions a mile long, which vary by generation. 38bf215546Sopenharmony_ci * Do this before doing that, or suffer the consequences (usually a GPU hang). 39bf215546Sopenharmony_ci * 40bf215546Sopenharmony_ci * This file contains helpers for emitting them safely. You can simply call 41bf215546Sopenharmony_ci * crocus_emit_pipe_control_flush() with the desired operations (as logical 42bf215546Sopenharmony_ci * PIPE_CONTROL_* bits), and it will take care of splitting it into multiple 43bf215546Sopenharmony_ci * PIPE_CONTROL commands as necessary. The per-generation workarounds are 44bf215546Sopenharmony_ci * applied in crocus_emit_raw_pipe_control() in crocus_state.c. 45bf215546Sopenharmony_ci */ 46bf215546Sopenharmony_ci 47bf215546Sopenharmony_ci#include "crocus_context.h" 48bf215546Sopenharmony_ci#include "util/hash_table.h" 49bf215546Sopenharmony_ci#include "util/set.h" 50bf215546Sopenharmony_ci 51bf215546Sopenharmony_ci/** 52bf215546Sopenharmony_ci * Emit a PIPE_CONTROL with various flushing flags. 53bf215546Sopenharmony_ci * 54bf215546Sopenharmony_ci * The caller is responsible for deciding what flags are appropriate for the 55bf215546Sopenharmony_ci * given generation. 56bf215546Sopenharmony_ci */ 57bf215546Sopenharmony_civoid 58bf215546Sopenharmony_cicrocus_emit_pipe_control_flush(struct crocus_batch *batch, 59bf215546Sopenharmony_ci const char *reason, 60bf215546Sopenharmony_ci uint32_t flags) 61bf215546Sopenharmony_ci{ 62bf215546Sopenharmony_ci const struct intel_device_info *devinfo = &batch->screen->devinfo; 63bf215546Sopenharmony_ci 64bf215546Sopenharmony_ci if (devinfo->ver >= 6 && 65bf215546Sopenharmony_ci (flags & PIPE_CONTROL_CACHE_FLUSH_BITS) && 66bf215546Sopenharmony_ci (flags & PIPE_CONTROL_CACHE_INVALIDATE_BITS)) { 67bf215546Sopenharmony_ci /* A pipe control command with flush and invalidate bits set 68bf215546Sopenharmony_ci * simultaneously is an inherently racy operation on Gen6+ if the 69bf215546Sopenharmony_ci * contents of the flushed caches were intended to become visible from 70bf215546Sopenharmony_ci * any of the invalidated caches. Split it in two PIPE_CONTROLs, the 71bf215546Sopenharmony_ci * first one should stall the pipeline to make sure that the flushed R/W 72bf215546Sopenharmony_ci * caches are coherent with memory once the specified R/O caches are 73bf215546Sopenharmony_ci * invalidated. On pre-Gen6 hardware the (implicit) R/O cache 74bf215546Sopenharmony_ci * invalidation seems to happen at the bottom of the pipeline together 75bf215546Sopenharmony_ci * with any write cache flush, so this shouldn't be a concern. In order 76bf215546Sopenharmony_ci * to ensure a full stall, we do an end-of-pipe sync. 77bf215546Sopenharmony_ci */ 78bf215546Sopenharmony_ci crocus_emit_end_of_pipe_sync(batch, reason, 79bf215546Sopenharmony_ci flags & PIPE_CONTROL_CACHE_FLUSH_BITS); 80bf215546Sopenharmony_ci flags &= ~(PIPE_CONTROL_CACHE_FLUSH_BITS | PIPE_CONTROL_CS_STALL); 81bf215546Sopenharmony_ci } 82bf215546Sopenharmony_ci 83bf215546Sopenharmony_ci batch->screen->vtbl.emit_raw_pipe_control(batch, reason, flags, NULL, 0, 0); 84bf215546Sopenharmony_ci} 85bf215546Sopenharmony_ci 86bf215546Sopenharmony_ci/** 87bf215546Sopenharmony_ci * Emit a PIPE_CONTROL that writes to a buffer object. 88bf215546Sopenharmony_ci * 89bf215546Sopenharmony_ci * \p flags should contain one of the following items: 90bf215546Sopenharmony_ci * - PIPE_CONTROL_WRITE_IMMEDIATE 91bf215546Sopenharmony_ci * - PIPE_CONTROL_WRITE_TIMESTAMP 92bf215546Sopenharmony_ci * - PIPE_CONTROL_WRITE_DEPTH_COUNT 93bf215546Sopenharmony_ci */ 94bf215546Sopenharmony_civoid 95bf215546Sopenharmony_cicrocus_emit_pipe_control_write(struct crocus_batch *batch, 96bf215546Sopenharmony_ci const char *reason, uint32_t flags, 97bf215546Sopenharmony_ci struct crocus_bo *bo, uint32_t offset, 98bf215546Sopenharmony_ci uint64_t imm) 99bf215546Sopenharmony_ci{ 100bf215546Sopenharmony_ci batch->screen->vtbl.emit_raw_pipe_control(batch, reason, flags, bo, offset, imm); 101bf215546Sopenharmony_ci} 102bf215546Sopenharmony_ci 103bf215546Sopenharmony_ci/** 104bf215546Sopenharmony_ci * Restriction [DevSNB, DevIVB]: 105bf215546Sopenharmony_ci * 106bf215546Sopenharmony_ci * Prior to changing Depth/Stencil Buffer state (i.e. any combination of 107bf215546Sopenharmony_ci * 3DSTATE_DEPTH_BUFFER, 3DSTATE_CLEAR_PARAMS, 3DSTATE_STENCIL_BUFFER, 108bf215546Sopenharmony_ci * 3DSTATE_HIER_DEPTH_BUFFER) SW must first issue a pipelined depth stall 109bf215546Sopenharmony_ci * (PIPE_CONTROL with Depth Stall bit set), followed by a pipelined depth 110bf215546Sopenharmony_ci * cache flush (PIPE_CONTROL with Depth Flush Bit set), followed by 111bf215546Sopenharmony_ci * another pipelined depth stall (PIPE_CONTROL with Depth Stall bit set), 112bf215546Sopenharmony_ci * unless SW can otherwise guarantee that the pipeline from WM onwards is 113bf215546Sopenharmony_ci * already flushed (e.g., via a preceding MI_FLUSH). 114bf215546Sopenharmony_ci */ 115bf215546Sopenharmony_civoid 116bf215546Sopenharmony_cicrocus_emit_depth_stall_flushes(struct crocus_batch *batch) 117bf215546Sopenharmony_ci{ 118bf215546Sopenharmony_ci UNUSED const struct intel_device_info *devinfo = &batch->screen->devinfo; 119bf215546Sopenharmony_ci 120bf215546Sopenharmony_ci assert(devinfo->ver >= 6); 121bf215546Sopenharmony_ci 122bf215546Sopenharmony_ci /* Starting on BDW, these pipe controls are unnecessary. 123bf215546Sopenharmony_ci * 124bf215546Sopenharmony_ci * WM HW will internally manage the draining pipe and flushing of the caches 125bf215546Sopenharmony_ci * when this command is issued. The PIPE_CONTROL restrictions are removed. 126bf215546Sopenharmony_ci */ 127bf215546Sopenharmony_ci if (devinfo->ver >= 8) 128bf215546Sopenharmony_ci return; 129bf215546Sopenharmony_ci 130bf215546Sopenharmony_ci crocus_emit_pipe_control_flush(batch, "depth stall", PIPE_CONTROL_DEPTH_STALL); 131bf215546Sopenharmony_ci crocus_emit_pipe_control_flush(batch, "depth stall", PIPE_CONTROL_DEPTH_CACHE_FLUSH); 132bf215546Sopenharmony_ci crocus_emit_pipe_control_flush(batch, "depth stall", PIPE_CONTROL_DEPTH_STALL); 133bf215546Sopenharmony_ci} 134bf215546Sopenharmony_ci 135bf215546Sopenharmony_ci/* 136bf215546Sopenharmony_ci * From Sandybridge PRM, volume 2, "1.7.2 End-of-Pipe Synchronization": 137bf215546Sopenharmony_ci * 138bf215546Sopenharmony_ci * Write synchronization is a special case of end-of-pipe 139bf215546Sopenharmony_ci * synchronization that requires that the render cache and/or depth 140bf215546Sopenharmony_ci * related caches are flushed to memory, where the data will become 141bf215546Sopenharmony_ci * globally visible. This type of synchronization is required prior to 142bf215546Sopenharmony_ci * SW (CPU) actually reading the result data from memory, or initiating 143bf215546Sopenharmony_ci * an operation that will use as a read surface (such as a texture 144bf215546Sopenharmony_ci * surface) a previous render target and/or depth/stencil buffer 145bf215546Sopenharmony_ci * 146bf215546Sopenharmony_ci * From Haswell PRM, volume 2, part 1, "End-of-Pipe Synchronization": 147bf215546Sopenharmony_ci * 148bf215546Sopenharmony_ci * Exercising the write cache flush bits (Render Target Cache Flush 149bf215546Sopenharmony_ci * Enable, Depth Cache Flush Enable, DC Flush) in PIPE_CONTROL only 150bf215546Sopenharmony_ci * ensures the write caches are flushed and doesn't guarantee the data 151bf215546Sopenharmony_ci * is globally visible. 152bf215546Sopenharmony_ci * 153bf215546Sopenharmony_ci * SW can track the completion of the end-of-pipe-synchronization by 154bf215546Sopenharmony_ci * using "Notify Enable" and "PostSync Operation - Write Immediate 155bf215546Sopenharmony_ci * Data" in the PIPE_CONTROL command. 156bf215546Sopenharmony_ci */ 157bf215546Sopenharmony_civoid 158bf215546Sopenharmony_cicrocus_emit_end_of_pipe_sync(struct crocus_batch *batch, 159bf215546Sopenharmony_ci const char *reason, uint32_t flags) 160bf215546Sopenharmony_ci{ 161bf215546Sopenharmony_ci const struct intel_device_info *devinfo = &batch->screen->devinfo; 162bf215546Sopenharmony_ci 163bf215546Sopenharmony_ci if (devinfo->ver >= 6) { 164bf215546Sopenharmony_ci /* From Sandybridge PRM, volume 2, "1.7.3.1 Writing a Value to Memory": 165bf215546Sopenharmony_ci * 166bf215546Sopenharmony_ci * "The most common action to perform upon reaching a synchronization 167bf215546Sopenharmony_ci * point is to write a value out to memory. An immediate value 168bf215546Sopenharmony_ci * (included with the synchronization command) may be written." 169bf215546Sopenharmony_ci * 170bf215546Sopenharmony_ci * From Broadwell PRM, volume 7, "End-of-Pipe Synchronization": 171bf215546Sopenharmony_ci * 172bf215546Sopenharmony_ci * "In case the data flushed out by the render engine is to be read 173bf215546Sopenharmony_ci * back in to the render engine in coherent manner, then the render 174bf215546Sopenharmony_ci * engine has to wait for the fence completion before accessing the 175bf215546Sopenharmony_ci * flushed data. This can be achieved by following means on various 176bf215546Sopenharmony_ci * products: PIPE_CONTROL command with CS Stall and the required 177bf215546Sopenharmony_ci * write caches flushed with Post-Sync-Operation as Write Immediate 178bf215546Sopenharmony_ci * Data. 179bf215546Sopenharmony_ci * 180bf215546Sopenharmony_ci * Example: 181bf215546Sopenharmony_ci * - Workload-1 (3D/GPGPU/MEDIA) 182bf215546Sopenharmony_ci * - PIPE_CONTROL (CS Stall, Post-Sync-Operation Write Immediate 183bf215546Sopenharmony_ci * Data, Required Write Cache Flush bits set) 184bf215546Sopenharmony_ci * - Workload-2 (Can use the data produce or output by Workload-1) 185bf215546Sopenharmony_ci */ 186bf215546Sopenharmony_ci crocus_emit_pipe_control_write(batch, reason, 187bf215546Sopenharmony_ci flags | PIPE_CONTROL_CS_STALL | 188bf215546Sopenharmony_ci PIPE_CONTROL_WRITE_IMMEDIATE, 189bf215546Sopenharmony_ci batch->ice->workaround_bo, 190bf215546Sopenharmony_ci batch->ice->workaround_offset, 0); 191bf215546Sopenharmony_ci 192bf215546Sopenharmony_ci if (batch->screen->devinfo.platform == INTEL_PLATFORM_HSW) { 193bf215546Sopenharmony_ci#define GEN7_3DPRIM_START_INSTANCE 0x243C 194bf215546Sopenharmony_ci batch->screen->vtbl.load_register_mem32(batch, GEN7_3DPRIM_START_INSTANCE, 195bf215546Sopenharmony_ci batch->ice->workaround_bo, 196bf215546Sopenharmony_ci batch->ice->workaround_offset); 197bf215546Sopenharmony_ci } 198bf215546Sopenharmony_ci } else { 199bf215546Sopenharmony_ci /* On gen4-5, a regular pipe control seems to suffice. */ 200bf215546Sopenharmony_ci crocus_emit_pipe_control_flush(batch, reason, flags); 201bf215546Sopenharmony_ci } 202bf215546Sopenharmony_ci} 203bf215546Sopenharmony_ci 204bf215546Sopenharmony_ci/* Emit a pipelined flush to either flush render and texture cache for 205bf215546Sopenharmony_ci * reading from a FBO-drawn texture, or flush so that frontbuffer 206bf215546Sopenharmony_ci * render appears on the screen in DRI1. 207bf215546Sopenharmony_ci * 208bf215546Sopenharmony_ci * This is also used for the always_flush_cache driconf debug option. 209bf215546Sopenharmony_ci */ 210bf215546Sopenharmony_civoid 211bf215546Sopenharmony_cicrocus_emit_mi_flush(struct crocus_batch *batch) 212bf215546Sopenharmony_ci{ 213bf215546Sopenharmony_ci const struct intel_device_info *devinfo = &batch->screen->devinfo; 214bf215546Sopenharmony_ci int flags = PIPE_CONTROL_RENDER_TARGET_FLUSH; 215bf215546Sopenharmony_ci if (devinfo->ver >= 6) { 216bf215546Sopenharmony_ci flags |= PIPE_CONTROL_INSTRUCTION_INVALIDATE | 217bf215546Sopenharmony_ci PIPE_CONTROL_CONST_CACHE_INVALIDATE | 218bf215546Sopenharmony_ci PIPE_CONTROL_DATA_CACHE_FLUSH | 219bf215546Sopenharmony_ci PIPE_CONTROL_DEPTH_CACHE_FLUSH | 220bf215546Sopenharmony_ci PIPE_CONTROL_VF_CACHE_INVALIDATE | 221bf215546Sopenharmony_ci PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE | 222bf215546Sopenharmony_ci PIPE_CONTROL_CS_STALL; 223bf215546Sopenharmony_ci } 224bf215546Sopenharmony_ci crocus_emit_pipe_control_flush(batch, "mi flush", flags); 225bf215546Sopenharmony_ci} 226bf215546Sopenharmony_ci 227bf215546Sopenharmony_ci/** 228bf215546Sopenharmony_ci * Emits a PIPE_CONTROL with a non-zero post-sync operation, for 229bf215546Sopenharmony_ci * implementing two workarounds on gen6. From section 1.4.7.1 230bf215546Sopenharmony_ci * "PIPE_CONTROL" of the Sandy Bridge PRM volume 2 part 1: 231bf215546Sopenharmony_ci * 232bf215546Sopenharmony_ci * [DevSNB-C+{W/A}] Before any depth stall flush (including those 233bf215546Sopenharmony_ci * produced by non-pipelined state commands), software needs to first 234bf215546Sopenharmony_ci * send a PIPE_CONTROL with no bits set except Post-Sync Operation != 235bf215546Sopenharmony_ci * 0. 236bf215546Sopenharmony_ci * 237bf215546Sopenharmony_ci * [Dev-SNB{W/A}]: Before a PIPE_CONTROL with Write Cache Flush Enable 238bf215546Sopenharmony_ci * =1, a PIPE_CONTROL with any non-zero post-sync-op is required. 239bf215546Sopenharmony_ci * 240bf215546Sopenharmony_ci * And the workaround for these two requires this workaround first: 241bf215546Sopenharmony_ci * 242bf215546Sopenharmony_ci * [Dev-SNB{W/A}]: Pipe-control with CS-stall bit set must be sent 243bf215546Sopenharmony_ci * BEFORE the pipe-control with a post-sync op and no write-cache 244bf215546Sopenharmony_ci * flushes. 245bf215546Sopenharmony_ci * 246bf215546Sopenharmony_ci * And this last workaround is tricky because of the requirements on 247bf215546Sopenharmony_ci * that bit. From section 1.4.7.2.3 "Stall" of the Sandy Bridge PRM 248bf215546Sopenharmony_ci * volume 2 part 1: 249bf215546Sopenharmony_ci * 250bf215546Sopenharmony_ci * "1 of the following must also be set: 251bf215546Sopenharmony_ci * - Render Target Cache Flush Enable ([12] of DW1) 252bf215546Sopenharmony_ci * - Depth Cache Flush Enable ([0] of DW1) 253bf215546Sopenharmony_ci * - Stall at Pixel Scoreboard ([1] of DW1) 254bf215546Sopenharmony_ci * - Depth Stall ([13] of DW1) 255bf215546Sopenharmony_ci * - Post-Sync Operation ([13] of DW1) 256bf215546Sopenharmony_ci * - Notify Enable ([8] of DW1)" 257bf215546Sopenharmony_ci * 258bf215546Sopenharmony_ci * The cache flushes require the workaround flush that triggered this 259bf215546Sopenharmony_ci * one, so we can't use it. Depth stall would trigger the same. 260bf215546Sopenharmony_ci * Post-sync nonzero is what triggered this second workaround, so we 261bf215546Sopenharmony_ci * can't use that one either. Notify enable is IRQs, which aren't 262bf215546Sopenharmony_ci * really our business. That leaves only stall at scoreboard. 263bf215546Sopenharmony_ci */ 264bf215546Sopenharmony_civoid 265bf215546Sopenharmony_cicrocus_emit_post_sync_nonzero_flush(struct crocus_batch *batch) 266bf215546Sopenharmony_ci{ 267bf215546Sopenharmony_ci crocus_emit_pipe_control_flush(batch, "nonzero", 268bf215546Sopenharmony_ci PIPE_CONTROL_CS_STALL | 269bf215546Sopenharmony_ci PIPE_CONTROL_STALL_AT_SCOREBOARD); 270bf215546Sopenharmony_ci 271bf215546Sopenharmony_ci crocus_emit_pipe_control_write(batch, "nonzero", 272bf215546Sopenharmony_ci PIPE_CONTROL_WRITE_IMMEDIATE, 273bf215546Sopenharmony_ci batch->ice->workaround_bo, 274bf215546Sopenharmony_ci batch->ice->workaround_offset, 0); 275bf215546Sopenharmony_ci} 276bf215546Sopenharmony_ci 277bf215546Sopenharmony_ci/** 278bf215546Sopenharmony_ci * Flush and invalidate all caches (for debugging purposes). 279bf215546Sopenharmony_ci */ 280bf215546Sopenharmony_civoid 281bf215546Sopenharmony_cicrocus_flush_all_caches(struct crocus_batch *batch) 282bf215546Sopenharmony_ci{ 283bf215546Sopenharmony_ci crocus_emit_pipe_control_flush(batch, "debug: flush all caches", 284bf215546Sopenharmony_ci PIPE_CONTROL_CS_STALL | 285bf215546Sopenharmony_ci PIPE_CONTROL_DATA_CACHE_FLUSH | 286bf215546Sopenharmony_ci PIPE_CONTROL_DEPTH_CACHE_FLUSH | 287bf215546Sopenharmony_ci PIPE_CONTROL_RENDER_TARGET_FLUSH | 288bf215546Sopenharmony_ci PIPE_CONTROL_VF_CACHE_INVALIDATE | 289bf215546Sopenharmony_ci PIPE_CONTROL_INSTRUCTION_INVALIDATE | 290bf215546Sopenharmony_ci PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE | 291bf215546Sopenharmony_ci PIPE_CONTROL_CONST_CACHE_INVALIDATE | 292bf215546Sopenharmony_ci PIPE_CONTROL_STATE_CACHE_INVALIDATE); 293bf215546Sopenharmony_ci} 294bf215546Sopenharmony_ci 295bf215546Sopenharmony_cistatic void 296bf215546Sopenharmony_cicrocus_texture_barrier(struct pipe_context *ctx, unsigned flags) 297bf215546Sopenharmony_ci{ 298bf215546Sopenharmony_ci struct crocus_context *ice = (void *) ctx; 299bf215546Sopenharmony_ci struct crocus_batch *render_batch = &ice->batches[CROCUS_BATCH_RENDER]; 300bf215546Sopenharmony_ci struct crocus_batch *compute_batch = &ice->batches[CROCUS_BATCH_COMPUTE]; 301bf215546Sopenharmony_ci const struct intel_device_info *devinfo = &render_batch->screen->devinfo; 302bf215546Sopenharmony_ci 303bf215546Sopenharmony_ci if (devinfo->ver < 6) { 304bf215546Sopenharmony_ci crocus_emit_mi_flush(render_batch); 305bf215546Sopenharmony_ci return; 306bf215546Sopenharmony_ci } 307bf215546Sopenharmony_ci 308bf215546Sopenharmony_ci if (render_batch->contains_draw) { 309bf215546Sopenharmony_ci crocus_batch_maybe_flush(render_batch, 48); 310bf215546Sopenharmony_ci crocus_emit_pipe_control_flush(render_batch, 311bf215546Sopenharmony_ci "API: texture barrier (1/2)", 312bf215546Sopenharmony_ci (flags == 1 ? PIPE_CONTROL_DEPTH_CACHE_FLUSH : 0) | 313bf215546Sopenharmony_ci PIPE_CONTROL_RENDER_TARGET_FLUSH | 314bf215546Sopenharmony_ci PIPE_CONTROL_CS_STALL); 315bf215546Sopenharmony_ci crocus_emit_pipe_control_flush(render_batch, 316bf215546Sopenharmony_ci "API: texture barrier (2/2)", 317bf215546Sopenharmony_ci PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE); 318bf215546Sopenharmony_ci } 319bf215546Sopenharmony_ci 320bf215546Sopenharmony_ci if (compute_batch->contains_draw) { 321bf215546Sopenharmony_ci crocus_batch_maybe_flush(compute_batch, 48); 322bf215546Sopenharmony_ci crocus_emit_pipe_control_flush(compute_batch, 323bf215546Sopenharmony_ci "API: texture barrier (1/2)", 324bf215546Sopenharmony_ci PIPE_CONTROL_CS_STALL); 325bf215546Sopenharmony_ci crocus_emit_pipe_control_flush(compute_batch, 326bf215546Sopenharmony_ci "API: texture barrier (2/2)", 327bf215546Sopenharmony_ci PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE); 328bf215546Sopenharmony_ci } 329bf215546Sopenharmony_ci} 330bf215546Sopenharmony_ci 331bf215546Sopenharmony_cistatic void 332bf215546Sopenharmony_cicrocus_memory_barrier(struct pipe_context *ctx, unsigned flags) 333bf215546Sopenharmony_ci{ 334bf215546Sopenharmony_ci struct crocus_context *ice = (void *) ctx; 335bf215546Sopenharmony_ci unsigned bits = PIPE_CONTROL_DATA_CACHE_FLUSH | PIPE_CONTROL_CS_STALL; 336bf215546Sopenharmony_ci const struct intel_device_info *devinfo = &ice->batches[0].screen->devinfo; 337bf215546Sopenharmony_ci 338bf215546Sopenharmony_ci assert(devinfo->ver >= 7); 339bf215546Sopenharmony_ci 340bf215546Sopenharmony_ci if (flags & (PIPE_BARRIER_VERTEX_BUFFER | 341bf215546Sopenharmony_ci PIPE_BARRIER_INDEX_BUFFER | 342bf215546Sopenharmony_ci PIPE_BARRIER_INDIRECT_BUFFER)) { 343bf215546Sopenharmony_ci bits |= PIPE_CONTROL_VF_CACHE_INVALIDATE; 344bf215546Sopenharmony_ci } 345bf215546Sopenharmony_ci 346bf215546Sopenharmony_ci if (flags & PIPE_BARRIER_CONSTANT_BUFFER) { 347bf215546Sopenharmony_ci bits |= PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE | 348bf215546Sopenharmony_ci PIPE_CONTROL_CONST_CACHE_INVALIDATE; 349bf215546Sopenharmony_ci } 350bf215546Sopenharmony_ci 351bf215546Sopenharmony_ci if (flags & (PIPE_BARRIER_TEXTURE | PIPE_BARRIER_FRAMEBUFFER)) { 352bf215546Sopenharmony_ci bits |= PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE | 353bf215546Sopenharmony_ci PIPE_CONTROL_RENDER_TARGET_FLUSH; 354bf215546Sopenharmony_ci } 355bf215546Sopenharmony_ci 356bf215546Sopenharmony_ci /* Typed surface messages are handled by the render cache on IVB, so we 357bf215546Sopenharmony_ci * need to flush it too. 358bf215546Sopenharmony_ci */ 359bf215546Sopenharmony_ci if (devinfo->verx10 < 75) 360bf215546Sopenharmony_ci bits |= PIPE_CONTROL_RENDER_TARGET_FLUSH; 361bf215546Sopenharmony_ci 362bf215546Sopenharmony_ci for (int i = 0; i < ice->batch_count; i++) { 363bf215546Sopenharmony_ci if (ice->batches[i].contains_draw) { 364bf215546Sopenharmony_ci crocus_batch_maybe_flush(&ice->batches[i], 24); 365bf215546Sopenharmony_ci crocus_emit_pipe_control_flush(&ice->batches[i], "API: memory barrier", 366bf215546Sopenharmony_ci bits); 367bf215546Sopenharmony_ci } 368bf215546Sopenharmony_ci } 369bf215546Sopenharmony_ci} 370bf215546Sopenharmony_ci 371bf215546Sopenharmony_civoid 372bf215546Sopenharmony_cicrocus_init_flush_functions(struct pipe_context *ctx) 373bf215546Sopenharmony_ci{ 374bf215546Sopenharmony_ci ctx->memory_barrier = crocus_memory_barrier; 375bf215546Sopenharmony_ci ctx->texture_barrier = crocus_texture_barrier; 376bf215546Sopenharmony_ci} 377