Re: [Mesa-dev] [PATCH 5/5] radeonsi: allow out-of-order rasterization in commutative blending cases

2017-09-26 Thread Nicolai Hähnle

On 21.09.2017 23:44, Matias N. Goldberg wrote:

I'm reviewing the patch and there's something that confuses me about 
radeonsi_assume_no_z_fights (which got implemented in a later patch). It 
appears to be that part of the logic is flawed.

Please correct me whenever you feel I misunderstood what is going on.

Assuming colour writes are enabled, si_out_of_order_rasterization will return 
true only if the following conditions are met (simplified):
* There is a zsbuf set (If I interpret it correctly, this means if there is a 
zs buffer attached)
* dsa_order_invariant.pass_set is true
* dsa_order_invariant.pass_last is true


That's not what the code does, look again:

* if blending is enabled and commutative, pass_set must be true
* if blending is enabled and non-commutative, we simply cannot enable ooo
o if blending is disabled, pass_last must be true

What may be confusing when you read the code is that, with multiple 
render targets, it's theoretically possible for render targets to have 
different blend states.




_or_

* There is no zsbuf set
* dsa_order_invariant.pass_last is true


However, the logic is apparently contradictory, because:
* pass_set  will only be true when depth writes are disabled or depth func is 
set to always or depth func is set to never.
* pass_last will only be true when depth writes are enabled or depth func is 
not set to always nor not_equal.


!!This is impossible to satisfy unless depth function is set to never!!
Not only this is extremely rare, it appears this is not the intention behind the option 
"radeonsi_assume_no_z_fights" which I believe is an optimization for gamers to 
get a performance boost in most games where forcing this option doesn't matter (either 
because the artifacts are extremely rare or not present).

Additionally, there seems to be a bug because si_out_of_order_rasterization can 
return true if there is no zs buffer and user enabled 
radeonsi_assume_no_z_fights, which AFAIK is blatantly wrong (correct me if I'm 
wrong, but if there is no zs buffer, out of order rasterization can cause 
really wrong results).


When there is no Z buffer, radeonsi_assume_no_z_fights has no effect. 
radeonsi_assume_no_z_fights only affects anything via the 
si_dsa_order_invariance settings, and without a Z buffer we simply use 
the default (which is set in si_state.c:3232, the initializer of the 
dsa_order_invariance variable).


Cheers,
Nicolai




Maybe I misunderstood what's going on, or I missed something key. But if I'm 
right then the logic needs to be revised.


It would appear to me that idea of radeonsi_assume_no_z_fights is that it 
should always enable OoO rasterization as long as depth writes are on and a 
valid zs is present (and other conditions are met such as shaders not 
requesting early depth stencil, blending operations, etc). But written as is 
right now, it will almost never be enabled even if the options is forced on.

Cheers
Matias

De: Marek Olšák <mar...@gmail.com>
Para: Nicolai Hähnle <nhaeh...@gmail.com>
CC: "mesa-dev@lists.freedesktop.org" <mesa-dev@lists.freedesktop.org>; Nicolai 
Hähnle <nicolai.haeh...@amd.com>
Enviado: Miércoles, 13 de septiembre, 2017 21:19:26
Asunto: Re: [Mesa-dev] [PATCH 5/5] radeonsi: allow out-of-order rasterization 
in commutative blending cases



For the series:

Reviewed-by: Marek Olšák <marek.ol...@amd.com>

Marek

On Sat, Sep 9, 2017 at 12:43 PM, Nicolai Hähnle <nhaeh...@gmail.com> wrote:

From: Nicolai Hähnle <nicolai.haeh...@amd.com>

We do not enable this by default for additive blending, since it slightly
breaks OpenGL invariance guarantees due to non-determinism.

Still, there may be some applications can benefit from white-listing
via the radeonsi_commutative_blend_add drirc setting without any real
visible artifacts.
---
  src/gallium/drivers/radeonsi/driinfo_radeonsi.h |  1 +
  src/gallium/drivers/radeonsi/si_pipe.c  |  2 +
  src/gallium/drivers/radeonsi/si_pipe.h  |  1 +
  src/gallium/drivers/radeonsi/si_state.c | 67 +++--
  src/gallium/drivers/radeonsi/si_state.h |  1 +
  src/util/xmlpool/t_options.h|  5 ++
  6 files changed, 73 insertions(+), 4 deletions(-)

diff --git a/src/gallium/drivers/radeonsi/driinfo_radeonsi.h 
b/src/gallium/drivers/radeonsi/driinfo_radeonsi.h
index 8be85289a0c..989e5175cc0 100644
--- a/src/gallium/drivers/radeonsi/driinfo_radeonsi.h
+++ b/src/gallium/drivers/radeonsi/driinfo_radeonsi.h
@@ -1,5 +1,6 @@
  // DriConf options specific to radeonsi
  DRI_CONF_SECTION_PERFORMANCE
  DRI_CONF_RADEONSI_ENABLE_SISCHED("false")
  DRI_CONF_RADEONSI_ASSUME_NO_Z_FIGHTS("false")
+DRI_CONF_RADEONSI_COMMUTATIVE_BLEND_ADD("false")
  DRI_CONF_SECTION_END
diff --git a/src/gallium/drivers/radeonsi/si_pipe.c 
b/src/gallium/drivers/radeonsi/si_pipe.c
index b4972be739c..c44ea3be740 1006

Re: [Mesa-dev] [PATCH 5/5] radeonsi: allow out-of-order rasterization in commutative blending cases

2017-09-21 Thread Matias N. Goldberg
I'm reviewing the patch and there's something that confuses me about 
radeonsi_assume_no_z_fights (which got implemented in a later patch). It 
appears to be that part of the logic is flawed.

Please correct me whenever you feel I misunderstood what is going on.

Assuming colour writes are enabled, si_out_of_order_rasterization will return 
true only if the following conditions are met (simplified):
* There is a zsbuf set (If I interpret it correctly, this means if there is a 
zs buffer attached)
* dsa_order_invariant.pass_set is true
* dsa_order_invariant.pass_last is true


_or_

* There is no zsbuf set
* dsa_order_invariant.pass_last is true


However, the logic is apparently contradictory, because:
* pass_set  will only be true when depth writes are disabled or depth func is 
set to always or depth func is set to never.
* pass_last will only be true when depth writes are enabled or depth func is 
not set to always nor not_equal.


!!This is impossible to satisfy unless depth function is set to never!!
Not only this is extremely rare, it appears this is not the intention behind 
the option "radeonsi_assume_no_z_fights" which I believe is an optimization for 
gamers to get a performance boost in most games where forcing this option 
doesn't matter (either because the artifacts are extremely rare or not present).

Additionally, there seems to be a bug because si_out_of_order_rasterization can 
return true if there is no zs buffer and user enabled 
radeonsi_assume_no_z_fights, which AFAIK is blatantly wrong (correct me if I'm 
wrong, but if there is no zs buffer, out of order rasterization can cause 
really wrong results).

Maybe I misunderstood what's going on, or I missed something key. But if I'm 
right then the logic needs to be revised.


It would appear to me that idea of radeonsi_assume_no_z_fights is that it 
should always enable OoO rasterization as long as depth writes are on and a 
valid zs is present (and other conditions are met such as shaders not 
requesting early depth stencil, blending operations, etc). But written as is 
right now, it will almost never be enabled even if the options is forced on.

Cheers
Matias

De: Marek Olšák <mar...@gmail.com>
Para: Nicolai Hähnle <nhaeh...@gmail.com> 
CC: "mesa-dev@lists.freedesktop.org" <mesa-dev@lists.freedesktop.org>; Nicolai 
Hähnle <nicolai.haeh...@amd.com>
Enviado: Miércoles, 13 de septiembre, 2017 21:19:26
Asunto: Re: [Mesa-dev] [PATCH 5/5] radeonsi: allow out-of-order rasterization 
in commutative blending cases



For the series:

Reviewed-by: Marek Olšák <marek.ol...@amd.com>

Marek

On Sat, Sep 9, 2017 at 12:43 PM, Nicolai Hähnle <nhaeh...@gmail.com> wrote:
> From: Nicolai Hähnle <nicolai.haeh...@amd.com>
>
> We do not enable this by default for additive blending, since it slightly
> breaks OpenGL invariance guarantees due to non-determinism.
>
> Still, there may be some applications can benefit from white-listing
> via the radeonsi_commutative_blend_add drirc setting without any real
> visible artifacts.
> ---
>  src/gallium/drivers/radeonsi/driinfo_radeonsi.h |  1 +
>  src/gallium/drivers/radeonsi/si_pipe.c  |  2 +
>  src/gallium/drivers/radeonsi/si_pipe.h  |  1 +
>  src/gallium/drivers/radeonsi/si_state.c | 67 
> +++--
>  src/gallium/drivers/radeonsi/si_state.h |  1 +
>  src/util/xmlpool/t_options.h|  5 ++
>  6 files changed, 73 insertions(+), 4 deletions(-)
>
> diff --git a/src/gallium/drivers/radeonsi/driinfo_radeonsi.h 
> b/src/gallium/drivers/radeonsi/driinfo_radeonsi.h
> index 8be85289a0c..989e5175cc0 100644
> --- a/src/gallium/drivers/radeonsi/driinfo_radeonsi.h
> +++ b/src/gallium/drivers/radeonsi/driinfo_radeonsi.h
> @@ -1,5 +1,6 @@
>  // DriConf options specific to radeonsi
>  DRI_CONF_SECTION_PERFORMANCE
>  DRI_CONF_RADEONSI_ENABLE_SISCHED("false")
>  DRI_CONF_RADEONSI_ASSUME_NO_Z_FIGHTS("false")
> +DRI_CONF_RADEONSI_COMMUTATIVE_BLEND_ADD("false")
>  DRI_CONF_SECTION_END
> diff --git a/src/gallium/drivers/radeonsi/si_pipe.c 
> b/src/gallium/drivers/radeonsi/si_pipe.c
> index b4972be739c..c44ea3be740 100644
> --- a/src/gallium/drivers/radeonsi/si_pipe.c
> +++ b/src/gallium/drivers/radeonsi/si_pipe.c
> @@ -1043,20 +1043,22 @@ struct pipe_screen *radeonsi_screen_create(struct 
> radeon_winsys *ws,
> (sscreen->b.chip_class == SI &&
>  sscreen->b.info.pfp_fw_version >= 79 &&
>  sscreen->b.info.me_fw_version >= 142);
>
> sscreen->has_ds_bpermute = sscreen->b.chip_class >= VI;
> sscreen->has_out_of_order_rast = sscreen->b.chip_class >= VI &&
>  

Re: [Mesa-dev] [PATCH 5/5] radeonsi: allow out-of-order rasterization in commutative blending cases

2017-09-13 Thread Dieter Nützel

For the series:

Tested-by: Dieter Nützel 

Greetings,
Dieter

Am 09.09.2017 12:43, schrieb Nicolai Hähnle:

From: Nicolai Hähnle 

We do not enable this by default for additive blending, since it 
slightly

breaks OpenGL invariance guarantees due to non-determinism.

Still, there may be some applications can benefit from white-listing
via the radeonsi_commutative_blend_add drirc setting without any real
visible artifacts.
---
 src/gallium/drivers/radeonsi/driinfo_radeonsi.h |  1 +
 src/gallium/drivers/radeonsi/si_pipe.c  |  2 +
 src/gallium/drivers/radeonsi/si_pipe.h  |  1 +
 src/gallium/drivers/radeonsi/si_state.c | 67 
+++--

 src/gallium/drivers/radeonsi/si_state.h |  1 +
 src/util/xmlpool/t_options.h|  5 ++
 6 files changed, 73 insertions(+), 4 deletions(-)

diff --git a/src/gallium/drivers/radeonsi/driinfo_radeonsi.h
b/src/gallium/drivers/radeonsi/driinfo_radeonsi.h
index 8be85289a0c..989e5175cc0 100644
--- a/src/gallium/drivers/radeonsi/driinfo_radeonsi.h
+++ b/src/gallium/drivers/radeonsi/driinfo_radeonsi.h
@@ -1,5 +1,6 @@
 // DriConf options specific to radeonsi
 DRI_CONF_SECTION_PERFORMANCE
 DRI_CONF_RADEONSI_ENABLE_SISCHED("false")
 DRI_CONF_RADEONSI_ASSUME_NO_Z_FIGHTS("false")
+DRI_CONF_RADEONSI_COMMUTATIVE_BLEND_ADD("false")
 DRI_CONF_SECTION_END
diff --git a/src/gallium/drivers/radeonsi/si_pipe.c
b/src/gallium/drivers/radeonsi/si_pipe.c
index b4972be739c..c44ea3be740 100644
--- a/src/gallium/drivers/radeonsi/si_pipe.c
+++ b/src/gallium/drivers/radeonsi/si_pipe.c
@@ -1043,20 +1043,22 @@ struct pipe_screen
*radeonsi_screen_create(struct radeon_winsys *ws,
(sscreen->b.chip_class == SI &&
 sscreen->b.info.pfp_fw_version >= 79 &&
 sscreen->b.info.me_fw_version >= 142);

sscreen->has_ds_bpermute = sscreen->b.chip_class >= VI;
sscreen->has_out_of_order_rast = sscreen->b.chip_class >= VI &&
 sscreen->b.info.max_se >= 2 &&
 !(sscreen->b.debug_flags & 
DBG_NO_OUT_OF_ORDER);
sscreen->assume_no_z_fights =
driQueryOptionb(config->options, "radeonsi_assume_no_z_fights");
+   sscreen->commutative_blend_add =
+   driQueryOptionb(config->options, 
"radeonsi_commutative_blend_add");
 	sscreen->has_msaa_sample_loc_bug = (sscreen->b.family >= 
CHIP_POLARIS10 &&

sscreen->b.family <= 
CHIP_POLARIS12) ||
   sscreen->b.family == CHIP_VEGA10 ||
   sscreen->b.family == CHIP_RAVEN;
sscreen->dpbb_allowed = sscreen->b.chip_class >= GFX9 &&
!(sscreen->b.debug_flags & DBG_NO_DPBB);
sscreen->dfsm_allowed = sscreen->dpbb_allowed &&
!(sscreen->b.debug_flags & DBG_NO_DFSM);

/* While it would be nice not to have this flag, we are constrained
diff --git a/src/gallium/drivers/radeonsi/si_pipe.h
b/src/gallium/drivers/radeonsi/si_pipe.h
index d200c9f571f..27e2bc81172 100644
--- a/src/gallium/drivers/radeonsi/si_pipe.h
+++ b/src/gallium/drivers/radeonsi/si_pipe.h
@@ -90,20 +90,21 @@ struct u_suballocator;
 struct si_screen {
struct r600_common_screen   b;
unsignedgs_table_depth;
unsignedtess_offchip_block_dw_size;
boolhas_clear_state;
boolhas_distributed_tess;
boolhas_draw_indirect_multi;
boolhas_ds_bpermute;
boolhas_out_of_order_rast;
boolassume_no_z_fights;
+   boolcommutative_blend_add;
boolhas_msaa_sample_loc_bug;
booldpbb_allowed;
booldfsm_allowed;
boolllvm_has_working_vgpr_indexing;

/* Whether shaders are monolithic (1-part) or separate (3-part). */
booluse_monolithic_shaders;
boolrecord_llvm_ir;

mtx_t   shader_parts_mutex;
diff --git a/src/gallium/drivers/radeonsi/si_state.c
b/src/gallium/drivers/radeonsi/si_state.c
index a8af5752771..6a063e7f7a6 100644
--- a/src/gallium/drivers/radeonsi/si_state.c
+++ b/src/gallium/drivers/radeonsi/si_state.c
@@ -370,20 +370,62 @@ static uint32_t
si_translate_blend_opt_factor(int blend_fact, bool is_alpha)
case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
return V_028760_BLEND_OPT_PRESERVE_A0_IGNORE_A1;
case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
return is_alpha ? 

Re: [Mesa-dev] [PATCH 5/5] radeonsi: allow out-of-order rasterization in commutative blending cases

2017-09-13 Thread Marek Olšák
For the series:

Reviewed-by: Marek Olšák 

Marek

On Sat, Sep 9, 2017 at 12:43 PM, Nicolai Hähnle  wrote:
> From: Nicolai Hähnle 
>
> We do not enable this by default for additive blending, since it slightly
> breaks OpenGL invariance guarantees due to non-determinism.
>
> Still, there may be some applications can benefit from white-listing
> via the radeonsi_commutative_blend_add drirc setting without any real
> visible artifacts.
> ---
>  src/gallium/drivers/radeonsi/driinfo_radeonsi.h |  1 +
>  src/gallium/drivers/radeonsi/si_pipe.c  |  2 +
>  src/gallium/drivers/radeonsi/si_pipe.h  |  1 +
>  src/gallium/drivers/radeonsi/si_state.c | 67 
> +++--
>  src/gallium/drivers/radeonsi/si_state.h |  1 +
>  src/util/xmlpool/t_options.h|  5 ++
>  6 files changed, 73 insertions(+), 4 deletions(-)
>
> diff --git a/src/gallium/drivers/radeonsi/driinfo_radeonsi.h 
> b/src/gallium/drivers/radeonsi/driinfo_radeonsi.h
> index 8be85289a0c..989e5175cc0 100644
> --- a/src/gallium/drivers/radeonsi/driinfo_radeonsi.h
> +++ b/src/gallium/drivers/radeonsi/driinfo_radeonsi.h
> @@ -1,5 +1,6 @@
>  // DriConf options specific to radeonsi
>  DRI_CONF_SECTION_PERFORMANCE
>  DRI_CONF_RADEONSI_ENABLE_SISCHED("false")
>  DRI_CONF_RADEONSI_ASSUME_NO_Z_FIGHTS("false")
> +DRI_CONF_RADEONSI_COMMUTATIVE_BLEND_ADD("false")
>  DRI_CONF_SECTION_END
> diff --git a/src/gallium/drivers/radeonsi/si_pipe.c 
> b/src/gallium/drivers/radeonsi/si_pipe.c
> index b4972be739c..c44ea3be740 100644
> --- a/src/gallium/drivers/radeonsi/si_pipe.c
> +++ b/src/gallium/drivers/radeonsi/si_pipe.c
> @@ -1043,20 +1043,22 @@ struct pipe_screen *radeonsi_screen_create(struct 
> radeon_winsys *ws,
> (sscreen->b.chip_class == SI &&
>  sscreen->b.info.pfp_fw_version >= 79 &&
>  sscreen->b.info.me_fw_version >= 142);
>
> sscreen->has_ds_bpermute = sscreen->b.chip_class >= VI;
> sscreen->has_out_of_order_rast = sscreen->b.chip_class >= VI &&
>  sscreen->b.info.max_se >= 2 &&
>  !(sscreen->b.debug_flags & 
> DBG_NO_OUT_OF_ORDER);
> sscreen->assume_no_z_fights =
> driQueryOptionb(config->options, 
> "radeonsi_assume_no_z_fights");
> +   sscreen->commutative_blend_add =
> +   driQueryOptionb(config->options, 
> "radeonsi_commutative_blend_add");
> sscreen->has_msaa_sample_loc_bug = (sscreen->b.family >= 
> CHIP_POLARIS10 &&
> sscreen->b.family <= 
> CHIP_POLARIS12) ||
>sscreen->b.family == CHIP_VEGA10 ||
>sscreen->b.family == CHIP_RAVEN;
> sscreen->dpbb_allowed = sscreen->b.chip_class >= GFX9 &&
> !(sscreen->b.debug_flags & DBG_NO_DPBB);
> sscreen->dfsm_allowed = sscreen->dpbb_allowed &&
> !(sscreen->b.debug_flags & DBG_NO_DFSM);
>
> /* While it would be nice not to have this flag, we are constrained
> diff --git a/src/gallium/drivers/radeonsi/si_pipe.h 
> b/src/gallium/drivers/radeonsi/si_pipe.h
> index d200c9f571f..27e2bc81172 100644
> --- a/src/gallium/drivers/radeonsi/si_pipe.h
> +++ b/src/gallium/drivers/radeonsi/si_pipe.h
> @@ -90,20 +90,21 @@ struct u_suballocator;
>  struct si_screen {
> struct r600_common_screen   b;
> unsignedgs_table_depth;
> unsignedtess_offchip_block_dw_size;
> boolhas_clear_state;
> boolhas_distributed_tess;
> boolhas_draw_indirect_multi;
> boolhas_ds_bpermute;
> boolhas_out_of_order_rast;
> boolassume_no_z_fights;
> +   boolcommutative_blend_add;
> boolhas_msaa_sample_loc_bug;
> booldpbb_allowed;
> booldfsm_allowed;
> boolllvm_has_working_vgpr_indexing;
>
> /* Whether shaders are monolithic (1-part) or separate (3-part). */
> booluse_monolithic_shaders;
> boolrecord_llvm_ir;
>
> mtx_t   shader_parts_mutex;
> diff --git a/src/gallium/drivers/radeonsi/si_state.c 
> b/src/gallium/drivers/radeonsi/si_state.c
> index a8af5752771..6a063e7f7a6 100644
> --- a/src/gallium/drivers/radeonsi/si_state.c
> +++ b/src/gallium/drivers/radeonsi/si_state.c
> @@ -370,20 +370,62 @@ static uint32_t si_translate_blend_opt_factor(int 
> blend_fact, bool 

[Mesa-dev] [PATCH 5/5] radeonsi: allow out-of-order rasterization in commutative blending cases

2017-09-09 Thread Nicolai Hähnle
From: Nicolai Hähnle 

We do not enable this by default for additive blending, since it slightly
breaks OpenGL invariance guarantees due to non-determinism.

Still, there may be some applications can benefit from white-listing
via the radeonsi_commutative_blend_add drirc setting without any real
visible artifacts.
---
 src/gallium/drivers/radeonsi/driinfo_radeonsi.h |  1 +
 src/gallium/drivers/radeonsi/si_pipe.c  |  2 +
 src/gallium/drivers/radeonsi/si_pipe.h  |  1 +
 src/gallium/drivers/radeonsi/si_state.c | 67 +++--
 src/gallium/drivers/radeonsi/si_state.h |  1 +
 src/util/xmlpool/t_options.h|  5 ++
 6 files changed, 73 insertions(+), 4 deletions(-)

diff --git a/src/gallium/drivers/radeonsi/driinfo_radeonsi.h 
b/src/gallium/drivers/radeonsi/driinfo_radeonsi.h
index 8be85289a0c..989e5175cc0 100644
--- a/src/gallium/drivers/radeonsi/driinfo_radeonsi.h
+++ b/src/gallium/drivers/radeonsi/driinfo_radeonsi.h
@@ -1,5 +1,6 @@
 // DriConf options specific to radeonsi
 DRI_CONF_SECTION_PERFORMANCE
 DRI_CONF_RADEONSI_ENABLE_SISCHED("false")
 DRI_CONF_RADEONSI_ASSUME_NO_Z_FIGHTS("false")
+DRI_CONF_RADEONSI_COMMUTATIVE_BLEND_ADD("false")
 DRI_CONF_SECTION_END
diff --git a/src/gallium/drivers/radeonsi/si_pipe.c 
b/src/gallium/drivers/radeonsi/si_pipe.c
index b4972be739c..c44ea3be740 100644
--- a/src/gallium/drivers/radeonsi/si_pipe.c
+++ b/src/gallium/drivers/radeonsi/si_pipe.c
@@ -1043,20 +1043,22 @@ struct pipe_screen *radeonsi_screen_create(struct 
radeon_winsys *ws,
(sscreen->b.chip_class == SI &&
 sscreen->b.info.pfp_fw_version >= 79 &&
 sscreen->b.info.me_fw_version >= 142);
 
sscreen->has_ds_bpermute = sscreen->b.chip_class >= VI;
sscreen->has_out_of_order_rast = sscreen->b.chip_class >= VI &&
 sscreen->b.info.max_se >= 2 &&
 !(sscreen->b.debug_flags & 
DBG_NO_OUT_OF_ORDER);
sscreen->assume_no_z_fights =
driQueryOptionb(config->options, "radeonsi_assume_no_z_fights");
+   sscreen->commutative_blend_add =
+   driQueryOptionb(config->options, 
"radeonsi_commutative_blend_add");
sscreen->has_msaa_sample_loc_bug = (sscreen->b.family >= CHIP_POLARIS10 
&&
sscreen->b.family <= 
CHIP_POLARIS12) ||
   sscreen->b.family == CHIP_VEGA10 ||
   sscreen->b.family == CHIP_RAVEN;
sscreen->dpbb_allowed = sscreen->b.chip_class >= GFX9 &&
!(sscreen->b.debug_flags & DBG_NO_DPBB);
sscreen->dfsm_allowed = sscreen->dpbb_allowed &&
!(sscreen->b.debug_flags & DBG_NO_DFSM);
 
/* While it would be nice not to have this flag, we are constrained
diff --git a/src/gallium/drivers/radeonsi/si_pipe.h 
b/src/gallium/drivers/radeonsi/si_pipe.h
index d200c9f571f..27e2bc81172 100644
--- a/src/gallium/drivers/radeonsi/si_pipe.h
+++ b/src/gallium/drivers/radeonsi/si_pipe.h
@@ -90,20 +90,21 @@ struct u_suballocator;
 struct si_screen {
struct r600_common_screen   b;
unsignedgs_table_depth;
unsignedtess_offchip_block_dw_size;
boolhas_clear_state;
boolhas_distributed_tess;
boolhas_draw_indirect_multi;
boolhas_ds_bpermute;
boolhas_out_of_order_rast;
boolassume_no_z_fights;
+   boolcommutative_blend_add;
boolhas_msaa_sample_loc_bug;
booldpbb_allowed;
booldfsm_allowed;
boolllvm_has_working_vgpr_indexing;
 
/* Whether shaders are monolithic (1-part) or separate (3-part). */
booluse_monolithic_shaders;
boolrecord_llvm_ir;
 
mtx_t   shader_parts_mutex;
diff --git a/src/gallium/drivers/radeonsi/si_state.c 
b/src/gallium/drivers/radeonsi/si_state.c
index a8af5752771..6a063e7f7a6 100644
--- a/src/gallium/drivers/radeonsi/si_state.c
+++ b/src/gallium/drivers/radeonsi/si_state.c
@@ -370,20 +370,62 @@ static uint32_t si_translate_blend_opt_factor(int 
blend_fact, bool is_alpha)
case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
return V_028760_BLEND_OPT_PRESERVE_A0_IGNORE_A1;
case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
return is_alpha ? V_028760_BLEND_OPT_PRESERVE_ALL_IGNORE_NONE
: V_028760_BLEND_OPT_PRESERVE_NONE_IGNORE_A0;