Path: blob/21.2-virgl/src/intel/vulkan/genX_blorp_exec.c
4547 views
/*1* Copyright © 2016 Intel Corporation2*3* Permission is hereby granted, free of charge, to any person obtaining a4* copy of this software and associated documentation files (the "Software"),5* to deal in the Software without restriction, including without limitation6* the rights to use, copy, modify, merge, publish, distribute, sublicense,7* and/or sell copies of the Software, and to permit persons to whom the8* Software is furnished to do so, subject to the following conditions:9*10* The above copyright notice and this permission notice (including the next11* paragraph) shall be included in all copies or substantial portions of the12* Software.13*14* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL17* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER18* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING19* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS20* IN THE SOFTWARE.21*/2223#include <assert.h>2425#include "anv_private.h"26#include "anv_measure.h"2728/* These are defined in anv_private.h and blorp_genX_exec.h */29#undef __gen_address_type30#undef __gen_user_data31#undef __gen_combine_address3233#include "common/intel_l3_config.h"34#include "blorp/blorp_genX_exec.h"3536static void blorp_measure_start(struct blorp_batch *_batch,37const struct blorp_params *params)38{39struct anv_cmd_buffer *cmd_buffer = _batch->driver_batch;40anv_measure_snapshot(cmd_buffer,41params->snapshot_type,42NULL, 0);43}4445static void *46blorp_emit_dwords(struct blorp_batch *batch, unsigned n)47{48struct anv_cmd_buffer *cmd_buffer = batch->driver_batch;49return anv_batch_emit_dwords(&cmd_buffer->batch, n);50}5152static uint64_t53blorp_emit_reloc(struct blorp_batch *batch,54void *location, struct blorp_address address, uint32_t delta)55{56struct anv_cmd_buffer *cmd_buffer = batch->driver_batch;57assert(cmd_buffer->batch.start <= location &&58location < cmd_buffer->batch.end);59return anv_batch_emit_reloc(&cmd_buffer->batch, location,60address.buffer, address.offset + delta);61}6263static void64blorp_surface_reloc(struct blorp_batch *batch, uint32_t ss_offset,65struct blorp_address address, uint32_t delta)66{67struct anv_cmd_buffer *cmd_buffer = batch->driver_batch;68VkResult result;6970if (ANV_ALWAYS_SOFTPIN) {71result = anv_reloc_list_add_bo(&cmd_buffer->surface_relocs,72&cmd_buffer->pool->alloc,73address.buffer);74if (unlikely(result != VK_SUCCESS))75anv_batch_set_error(&cmd_buffer->batch, result);76return;77}7879uint64_t address_u64 = 0;80result = anv_reloc_list_add(&cmd_buffer->surface_relocs,81&cmd_buffer->pool->alloc,82ss_offset, address.buffer,83address.offset + delta,84&address_u64);85if (result != VK_SUCCESS)86anv_batch_set_error(&cmd_buffer->batch, result);8788void *dest = anv_block_pool_map(89&cmd_buffer->device->surface_state_pool.block_pool, ss_offset, 8);90write_reloc(cmd_buffer->device, dest, address_u64, false);91}9293static uint64_t94blorp_get_surface_address(struct blorp_batch *blorp_batch,95struct blorp_address address)96{97if (ANV_ALWAYS_SOFTPIN) {98struct anv_address anv_addr = {99.bo = address.buffer,100.offset = address.offset,101};102return anv_address_physical(anv_addr);103} else {104/* We'll let blorp_surface_reloc write the address. */105return 0;106}107}108109#if GFX_VER >= 7 && GFX_VER < 10110static struct blorp_address111blorp_get_surface_base_address(struct blorp_batch *batch)112{113struct anv_cmd_buffer *cmd_buffer = batch->driver_batch;114return (struct blorp_address) {115.buffer = cmd_buffer->device->surface_state_pool.block_pool.bo,116.offset = 0,117};118}119#endif120121static void *122blorp_alloc_dynamic_state(struct blorp_batch *batch,123uint32_t size,124uint32_t alignment,125uint32_t *offset)126{127struct anv_cmd_buffer *cmd_buffer = batch->driver_batch;128129struct anv_state state =130anv_cmd_buffer_alloc_dynamic_state(cmd_buffer, size, alignment);131132*offset = state.offset;133return state.map;134}135136static void137blorp_alloc_binding_table(struct blorp_batch *batch, unsigned num_entries,138unsigned state_size, unsigned state_alignment,139uint32_t *bt_offset,140uint32_t *surface_offsets, void **surface_maps)141{142struct anv_cmd_buffer *cmd_buffer = batch->driver_batch;143144uint32_t state_offset;145struct anv_state bt_state;146147VkResult result =148anv_cmd_buffer_alloc_blorp_binding_table(cmd_buffer, num_entries,149&state_offset, &bt_state);150if (result != VK_SUCCESS)151return;152153uint32_t *bt_map = bt_state.map;154*bt_offset = bt_state.offset;155156for (unsigned i = 0; i < num_entries; i++) {157struct anv_state surface_state =158anv_cmd_buffer_alloc_surface_state(cmd_buffer);159bt_map[i] = surface_state.offset + state_offset;160surface_offsets[i] = surface_state.offset;161surface_maps[i] = surface_state.map;162}163}164165static void *166blorp_alloc_vertex_buffer(struct blorp_batch *batch, uint32_t size,167struct blorp_address *addr)168{169struct anv_cmd_buffer *cmd_buffer = batch->driver_batch;170struct anv_state vb_state =171anv_cmd_buffer_alloc_dynamic_state(cmd_buffer, size, 64);172173*addr = (struct blorp_address) {174.buffer = cmd_buffer->device->dynamic_state_pool.block_pool.bo,175.offset = vb_state.offset,176.mocs = isl_mocs(&cmd_buffer->device->isl_dev,177ISL_SURF_USAGE_VERTEX_BUFFER_BIT, false),178};179180return vb_state.map;181}182183static void184blorp_vf_invalidate_for_vb_48b_transitions(struct blorp_batch *batch,185const struct blorp_address *addrs,186uint32_t *sizes,187unsigned num_vbs)188{189struct anv_cmd_buffer *cmd_buffer = batch->driver_batch;190191for (unsigned i = 0; i < num_vbs; i++) {192struct anv_address anv_addr = {193.bo = addrs[i].buffer,194.offset = addrs[i].offset,195};196genX(cmd_buffer_set_binding_for_gfx8_vb_flush)(cmd_buffer,197i, anv_addr, sizes[i]);198}199200genX(cmd_buffer_apply_pipe_flushes)(cmd_buffer);201202/* Technically, we should call this *after* 3DPRIMITIVE but it doesn't203* really matter for blorp because we never call apply_pipe_flushes after204* this point.205*/206genX(cmd_buffer_update_dirty_vbs_for_gfx8_vb_flush)(cmd_buffer, SEQUENTIAL,207(1 << num_vbs) - 1);208}209210UNUSED static struct blorp_address211blorp_get_workaround_address(struct blorp_batch *batch)212{213struct anv_cmd_buffer *cmd_buffer = batch->driver_batch;214215return (struct blorp_address) {216.buffer = cmd_buffer->device->workaround_address.bo,217.offset = cmd_buffer->device->workaround_address.offset,218};219}220221static void222blorp_flush_range(struct blorp_batch *batch, void *start, size_t size)223{224/* We don't need to flush states anymore, since everything will be snooped.225*/226}227228static const struct intel_l3_config *229blorp_get_l3_config(struct blorp_batch *batch)230{231struct anv_cmd_buffer *cmd_buffer = batch->driver_batch;232return cmd_buffer->state.current_l3_config;233}234235void236genX(blorp_exec)(struct blorp_batch *batch,237const struct blorp_params *params)238{239struct anv_cmd_buffer *cmd_buffer = batch->driver_batch;240241if (!cmd_buffer->state.current_l3_config) {242const struct intel_l3_config *cfg =243intel_get_default_l3_config(&cmd_buffer->device->info);244genX(cmd_buffer_config_l3)(cmd_buffer, cfg);245}246247const unsigned scale = params->fast_clear_op ? UINT_MAX : 1;248genX(cmd_buffer_emit_hashing_mode)(cmd_buffer, params->x1 - params->x0,249params->y1 - params->y0, scale);250251#if GFX_VER >= 11252/* The PIPE_CONTROL command description says:253*254* "Whenever a Binding Table Index (BTI) used by a Render Taget Message255* points to a different RENDER_SURFACE_STATE, SW must issue a Render256* Target Cache Flush by enabling this bit. When render target flush257* is set due to new association of BTI, PS Scoreboard Stall bit must258* be set in this packet."259*/260anv_add_pending_pipe_bits(cmd_buffer,261ANV_PIPE_RENDER_TARGET_CACHE_FLUSH_BIT |262ANV_PIPE_STALL_AT_SCOREBOARD_BIT,263"before blorp BTI change");264#endif265266#if GFX_VERx10 == 120267if (!(batch->flags & BLORP_BATCH_NO_EMIT_DEPTH_STENCIL)) {268/* Wa_14010455700269*270* ISL will change some CHICKEN registers depending on the depth surface271* format, along with emitting the depth and stencil packets. In that272* case, we want to do a depth flush and stall, so the pipeline is not273* using these settings while we change the registers.274*/275cmd_buffer->state.pending_pipe_bits |=276ANV_PIPE_DEPTH_CACHE_FLUSH_BIT |277ANV_PIPE_DEPTH_STALL_BIT |278ANV_PIPE_END_OF_PIPE_SYNC_BIT;279}280#endif281282#if GFX_VER == 7283/* The MI_LOAD/STORE_REGISTER_MEM commands which BLORP uses to implement284* indirect fast-clear colors can cause GPU hangs if we don't stall first.285* See genX(cmd_buffer_mi_memcpy) for more details.286*/287if (params->src.clear_color_addr.buffer ||288params->dst.clear_color_addr.buffer) {289anv_add_pending_pipe_bits(cmd_buffer,290ANV_PIPE_CS_STALL_BIT,291"before blorp prep fast clear");292}293#endif294295genX(cmd_buffer_apply_pipe_flushes)(cmd_buffer);296297genX(flush_pipeline_select_3d)(cmd_buffer);298299genX(cmd_buffer_emit_gfx7_depth_flush)(cmd_buffer);300301/* BLORP doesn't do anything fancy with depth such as discards, so we want302* the PMA fix off. Also, off is always the safe option.303*/304genX(cmd_buffer_enable_pma_fix)(cmd_buffer, false);305306blorp_exec(batch, params);307308#if GFX_VER >= 11309/* The PIPE_CONTROL command description says:310*311* "Whenever a Binding Table Index (BTI) used by a Render Taget Message312* points to a different RENDER_SURFACE_STATE, SW must issue a Render313* Target Cache Flush by enabling this bit. When render target flush314* is set due to new association of BTI, PS Scoreboard Stall bit must315* be set in this packet."316*/317anv_add_pending_pipe_bits(cmd_buffer,318ANV_PIPE_RENDER_TARGET_CACHE_FLUSH_BIT |319ANV_PIPE_STALL_AT_SCOREBOARD_BIT,320"after blorp BTI change");321#endif322323cmd_buffer->state.gfx.vb_dirty = ~0;324cmd_buffer->state.gfx.dirty = ~0;325cmd_buffer->state.push_constants_dirty = ~0;326}327328329