[Mesa-dev] [PATCH 2/2] i965: check each field separately in backend_end::equals()
Francisco Jerez
currojerez at riseup.net
Fri May 13 03:38:31 UTC 2016
Samuel Iglesias Gonsálvez <siglesias at igalia.com> writes:
> Extra bits required to make room for the df field of the union don't get
> initialized in all codepaths, so backend_reg comparisons done using
> memcmp() can basically return random results. Check field by field to
> avoid this.
>
> Signed-off-by: Samuel Iglesias Gonsálvez <siglesias at igalia.com>
> Reported-by: Francisco Jerez <currojerez at riseup.net>
This seemed to avoid the problem on at least the few tests I ran
manually under valgrind, but I have doubts that it is a complete fix,
grepping for 'memcmp' in the back-end gives the following uses with a
brw_reg as argument that will likely still give non-deterministic
results even with this patch applied:
brw_fs_generator.cpp:1009: if (memcmp(&surface_reg, &sampler_reg, sizeof(surface_reg)) == 0) {
brw_vec4_generator.cpp:298: if (memcmp(&surface_reg, &sampler_reg, sizeof(surface_reg)) == 0) {
Might be a good idea to factor out the manual comparison into a static
function in brw_reg.h you could use in the FS and VEC4 generators to
avoid duplicating the complex expression? Or maybe find out why PATCH 1
is not sufficient to fix the issue? Most likely something else other
than brw_reg() is attempting to initialize brw_reg structs manually?
One more comment below.
> ---
> src/mesa/drivers/dri/i965/brw_reg.h | 1 +
> src/mesa/drivers/dri/i965/brw_shader.cpp | 21 +++++++++++++++++++--
> 2 files changed, 20 insertions(+), 2 deletions(-)
>
> diff --git a/src/mesa/drivers/dri/i965/brw_reg.h b/src/mesa/drivers/dri/i965/brw_reg.h
> index 3b76d7d..68128bd 100644
> --- a/src/mesa/drivers/dri/i965/brw_reg.h
> +++ b/src/mesa/drivers/dri/i965/brw_reg.h
> @@ -233,6 +233,7 @@ uint32_t brw_swizzle_immediate(enum brw_reg_type type, uint32_t x, unsigned swz)
> * WM programs to implement shaders decomposed into "channel serial"
> * or "structure of array" form:
> */
> +/* IMPORTANT: update backend_reg::equals() if you add a new field here. */
> struct brw_reg {
> enum brw_reg_type type:4;
> enum brw_reg_file file:3; /* :2 hardware format */
> diff --git a/src/mesa/drivers/dri/i965/brw_shader.cpp b/src/mesa/drivers/dri/i965/brw_shader.cpp
> index a23f14e..7871f51 100644
> --- a/src/mesa/drivers/dri/i965/brw_shader.cpp
> +++ b/src/mesa/drivers/dri/i965/brw_shader.cpp
> @@ -687,8 +687,25 @@ backend_shader::backend_shader(const struct brw_compiler *compiler,
> bool
> backend_reg::equals(const backend_reg &r) const
> {
> - return memcmp((brw_reg *)this, (brw_reg *)&r, sizeof(brw_reg)) == 0 &&
> - reg_offset == r.reg_offset;
> + bool equal = true;
No need for this variable, you can just return false early.
> +
> + if (this->reg_offset != r.reg_offset ||
> + this->type != r.type ||
> + this->file != r.file ||
> + this->negate != r.negate ||
> + this->abs != r.abs ||
> + this->address_mode != r.address_mode ||
> + this->pad0 != r.pad0 ||
> + this->subnr != r.subnr ||
> + this->nr != r.nr ||
> + this->ud != r.ud)
> + equal = false;
> +
> + /* Check higher 32 bits of the brw_reg's union if they are filled */
> + if (equal && this->type == BRW_REGISTER_TYPE_DF && this->df != r.df)
> + equal = false;
> +
> + return equal;
> }
>
> bool
> --
> 2.5.0
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 212 bytes
Desc: not available
URL: <https://lists.freedesktop.org/archives/mesa-dev/attachments/20160512/457390fb/attachment.sig>
More information about the mesa-dev
mailing list