aboutsummaryrefslogtreecommitdiffstats
path: root/src/mesa/drivers
diff options
context:
space:
mode:
authorFrancisco Jerez <[email protected]>2015-08-26 21:59:46 +0300
committerFrancisco Jerez <[email protected]>2015-09-28 18:10:39 +0300
commitb61292296bd7e1876fdb64725a783a7e96f6c4c1 (patch)
tree3fd2fc0123e40a178226ef81d0c6f2f8cf90aef8 /src/mesa/drivers
parent2518645f63e2f66d3638180f44a007541928319c (diff)
i965/fs: Fix hang on IVB and VLV with image format mismatch.
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 <[email protected]> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=91718 CC: [email protected] Reviewed-by: Ian Romanick <[email protected]>
Diffstat (limited to 'src/mesa/drivers')
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs_surface_builder.cpp42
1 files 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 88f22fa9c7f..534d8490cdf 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)
{
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));
/* 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 =