2 * Copyright (C) 2008-2009 Advanced Micro Devices, Inc.
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 * Richard Li <RichardZ.Li@amd.com>, <richardradeon@gmail.com>
25 * CooperYuan <cooper.yuan@amd.com>, <cooperyuan@gmail.com>
34 #include "main/imports.h"
36 #include "program/prog_parameter.h"
37 #include "program/prog_statevars.h"
38 #include "program/program.h"
40 #include "r600_context.h"
41 #include "r600_cmdbuf.h"
42 #include "r600_emit.h"
44 #include "evergreen_vertprog.h"
45 #include "evergreen_fragprog.h"
47 void evergreen_insert_wpos_code(struct gl_context
*ctx
, struct gl_fragment_program
*fprog
)
49 static const gl_state_index winstate
[STATE_LENGTH
]
50 = { STATE_INTERNAL
, STATE_FB_SIZE
, 0, 0, 0};
51 struct prog_instruction
*newInst
, *inst
;
52 GLint win_size
; /* state reference */
53 GLuint wpos_temp
; /* temp register */
56 /* PARAM win_size = STATE_FB_SIZE */
57 win_size
= _mesa_add_state_reference(fprog
->Base
.Parameters
, winstate
);
59 wpos_temp
= fprog
->Base
.NumTemporaries
++;
61 /* scan program where WPOS is used and replace with wpos_temp */
62 inst
= fprog
->Base
.Instructions
;
63 for (i
= 0; i
< fprog
->Base
.NumInstructions
; i
++) {
64 for (j
=0; j
< 3; j
++) {
65 if(inst
->SrcReg
[j
].File
== PROGRAM_INPUT
&&
66 inst
->SrcReg
[j
].Index
== FRAG_ATTRIB_WPOS
) {
67 inst
->SrcReg
[j
].File
= PROGRAM_TEMPORARY
;
68 inst
->SrcReg
[j
].Index
= wpos_temp
;
74 _mesa_insert_instructions(&(fprog
->Base
), 0, 1);
76 newInst
= fprog
->Base
.Instructions
;
78 * wpos_temp.xyzw = wpos.x-yzw + winsize.0y00 */
79 newInst
[0].Opcode
= OPCODE_ADD
;
80 newInst
[0].DstReg
.File
= PROGRAM_TEMPORARY
;
81 newInst
[0].DstReg
.Index
= wpos_temp
;
82 newInst
[0].DstReg
.WriteMask
= WRITEMASK_XYZW
;
84 newInst
[0].SrcReg
[0].File
= PROGRAM_INPUT
;
85 newInst
[0].SrcReg
[0].Index
= FRAG_ATTRIB_WPOS
;
86 newInst
[0].SrcReg
[0].Swizzle
= SWIZZLE_XYZW
;
87 newInst
[0].SrcReg
[0].Negate
= NEGATE_Y
;
89 newInst
[0].SrcReg
[1].File
= PROGRAM_STATE_VAR
;
90 newInst
[0].SrcReg
[1].Index
= win_size
;
91 newInst
[0].SrcReg
[1].Swizzle
= MAKE_SWIZZLE4(SWIZZLE_ZERO
, SWIZZLE_Y
, SWIZZLE_ZERO
, SWIZZLE_ZERO
);
95 //TODO : Validate FP input with VP output.
96 void evergreen_Map_Fragment_Program(r700_AssemblerBase
*pAsm
,
97 struct gl_fragment_program
*mesa_fp
,
98 struct gl_context
*ctx
)
103 /* match fp inputs with vp exports. */
104 struct evergreen_vertex_program_cont
*vpc
=
105 (struct evergreen_vertex_program_cont
*)ctx
->VertexProgram
._Current
;
106 GLbitfield OutputsWritten
= vpc
->mesa_program
.Base
.OutputsWritten
;
108 pAsm
->number_used_registers
= 0;
110 //Input mapping : mesa_fp->Base.InputsRead set the flag, set in
111 //The flags parsed in parse_attrib_binding. FRAG_ATTRIB_COLx, FRAG_ATTRIB_TEXx, ...
112 //MUST match order in Map_Vertex_Output
113 unBit
= 1 << FRAG_ATTRIB_WPOS
;
114 if(mesa_fp
->Base
.InputsRead
& unBit
)
116 pAsm
->uiFP_AttributeMap
[FRAG_ATTRIB_WPOS
] = pAsm
->number_used_registers
++;
119 unBit
= 1 << VERT_RESULT_COL0
;
120 if(OutputsWritten
& unBit
)
122 pAsm
->uiFP_AttributeMap
[FRAG_ATTRIB_COL0
] = pAsm
->number_used_registers
++;
125 unBit
= 1 << VERT_RESULT_COL1
;
126 if(OutputsWritten
& unBit
)
128 pAsm
->uiFP_AttributeMap
[FRAG_ATTRIB_COL1
] = pAsm
->number_used_registers
++;
131 unBit
= 1 << VERT_RESULT_FOGC
;
132 if(OutputsWritten
& unBit
)
134 pAsm
->uiFP_AttributeMap
[FRAG_ATTRIB_FOGC
] = pAsm
->number_used_registers
++;
139 unBit
= 1 << (VERT_RESULT_TEX0
+ i
);
140 if(OutputsWritten
& unBit
)
142 pAsm
->uiFP_AttributeMap
[FRAG_ATTRIB_TEX0
+ i
] = pAsm
->number_used_registers
++;
146 /* order has been taken care of */
148 for(i
=VERT_RESULT_VAR0
; i
<VERT_RESULT_MAX
; i
++)
151 if(OutputsWritten
& unBit
)
153 pAsm
->uiFP_AttributeMap
[i
-VERT_RESULT_VAR0
+FRAG_ATTRIB_VAR0
] = pAsm
->number_used_registers
++;
157 if( (mesa_fp
->Base
.InputsRead
>> FRAG_ATTRIB_VAR0
) > 0 )
159 struct evergreen_vertex_program_cont
*vpc
=
160 (struct evergreen_vertex_program_cont
*)ctx
->VertexProgram
._Current
;
161 struct gl_program_parameter_list
* VsVarying
= vpc
->mesa_program
.Base
.Varying
;
162 struct gl_program_parameter_list
* PsVarying
= mesa_fp
->Base
.Varying
;
163 struct gl_program_parameter
* pVsParam
;
164 struct gl_program_parameter
* pPsParam
;
166 GLuint unMaxVarying
= 0;
168 for(i
=0; i
<VsVarying
->NumParameters
; i
++)
170 pAsm
->uiFP_AttributeMap
[i
+ FRAG_ATTRIB_VAR0
] = 0;
173 for(i
=FRAG_ATTRIB_VAR0
; i
<FRAG_ATTRIB_MAX
; i
++)
176 if(mesa_fp
->Base
.InputsRead
& unBit
)
178 j
= i
- FRAG_ATTRIB_VAR0
;
179 pPsParam
= PsVarying
->Parameters
+ j
;
181 for(k
=0; k
<VsVarying
->NumParameters
; k
++)
183 pVsParam
= VsVarying
->Parameters
+ k
;
185 if( strcmp(pPsParam
->Name
, pVsParam
->Name
) == 0)
187 pAsm
->uiFP_AttributeMap
[i
] = pAsm
->number_used_registers
+ k
;
198 pAsm
->number_used_registers
+= unMaxVarying
+ 1;
201 unBit
= 1 << FRAG_ATTRIB_FACE
;
202 if(mesa_fp
->Base
.InputsRead
& unBit
)
204 pAsm
->uiFP_AttributeMap
[FRAG_ATTRIB_FACE
] = pAsm
->number_used_registers
++;
207 unBit
= 1 << FRAG_ATTRIB_PNTC
;
208 if(mesa_fp
->Base
.InputsRead
& unBit
)
210 pAsm
->uiFP_AttributeMap
[FRAG_ATTRIB_PNTC
] = pAsm
->number_used_registers
++;
213 pAsm
->uIIns
= pAsm
->number_used_registers
;
215 /* Map temporary registers (GPRs) */
216 pAsm
->starting_temp_register_number
= pAsm
->number_used_registers
;
218 if(mesa_fp
->Base
.NumNativeTemporaries
>= mesa_fp
->Base
.NumTemporaries
)
220 pAsm
->number_used_registers
+= mesa_fp
->Base
.NumNativeTemporaries
;
224 pAsm
->number_used_registers
+= mesa_fp
->Base
.NumTemporaries
;
228 pAsm
->number_of_exports
= 0;
229 pAsm
->number_of_colorandz_exports
= 0; /* don't include stencil and mask out. */
230 pAsm
->starting_export_register_number
= pAsm
->number_used_registers
;
231 unBit
= 1 << FRAG_RESULT_COLOR
;
232 if(mesa_fp
->Base
.OutputsWritten
& unBit
)
234 pAsm
->uiFP_OutputMap
[FRAG_RESULT_COLOR
] = pAsm
->number_used_registers
++;
235 pAsm
->number_of_exports
++;
236 pAsm
->number_of_colorandz_exports
++;
238 unBit
= 1 << FRAG_RESULT_DEPTH
;
239 if(mesa_fp
->Base
.OutputsWritten
& unBit
)
241 pAsm
->depth_export_register_number
= pAsm
->number_used_registers
;
242 pAsm
->uiFP_OutputMap
[FRAG_RESULT_DEPTH
] = pAsm
->number_used_registers
++;
243 pAsm
->number_of_exports
++;
244 pAsm
->number_of_colorandz_exports
++;
245 pAsm
->pR700Shader
->depthIsExported
= 1;
248 pAsm
->flag_reg_index
= pAsm
->number_used_registers
++;
250 pAsm
->uFirstHelpReg
= pAsm
->number_used_registers
;
253 GLboolean
evergreen_Find_Instruction_Dependencies_fp(struct evergreen_fragment_program
*fp
,
254 struct gl_fragment_program
*mesa_fp
)
257 GLint
* puiTEMPwrites
;
258 GLint
* puiTEMPreads
;
259 struct prog_instruction
* pILInst
;
261 struct prog_instruction
* texcoord_DepInst
;
264 puiTEMPwrites
= (GLint
*) MALLOC(sizeof(GLuint
)*mesa_fp
->Base
.NumTemporaries
);
265 puiTEMPreads
= (GLint
*) MALLOC(sizeof(GLuint
)*mesa_fp
->Base
.NumTemporaries
);
267 for(i
=0; i
<mesa_fp
->Base
.NumTemporaries
; i
++)
269 puiTEMPwrites
[i
] = -1;
270 puiTEMPreads
[i
] = -1;
273 pInstDeps
= (InstDeps
*)MALLOC(sizeof(InstDeps
)*mesa_fp
->Base
.NumInstructions
);
275 for(i
=0; i
<mesa_fp
->Base
.NumInstructions
; i
++)
277 pInstDeps
[i
].nDstDep
= -1;
278 pILInst
= &(mesa_fp
->Base
.Instructions
[i
]);
281 if(pILInst
->DstReg
.File
== PROGRAM_TEMPORARY
)
283 //Set lastwrite for the temp
284 puiTEMPwrites
[pILInst
->DstReg
.Index
] = i
;
290 if(pILInst
->SrcReg
[j
].File
== PROGRAM_TEMPORARY
)
293 pInstDeps
[i
].nSrcDeps
[j
] = puiTEMPwrites
[pILInst
->SrcReg
[j
].Index
];
295 if(puiTEMPreads
[pILInst
->SrcReg
[j
].Index
] < 0 )
297 puiTEMPreads
[pILInst
->SrcReg
[j
].Index
] = i
;
302 pInstDeps
[i
].nSrcDeps
[j
] = -1;
307 fp
->r700AsmCode
.pInstDeps
= pInstDeps
;
309 //Find dep for tex inst
310 for(i
=0; i
<mesa_fp
->Base
.NumInstructions
; i
++)
312 pILInst
= &(mesa_fp
->Base
.Instructions
[i
]);
314 if(GL_TRUE
== IsTex(pILInst
->Opcode
))
315 { //src0 is the tex coord register, src1 is texunit, src2 is textype
316 nDepInstID
= pInstDeps
[i
].nSrcDeps
[0];
319 texcoord_DepInst
= &(mesa_fp
->Base
.Instructions
[nDepInstID
]);
320 if(GL_TRUE
== IsAlu(texcoord_DepInst
->Opcode
) )
322 pInstDeps
[nDepInstID
].nDstDep
= i
;
323 pInstDeps
[i
].nDstDep
= i
;
325 else if(GL_TRUE
== IsTex(texcoord_DepInst
->Opcode
) )
327 pInstDeps
[i
].nDstDep
= i
;
333 // make sure that we dont overwrite src used earlier
334 nDepInstID
= puiTEMPreads
[pILInst
->DstReg
.Index
];
337 pInstDeps
[i
].nDstDep
= puiTEMPreads
[pILInst
->DstReg
.Index
];
338 texcoord_DepInst
= &(mesa_fp
->Base
.Instructions
[nDepInstID
]);
339 if(GL_TRUE
== IsAlu(texcoord_DepInst
->Opcode
) )
341 pInstDeps
[nDepInstID
].nDstDep
= i
;
355 GLboolean
evergreenTranslateFragmentShader(struct evergreen_fragment_program
*fp
,
356 struct gl_fragment_program
*mesa_fp
,
357 struct gl_context
*ctx
)
359 GLuint number_of_colors_exported
;
360 GLboolean z_enabled
= GL_FALSE
;
361 GLuint unBit
, shadow_unit
;
363 struct prog_instruction
*inst
;
364 gl_state_index shadow_ambient
[STATE_LENGTH
]
365 = { STATE_INTERNAL
, STATE_SHADOW_AMBIENT
, 0, 0, 0};
368 Init_r700_AssemblerBase( SPT_FP
, &(fp
->r700AsmCode
), &(fp
->r700Shader
) );
371 fp
->r700AsmCode
.bUseMemConstant
= GL_TRUE
;
372 fp
->r700AsmCode
.unAsic
= 8;
374 if(mesa_fp
->Base
.InputsRead
& FRAG_BIT_WPOS
)
376 evergreen_insert_wpos_code(ctx
, mesa_fp
);
379 /* add/map consts for ARB_shadow_ambient */
380 if(mesa_fp
->Base
.ShadowSamplers
)
382 inst
= mesa_fp
->Base
.Instructions
;
383 for (i
= 0; i
< mesa_fp
->Base
.NumInstructions
; i
++)
385 if(inst
->TexShadow
== 1)
387 shadow_unit
= inst
->TexSrcUnit
;
388 shadow_ambient
[2] = shadow_unit
;
389 fp
->r700AsmCode
.shadow_regs
[shadow_unit
] =
390 _mesa_add_state_reference(mesa_fp
->Base
.Parameters
, shadow_ambient
);
396 evergreen_Map_Fragment_Program(&(fp
->r700AsmCode
), mesa_fp
, ctx
);
398 if( GL_FALSE
== evergreen_Find_Instruction_Dependencies_fp(fp
, mesa_fp
) )
403 InitShaderProgram(&(fp
->r700AsmCode
));
405 for(i
=0; i
< MAX_SAMPLERS
; i
++)
407 fp
->r700AsmCode
.SamplerUnits
[i
] = fp
->mesa_program
.Base
.SamplerUnits
[i
];
410 fp
->r700AsmCode
.unCurNumILInsts
= mesa_fp
->Base
.NumInstructions
;
412 if( GL_FALSE
== AssembleInstr(0,
414 mesa_fp
->Base
.NumInstructions
,
415 &(mesa_fp
->Base
.Instructions
[0]),
416 &(fp
->r700AsmCode
)) )
421 if(GL_FALSE
== Process_Fragment_Exports(&(fp
->r700AsmCode
), mesa_fp
->Base
.OutputsWritten
) )
426 if( GL_FALSE
== RelocProgram(&(fp
->r700AsmCode
), &(mesa_fp
->Base
)) )
431 fp
->r700Shader
.nRegs
= (fp
->r700AsmCode
.number_used_registers
== 0) ? 0
432 : (fp
->r700AsmCode
.number_used_registers
- 1);
434 fp
->r700Shader
.nParamExports
= fp
->r700AsmCode
.number_of_exports
;
436 number_of_colors_exported
= fp
->r700AsmCode
.number_of_colorandz_exports
;
438 unBit
= 1 << FRAG_RESULT_DEPTH
;
439 if(mesa_fp
->Base
.OutputsWritten
& unBit
)
442 number_of_colors_exported
--;
445 /* illegal to set this to 0 */
446 if(number_of_colors_exported
|| z_enabled
)
448 fp
->r700Shader
.exportMode
= number_of_colors_exported
<< 1 | z_enabled
;
452 fp
->r700Shader
.exportMode
= (1 << 1);
455 fp
->translated
= GL_TRUE
;
460 void evergreenSelectFragmentShader(struct gl_context
*ctx
)
462 context_t
*context
= EVERGREEN_CONTEXT(ctx
);
463 struct evergreen_fragment_program
*fp
= (struct evergreen_fragment_program
*)
464 (ctx
->FragmentProgram
._Current
);
465 if (context
->radeon
.radeonScreen
->chip_family
< CHIP_FAMILY_RV770
)
467 fp
->r700AsmCode
.bR6xx
= 1;
470 if (GL_FALSE
== fp
->translated
)
471 evergreenTranslateFragmentShader(fp
, &(fp
->mesa_program
), ctx
);
474 void * evergreenGetActiveFpShaderBo(struct gl_context
* ctx
)
476 struct evergreen_fragment_program
*fp
= (struct evergreen_fragment_program
*)
477 (ctx
->FragmentProgram
._Current
);
482 void * evergreenGetActiveFpShaderConstBo(struct gl_context
* ctx
)
484 struct evergreen_fragment_program
*fp
= (struct evergreen_fragment_program
*)
485 (ctx
->FragmentProgram
._Current
);
490 GLboolean
evergreenSetupFragmentProgram(struct gl_context
* ctx
)
492 context_t
*context
= EVERGREEN_CONTEXT(ctx
);
493 EVERGREEN_CHIP_CONTEXT
*evergreen
= GET_EVERGREEN_CHIP(context
);
494 struct evergreen_fragment_program
*fp
= (struct evergreen_fragment_program
*)
495 (ctx
->FragmentProgram
._Current
);
496 r700_AssemblerBase
*pAsm
= &(fp
->r700AsmCode
);
497 struct gl_fragment_program
*mesa_fp
= &(fp
->mesa_program
);
499 unsigned int unNumOfReg
;
502 GLboolean point_sprite
= GL_FALSE
;
504 if(GL_FALSE
== fp
->loaded
)
506 if(fp
->r700Shader
.bNeedsAssembly
== GL_TRUE
)
508 Assemble( &(fp
->r700Shader
) );
513 (GLvoid
*)(fp
->r700Shader
.pProgram
),
514 fp
->r700Shader
.uShaderBinaryDWORDSize
,
517 fp
->loaded
= GL_TRUE
;
520 /* TODO : enable this after MemUse fixed *=
521 (context->chipobj.MemUse)(context, fp->shadercode.buf->id);
524 EVERGREEN_STATECHANGE(context
, sq
);
526 evergreen
->SQ_PGM_RESOURCES_PS
.u32All
= 0;
527 SETbit(evergreen
->SQ_PGM_RESOURCES_PS
.u32All
, PGM_RESOURCES__PRIME_CACHE_ON_DRAW_bit
);
529 evergreen
->ps
.SQ_ALU_CONST_CACHE_PS_0
.u32All
= 0;
530 evergreen
->ps
.SQ_PGM_START_PS
.u32All
= 0;
532 EVERGREEN_STATECHANGE(context
, spi
);
534 unNumOfReg
= fp
->r700Shader
.nRegs
+ 1;
536 ui
= (evergreen
->SPI_PS_IN_CONTROL_0
.u32All
& NUM_INTERP_mask
) / (1 << NUM_INTERP_shift
);
538 /* PS uses fragment.position */
539 if (mesa_fp
->Base
.InputsRead
& (1 << FRAG_ATTRIB_WPOS
))
542 SETfield(evergreen
->SPI_PS_IN_CONTROL_0
.u32All
, ui
, NUM_INTERP_shift
, NUM_INTERP_mask
);
543 SETfield(evergreen
->SPI_PS_IN_CONTROL_0
.u32All
, CENTERS_ONLY
, BARYC_SAMPLE_CNTL_shift
, BARYC_SAMPLE_CNTL_mask
);
544 SETbit(evergreen
->SPI_PS_IN_CONTROL_0
.u32All
, POSITION_ENA_bit
);
545 SETbit(evergreen
->SPI_INPUT_Z
.u32All
, PROVIDE_Z_TO_SPI_bit
);
549 CLEARbit(evergreen
->SPI_PS_IN_CONTROL_0
.u32All
, POSITION_ENA_bit
);
550 CLEARbit(evergreen
->SPI_INPUT_Z
.u32All
, PROVIDE_Z_TO_SPI_bit
);
553 if (mesa_fp
->Base
.InputsRead
& (1 << FRAG_ATTRIB_FACE
))
556 SETfield(evergreen
->SPI_PS_IN_CONTROL_0
.u32All
, ui
, NUM_INTERP_shift
, NUM_INTERP_mask
);
557 SETbit(evergreen
->SPI_PS_IN_CONTROL_1
.u32All
, FRONT_FACE_ENA_bit
);
558 SETbit(evergreen
->SPI_PS_IN_CONTROL_1
.u32All
, FRONT_FACE_ALL_BITS_bit
);
559 SETfield(evergreen
->SPI_PS_IN_CONTROL_1
.u32All
, pAsm
->uiFP_AttributeMap
[FRAG_ATTRIB_FACE
], FRONT_FACE_ADDR_shift
, FRONT_FACE_ADDR_mask
);
563 CLEARbit(evergreen
->SPI_PS_IN_CONTROL_1
.u32All
, FRONT_FACE_ENA_bit
);
566 /* see if we need any point_sprite replacements */
567 for (i
= VERT_RESULT_TEX0
; i
<= VERT_RESULT_TEX7
; i
++)
569 if(ctx
->Point
.CoordReplace
[i
- VERT_RESULT_TEX0
] == GL_TRUE
)
570 point_sprite
= GL_TRUE
;
573 if ((mesa_fp
->Base
.InputsRead
& (1 << FRAG_ATTRIB_PNTC
)) || point_sprite
)
575 /* for FRAG_ATTRIB_PNTC we need to increase num_interp */
576 if(mesa_fp
->Base
.InputsRead
& (1 << FRAG_ATTRIB_PNTC
))
579 SETfield(evergreen
->SPI_PS_IN_CONTROL_0
.u32All
, ui
, NUM_INTERP_shift
, NUM_INTERP_mask
);
581 SETbit(evergreen
->SPI_INTERP_CONTROL_0
.u32All
, PNT_SPRITE_ENA_bit
);
582 SETfield(evergreen
->SPI_INTERP_CONTROL_0
.u32All
, SPI_PNT_SPRITE_SEL_S
, PNT_SPRITE_OVRD_X_shift
, PNT_SPRITE_OVRD_X_mask
);
583 SETfield(evergreen
->SPI_INTERP_CONTROL_0
.u32All
, SPI_PNT_SPRITE_SEL_T
, PNT_SPRITE_OVRD_Y_shift
, PNT_SPRITE_OVRD_Y_mask
);
584 SETfield(evergreen
->SPI_INTERP_CONTROL_0
.u32All
, SPI_PNT_SPRITE_SEL_0
, PNT_SPRITE_OVRD_Z_shift
, PNT_SPRITE_OVRD_Z_mask
);
585 SETfield(evergreen
->SPI_INTERP_CONTROL_0
.u32All
, SPI_PNT_SPRITE_SEL_1
, PNT_SPRITE_OVRD_W_shift
, PNT_SPRITE_OVRD_W_mask
);
586 if(ctx
->Point
.SpriteOrigin
== GL_LOWER_LEFT
)
587 SETbit(evergreen
->SPI_INTERP_CONTROL_0
.u32All
, PNT_SPRITE_TOP_1_bit
);
589 CLEARbit(evergreen
->SPI_INTERP_CONTROL_0
.u32All
, PNT_SPRITE_TOP_1_bit
);
593 CLEARbit(evergreen
->SPI_INTERP_CONTROL_0
.u32All
, PNT_SPRITE_ENA_bit
);
597 ui
= (unNumOfReg
< ui
) ? ui
: unNumOfReg
;
599 SETfield(evergreen
->SQ_PGM_RESOURCES_PS
.u32All
, ui
, NUM_GPRS_shift
, NUM_GPRS_mask
);
601 CLEARbit(evergreen
->SQ_PGM_RESOURCES_PS
.u32All
, UNCACHED_FIRST_INST_bit
);
603 if(fp
->r700Shader
.uStackSize
) /* we don't use branch for now, it should be zero. */
605 SETfield(evergreen
->SQ_PGM_RESOURCES_PS
.u32All
, fp
->r700Shader
.uStackSize
,
606 STACK_SIZE_shift
, STACK_SIZE_mask
);
609 SETfield(evergreen
->SQ_PGM_EXPORTS_PS
.u32All
, fp
->r700Shader
.exportMode
,
610 EXPORT_MODE_shift
, EXPORT_MODE_mask
);
613 struct evergreen_vertex_program_cont
*vpc
=
614 (struct evergreen_vertex_program_cont
*)ctx
->VertexProgram
._Current
;
615 GLbitfield OutputsWritten
= vpc
->mesa_program
.Base
.OutputsWritten
;
617 for(ui
= 0; ui
< EVERGREEN_MAX_SHADER_EXPORTS
; ui
++)
618 evergreen
->SPI_PS_INPUT_CNTL
[ui
].u32All
= 0;
620 unBit
= 1 << FRAG_ATTRIB_WPOS
;
621 if(mesa_fp
->Base
.InputsRead
& unBit
)
623 ui
= pAsm
->uiFP_AttributeMap
[FRAG_ATTRIB_WPOS
];
624 SETbit(evergreen
->SPI_PS_INPUT_CNTL
[ui
].u32All
, SEL_CENTROID_bit
);
625 SETfield(evergreen
->SPI_PS_INPUT_CNTL
[ui
].u32All
, ui
,
626 SEMANTIC_shift
, SEMANTIC_mask
);
627 if (evergreen
->SPI_INTERP_CONTROL_0
.u32All
& FLAT_SHADE_ENA_bit
)
628 SETbit(evergreen
->SPI_PS_INPUT_CNTL
[ui
].u32All
, FLAT_SHADE_bit
);
630 CLEARbit(evergreen
->SPI_PS_INPUT_CNTL
[ui
].u32All
, FLAT_SHADE_bit
);
633 unBit
= 1 << VERT_RESULT_COL0
;
634 if(OutputsWritten
& unBit
)
636 ui
= pAsm
->uiFP_AttributeMap
[FRAG_ATTRIB_COL0
];
637 SETbit(evergreen
->SPI_PS_INPUT_CNTL
[ui
].u32All
, SEL_CENTROID_bit
);
638 SETfield(evergreen
->SPI_PS_INPUT_CNTL
[ui
].u32All
, ui
,
639 SEMANTIC_shift
, SEMANTIC_mask
);
640 if (evergreen
->SPI_INTERP_CONTROL_0
.u32All
& FLAT_SHADE_ENA_bit
)
641 SETbit(evergreen
->SPI_PS_INPUT_CNTL
[ui
].u32All
, FLAT_SHADE_bit
);
643 CLEARbit(evergreen
->SPI_PS_INPUT_CNTL
[ui
].u32All
, FLAT_SHADE_bit
);
646 unBit
= 1 << VERT_RESULT_COL1
;
647 if(OutputsWritten
& unBit
)
649 ui
= pAsm
->uiFP_AttributeMap
[FRAG_ATTRIB_COL1
];
650 SETbit(evergreen
->SPI_PS_INPUT_CNTL
[ui
].u32All
, SEL_CENTROID_bit
);
651 SETfield(evergreen
->SPI_PS_INPUT_CNTL
[ui
].u32All
, ui
,
652 SEMANTIC_shift
, SEMANTIC_mask
);
653 if (evergreen
->SPI_INTERP_CONTROL_0
.u32All
& FLAT_SHADE_ENA_bit
)
654 SETbit(evergreen
->SPI_PS_INPUT_CNTL
[ui
].u32All
, FLAT_SHADE_bit
);
656 CLEARbit(evergreen
->SPI_PS_INPUT_CNTL
[ui
].u32All
, FLAT_SHADE_bit
);
659 unBit
= 1 << VERT_RESULT_FOGC
;
660 if(OutputsWritten
& unBit
)
662 ui
= pAsm
->uiFP_AttributeMap
[FRAG_ATTRIB_FOGC
];
663 SETbit(evergreen
->SPI_PS_INPUT_CNTL
[ui
].u32All
, SEL_CENTROID_bit
);
664 SETfield(evergreen
->SPI_PS_INPUT_CNTL
[ui
].u32All
, ui
,
665 SEMANTIC_shift
, SEMANTIC_mask
);
666 if (evergreen
->SPI_INTERP_CONTROL_0
.u32All
& FLAT_SHADE_ENA_bit
)
667 SETbit(evergreen
->SPI_PS_INPUT_CNTL
[ui
].u32All
, FLAT_SHADE_bit
);
669 CLEARbit(evergreen
->SPI_PS_INPUT_CNTL
[ui
].u32All
, FLAT_SHADE_bit
);
674 unBit
= 1 << (VERT_RESULT_TEX0
+ i
);
675 if(OutputsWritten
& unBit
)
677 ui
= pAsm
->uiFP_AttributeMap
[FRAG_ATTRIB_TEX0
+ i
];
678 SETbit(evergreen
->SPI_PS_INPUT_CNTL
[ui
].u32All
, SEL_CENTROID_bit
);
679 SETfield(evergreen
->SPI_PS_INPUT_CNTL
[ui
].u32All
, ui
,
680 SEMANTIC_shift
, SEMANTIC_mask
);
681 CLEARbit(evergreen
->SPI_PS_INPUT_CNTL
[ui
].u32All
, FLAT_SHADE_bit
);
682 /* ARB_point_sprite */
683 if(ctx
->Point
.CoordReplace
[i
] == GL_TRUE
)
685 SETbit(evergreen
->SPI_PS_INPUT_CNTL
[ui
].u32All
, PT_SPRITE_TEX_bit
);
690 unBit
= 1 << FRAG_ATTRIB_FACE
;
691 if(mesa_fp
->Base
.InputsRead
& unBit
)
693 ui
= pAsm
->uiFP_AttributeMap
[FRAG_ATTRIB_FACE
];
694 SETbit(evergreen
->SPI_PS_INPUT_CNTL
[ui
].u32All
, SEL_CENTROID_bit
);
695 SETfield(evergreen
->SPI_PS_INPUT_CNTL
[ui
].u32All
, ui
,
696 SEMANTIC_shift
, SEMANTIC_mask
);
697 if (evergreen
->SPI_INTERP_CONTROL_0
.u32All
& FLAT_SHADE_ENA_bit
)
698 SETbit(evergreen
->SPI_PS_INPUT_CNTL
[ui
].u32All
, FLAT_SHADE_bit
);
700 CLEARbit(evergreen
->SPI_PS_INPUT_CNTL
[ui
].u32All
, FLAT_SHADE_bit
);
702 unBit
= 1 << FRAG_ATTRIB_PNTC
;
703 if(mesa_fp
->Base
.InputsRead
& unBit
)
705 ui
= pAsm
->uiFP_AttributeMap
[FRAG_ATTRIB_PNTC
];
706 SETbit(evergreen
->SPI_PS_INPUT_CNTL
[ui
].u32All
, SEL_CENTROID_bit
);
707 SETfield(evergreen
->SPI_PS_INPUT_CNTL
[ui
].u32All
, ui
,
708 SEMANTIC_shift
, SEMANTIC_mask
);
709 if (evergreen
->SPI_INTERP_CONTROL_0
.u32All
& FLAT_SHADE_ENA_bit
)
710 SETbit(evergreen
->SPI_PS_INPUT_CNTL
[ui
].u32All
, FLAT_SHADE_bit
);
712 CLEARbit(evergreen
->SPI_PS_INPUT_CNTL
[ui
].u32All
, FLAT_SHADE_bit
);
713 SETbit(evergreen
->SPI_PS_INPUT_CNTL
[ui
].u32All
, PT_SPRITE_TEX_bit
);
719 for(i
=VERT_RESULT_VAR0
; i
<VERT_RESULT_MAX
; i
++)
722 if(OutputsWritten
& unBit
)
724 ui
= pAsm
->uiFP_AttributeMap
[i
-VERT_RESULT_VAR0
+FRAG_ATTRIB_VAR0
];
725 SETbit(evergreen
->SPI_PS_INPUT_CNTL
[ui
].u32All
, SEL_CENTROID_bit
);
726 SETfield(evergreen
->SPI_PS_INPUT_CNTL
[ui
].u32All
, ui
,
727 SEMANTIC_shift
, SEMANTIC_mask
);
728 if (evergreen
->SPI_INTERP_CONTROL_0
.u32All
& FLAT_SHADE_ENA_bit
)
729 SETbit(evergreen
->SPI_PS_INPUT_CNTL
[ui
].u32All
, FLAT_SHADE_bit
);
731 CLEARbit(evergreen
->SPI_PS_INPUT_CNTL
[ui
].u32All
, FLAT_SHADE_bit
);
735 exportCount
= (evergreen
->SQ_PGM_EXPORTS_PS
.u32All
& EXPORT_MODE_mask
) / (1 << EXPORT_MODE_shift
);
740 GLboolean
evergreenSetupFPconstants(struct gl_context
* ctx
)
742 context_t
*context
= EVERGREEN_CONTEXT(ctx
);
743 EVERGREEN_CHIP_CONTEXT
*evergreen
= GET_EVERGREEN_CHIP(context
);
744 struct evergreen_fragment_program
*fp
= (struct evergreen_fragment_program
*)
745 (ctx
->FragmentProgram
._Current
);
746 r700_AssemblerBase
*pAsm
= &(fp
->r700AsmCode
);
748 struct gl_program_parameter_list
*paramList
;
749 unsigned int unNumParamData
;
753 /* sent out shader constants. */
754 paramList
= fp
->mesa_program
.Base
.Parameters
;
756 if(NULL
!= paramList
)
758 _mesa_load_state_parameters(ctx
, paramList
);
760 if (paramList
->NumParameters
> EVERGREEN_MAX_DX9_CONSTS
)
763 EVERGREEN_STATECHANGE(context
, sq
);
765 evergreen
->ps
.num_consts
= paramList
->NumParameters
;
767 unNumParamData
= paramList
->NumParameters
;
769 for(ui
=0; ui
<unNumParamData
; ui
++) {
770 evergreen
->ps
.consts
[ui
][0].f32All
= paramList
->ParameterValues
[ui
][0];
771 evergreen
->ps
.consts
[ui
][1].f32All
= paramList
->ParameterValues
[ui
][1];
772 evergreen
->ps
.consts
[ui
][2].f32All
= paramList
->ParameterValues
[ui
][2];
773 evergreen
->ps
.consts
[ui
][3].f32All
= paramList
->ParameterValues
[ui
][3];
776 /* alloc multiple of 16 constants */
777 alloc_size
= ((unNumParamData
* 4 * 4) + 255) & ~255;
779 /* Load fp constants to gpu */
780 if(unNumParamData
> 0)
782 radeonAllocDmaRegion(&context
->radeon
,
783 &context
->fp_Constbo
,
784 &context
->fp_bo_offset
,
787 r600EmitShaderConsts(ctx
,
789 context
->fp_bo_offset
,
790 (GLvoid
*)&(evergreen
->ps
.consts
[0][0]),
791 unNumParamData
* 4 * 4);
794 evergreen
->ps
.num_consts
= 0;
796 COMPILED_SUB
* pCompiledSub
;
798 GLuint unConstOffset
= evergreen
->ps
.num_consts
;
799 for(ui
=0; ui
<pAsm
->unNumPresub
; ui
++)
801 pCompiledSub
= pAsm
->presubs
[ui
].pCompiledSub
;
803 evergreen
->ps
.num_consts
+= pCompiledSub
->NumParameters
;
805 for(uj
=0; uj
<pCompiledSub
->NumParameters
; uj
++)
807 evergreen
->ps
.consts
[uj
+ unConstOffset
][0].f32All
= pCompiledSub
->ParameterValues
[uj
][0];
808 evergreen
->ps
.consts
[uj
+ unConstOffset
][1].f32All
= pCompiledSub
->ParameterValues
[uj
][1];
809 evergreen
->ps
.consts
[uj
+ unConstOffset
][2].f32All
= pCompiledSub
->ParameterValues
[uj
][2];
810 evergreen
->ps
.consts
[uj
+ unConstOffset
][3].f32All
= pCompiledSub
->ParameterValues
[uj
][3];
812 unConstOffset
+= pCompiledSub
->NumParameters
;