intel/decoder: Make get_state_size take a full 64-bit address and a base
authorKenneth Graunke <kenneth@whitecape.org>
Wed, 2 Oct 2019 19:09:33 +0000 (15:09 -0400)
committerKenneth Graunke <kenneth@whitecape.org>
Wed, 11 Dec 2019 03:10:49 +0000 (19:10 -0800)
i965 wants to use an offset from a base because everything is in a
single buffer whose address may be relocated, and all base addresses
are set to the start of that buffer.

iris wants to use a full 64-bit address, because state lives in separate
buffers which may be in the shader, surface, and dynamic memory zones,
where addresses grow downward from the top of a 4GB zone,  So it's very
possible for a 32-bit offset to exist relative to multiple bases,
leading to the wrong state size.

src/gallium/drivers/iris/iris_batch.c
src/gallium/drivers/iris/iris_state.c
src/intel/common/gen_batch_decoder.c
src/intel/common/gen_decoder.h
src/mesa/drivers/dri/i965/intel_batchbuffer.c

index 9dbe4a51bdebc9bb6591d6b7d0c56725d4995d90..a44715a9458b6a02de86cd81e7dab5ddb88e161e 100644 (file)
@@ -150,20 +150,13 @@ decode_get_bo(void *v_batch, bool ppgtt, uint64_t address)
 }
 
 static unsigned
-decode_get_state_size(void *v_batch, uint32_t offset_from_base)
+decode_get_state_size(void *v_batch,
+                      uint64_t address,
+                      UNUSED uint64_t base_address)
 {
    struct iris_batch *batch = v_batch;
-
-   /* The decoder gives us offsets from a base address, which is not great.
-    * Binding tables are relative to surface state base address, and other
-    * state is relative to dynamic state base address.  These could alias,
-    * but in practice it's unlikely because surface offsets are always in
-    * the [0, 64K) range, and we assign dynamic state addresses starting at
-    * the top of the 4GB range.  We should fix this but it's likely good
-    * enough for now.
-    */
    unsigned size = (uintptr_t)
-      _mesa_hash_table_u64_search(batch->state_sizes, offset_from_base);
+      _mesa_hash_table_u64_search(batch->state_sizes, address);
 
    return size;
 }
index 6e90d33502b162fcc94a7b4c9944455b729487ee..4e0fefa9251889350ed452e5e547c67f5bfe9adc 100644 (file)
@@ -346,9 +346,10 @@ stream_state(struct iris_batch *batch,
    struct iris_bo *bo = iris_resource_bo(*out_res);
    iris_use_pinned_bo(batch, bo, false);
 
-   *out_offset += iris_bo_offset_from_base_address(bo);
+   iris_record_state_size(batch->state_sizes,
+                          bo->gtt_offset + *out_offset, size);
 
-   iris_record_state_size(batch->state_sizes, *out_offset, size);
+   *out_offset += iris_bo_offset_from_base_address(bo);
 
    return ptr;
 }
@@ -1988,10 +1989,12 @@ iris_upload_sampler_states(struct iris_context *ice, gl_shader_stage stage)
       return;
 
    struct pipe_resource *res = shs->sampler_table.res;
-   shs->sampler_table.offset +=
-      iris_bo_offset_from_base_address(iris_resource_bo(res));
+   struct iris_bo *bo = iris_resource_bo(res);
+
+   iris_record_state_size(ice->state.sizes,
+                          bo->gtt_offset + shs->sampler_table.offset, size);
 
-   iris_record_state_size(ice->state.sizes, shs->sampler_table.offset, size);
+   shs->sampler_table.offset += iris_bo_offset_from_base_address(bo);
 
    /* Make sure all land in the same BO */
    iris_border_color_pool_reserve(ice, IRIS_MAX_TEXTURE_SAMPLERS);
index 41425e8bf685d6b6d03a573f1e554f14bcbd7ad3..2a5261b2f929e73f4859ab73fa306ee230383a2d 100644 (file)
@@ -36,7 +36,8 @@ gen_batch_decode_ctx_init(struct gen_batch_decode_ctx *ctx,
                           struct gen_batch_decode_bo (*get_bo)(void *,
                                                                bool,
                                                                uint64_t),
-                          unsigned (*get_state_size)(void *, uint32_t),
+                          unsigned (*get_state_size)(void *, uint64_t,
+                                                     uint64_t),
                           void *user_data)
 {
    memset(ctx, 0, sizeof(*ctx));
@@ -110,14 +111,15 @@ ctx_get_bo(struct gen_batch_decode_ctx *ctx, bool ppgtt, uint64_t addr)
 
 static int
 update_count(struct gen_batch_decode_ctx *ctx,
-             uint32_t offset_from_dsba,
+             uint64_t address,
+             uint64_t base_address,
              unsigned element_dwords,
              unsigned guess)
 {
    unsigned size = 0;
 
    if (ctx->get_state_size)
-      size = ctx->get_state_size(ctx->user_data, offset_from_dsba);
+      size = ctx->get_state_size(ctx->user_data, address, base_address);
 
    if (size > 0)
       return size / (sizeof(uint32_t) * element_dwords);
@@ -249,8 +251,10 @@ dump_binding_table(struct gen_batch_decode_ctx *ctx, uint32_t offset, int count)
       return;
    }
 
-   if (count < 0)
-      count = update_count(ctx, offset, 1, 8);
+   if (count < 0) {
+      count = update_count(ctx, ctx->surface_base + offset,
+                           ctx->surface_base, 1, 8);
+   }
 
    if (offset % 32 != 0 || offset >= UINT16_MAX) {
       fprintf(ctx->fp, "  invalid binding table pointer\n");
@@ -289,11 +293,13 @@ static void
 dump_samplers(struct gen_batch_decode_ctx *ctx, uint32_t offset, int count)
 {
    struct gen_group *strct = gen_spec_find_struct(ctx->spec, "SAMPLER_STATE");
+   uint64_t state_addr = ctx->dynamic_base + offset;
 
-   if (count < 0)
-      count = update_count(ctx, offset, strct->dw_length, 4);
+   if (count < 0) {
+      count = update_count(ctx, state_addr, ctx->dynamic_base,
+                           strct->dw_length, 4);
+   }
 
-   uint64_t state_addr = ctx->dynamic_base + offset;
    struct gen_batch_decode_bo bo = ctx_get_bo(ctx, true, state_addr);
    const void *state_map = bo.map;
 
@@ -765,7 +771,8 @@ decode_dynamic_state_pointers(struct gen_batch_decode_ctx *ctx,
       state = gen_spec_find_struct(ctx->spec, struct_type);
    }
 
-   count = update_count(ctx, state_offset, state->dw_length, count);
+   count = update_count(ctx, ctx->dynamic_base + state_offset,
+                        ctx->dynamic_base, state->dw_length, count);
 
    for (int i = 0; i < count; i++) {
       fprintf(ctx->fp, "%s %d\n", struct_type, i);
index 153e48d8e4944d338ba90ed06b89852b56076d54..0b770ee36913a47f43946b5d6d5f07299c2d6719 100644 (file)
@@ -231,7 +231,8 @@ struct gen_batch_decode_ctx {
     */
    struct gen_batch_decode_bo (*get_bo)(void *user_data, bool ppgtt, uint64_t address);
    unsigned (*get_state_size)(void *user_data,
-                              uint32_t offset_from_dynamic_state_base_addr);
+                              uint64_t address,
+                              uint64_t base_address);
    void *user_data;
 
    FILE *fp;
@@ -259,7 +260,8 @@ void gen_batch_decode_ctx_init(struct gen_batch_decode_ctx *ctx,
                                                                     bool,
                                                                     uint64_t),
 
-                               unsigned (*get_state_size)(void *, uint32_t),
+                               unsigned (*get_state_size)(void *, uint64_t,
+                                                          uint64_t),
                                void *user_data);
 void gen_batch_decode_ctx_finish(struct gen_batch_decode_ctx *ctx);
 
index af076f65f0b29bc21613f2d650fe054ca24f3327..d5676e9cb9f234fabed512cc12a541d008935930 100644 (file)
@@ -104,12 +104,13 @@ decode_get_bo(void *v_brw, bool ppgtt, uint64_t address)
 }
 
 static unsigned
-decode_get_state_size(void *v_brw, uint32_t offset_from_dsba)
+decode_get_state_size(void *v_brw, uint64_t address, uint64_t base_address)
 {
    struct brw_context *brw = v_brw;
    struct intel_batchbuffer *batch = &brw->batch;
-   unsigned size = (uintptr_t) _mesa_hash_table_u64_search(
-      batch->state_batch_sizes, offset_from_dsba);
+   unsigned size = (uintptr_t)
+      _mesa_hash_table_u64_search(batch->state_batch_sizes,
+                                  address - base_address);
    return size;
 }