r300: Vertex program position end bits are known.

Possibly performance may improve by setting it to the last instruction that
writes result.position, rather than the last instruction in the vertex program.
This commit is contained in:
Oliver McFadden 2007-06-20 12:03:42 +00:00
parent 27c8488526
commit 252fc61e48
3 changed files with 11 additions and 9 deletions

View file

@ -588,7 +588,7 @@ struct r300_vertex_shader_state {
struct r300_vertex_shader_fragment unknown2;
int program_start;
int unknown_ptr1; /* pointer within program space */
int program_pos_end;
int program_end;
int param_offset;

View file

@ -336,13 +336,15 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
* The meaning of the two UNKNOWN fields is obviously not known. However,
* experiments so far have shown that both *must* point to an instruction
* inside the vertex program, otherwise the GPU locks up.
*
* fglrx usually sets CNTL_3_UNKNOWN to the end of the program and
* CNTL_1_UNKNOWN points to instruction where last write to position takes
* place.
* R300_PVS_CNTL_1_POS_END_SHIFT points to instruction where last write to
* position takes place.
*
* Most likely this is used to ignore rest of the program in cases
* where group of verts arent visible. For some reason this "section"
* is sometimes accepted other instruction that have no relationship with
*position calculations.
* position calculations.
*/
#define R300_VAP_PVS_CNTL_1 0x22D0
# define R300_PVS_CNTL_1_PROGRAM_START_SHIFT 0

View file

@ -1531,7 +1531,7 @@ static void r300GenerateSimpleVertexShader(r300ContextPtr r300)
r300->state.vertex_shader.param_count = 0x4; /* 4 vector values - 4x4 matrix */
r300->state.vertex_shader.program_start = 0x0;
r300->state.vertex_shader.unknown_ptr1 = 0x4; /* magic value ? */
r300->state.vertex_shader.program_pos_end = 0x4;
r300->state.vertex_shader.program_end = 0x0;
r300->state.vertex_shader.unknown_ptr2 = 0x0; /* magic value */
@ -1563,7 +1563,7 @@ static void r300GenerateSimpleVertexShader(r300ContextPtr r300)
r300->state.vertex_shader.program.length =
(r300->state.vertex_shader.program_end + 1) * 4;
r300->state.vertex_shader.unknown_ptr1 = r300->state.vertex_shader.program_end; /* magic value ? */
r300->state.vertex_shader.program_pos_end = r300->state.vertex_shader.program_end;
r300->state.vertex_shader.unknown_ptr2 = r300->state.vertex_shader.program_end; /* magic value ? */
r300->state.vertex_shader.unknown_ptr3 = r300->state.vertex_shader.program_end; /* magic value ? */
@ -1607,7 +1607,7 @@ static void r300SetupVertexProgram(r300ContextPtr rmesa)
(param_count << R300_PVS_CNTL_2_PARAM_COUNT_SHIFT);
rmesa->hw.pvs.cmd[R300_PVS_CNTL_3] =
(0 << R300_PVS_CNTL_3_PROGRAM_UNKNOWN_SHIFT) |
(inst_count << 0);
(inst_count << R300_PVS_CNTL_3_PROGRAM_UNKNOWN2_SHIFT);
/* This is done for vertex shader fragments, but also needs to be done for vap_pvs,
so I leave it as a reminder */
@ -1648,14 +1648,14 @@ static void r300SetupVertexShader(r300ContextPtr rmesa)
R300_STATECHANGE(rmesa, pvs);
rmesa->hw.pvs.cmd[R300_PVS_CNTL_1] =
(rmesa->state.vertex_shader.program_start << R300_PVS_CNTL_1_PROGRAM_START_SHIFT) |
(rmesa->state.vertex_shader.unknown_ptr1 << R300_PVS_CNTL_1_POS_END_SHIFT) |
(rmesa->state.vertex_shader.program_pos_end << R300_PVS_CNTL_1_POS_END_SHIFT) |
(rmesa->state.vertex_shader.program_end << R300_PVS_CNTL_1_PROGRAM_END_SHIFT);
rmesa->hw.pvs.cmd[R300_PVS_CNTL_2] =
(rmesa->state.vertex_shader.param_offset << R300_PVS_CNTL_2_PARAM_OFFSET_SHIFT) |
(rmesa->state.vertex_shader.param_count << R300_PVS_CNTL_2_PARAM_COUNT_SHIFT);
rmesa->hw.pvs.cmd[R300_PVS_CNTL_3] =
(rmesa->state.vertex_shader.unknown_ptr2 << R300_PVS_CNTL_3_PROGRAM_UNKNOWN_SHIFT) |
(rmesa->state.vertex_shader.unknown_ptr3 << 0);
(rmesa->state.vertex_shader.unknown_ptr3 << R300_PVS_CNTL_3_PROGRAM_UNKNOWN2_SHIFT);
/* This is done for vertex shader fragments, but also needs to be done for vap_pvs,
so I leave it as a reminder */