summaryrefslogtreecommitdiffstats
path: root/src/intel/isl
diff options
context:
space:
mode:
Diffstat (limited to 'src/intel/isl')
-rw-r--r--src/intel/isl/isl_surface_state.c22
1 files changed, 21 insertions, 1 deletions
diff --git a/src/intel/isl/isl_surface_state.c b/src/intel/isl/isl_surface_state.c
index bfb27fa4a44..c205b3d2c0b 100644
--- a/src/intel/isl/isl_surface_state.c
+++ b/src/intel/isl/isl_surface_state.c
@@ -673,7 +673,27 @@ void
isl_genX(buffer_fill_state_s)(void *state,
const struct isl_buffer_fill_state_info *restrict info)
{
- uint32_t num_elements = info->size / info->stride;
+ uint64_t buffer_size = info->size;
+
+ /* Uniform and Storage buffers need to have surface size not less that the
+ * aligned 32-bit size of the buffer. To calculate the array lenght on
+ * unsized arrays in StorageBuffer the last 2 bits store the padding size
+ * added to the surface, so we can calculate latter the original buffer
+ * size to know the number of elements.
+ *
+ * surface_size = isl_align(buffer_size, 4) +
+ * (isl_align(buffer_size) - buffer_size)
+ *
+ * buffer_size = (surface_size & ~3) - (surface_size & 3)
+ */
+ if (info->format == ISL_FORMAT_RAW ||
+ info->stride < isl_format_get_layout(info->format)->bpb / 8) {
+ assert(info->stride == 1);
+ uint64_t aligned_size = isl_align(buffer_size, 4);
+ buffer_size = aligned_size + (aligned_size - buffer_size);
+ }
+
+ uint32_t num_elements = buffer_size / info->stride;
if (GEN_GEN >= 7) {
/* From the IVB PRM, SURFACE_STATE::Height,