diff options
Diffstat (limited to 'src/intel/isl')
-rw-r--r-- | src/intel/isl/isl_surface_state.c | 22 |
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, |