r300: register allocation sometimes generate invalid swizzles
- Issue:
Consider these failing tests on r300 and r400, when noopt
is enabled they are passing:
dEQP-GLES2.functional.shaders.indexing.vector_subscript.vec2_dynamic_subscript_write_dynamic_subscript_read_fragment,UnexpectedPass
dEQP-GLES2.functional.shaders.indexing.vector_subscript.vec3_dynamic_subscript_write_component_read_fragment,UnexpectedPass
dEQP-GLES2.functional.shaders.indexing.vector_subscript.vec3_dynamic_subscript_write_direct_read_fragment,UnexpectedPass
dEQP-GLES2.functional.shaders.indexing.vector_subscript.vec3_dynamic_subscript_write_dynamic_subscript_read_fragment,UnexpectedPass
dEQP-GLES2.functional.shaders.indexing.vector_subscript.vec3_dynamic_subscript_write_static_loop_subscript_read_fragment,UnexpectedPass
dEQP-GLES2.functional.shaders.indexing.vector_subscript.vec3_dynamic_subscript_write_static_subscript_read_fragment,UnexpectedPass
dEQP-GLES2.functional.shaders.indexing.vector_subscript.vec4_dynamic_subscript_write_dynamic_subscript_read_fragment,Fail
dEQP-GLES2.functional.shaders.indexing.vector_subscript.vec4_dynamic_subscript_write_dynamic_subscript_read_vertex,Fail
dEQP-GLES2.functional.shaders.operator.angle_and_trigonometry.asin.highp_vec2_fragment,UnexpectedPass
dEQP-GLES2.functional.shaders.operator.angle_and_trigonometry.asin.mediump_vec2_fragment,UnexpectedPass
dEQP-GLES2.functional.shaders.operator.angle_and_trigonometry.atan.highp_vec2_fragment,UnexpectedPass
dEQP-GLES2.functional.shaders.operator.angle_and_trigonometry.atan.mediump_vec2_fragment,UnexpectedPass
dEQP-GLES2.functional.shaders.random.all_features.fragment.91,UnexpectedPass
(It's last batch of tests which can be fixed with flag "noopt".)
- Problem:
Each of them is failing due to generating not native swizzle.
Fragment Program: after 'register allocation'
# Radeon Compiler Program
...
Not a native swizzle: 00000fca
- Source of problem:
I tracked that swizzle is generated in register allocation
step, but there are several problems blocking me from understanding what's going on.
First of all there's workaround for pre r500 hardware, but it's not enabled because at this step pair instructions are used:
if (!s->C->is_r500 && var->Inst->Type == RC_INSTRUCTION_NORMAL) {
writemask = rc_variable_writemask_sum(var);
}
If I make this for pair instructions or move this pass earlier (to be using normal instructions) some tests are fixed, but random others are broken.
So overall I think we should make deeper changes:
-
make new swizzle predictable (or at least understand what's going on)
-
before code is overwritten assure that all swizzles are ok (so it won't explode later)
-
tie inputs closer more to registers (when I was permutating passes I did see that sometimes
inputs
aren't updated and instruction are reading from wrong channel. Currently it's done in two loops.)
@ondracka I do wonder if you have seen something similar?