#include "util/u_transfer.h"
#include "util/u_upload_mgr.h"
#include "util/u_viewport.h"
+#include "util/u_memory.h"
#include "drm-uapi/i915_drm.h"
#include "nir.h"
#include "intel/compiler/brw_compiler.h"
uint32_t packets[GENX(3DSTATE_DEPTH_BUFFER_length) +
GENX(3DSTATE_STENCIL_BUFFER_length) +
GENX(3DSTATE_HIER_DEPTH_BUFFER_length) +
- GENX(3DSTATE_CLEAR_PARAMS_length)];
+ GENX(3DSTATE_CLEAR_PARAMS_length) +
+ GENX(MI_LOAD_REGISTER_IMM_length) * 2];
};
/**
state->stencil[0].writemask != 0 ||
(two_sided_stencil && state->stencil[1].writemask != 0);
- /* The state tracker needs to optimize away EQUAL writes for us. */
+ /* gallium frontends need to optimize away EQUAL writes for us. */
assert(!(state->depth.func == PIPE_FUNC_EQUAL && state->depth.writemask));
iris_pack_command(GENX(3DSTATE_WM_DEPTH_STENCIL), cso->wmds, wmds) {
struct iris_shader_state *shs = &ice->state.shaders[stage];
const struct shader_info *info = iris_get_shader_info(ice, stage);
- /* We assume the state tracker will call pipe->bind_sampler_states()
+ /* We assume gallium frontends will call pipe->bind_sampler_states()
* if the program's number of textures changes.
*/
unsigned count = info ? util_last_bit(info->textures_used) : 0;
* texture, the tile offsets may be anything and we can't rely on
* X/Y Offset.
*
- * Return NULL to force the state tracker to take fallback paths.
+ * Return NULL to force gallium frontends to take fallback paths.
*/
if (view->array_len > 1 || GEN_GEN == 8)
return NULL;
{
struct iris_context *ice = (struct iris_context *) ctx;
struct iris_screen *screen = (struct iris_screen *)ctx->screen;
- const struct gen_device_info *devinfo = &screen->devinfo;
gl_shader_stage stage = stage_from_pipe(p_stage);
struct iris_shader_state *shs = &ice->state.shaders[stage];
#if GEN_GEN == 8
res->bind_history |= PIPE_BIND_SHADER_IMAGE;
res->bind_stages |= 1 << stage;
- isl_surf_usage_flags_t usage = ISL_SURF_USAGE_STORAGE_BIT;
- enum isl_format isl_fmt =
- iris_format_for_usage(devinfo, img->format, usage).fmt;
-
- bool untyped_fallback = false;
+ enum isl_format isl_fmt = iris_image_view_get_format(ice, img);
- if (img->shader_access & PIPE_IMAGE_ACCESS_READ) {
- /* On Gen8, try to use typed surfaces reads (which support a
- * limited number of formats), and if not possible, fall back
- * to untyped reads.
- */
- untyped_fallback = GEN_GEN == 8 &&
- !isl_has_matching_typed_storage_image_format(devinfo, isl_fmt);
+ /* Render compression with images supported on gen12+ only. */
+ unsigned aux_usages = GEN_GEN >= 12 ? res->aux.possible_usages :
+ 1 << ISL_AUX_USAGE_NONE;
- if (untyped_fallback)
- isl_fmt = ISL_FORMAT_RAW;
- else
- isl_fmt = isl_lower_storage_image_format(devinfo, isl_fmt);
- }
-
- alloc_surface_states(&iv->surface_state, 1 << ISL_AUX_USAGE_NONE);
+ alloc_surface_states(&iv->surface_state, aux_usages);
iv->surface_state.bo_address = res->bo->gtt_offset;
void *map = iv->surface_state.cpu;
.base_array_layer = img->u.tex.first_layer,
.array_len = img->u.tex.last_layer - img->u.tex.first_layer + 1,
.swizzle = ISL_SWIZZLE_IDENTITY,
- .usage = usage,
+ .usage = ISL_SURF_USAGE_STORAGE_BIT,
};
- if (untyped_fallback) {
+ /* If using untyped fallback. */
+ if (isl_fmt == ISL_FORMAT_RAW) {
fill_buffer_surface_state(&screen->isl_dev, res, map,
isl_fmt, ISL_SWIZZLE_IDENTITY,
0, res->bo->size);
} else {
- /* Images don't support compression */
- unsigned aux_modes = 1 << ISL_AUX_USAGE_NONE;
+ unsigned aux_modes = aux_usages;
while (aux_modes) {
enum isl_aux_usage usage = u_bit_scan(&aux_modes);
value = fui(ice->state.default_inner_level[0]);
} else if (sysval == BRW_PARAM_BUILTIN_TESS_LEVEL_INNER_Y) {
value = fui(ice->state.default_inner_level[1]);
+ } else if (sysval >= BRW_PARAM_BUILTIN_WORK_GROUP_SIZE_X &&
+ sysval <= BRW_PARAM_BUILTIN_WORK_GROUP_SIZE_Z) {
+ unsigned i = sysval - BRW_PARAM_BUILTIN_WORK_GROUP_SIZE_X;
+ value = ice->state.last_block[i];
} else {
assert(!"unhandled system value");
}
/* XXX: this should be generated when putting programs in place */
- for (int fs_attr = 0; fs_attr < VARYING_SLOT_MAX; fs_attr++) {
+ for (uint8_t idx = 0; idx < wm_prog_data->urb_setup_attribs_count; idx++) {
+ const uint8_t fs_attr = wm_prog_data->urb_setup_attribs[idx];
const int input_index = wm_prog_data->urb_setup[fs_attr];
if (input_index < 0 || input_index >= 16)
continue;
* more than 2 times the number of instance count.
*/
assert((devinfo->max_tcs_threads / 2) > tcs_prog_data->instances);
+ hs.DispatchGRFStartRegisterForURBData = prog_data->dispatch_grf_start_reg & 0x1f;
+ hs.DispatchGRFStartRegisterForURBData5 = prog_data->dispatch_grf_start_reg >> 5;
#endif
hs.InstanceCount = tcs_prog_data->instances - 1;
hs.MaximumNumberofThreads = devinfo->max_tcs_threads - 1;
hs.IncludeVertexHandles = true;
+#if GEN_GEN == 12
+ /* Patch Count threshold specifies the maximum number of patches that
+ * will be accumulated before a thread dispatch is forced.
+ */
+ hs.PatchCountThreshold = tcs_prog_data->patch_count_threshold;
+#endif
+
#if GEN_GEN >= 9
hs.DispatchMode = vue_prog_data->dispatch_mode;
hs.IncludePrimitiveID = tcs_prog_data->include_primitive_id;
iris_pack_state(GENX(INTERFACE_DESCRIPTOR_DATA), map, desc) {
desc.KernelStartPointer = KSP(shader);
desc.ConstantURBEntryReadLength = cs_prog_data->push.per_thread.regs;
- desc.NumberofThreadsinGPGPUThreadGroup = cs_prog_data->threads;
desc.SharedLocalMemorySize =
encode_slm_size(GEN_GEN, prog_data->total_shared);
desc.BarrierEnable = cs_prog_data->uses_barrier;
desc.CrossThreadConstantDataReadLength =
cs_prog_data->push.cross_thread.regs;
+#if GEN_GEN >= 12
+ /* TODO: Check if we are missing workarounds and enable mid-thread
+ * preemption.
+ *
+ * We still have issues with mid-thread preemption (it was already
+ * disabled by the kernel on gen11, due to missing workarounds). It's
+ * possible that we are just missing some workarounds, and could enable
+ * it later, but for now let's disable it to fix a GPU in compute in Car
+ * Chase (and possibly more).
+ */
+ desc.ThreadPreemptionDisable = true;
+#endif
}
}
static uint32_t
use_image(struct iris_batch *batch, struct iris_context *ice,
- struct iris_shader_state *shs, int i)
+ struct iris_shader_state *shs, const struct shader_info *info,
+ int i)
{
struct iris_image_view *iv = &shs->image[i];
struct iris_resource *res = (void *) iv->base.resource;
if (res->aux.bo)
iris_use_pinned_bo(batch, res->aux.bo, write);
- return iv->surface_state.ref.offset;
+ enum isl_aux_usage aux_usage =
+ iris_image_view_aux_usage(ice, &iv->base, info);
+
+ return iv->surface_state.ref.offset +
+ surf_state_offset_for_aux(res, res->aux.possible_usages, aux_usage);
}
#define push_bt_entry(addr) \
}
foreach_surface_used(i, IRIS_SURFACE_GROUP_IMAGE) {
- uint32_t addr = use_image(batch, ice, shs, i);
+ uint32_t addr = use_image(batch, ice, shs, info, i);
push_bt_entry(addr);
}
return;
uint32_t aux_map_state_num = gen_aux_map_get_state_num(aux_map_ctx);
if (batch->last_aux_map_state != aux_map_state_num) {
+ /* HSD 1209978178: docs say that before programming the aux table:
+ *
+ * "Driver must ensure that the engine is IDLE but ensure it doesn't
+ * add extra flushes in the case it knows that the engine is already
+ * IDLE."
+ *
+ * An end of pipe sync is needed here, otherwise we see GPU hangs in
+ * dEQP-GLES31.functional.copy_image.* tests.
+ */
+ iris_emit_end_of_pipe_sync(batch, "Invalidate aux map table",
+ PIPE_CONTROL_CS_STALL);
+
/* If the aux-map state number increased, then we need to rewrite the
* register. Rewriting the register is used to both set the aux-map
* translation table address, and also to invalidate any previously
* first.
*/
uint32_t clear_length = GENX(3DSTATE_CLEAR_PARAMS_length) * 4;
- uint32_t cso_z_size = sizeof(cso_z->packets) - clear_length;
+ uint32_t cso_z_size = batch->screen->isl_dev.ds.size - clear_length;;
+
+#if GEN_GEN == 12
+ /* GEN:BUG:14010455700
+ *
+ * ISL will change some CHICKEN registers depending on the depth surface
+ * format, along with emitting the depth and stencil packets. In that
+ * case, we want to do a depth flush and stall, so the pipeline is not
+ * using these settings while we change the registers.
+ */
+ iris_emit_end_of_pipe_sync(batch,
+ "Workaround: Stop pipeline for 14010455700",
+ PIPE_CONTROL_DEPTH_STALL |
+ PIPE_CONTROL_DEPTH_CACHE_FLUSH);
+#endif
+
iris_batch_emit(batch, cso_z->packets, cso_z_size);
if (GEN_GEN >= 12) {
/* GEN:BUG:1408224581
if (dirty & IRIS_DIRTY_VERTEX_BUFFERS) {
int count = util_bitcount64(ice->state.bound_vertex_buffers);
- int dynamic_bound = ice->state.bound_vertex_buffers;
+ uint64_t dynamic_bound = ice->state.bound_vertex_buffers;
if (ice->state.vs_uses_draw_params) {
assert(ice->draw.draw_params.res);
struct brw_stage_prog_data *prog_data = shader->prog_data;
struct brw_cs_prog_data *cs_prog_data = (void *) prog_data;
+ const uint32_t group_size = grid->block[0] * grid->block[1] * grid->block[2];
+ const unsigned threads = DIV_ROUND_UP(group_size, cs_prog_data->simd_size);
+
/* Always pin the binder. If we're emitting new binding table pointers,
* we need it. If not, we're probably inheriting old tables via the
* context, and need it anyway. Since true zero-bindings cases are
vfe.URBEntryAllocationSize = 2;
vfe.CURBEAllocationSize =
- ALIGN(cs_prog_data->push.per_thread.regs * cs_prog_data->threads +
+ ALIGN(cs_prog_data->push.per_thread.regs * threads +
cs_prog_data->push.cross_thread.regs, 2);
}
}
assert(cs_prog_data->push.cross_thread.dwords == 0 &&
cs_prog_data->push.per_thread.dwords == 1 &&
cs_prog_data->base.param[0] == BRW_PARAM_BUILTIN_SUBGROUP_ID);
+ const unsigned push_const_size =
+ brw_cs_push_const_total_size(cs_prog_data, threads);
uint32_t *curbe_data_map =
stream_state(batch, ice->state.dynamic_uploader,
&ice->state.last_res.cs_thread_ids,
- ALIGN(cs_prog_data->push.total.size, 64), 64,
+ ALIGN(push_const_size, 64), 64,
&curbe_data_offset);
assert(curbe_data_map);
- memset(curbe_data_map, 0x5a, ALIGN(cs_prog_data->push.total.size, 64));
- iris_fill_cs_push_const_buffer(cs_prog_data, curbe_data_map);
+ memset(curbe_data_map, 0x5a, ALIGN(push_const_size, 64));
+ iris_fill_cs_push_const_buffer(cs_prog_data, threads, curbe_data_map);
iris_emit_cmd(batch, GENX(MEDIA_CURBE_LOAD), curbe) {
- curbe.CURBETotalDataLength =
- ALIGN(cs_prog_data->push.total.size, 64);
+ curbe.CURBETotalDataLength = ALIGN(push_const_size, 64);
curbe.CURBEDataStartAddress = curbe_data_offset;
}
}
iris_pack_state(GENX(INTERFACE_DESCRIPTOR_DATA), desc, idd) {
idd.SamplerStatePointer = shs->sampler_table.offset;
idd.BindingTablePointer = binder->bt_offset[MESA_SHADER_COMPUTE];
+ idd.NumberofThreadsinGPGPUThreadGroup = threads;
}
for (int i = 0; i < GENX(INTERFACE_DESCRIPTOR_DATA_length); i++)
}
}
- uint32_t group_size = grid->block[0] * grid->block[1] * grid->block[2];
uint32_t remainder = group_size & (cs_prog_data->simd_size - 1);
uint32_t right_mask;
ggw.SIMDSize = cs_prog_data->simd_size / 16;
ggw.ThreadDepthCounterMaximum = 0;
ggw.ThreadHeightCounterMaximum = 0;
- ggw.ThreadWidthCounterMaximum = cs_prog_data->threads - 1;
+ ggw.ThreadWidthCounterMaximum = threads - 1;
ggw.ThreadGroupIDXDimension = grid->grid[0];
ggw.ThreadGroupIDYDimension = grid->grid[1];
ggw.ThreadGroupIDZDimension = grid->grid[2];
ctx->set_stream_output_targets = iris_set_stream_output_targets;
ctx->set_frontend_noop = iris_set_frontend_noop;
- ice->vtbl.destroy_state = iris_destroy_state;
- ice->vtbl.init_render_context = iris_init_render_context;
- ice->vtbl.init_compute_context = iris_init_compute_context;
- ice->vtbl.upload_render_state = iris_upload_render_state;
- ice->vtbl.update_surface_base_address = iris_update_surface_base_address;
- ice->vtbl.upload_compute_state = iris_upload_compute_state;
- ice->vtbl.emit_raw_pipe_control = iris_emit_raw_pipe_control;
- ice->vtbl.emit_mi_report_perf_count = iris_emit_mi_report_perf_count;
- ice->vtbl.rebind_buffer = iris_rebind_buffer;
- ice->vtbl.load_register_reg32 = iris_load_register_reg32;
- ice->vtbl.load_register_reg64 = iris_load_register_reg64;
- ice->vtbl.load_register_imm32 = iris_load_register_imm32;
- ice->vtbl.load_register_imm64 = iris_load_register_imm64;
- ice->vtbl.load_register_mem32 = iris_load_register_mem32;
- ice->vtbl.load_register_mem64 = iris_load_register_mem64;
- ice->vtbl.store_register_mem32 = iris_store_register_mem32;
- ice->vtbl.store_register_mem64 = iris_store_register_mem64;
- ice->vtbl.store_data_imm32 = iris_store_data_imm32;
- ice->vtbl.store_data_imm64 = iris_store_data_imm64;
- ice->vtbl.copy_mem_mem = iris_copy_mem_mem;
- ice->vtbl.derived_program_state_size = iris_derived_program_state_size;
- ice->vtbl.store_derived_program_state = iris_store_derived_program_state;
- ice->vtbl.create_so_decl_list = iris_create_so_decl_list;
- ice->vtbl.populate_vs_key = iris_populate_vs_key;
- ice->vtbl.populate_tcs_key = iris_populate_tcs_key;
- ice->vtbl.populate_tes_key = iris_populate_tes_key;
- ice->vtbl.populate_gs_key = iris_populate_gs_key;
- ice->vtbl.populate_fs_key = iris_populate_fs_key;
- ice->vtbl.populate_cs_key = iris_populate_cs_key;
- ice->vtbl.lost_genx_state = iris_lost_genx_state;
+ screen->vtbl.destroy_state = iris_destroy_state;
+ screen->vtbl.init_render_context = iris_init_render_context;
+ screen->vtbl.init_compute_context = iris_init_compute_context;
+ screen->vtbl.upload_render_state = iris_upload_render_state;
+ screen->vtbl.update_surface_base_address = iris_update_surface_base_address;
+ screen->vtbl.upload_compute_state = iris_upload_compute_state;
+ screen->vtbl.emit_raw_pipe_control = iris_emit_raw_pipe_control;
+ screen->vtbl.emit_mi_report_perf_count = iris_emit_mi_report_perf_count;
+ screen->vtbl.rebind_buffer = iris_rebind_buffer;
+ screen->vtbl.load_register_reg32 = iris_load_register_reg32;
+ screen->vtbl.load_register_reg64 = iris_load_register_reg64;
+ screen->vtbl.load_register_imm32 = iris_load_register_imm32;
+ screen->vtbl.load_register_imm64 = iris_load_register_imm64;
+ screen->vtbl.load_register_mem32 = iris_load_register_mem32;
+ screen->vtbl.load_register_mem64 = iris_load_register_mem64;
+ screen->vtbl.store_register_mem32 = iris_store_register_mem32;
+ screen->vtbl.store_register_mem64 = iris_store_register_mem64;
+ screen->vtbl.store_data_imm32 = iris_store_data_imm32;
+ screen->vtbl.store_data_imm64 = iris_store_data_imm64;
+ screen->vtbl.copy_mem_mem = iris_copy_mem_mem;
+ screen->vtbl.derived_program_state_size = iris_derived_program_state_size;
+ screen->vtbl.store_derived_program_state = iris_store_derived_program_state;
+ screen->vtbl.create_so_decl_list = iris_create_so_decl_list;
+ screen->vtbl.populate_vs_key = iris_populate_vs_key;
+ screen->vtbl.populate_tcs_key = iris_populate_tcs_key;
+ screen->vtbl.populate_tes_key = iris_populate_tes_key;
+ screen->vtbl.populate_gs_key = iris_populate_gs_key;
+ screen->vtbl.populate_fs_key = iris_populate_fs_key;
+ screen->vtbl.populate_cs_key = iris_populate_cs_key;
+ screen->vtbl.lost_genx_state = iris_lost_genx_state;
ice->state.dirty = ~0ull;