tu: C++-proofing: fix offsetof with dynamic array index
authorDanylo Piliaiev <dpiliaiev@igalia.com>
Mon, 13 Mar 2023 13:09:20 +0000 (14:09 +0100)
committerMarge Bot <emma+marge@anholt.net>
Fri, 24 Mar 2023 15:49:25 +0000 (15:49 +0000)
Signed-off-by: Danylo Piliaiev <dpiliaiev@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/21931>

src/freedreno/vulkan/tu_clear_blit.c
src/freedreno/vulkan/tu_cmd_buffer.c
src/freedreno/vulkan/tu_descriptor_set.c
src/freedreno/vulkan/tu_device.c
src/freedreno/vulkan/tu_device.h
src/freedreno/vulkan/tu_query.c
src/freedreno/vulkan/tu_util.h

index 88d0324..7586333 100644 (file)
@@ -741,7 +741,7 @@ compile_shader(struct tu_device *dev, struct nir_shader *nir,
    memcpy(&global->shaders[*offset], so->bin,
           sizeof(uint32_t) * so->info.sizedwords);
    dev->global_shader_va[idx] = dev->global_bo->iova +
-      gb_offset(shaders[*offset]);
+      offsetof_arr(struct tu6_global, shaders, *offset);
    *offset += align(so->info.sizedwords, 32);
 }
 
index d4731ed..7ef4e8b 100644 (file)
@@ -2565,7 +2565,7 @@ tu_CmdEndTransformFeedbackEXT(VkCommandBuffer commandBuffer,
    for (uint32_t i = 0; i < IR3_MAX_SO_BUFFERS; i++) {
       /* note: FLUSH_BASE is always the same, so it could go in init_hw()? */
       tu_cs_emit_pkt4(cs, REG_A6XX_VPC_SO_FLUSH_BASE(i), 2);
-      tu_cs_emit_qw(cs, global_iova(cmd, flush_base[i]));
+      tu_cs_emit_qw(cs, global_iova_arr(cmd, flush_base, i));
       tu6_emit_event_write(cmd, cs, FLUSH_SO_0 + i);
    }
 
@@ -2586,7 +2586,7 @@ tu_CmdEndTransformFeedbackEXT(VkCommandBuffer commandBuffer,
                      0x40000 | /* ??? */
                      CP_MEM_TO_REG_0_UNK31 |
                      CP_MEM_TO_REG_0_CNT(1));
-      tu_cs_emit_qw(cs, global_iova(cmd, flush_base[idx]));
+      tu_cs_emit_qw(cs, global_iova_arr(cmd, flush_base, idx));
 
       if (offset) {
          tu_cs_emit_pkt7(cs, CP_REG_RMW, 3);
@@ -5699,7 +5699,7 @@ tu_emit_compute_driver_params(struct tu_cmd_buffer *cmd,
       for (uint32_t i = 0; i < 3; i++) {
          tu_cs_emit_pkt7(cs, CP_MEM_TO_MEM, 5);
          tu_cs_emit(cs, 0);
-         tu_cs_emit_qw(cs, global_iova(cmd, cs_indirect_xyz[i]));
+         tu_cs_emit_qw(cs, global_iova_arr(cmd, cs_indirect_xyz, i));
          tu_cs_emit_qw(cs, indirect_iova + i * 4);
       }
 
index 4c0b8f2..d6b5668 100644 (file)
@@ -150,7 +150,7 @@ tu_CreateDescriptorSetLayout(
    }
 
    uint32_t samplers_offset =
-         offsetof(struct tu_descriptor_set_layout, binding[num_bindings]);
+      offsetof_arr(struct tu_descriptor_set_layout, binding, num_bindings);
 
    /* note: only need to store TEX_SAMP_DWORDS for immutable samples,
     * but using struct tu_sampler makes things simpler */
index 3b82ec5..28cea74 100644 (file)
@@ -3067,9 +3067,10 @@ tu_init_sampler(struct tu_device *device,
          color.uint32[1] = color.uint32[0];
       }
 
-      tu6_pack_border_color(device->global_bo->map + gb_offset(bcolor[border_color]),
-                            &color,
-                            pCreateInfo->borderColor == VK_BORDER_COLOR_INT_CUSTOM_EXT);
+      tu6_pack_border_color(
+         device->global_bo->map +
+            offsetof_arr(struct tu6_global, bcolor, border_color),
+         &color, pCreateInfo->borderColor == VK_BORDER_COLOR_INT_CUSTOM_EXT);
       border_color += TU_BORDER_COLOR_BUILTIN;
    }
 
index 525f3cc..d88797a 100644 (file)
@@ -200,6 +200,9 @@ struct tu6_global
 };
 #define gb_offset(member) offsetof(struct tu6_global, member)
 #define global_iova(cmd, member) ((cmd)->device->global_bo->iova + gb_offset(member))
+#define global_iova_arr(cmd, member, idx)                                    \
+   (global_iova(cmd, member) + sizeof_field(struct tu6_global, member[0]) * (idx))
+
 
 struct tu_device
 {
index 3dc5e5b..a13f2d4 100644 (file)
@@ -101,13 +101,14 @@ struct PACKED primitives_generated_query_slot {
 #define occlusion_query_iova(pool, query, field)                     \
    query_iova(struct occlusion_query_slot, pool, query, field)
 
-#define pipeline_stat_query_iova(pool, query, field)                 \
-   pool->bo->iova + pool->stride * (query) +                            \
-   offsetof(struct pipeline_stat_query_slot, field)
+#define pipeline_stat_query_iova(pool, query, field, idx)                    \
+   pool->bo->iova + pool->stride * (query) +                                 \
+      offsetof_arr(struct pipeline_stat_query_slot, field, (idx))
 
-#define primitive_query_iova(pool, query, field, i)                  \
-   query_iova(struct primitive_query_slot, pool, query, field) +     \
-   offsetof(struct primitive_slot_value, values[i])
+#define primitive_query_iova(pool, query, field, stream_id, i)               \
+   query_iova(struct primitive_query_slot, pool, query, field) +             \
+      sizeof_field(struct primitive_query_slot, field[0]) * (stream_id) +    \
+      offsetof_arr(struct primitive_slot_value, values, (i))
 
 #define perf_query_iova(pool, query, field, i)                          \
    pool->bo->iova + pool->stride * (query) +                             \
@@ -847,7 +848,7 @@ emit_begin_stat_query(struct tu_cmd_buffer *cmdbuf,
                       uint32_t query)
 {
    struct tu_cs *cs = cmdbuf->state.pass ? &cmdbuf->draw_cs : &cmdbuf->cs;
-   uint64_t begin_iova = pipeline_stat_query_iova(pool, query, begin);
+   uint64_t begin_iova = pipeline_stat_query_iova(pool, query, begin, 0);
 
    if (is_pipeline_query_with_vertex_stage(pool->pipeline_statistics)) {
       bool need_cond_exec = cmdbuf->state.pass && cmdbuf->state.prim_counters_running;
@@ -986,7 +987,7 @@ emit_begin_xfb_query(struct tu_cmd_buffer *cmdbuf,
                      uint32_t stream_id)
 {
    struct tu_cs *cs = cmdbuf->state.pass ? &cmdbuf->draw_cs : &cmdbuf->cs;
-   uint64_t begin_iova = primitive_query_iova(pool, query, begin[0], 0);
+   uint64_t begin_iova = primitive_query_iova(pool, query, begin, 0, 0);
 
    tu_cs_emit_regs(cs, A6XX_VPC_SO_STREAM_COUNTS(.qword = begin_iova));
    tu6_emit_event_write(cmdbuf, cs, WRITE_PRIMITIVE_COUNTS);
@@ -1218,7 +1219,7 @@ emit_end_stat_query(struct tu_cmd_buffer *cmdbuf,
                     uint32_t query)
 {
    struct tu_cs *cs = cmdbuf->state.pass ? &cmdbuf->draw_cs : &cmdbuf->cs;
-   uint64_t end_iova = pipeline_stat_query_iova(pool, query, end);
+   uint64_t end_iova = pipeline_stat_query_iova(pool, query, end, 0);
    uint64_t available_iova = query_available_iova(pool, query);
    uint64_t result_iova;
    uint64_t stat_start_iova;
@@ -1250,8 +1251,8 @@ emit_end_stat_query(struct tu_cmd_buffer *cmdbuf,
 
    for (int i = 0; i < STAT_COUNT; i++) {
       result_iova = query_result_iova(pool, query, uint64_t, i);
-      stat_start_iova = pipeline_stat_query_iova(pool, query, begin[i]);
-      stat_stop_iova = pipeline_stat_query_iova(pool, query, end[i]);
+      stat_start_iova = pipeline_stat_query_iova(pool, query, begin, i);
+      stat_stop_iova = pipeline_stat_query_iova(pool, query, end, i);
 
       tu_cs_emit_pkt7(cs, CP_MEM_TO_MEM, 9);
       tu_cs_emit(cs, CP_MEM_TO_MEM_0_WAIT_FOR_MEM_WRITES |
@@ -1362,13 +1363,13 @@ emit_end_xfb_query(struct tu_cmd_buffer *cmdbuf,
 {
    struct tu_cs *cs = cmdbuf->state.pass ? &cmdbuf->draw_cs : &cmdbuf->cs;
 
-   uint64_t end_iova = primitive_query_iova(pool, query, end[0], 0);
+   uint64_t end_iova = primitive_query_iova(pool, query, end, 0, 0);
    uint64_t result_written_iova = query_result_iova(pool, query, uint64_t, 0);
    uint64_t result_generated_iova = query_result_iova(pool, query, uint64_t, 1);
-   uint64_t begin_written_iova = primitive_query_iova(pool, query, begin[stream_id], 0);
-   uint64_t begin_generated_iova = primitive_query_iova(pool, query, begin[stream_id], 1);
-   uint64_t end_written_iova = primitive_query_iova(pool, query, end[stream_id], 0);
-   uint64_t end_generated_iova = primitive_query_iova(pool, query, end[stream_id], 1);
+   uint64_t begin_written_iova = primitive_query_iova(pool, query, begin, stream_id, 0);
+   uint64_t begin_generated_iova = primitive_query_iova(pool, query, begin, stream_id, 1);
+   uint64_t end_written_iova = primitive_query_iova(pool, query, end, stream_id, 0);
+   uint64_t end_generated_iova = primitive_query_iova(pool, query, end, stream_id, 1);
    uint64_t available_iova = query_available_iova(pool, query);
 
    tu_cs_emit_regs(cs, A6XX_VPC_SO_STREAM_COUNTS(.qword = end_iova));
index b4603f6..85f2239 100644 (file)
@@ -431,4 +431,9 @@ tu_dbg_log_gmem_load_store_skips(struct tu_device *device);
       mesa_log(MESA_LOG_WARN, (MESA_LOG_TAG), (fmt), ##__VA_ARGS__);    \
 } while(0)
 
+#define sizeof_field(s, field) sizeof(((s *) NULL)->field)
+
+#define offsetof_arr(s, field, idx)                                          \
+   (offsetof(s, field) + sizeof_field(s, field[0]) * (idx))
+
 #endif /* TU_UTIL_H */