unsigned size,
unsigned alignment,
uint32_t *out_offset,
- struct iris_bo **out_bo)
+ struct iris_bo **out_bo,
+ bool relative_to_base)
{
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);
+ struct iris_bo *bo = iris_resource_bo(res);
+ iris_use_pinned_bo(batch, bo, false);
- *out_offset += iris_bo_offset_from_base_address(*out_bo);
+ *out_bo = bo;
+ *out_offset += relative_to_base ? iris_bo_offset_from_base_address(bo)
+ : bo->gtt_offset;
pipe_resource_reference(&res, NULL);
struct iris_bo *bo;
return stream_state(batch, ice->state.dynamic_uploader,
- size, alignment, offset, &bo);
+ size, alignment, offset, &bo, true);
}
static void
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);
+ &surface_offsets[i], &bo, true);
bt_map[i] = surface_offsets[i];
}
}
uint32_t offset;
void *map = stream_state(batch, ice->ctx.stream_uploader, size, 64,
- &offset, &bo);
+ &offset, &bo, false);
*addr = (struct blorp_address) {
.buffer = bo,
blorp_init(&ice->blorp, ice, &screen->isl_dev);
ice->blorp.compiler = screen->compiler;
-
- ice->vtbl.blorp_exec = iris_blorp_exec;
+ ice->blorp.lookup_shader = iris_blorp_lookup_shader;
+ ice->blorp.upload_shader = iris_blorp_upload_shader;
+ ice->blorp.exec = iris_blorp_exec;
}
#include "intel/compiler/brw_eu.h"
#include "intel/compiler/brw_nir.h"
#include "iris_context.h"
+#include "iris_resource.h"
struct keybox {
uint8_t size;
uint8_t data[0];
};
-static struct keybox *
-make_keybox(void *mem_ctx,
- enum iris_program_cache_id cache_id,
- const void *key)
+static uint32_t
+key_size_for_cache(enum iris_program_cache_id cache_id)
{
static const unsigned key_sizes[] = {
[IRIS_CACHE_VS] = sizeof(struct brw_vs_prog_key),
[IRIS_CACHE_GS] = sizeof(struct brw_gs_prog_key),
[IRIS_CACHE_FS] = sizeof(struct brw_wm_prog_key),
[IRIS_CACHE_CS] = sizeof(struct brw_cs_prog_key),
- //[IRIS_CACHE_BLORP_BLIT] = sizeof(struct brw_blorp_blit_prog_key),
};
+ /* BLORP keys aren't all the same size. */
+ assert(cache_id != IRIS_CACHE_BLORP);
+
+ return key_sizes[cache_id];
+}
+
+static struct keybox *
+make_keybox(void *mem_ctx,
+ enum iris_program_cache_id cache_id,
+ const void *key,
+ uint32_t key_size)
+{
struct keybox *keybox =
- ralloc_size(mem_ctx, sizeof(struct keybox) + key_sizes[cache_id]);
+ ralloc_size(mem_ctx, sizeof(struct keybox) + key_size);
keybox->cache_id = cache_id;
- keybox->size = key_sizes[cache_id];
- memcpy(keybox->data, key, key_sizes[cache_id]);
+ keybox->size = key_size;
+ memcpy(keybox->data, key, key_size);
return keybox;
}
}
}
+static struct iris_compiled_shader *
+iris_find_cached_shader(struct iris_context *ice,
+ enum iris_program_cache_id cache_id,
+ const void *key,
+ uint32_t key_size)
+{
+ struct keybox *keybox =
+ make_keybox(ice->shaders.cache, cache_id, key, key_size);
+ struct hash_entry *entry =
+ _mesa_hash_table_search(ice->shaders.cache, keybox);
+
+ return entry ? entry->data : NULL;
+}
+
/**
* Looks for a program in the cache and binds it.
*
enum iris_program_cache_id cache_id,
const void *key)
{
- struct keybox *keybox = make_keybox(ice->shaders.cache, cache_id, key);
- struct hash_entry *entry =
- _mesa_hash_table_search(ice->shaders.cache, keybox);
+ unsigned key_size = key_size_for_cache(cache_id);
+ struct iris_compiled_shader *shader =
+ iris_find_cached_shader(ice, cache_id, key, key_size);
- if (!entry)
+ if (!shader)
return false;
- struct iris_compiled_shader *shader = entry->data;
-
- if (cache_id <= MESA_SHADER_STAGES &&
- memcmp(shader, ice->shaders.prog[cache_id], sizeof(*shader)) != 0) {
+ if (memcmp(shader, ice->shaders.prog[cache_id], sizeof(*shader)) != 0) {
ice->shaders.prog[cache_id] = shader;
ice->state.dirty |= dirty_flag_for_cache(cache_id);
}
return NULL;
}
-/**
- * Upload a new shader to the program cache, and bind it for use.
- *
- * \param prog_data must be ralloc'd and will be stolen.
- */
-void
-iris_upload_and_bind_shader(struct iris_context *ice,
- enum iris_program_cache_id cache_id,
- const void *key,
- const void *assembly,
- struct brw_stage_prog_data *prog_data)
+static struct iris_compiled_shader *
+iris_upload_shader(struct iris_context *ice,
+ enum iris_program_cache_id cache_id,
+ uint32_t key_size,
+ const void *key,
+ const void *assembly,
+ const struct brw_stage_prog_data *prog_data)
{
struct iris_screen *screen = (void *) ice->ctx.screen;
struct gen_device_info *devinfo = &screen->devinfo;
shader->prog_data = prog_data;
+ /* Store the 3DSTATE shader packets and other derived state. */
+ ice->vtbl.set_derived_program_state(devinfo, cache_id, shader);
+
+ struct keybox *keybox = make_keybox(cache, cache_id, key, key_size);
+ _mesa_hash_table_insert(ice->shaders.cache, keybox, shader);
+
+ return shader;
+}
+
+/**
+ * Upload a new shader to the program cache, and bind it for use.
+ *
+ * \param prog_data must be ralloc'd and will be stolen.
+ */
+void
+iris_upload_and_bind_shader(struct iris_context *ice,
+ enum iris_program_cache_id cache_id,
+ const void *key,
+ const void *assembly,
+ struct brw_stage_prog_data *prog_data)
+{
+ assert(cache_id != IRIS_CACHE_BLORP);
+
+ struct iris_compiled_shader *shader =
+ iris_upload_shader(ice, cache_id, key_size_for_cache(cache_id), key,
+ assembly, prog_data);
+
ralloc_steal(shader, shader->prog_data);
ralloc_steal(shader->prog_data, prog_data->param);
ralloc_steal(shader->prog_data, prog_data->pull_param);
- /* Store the 3DSTATE shader packets and other derived state. */
- ice->vtbl.set_derived_program_state(devinfo, cache_id, shader);
+ ice->shaders.prog[cache_id] = shader;
+ ice->state.dirty |= dirty_flag_for_cache(cache_id);
+}
- struct keybox *keybox = make_keybox(cache, cache_id, key);
- _mesa_hash_table_insert(ice->shaders.cache, keybox, shader);
+bool
+iris_blorp_lookup_shader(struct blorp_batch *blorp_batch,
+ const void *key, uint32_t key_size,
+ uint32_t *kernel_out, void *prog_data_out)
+{
+ struct blorp_context *blorp = blorp_batch->blorp;
+ struct iris_context *ice = blorp->driver_ctx;
+ struct iris_batch *batch = blorp_batch->driver_batch;
+ struct iris_compiled_shader *shader =
+ iris_find_cached_shader(ice, IRIS_CACHE_BLORP, key, key_size);
- if (cache_id <= MESA_SHADER_STAGES) {
- ice->shaders.prog[cache_id] = shader;
- ice->state.dirty |= dirty_flag_for_cache(cache_id);
- }
+ if (!shader)
+ return false;
+
+ struct iris_bo *bo = iris_resource_bo(shader->buffer);
+ *kernel_out = iris_bo_offset_from_base_address(bo) + shader->offset;
+ *((void **) prog_data_out) = shader->prog_data;
+
+ iris_use_pinned_bo(batch, bo, false);
+
+ return true;
+}
+
+bool
+iris_blorp_upload_shader(struct blorp_batch *blorp_batch,
+ const void *key, uint32_t key_size,
+ const void *kernel, UNUSED uint32_t kernel_size,
+ const struct brw_stage_prog_data *prog_data,
+ UNUSED uint32_t prog_data_size,
+ uint32_t *kernel_out, void *prog_data_out)
+{
+ struct blorp_context *blorp = blorp_batch->blorp;
+ struct iris_context *ice = blorp->driver_ctx;
+ struct iris_batch *batch = blorp_batch->driver_batch;
+
+ struct iris_compiled_shader *shader =
+ iris_upload_shader(ice, IRIS_CACHE_BLORP, key_size, key, kernel,
+ prog_data);
+
+ struct iris_bo *bo = iris_resource_bo(shader->buffer);
+ *kernel_out = iris_bo_offset_from_base_address(bo) + shader->offset;
+ *((void **) prog_data_out) = shader->prog_data;
+
+ iris_use_pinned_bo(batch, bo, false);
+
+ return true;
}
void
static const char *
cache_name(enum iris_program_cache_id cache_id)
{
- if (cache_id == IRIS_CACHE_BLORP_BLIT)
+ if (cache_id == IRIS_CACHE_BLORP)
return "BLORP";
return _mesa_shader_stage_to_string(cache_id);