[Mesa-dev] [PATCH v3] r600g: Implement GL_ARB_draw_indirect for EG/CM
Glenn Kennard
glenn.kennard at gmail.com
Fri Feb 6 16:42:40 PST 2015
On Fri, 06 Feb 2015 17:08:46 +0100, Marek Olšák <maraeo at gmail.com> wrote:
> Please bump the size of vgt_state for the SQ_VTX_BASE_VTX_LOC
> register. It's set by r600_init_atom in r600_state.c and
> evergreen_state.c
>
> Please bump R600_MAX_DRAW_CS_DWORDS. It's an upper bound of how many
> dwords draw_vbo can emit.
>
Thanks, will fix.
> I don't understand what get_vfetch_type is good for. Could you please
> explain it in the code? Also, I don't understand what constant buffer
> fetches have to do with VertexID.
>
Will add some more blurb to get_vfetch_type, in particular i can point at
the appropriate parts of gpu documentation.
As for the interaction of buffer fetches and VertexID, i'll attempt to
explain:
The way R_03CFF0_SQ_VTX_BASE_VTX_LOC is delivered to the vertex shader is
basically, it isn't. Instead what the
hardware does is poke the 64 unique values (one per wavefront thread, "64
state" in the documentation) into the fetch units into a hidden state
hardware register which the shader cannot read, at least not in any way
that i've been able to find.
Setting FETCH_MODE=SQ_VTX_FETCH_VERTEX_DATA (=0) on a VFETCH instruction
then tells the fetch unit to add the BASE_VTX and start instance offsets
before reading the value - see
r600_asm.c:r600_create_vertex_fetch_shader() which open codes 0 as the
fetch mode for vertex fetches.
This creates a problem for GLSL gl_VertexId, since the shader cannot apply
the offset. Lets look at the shader for the
tests/spec/arb_draw_indirect/vertexid.c piglit test case:
"#version 140\n"
"\n"
"in vec4 piglit_vertex;\n"
"out vec3 c;\n"
"\n"
"const vec3 colors[] = vec3[](\n"
" vec3(1, 0, 0),\n"
" vec3(1, 0, 0),\n"
" vec3(1, 0, 0),\n"
" vec3(1, 0, 0),\n"
"\n"
...
" vec3(1, 0, 1),\n"
" vec3(1, 0, 1),\n"
" vec3(1, 0, 1),\n"
" vec3(1, 0, 1)\n"
");\n"
"void main() {\n"
" c = colors[gl_VertexID];\n"
" gl_Position = piglit_vertex;\n"
"}\n"
Colors here is a constant array, and base offset needs to be applied to
look up the correct color value - the GL 4.5 spec is quite clear that it
should be applied to gl_VertexID. Since the hardware offers no way to add
base instance to gl_VertexID, i do the next best thing and enable offset
on the array fetch operation instead.
The detection logic is quite hacky, since really it needs to look if the
array expression depends in any way on gl_VertexId which requires looking
at def use chains, which aren't available in r600_asm.c - can probably
have SB compute the bit instead, but that sort of violates its "don't
change program meaning" principle, not to mention different behavior with
SB disabled.
All the actual shaders that i've found using gl_VertexId in conjunction
with indirect draws only use one constant array. I figure partial support
at least approximately matches what the binary driver supports, which
doesn't produce the correct value for gl_VertexId either for indirect
draws in various cases - in particular if the shader tries to compare
gl_VertexID against some other expression you get an incorrect value.
The driver does something totally different for direct draws, it adds the
base offset and start offset manually and feeds that to the hardware, with
BASE_VTX always set to 0, which allows it to work for all cases. Not an
option for indirect draws if you want any sort of performance out of them.
So to sum up, gl_VertexID i don't see the hardware being fully capable of
following the spec in conjunction with indirect drawing for all cases, at
least not without some very slow fallbacks reading back the draw
parameters to the cpu which is useless. One option would be to just drop
the attempt at supporting gl_VertexID from this patch if it's deemed too
hacky.
More information about the mesa-dev
mailing list