From c9d9e44720d917dc244a17afe5062257eba2e245 Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Sat, 21 Apr 2018 00:05:57 -0700 Subject: [PATCH] iris: bits of blorp code --- src/gallium/drivers/iris/iris_batch.h | 1 + src/gallium/drivers/iris/iris_blorp.c | 283 +++++++++++++++++++++++ src/gallium/drivers/iris/iris_bufmgr.h | 8 +- src/gallium/drivers/iris/iris_context.h | 10 + src/gallium/drivers/iris/iris_resource.h | 1 + src/gallium/drivers/iris/meson.build | 2 +- 6 files changed, 300 insertions(+), 5 deletions(-) create mode 100644 src/gallium/drivers/iris/iris_blorp.c diff --git a/src/gallium/drivers/iris/iris_batch.h b/src/gallium/drivers/iris/iris_batch.h index b58f0836156..b29ed5f1e9e 100644 --- a/src/gallium/drivers/iris/iris_batch.h +++ b/src/gallium/drivers/iris/iris_batch.h @@ -26,6 +26,7 @@ #include #include +#include "i915_drm.h" #include "common/gen_decoder.h" /* The kernel assumes batchbuffers are smaller than 256kB. */ diff --git a/src/gallium/drivers/iris/iris_blorp.c b/src/gallium/drivers/iris/iris_blorp.c new file mode 100644 index 00000000000..516a30d03bc --- /dev/null +++ b/src/gallium/drivers/iris/iris_blorp.c @@ -0,0 +1,283 @@ +/* + * Copyright © 2018 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +#include + +#include "iris_batch.h" +#include "iris_resource.h" +#include "iris_context.h" + +#include "blorp/blorp_genX_exec.h" +#include "util/u_upload_mgr.h" + +static uint32_t * +stream_state(struct iris_batch *batch, + struct u_upload_mgr *uploader, + unsigned size, + unsigned alignment, + uint32_t *out_offset, + struct iris_bo **out_bo) +{ + struct pipe_resource *res = NULL; + void *ptr = NULL; + + u_upload_alloc(uploader, 0, size, alignment, out_offset, &res, &ptr); + + *out_bo = iris_resource_bo(res); + iris_use_pinned_bo(batch, *out_bo, false); + + *out_offset += iris_bo_offset_from_base_address(*out_bo); + + pipe_resource_reference(&res, NULL); + + return ptr; +} + +static void * +blorp_emit_dwords(struct blorp_batch *blorp_batch, unsigned n) +{ + struct iris_batch *batch = blorp_batch->driver_batch; + return iris_get_command_space(batch, n * sizeof(uint32_t)); +} + +static uint64_t +blorp_emit_reloc(struct blorp_batch *blorp_batch, UNUSED void *location, + struct blorp_address addr, uint32_t delta) +{ + struct iris_batch *batch = blorp_batch->driver_batch; + struct iris_bo *bo = addr.buffer; + uint64_t result = addr.offset + delta; + + if (bo) { + iris_use_pinned_bo(batch, bo, addr.reloc_flags & RELOC_WRITE); + /* Assume this is a general address, not relative to a base. */ + result += bo->gtt_offset; + } + + return result; +} + +static void +blorp_surface_reloc(struct blorp_batch *blorp_batch, uint32_t ss_offset, + struct blorp_address addr, uint32_t delta) +{ + /* Don't do anything, blorp_alloc_binding_table already added the BO. */ +} + +UNUSED static struct blorp_address +blorp_get_surface_base_address(UNUSED struct blorp_batch *blorp_batch) +{ + return (struct blorp_address) { .offset = IRIS_MEMZONE_SURFACE_START }; +} + +static void * +blorp_alloc_dynamic_state(struct blorp_batch *blorp_batch, + uint32_t size, + uint32_t alignment, + uint32_t *offset) +{ + struct iris_context *ice = blorp_batch->blorp->driver_ctx; + struct iris_batch *batch = blorp_batch->driver_batch; + struct iris_bo *bo; + + return stream_state(batch, ice->state.dynamic_uploader, + size, alignment, offset, &bo); +} + +static void +blorp_alloc_binding_table(struct blorp_batch *blorp_batch, + unsigned num_entries, + unsigned state_size, + unsigned state_alignment, + uint32_t *bt_offset, + uint32_t *surface_offsets, + void **surface_maps) +{ + struct iris_context *ice = blorp_batch->blorp->driver_ctx; + struct iris_batch *batch = blorp_batch->driver_batch; + struct iris_bo *bo; + + uint32_t *bt_map = iris_binder_reserve(&ice->state.binder, + num_entries * sizeof(uint32_t), + bt_offset); + + for (unsigned i = 0; i < num_entries; i++) { + surface_maps[i] = stream_state(batch, ice->state.surface_uploader, + state_size, state_alignment, + &surface_offsets[i], &bo); + bt_map[i] = surface_offsets[i]; + } +} + +static void * +blorp_alloc_vertex_buffer(struct blorp_batch *blorp_batch, + uint32_t size, + struct blorp_address *addr) +{ + struct iris_context *ice = blorp_batch->blorp->driver_ctx; + struct iris_batch *batch = blorp_batch->driver_batch; + struct iris_bo *bo; + uint32_t offset; + + void *map = stream_state(batch, ice->ctx.stream_uploader, size, 64, + &offset, &bo); + + *addr = (struct blorp_address) { + .buffer = bo, + .offset = offset, + // XXX: Broadwell MOCS + .mocs = I915_MOCS_CACHED, + }; + + return map; +} + +static struct blorp_address +blorp_get_workaround_page(struct blorp_batch *blorp_batch) +{ + struct iris_batch *batch = blorp_batch->driver_batch; + + return (struct blorp_address) { .buffer = batch->screen->workaround_bo }; +} + +static void +blorp_flush_range(UNUSED struct blorp_batch *blorp_batch, + UNUSED void *start, + UNUSED size_t size) +{ + /* All allocated states come from the batch which we will flush before we + * submit it. There's nothing for us to do here. + */ +} + +static void +blorp_emit_urb_config(struct blorp_batch *blorp_batch, + unsigned vs_entry_size, + UNUSED unsigned sf_entry_size) +{ + // XXX: URB... +#if 0 + if (ice->urb.vsize >= vs_entry_size) + return; + + gen7_upload_urb(ice, vs_entry_size, false, false); +#endif +} + +static void +iris_blorp_exec(struct blorp_batch *blorp_batch, + const struct blorp_params *params) +{ + struct iris_context *ice = blorp_batch->blorp->driver_ctx; + struct iris_batch *batch = blorp_batch->driver_batch; + + /* Flush the sampler and render caches. We definitely need to flush the + * sampler cache so that we get updated contents from the render cache for + * the glBlitFramebuffer() source. Also, we are sometimes warned in the + * docs to flush the cache between reinterpretations of the same surface + * data with different formats, which blorp does for stencil and depth + * data. + */ + if (params->src.enabled) + iris_cache_flush_for_read(batch, params->src.addr.buffer); + if (params->dst.enabled) { + iris_cache_flush_for_render(batch, params->dst.addr.buffer, + params->dst.view.format, + params->dst.aux_usage); + } + if (params->depth.enabled) + iris_cache_flush_for_depth(batch, params->depth.addr.buffer); + if (params->stencil.enabled) + iris_cache_flush_for_depth(batch, params->stencil.addr.buffer); + + iris_require_command_space(batch, 1400); + //iris_require_statebuffer_space(ice, 600); // XXX: THIS. Need this. + batch->no_wrap = true; + + // XXX: Emit L3 state + +#if GEN_GEN == 8 + // XXX: PMA - gen8_write_pma_stall_bits(ice, 0); +#endif + + // XXX: knock this off...land Jason's i965 patches... + blorp_emit(blorp_batch, GENX(3DSTATE_DRAWING_RECTANGLE), rect) { + rect.ClippedDrawingRectangleXMax = MAX2(params->x1, params->x0) - 1; + rect.ClippedDrawingRectangleYMax = MAX2(params->y1, params->y0) - 1; + } + + blorp_exec(blorp_batch, params); + + batch->no_wrap = false; + + // XXX: aperture checks? + + /* We've smashed all state compared to what the normal 3D pipeline + * rendering tracks for GL. + */ + // XXX: skip some if (!(batch->flags & BLORP_BATCH_NO_EMIT_DEPTH_STENCIL)) + ice->state.dirty |= ~(IRIS_DIRTY_POLYGON_STIPPLE | + IRIS_DIRTY_LINE_STIPPLE); + +#if 0 + ice->state.dirty |= IRIS_DIRTY_VERTEX_BUFFERS | + IRIS_DIRTY_COLOR_CALC_STATE | + IRIS_DIRTY_CONSTANTS_VS | + IRIS_DIRTY_CONSTANTS_TCS | + IRIS_DIRTY_CONSTANTS_TES | + IRIS_DIRTY_CONSTANTS_GS | + IRIS_DIRTY_CONSTANTS_PS | + IRIS_DIRTY_CONSTANTS_PS | + IRIS_DIRTY_SAMPLER_STATES_VS | + IRIS_DIRTY_SAMPLER_STATES_TCS | + IRIS_DIRTY_SAMPLER_STATES_TES | + IRIS_DIRTY_SAMPLER_STATES_GS | + IRIS_DIRTY_SAMPLER_STATES_PS | + IRIS_DIRTY_SAMPLER_STATES_PS | + IRIS_DIRTY_MULTISAMPLE | + IRIS_DIRTY_SAMPLE_MASK | + IRIS_DIRTY_VS | + IRIS_DIRTY_TCS | + IRIS_DIRTY_TES | + // IRIS_DIRTY_STREAMOUT | + IRIS_DIRTY_GS | + IRIS_DIRTY_CLIP | + IRIS_DIRTY_FS | + IRIS_DIRTY_CC_VIEWPORT | +#endif + + if (params->dst.enabled) { + iris_render_cache_add_bo(batch, params->dst.addr.buffer, + params->dst.view.format, + params->dst.aux_usage); + } + if (params->depth.enabled) + iris_depth_cache_add_bo(batch, params->depth.addr.buffer); + if (params->stencil.enabled) + iris_depth_cache_add_bo(batch, params->stencil.addr.buffer); +} + +void +genX(init_blorp)(struct iris_context *ice) +{ + ice->vtbl.blorp_exec = iris_blorp_exec; +} diff --git a/src/gallium/drivers/iris/iris_bufmgr.h b/src/gallium/drivers/iris/iris_bufmgr.h index 05d0f922951..d587314aa5f 100644 --- a/src/gallium/drivers/iris/iris_bufmgr.h +++ b/src/gallium/drivers/iris/iris_bufmgr.h @@ -78,10 +78,10 @@ enum iris_memory_zone { /* Intentionally exclude IRIS_MEMZONE_BINDER */ #define IRIS_MEMZONE_COUNT (IRIS_MEMZONE_OTHER + 1) -#define IRIS_MEMZONE_SHADER_START (0 * (1ull << 32)) -#define IRIS_MEMZONE_SURFACE_START (1 * (1ull << 32)) -#define IRIS_MEMZONE_DYNAMIC_START (2 * (1ull << 32)) -#define IRIS_MEMZONE_OTHER_START (3 * (1ull << 32)) +#define IRIS_MEMZONE_SHADER_START (0ull * (1ull << 32)) +#define IRIS_MEMZONE_SURFACE_START (1ull * (1ull << 32)) +#define IRIS_MEMZONE_DYNAMIC_START (2ull * (1ull << 32)) +#define IRIS_MEMZONE_OTHER_START (3ull * (1ull << 32)) #define IRIS_BINDER_ADDRESS IRIS_MEMZONE_SURFACE_START diff --git a/src/gallium/drivers/iris/iris_context.h b/src/gallium/drivers/iris/iris_context.h index 185687c6564..6478e3a87c1 100644 --- a/src/gallium/drivers/iris/iris_context.h +++ b/src/gallium/drivers/iris/iris_context.h @@ -34,6 +34,8 @@ struct iris_bo; struct iris_context; +struct blorp_batch; +struct blorp_params; #define IRIS_RESOURCE_FLAG_SHADER_MEMZONE (PIPE_RESOURCE_FLAG_DRV_PRIV << 0) #define IRIS_RESOURCE_FLAG_SURFACE_MEMZONE (PIPE_RESOURCE_FLAG_DRV_PRIV << 1) @@ -208,6 +210,9 @@ struct iris_vtable { void (*emit_raw_pipe_control)(struct iris_batch *batch, uint32_t flags, struct iris_bo *bo, uint32_t offset, uint64_t imm); + void (*blorp_exec)(struct blorp_batch *blorp_batch, + const struct blorp_params *params); + unsigned (*derived_program_state_size)(enum iris_program_cache_id id); void (*set_derived_program_state)(const struct gen_device_info *devinfo, enum iris_program_cache_id cache_id, @@ -327,6 +332,11 @@ void iris_render_cache_add_bo(struct iris_batch *batch, void iris_cache_flush_for_depth(struct iris_batch *batch, struct iris_bo *bo); void iris_depth_cache_add_bo(struct iris_batch *batch, struct iris_bo *bo); +/* iris_blorp.c */ + +void gen9_init_blorp(struct iris_context *ice); +void gen10_init_blorp(struct iris_context *ice); + /* iris_state.c */ void gen9_init_state(struct iris_context *ice); diff --git a/src/gallium/drivers/iris/iris_resource.h b/src/gallium/drivers/iris/iris_resource.h index 211089b569f..6225509aa11 100644 --- a/src/gallium/drivers/iris/iris_resource.h +++ b/src/gallium/drivers/iris/iris_resource.h @@ -24,6 +24,7 @@ #define IRIS_RESOURCE_H #include "pipe/p_state.h" +#include "util/u_inlines.h" #include "intel/isl/isl.h" struct iris_resource { diff --git a/src/gallium/drivers/iris/meson.build b/src/gallium/drivers/iris/meson.build index 819deba7436..d09e2d546f5 100644 --- a/src/gallium/drivers/iris/meson.build +++ b/src/gallium/drivers/iris/meson.build @@ -46,7 +46,7 @@ iris_gen_libs = [] foreach v : ['90', '100'] _lib = static_library( 'libiris_gen@0@'.format(v), - ['iris_state.c', gen_xml_pack], + ['iris_blorp.c', 'iris_state.c', gen_xml_pack], include_directories : [inc_common, inc_intel, inc_nir], c_args : [c_vis_args, no_override_init_args, '-DGEN_VERSIONx10=@0@'.format(v)], -- 2.30.2