Skip to content

r300: add partial CMP support on R5xx

Pavel Ondračka requested to merge ondracka/mesa:r500_CMP into main

r300: add partial CMP support on R5xx

VE_COND_MUX_GTE4 is a nice match for the TGSI CMP opcode, however there is a big limitation due to the general shortcoming of the vertex shader engine that any instruction can read only two different temporary registers. So we still have to lower in some cases.

Shader-db RV530:
total instructions in shared programs: 130872 -> 130333 (-0.41%)
instructions in affected programs: 29854 -> 29315 (-1.81%)
helped: 294
HURT: 83
total temps in shared programs: 16747 -> 16775 (0.17%)
temps in affected programs: 407 -> 435 (6.88%)
helped: 10
HURT: 38

This is a draft at the moment as I'm hitting what looks like a nir_lower_int_to_float bug from the enabling of .has_fused_comp_and_csel in the spec/glsl-1.10/execution/vs-loop-array-index-unroll.shader_test piglit test.

So the old working state looks like this:

impl main {
	block block_0:
	/* preds: */
	vec1 32 ssa_0 = load_const (0x00000000 = 0.000000)
	vec4 32 ssa_1 = intrinsic load_input (ssa_0) (base=0, component=0, dest_type=float32, io location=VERT_ATTRIB_POS slots=1)	/* gl_Vertex */
	vec3 32 ssa_2 = load_const (0x00000000, 0x3e800000, 0x3f800000) = (0.000000, 0.250000, 1.000000)
	vec3 32 ssa_3 = load_const (0x00000000, 0x3f000000, 0x3f800000) = (0.000000, 0.500000, 1.000000)
	vec3 32 ssa_4 = load_const (0x00000000, 0x3f400000, 0x3f800000) = (0.000000, 0.750000, 1.000000)
	vec2 32 ssa_5 = load_const (0x00000000, 0x3f800000) = (0.000000, 1.000000)
	vec1 32 ssa_6 = load_const (0x3f800000 = 1.000000)
	vec1 32 ssa_7 = intrinsic load_ubo_vec4 (ssa_0, ssa_0) (access=0, base=0, component=0)
	vec4 32 ssa_8 = load_const (0x00000000, 0x00000001, 0x00000002, 0x00000003) = (0.000000, 0.000000, 0.000000, 0.000000)
	vec4  1 ssa_9 = ilt ssa_8, ssa_7.xxxx
	vec3 32 ssa_10 = bcsel ssa_9.www, ssa_5.xyy, ssa_4
	vec3 32 ssa_11 = bcsel ssa_9.zzz, ssa_10, ssa_3
	vec3 32 ssa_12 = bcsel ssa_9.yyy, ssa_11, ssa_2
	vec3 32 ssa_13 = bcsel ssa_9.xxx, ssa_12, ssa_6.xxx
	vec4 32 ssa_14 = fsat ssa_13.xyxz
	intrinsic store_output (ssa_14, ssa_0) (base=1, wrmask=xyzw, component=0, src_type=float32, io location=VARYING_SLOT_COL0 slots=1, xfb(), xfb2())	/* gl_FrontColor */
	intrinsic store_output (ssa_1, ssa_0) (base=0, wrmask=xyzw, component=0, src_type=float32, io location=VARYING_SLOT_POS slots=1, xfb(), xfb2())	/* gl_Position */
	/* succs: block_1 */
	block block_1:
}

nir_lower_int_to_float
shader: MESA_SHADER_VERTEX
source_sha1: {0xd7f02853, 0xf06e3416, 0xa43dce42, 0x9d6e2d93, 0xefc17eb0}
name: GLSL3
stage: 0
next_stage: 4
num_ubos: 1
inputs_read: 0
outputs_written: 0-1
subgroup_size: 1
bit_sizes_float: 0x20
bit_sizes_int: 0x21
first_ubo_is_default_ubo: true
flrp_lowered: true
inputs: 1
outputs: 2
uniforms: 1
decl_var shader_in INTERP_MODE_NONE vec4 gl_Vertex (VERT_ATTRIB_POS.xyzw, 0, 0)
decl_var ubo INTERP_MODE_NONE vec4[1] uniform_0 (0, 0, 0)
decl_var shader_out INTERP_MODE_NONE vec4 gl_Position (VARYING_SLOT_POS.xyzw, 0, 0)
decl_var shader_out INTERP_MODE_NONE vec4 gl_FrontColor (VARYING_SLOT_COL0.xyzw, 1, 0)
decl_function main (0 params)

impl main {
	block block_0:
	/* preds: */
	vec1 32 ssa_0 = load_const (0x00000000 = 0.000000)
	vec4 32 ssa_1 = intrinsic load_input (ssa_0) (base=0, component=0, dest_type=float32, io location=VERT_ATTRIB_POS slots=1)	/* gl_Vertex */
	vec3 32 ssa_2 = load_const (0x00000000, 0x3e800000, 0x3f800000) = (0.000000, 0.250000, 1.000000)
	vec3 32 ssa_3 = load_const (0x00000000, 0x3f000000, 0x3f800000) = (0.000000, 0.500000, 1.000000)
	vec3 32 ssa_4 = load_const (0x00000000, 0x3f400000, 0x3f800000) = (0.000000, 0.750000, 1.000000)
	vec2 32 ssa_5 = load_const (0x00000000, 0x3f800000) = (0.000000, 1.000000)
	vec1 32 ssa_6 = load_const (0x3f800000 = 1.000000)
	vec1 32 ssa_7 = intrinsic load_ubo_vec4 (ssa_0, ssa_0) (access=0, base=0, component=0)
	vec4 32 ssa_8 = load_const (0x00000000, 0x3f800000, 0x40000000, 0x40400000) = (0.000000, 1.000000, 2.000000, 3.000000)
	vec4  1 ssa_9 = flt ssa_8, ssa_7.xxxx
	vec3 32 ssa_10 = bcsel ssa_9.www, ssa_5.xyy, ssa_4
	vec3 32 ssa_11 = bcsel ssa_9.zzz, ssa_10, ssa_3
	vec3 32 ssa_12 = bcsel ssa_9.yyy, ssa_11, ssa_2
	vec3 32 ssa_13 = bcsel ssa_9.xxx, ssa_12, ssa_6.xxx
	vec4 32 ssa_14 = fsat ssa_13.xyxz
	intrinsic store_output (ssa_14, ssa_0) (base=1, wrmask=xyzw, component=0, src_type=float32, io location=VARYING_SLOT_COL0 slots=1, xfb(), xfb2())	/* gl_FrontColor */
	intrinsic store_output (ssa_1, ssa_0) (base=0, wrmask=xyzw, component=0, src_type=float32, io location=VARYING_SLOT_POS slots=1, xfb(), xfb2())	/* gl_Position */
	/* succs: block_1 */
	block block_1:
}

however when .has_fused_comp_and_csel is set, the last bcsel will get optimized to i32csel_gt and than some float constant are assumed to be integers and will get double converted to float again.

impl main {
	block block_0:
	/* preds: */
	vec1 32 ssa_0 = load_const (0x00000000 = 0.000000)
	vec4 32 ssa_1 = intrinsic load_input (ssa_0) (base=0, component=0, dest_type=float32, io location=VERT_ATTRIB_POS slots=1)	/* gl_Vertex */
	vec3 32 ssa_2 = load_const (0x00000000, 0x3e800000, 0x3f800000) = (0.000000, 0.250000, 1.000000)
	vec3 32 ssa_3 = load_const (0x00000000, 0x3f000000, 0x3f800000) = (0.000000, 0.500000, 1.000000)
	vec3 32 ssa_4 = load_const (0x00000000, 0x3f400000, 0x3f800000) = (0.000000, 0.750000, 1.000000)
	vec2 32 ssa_5 = load_const (0x00000000, 0x3f800000) = (0.000000, 1.000000)
	vec1 32 ssa_6 = load_const (0x3f800000 = 1.000000)
	vec1 32 ssa_7 = intrinsic load_ubo_vec4 (ssa_0, ssa_0) (access=0, base=0, component=0)
	vec4 32 ssa_8 = load_const (0x00000000, 0x00000001, 0x00000002, 0x00000003) = (0.000000, 0.000000, 0.000000, 0.000000)
	vec4  1 ssa_9 = ilt ssa_8, ssa_7.xxxx
	vec3 32 ssa_10 = bcsel ssa_9.www, ssa_5.xyy, ssa_4
	vec3 32 ssa_11 = bcsel ssa_9.zzz, ssa_10, ssa_3
	vec3 32 ssa_12 = bcsel ssa_9.yyy, ssa_11, ssa_2
	vec3 32 ssa_15 = i32csel_gt ssa_7.xxx, ssa_12, ssa_6.xxx
	vec4 32 ssa_14 = fsat ssa_15.xyxz
	intrinsic store_output (ssa_14, ssa_0) (base=1, wrmask=xyzw, component=0, src_type=float32, io location=VARYING_SLOT_COL0 slots=1, xfb(), xfb2())	/* gl_FrontColor */
	intrinsic store_output (ssa_1, ssa_0) (base=0, wrmask=xyzw, component=0, src_type=float32, io location=VARYING_SLOT_POS slots=1, xfb(), xfb2())	/* gl_Position */
	/* succs: block_1 */
	block block_1:
}

nir_lower_int_to_float
shader: MESA_SHADER_VERTEX
source_sha1: {0xd7f02853, 0xf06e3416, 0xa43dce42, 0x9d6e2d93, 0xefc17eb0}
name: GLSL3
stage: 0
next_stage: 4
num_ubos: 1
inputs_read: 0
outputs_written: 0-1
subgroup_size: 1
bit_sizes_float: 0x20
bit_sizes_int: 0x21
first_ubo_is_default_ubo: true
flrp_lowered: true
inputs: 1
outputs: 2
uniforms: 1
decl_var shader_in INTERP_MODE_NONE vec4 gl_Vertex (VERT_ATTRIB_POS.xyzw, 0, 0)
decl_var ubo INTERP_MODE_NONE vec4[1] uniform_0 (0, 0, 0)
decl_var shader_out INTERP_MODE_NONE vec4 gl_Position (VARYING_SLOT_POS.xyzw, 0, 0)
decl_var shader_out INTERP_MODE_NONE vec4 gl_FrontColor (VARYING_SLOT_COL0.xyzw, 1, 0)
decl_function main (0 params)

impl main {
	block block_0:
	/* preds: */
	vec1 32 ssa_0 = load_const (0x00000000 = 0.000000)
	vec4 32 ssa_1 = intrinsic load_input (ssa_0) (base=0, component=0, dest_type=float32, io location=VERT_ATTRIB_POS slots=1)	/* gl_Vertex */
	vec3 32 ssa_2 = load_const (0x00000000, 0x4e7a0000, 0x4e7e0000) = (0.000000, 1048576000.000000, 1065353216.000000)
	vec3 32 ssa_3 = load_const (0x00000000, 0x4e7c0000, 0x4e7e0000) = (0.000000, 1056964608.000000, 1065353216.000000)
	vec3 32 ssa_4 = load_const (0x00000000, 0x4e7d0000, 0x4e7e0000) = (0.000000, 1061158912.000000, 1065353216.000000)
	vec2 32 ssa_5 = load_const (0x00000000, 0x4e7e0000) = (0.000000, 1065353216.000000)
	vec1 32 ssa_6 = load_const (0x4e7e0000 = 1065353216.000000)
	vec1 32 ssa_7 = intrinsic load_ubo_vec4 (ssa_0, ssa_0) (access=0, base=0, component=0)
	vec4 32 ssa_8 = load_const (0x00000000, 0x3f800000, 0x40000000, 0x40400000) = (0.000000, 1.000000, 2.000000, 3.000000)
	vec4  1 ssa_9 = flt ssa_8, ssa_7.xxxx
	vec3 32 ssa_10 = bcsel ssa_9.www, ssa_5.xyy, ssa_4
	vec3 32 ssa_11 = bcsel ssa_9.zzz, ssa_10, ssa_3
	vec3 32 ssa_12 = bcsel ssa_9.yyy, ssa_11, ssa_2
	vec3 32 ssa_13 = fcsel_gt ssa_7.xxx, ssa_12, ssa_6.xxx
	vec4 32 ssa_14 = fsat ssa_13.xyxz
	intrinsic store_output (ssa_14, ssa_0) (base=1, wrmask=xyzw, component=0, src_type=float32, io location=VARYING_SLOT_COL0 slots=1, xfb(), xfb2())	/* gl_FrontColor */
	intrinsic store_output (ssa_1, ssa_0) (base=0, wrmask=xyzw, component=0, src_type=float32, io location=VARYING_SLOT_POS slots=1, xfb(), xfb2())	/* gl_Position */
	/* succs: block_1 */
	block block_1:
}

No idea how to fix this yet.

Merge request reports