[Mesa-dev] [Mesa-stable] [PATCH] i965/fs: Fix hang on IVB and VLV with image format mismatch.

Ian Romanick idr at freedesktop.org
Wed Sep 9 10:04:46 PDT 2015


On 09/09/2015 05:30 AM, Francisco Jerez wrote:
> Ian Romanick <idr at freedesktop.org> writes:
> 
>> On 09/03/2015 06:03 AM, Francisco Jerez wrote:
>>> IVB and VLV hang sporadically when an untyped surface read or write
>>> message is used to access a surface of format other than RAW, as may
>>> happen when there is a mismatch between the format qualifier of the
>>> image uniform and the format of the actual image bound to the
>>> pipeline.  According to the spec this condition gives undefined
>>> results but may not lead to program termination (which is one of the
>>> possible outcomes of the hang).  Fix it by checking at runtime whether
>>> the surface is of the right type.
>>>
>>> Fixes the "arb_shader_image_load_store.invalid/format mismatch" piglit
>>> subtest.
>>>
>>> Reported-by: Mark Janes <mark.a.janes at intel.com>
>>> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=91718
>>> CC: mesa-stable at lists.freedesktop.org
>>> ---
>>>  .../drivers/dri/i965/brw_fs_surface_builder.cpp    | 42 +++++++++++++++++++---
>>>  1 file changed, 38 insertions(+), 4 deletions(-)
>>>
>>> diff --git a/src/mesa/drivers/dri/i965/brw_fs_surface_builder.cpp b/src/mesa/drivers/dri/i965/brw_fs_surface_builder.cpp
>>> index f60afc9..57ce87f 100644
>>> --- a/src/mesa/drivers/dri/i965/brw_fs_surface_builder.cpp
>>> +++ b/src/mesa/drivers/dri/i965/brw_fs_surface_builder.cpp
>>> @@ -313,12 +313,42 @@ namespace {
>>>  
>>>     namespace image_validity {
>>>        /**
>>> +       * Check whether the bound image is suitable for untyped access.
>>> +       */
>>> +      brw_predicate
>>> +      emit_untyped_image_check(const fs_builder &bld, const fs_reg &image,
>>> +                               brw_predicate pred)
>>> +      {
>>> +         const brw_device_info *devinfo = bld.shader->devinfo;
>>> +         const fs_reg stride = offset(image, bld, BRW_IMAGE_PARAM_STRIDE_OFFSET);
>>> +
>>> +         if (devinfo->gen == 7 && !devinfo->is_haswell) {
>>> +            /* Check whether the first stride component (i.e. the Bpp value)
>>> +             * is greater than four, what on Gen7 indicates that a surface of
>>> +             * type RAW has been bound for untyped access.  Reading or writing
>>> +             * to a surface of type other than RAW using untyped surface
>>> +             * messages causes a hang on IVB and VLV.
>>> +             */
>>> +            set_predicate(pred,
>>> +                          bld.CMP(bld.null_reg_ud(), stride, fs_reg(4),
>>> +                                  BRW_CONDITIONAL_G));
>>> +
>>> +            return BRW_PREDICATE_NORMAL;
>>> +         } else {
>>> +            /* More recent generations handle the format mismatch
>>> +             * gracefully.
>>> +             */
>>> +            return pred;
>>> +         }
>>> +      }
>>> +
>>> +      /**
>>>         * Check whether there is an image bound at the given index and write
>>>         * the comparison result to f0.0.  Returns an appropriate predication
>>>         * mode to use on subsequent image operations.
>>>         */
>>>        brw_predicate
>>> -      emit_surface_check(const fs_builder &bld, const fs_reg &image)
>>> +      emit_typed_atomic_check(const fs_builder &bld, const fs_reg &image)
>>
>> This change seems spurious (and also reasonable).
>>
> The problem is that this patch introduces a new kind of surface check
> applicable to untyped surface reads and writes only, so it would have
> been confusing to keep the other surface check which is applicable to
> atomics only with its previous rather unspecific name.
> 
>>>        {
>>>           const brw_device_info *devinfo = bld.shader->devinfo;
>>>           const fs_reg size = offset(image, bld, BRW_IMAGE_PARAM_SIZE_OFFSET);
>>> @@ -895,7 +925,9 @@ namespace brw {
>>>               * surface read on the result,
>>>               */
>>>              const brw_predicate pred =
>>> -               emit_bounds_check(bld, image, saddr, dims);
>>> +               emit_untyped_image_check(bld, image,
>>> +                                        emit_bounds_check(bld, image,
>>> +                                                          saddr, dims));
>>
>> These appear to be the only two users of emit_bounds_check... shouldn't
>> the bounds still be tested?
>>
> Yes, they are still.

Ah... I completely missed that emit_bounds_check was moved into a
parameter of the call to emit_untyped_image_check.

Reviewed-by: Ian Romanick <ian.d.romanick at intel.com>

>>>  
>>>              /* and they don't know about surface coordinates, we need to
>>>               * convert them to a raw memory offset.
>>> @@ -1041,7 +1073,9 @@ namespace brw {
>>>                  * the surface write on the result,
>>>                  */
>>>                 const brw_predicate pred =
>>> -                  emit_bounds_check(bld, image, saddr, dims);
>>> +                  emit_untyped_image_check(bld, image,
>>> +                                           emit_bounds_check(bld, image,
>>> +                                                             saddr, dims));
>>>  
>>>                 /* and, phew, they don't know about surface coordinates, we
>>>                  * need to convert them to a raw memory offset.
>>> @@ -1072,7 +1106,7 @@ namespace brw {
>>>           using namespace image_coordinates;
>>>           using namespace surface_access;
>>>           /* Avoid performing an atomic operation on an unbound surface. */
>>> -         const brw_predicate pred = emit_surface_check(bld, image);
>>> +         const brw_predicate pred = emit_typed_atomic_check(bld, image);
>>>  
>>>           /* Transform the image coordinates into actual surface coordinates. */
>>>           const fs_reg saddr =
>>
>> _______________________________________________
>> mesa-stable mailing list
>> mesa-stable at lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/mesa-stable



More information about the mesa-dev mailing list