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"
35 #include "shader/prog_parameter.h"
36 #include "shader/prog_statevars.h"
38 #include "r600_context.h"
39 #include "r600_cmdbuf.h"
41 #include "r700_fragprog.h"
43 #include "r700_debug.h"
45 //TODO : Validate FP input with VP output.
46 void Map_Fragment_Program(r700_AssemblerBase
*pAsm
,
47 struct gl_fragment_program
*mesa_fp
)
53 pAsm
->number_used_registers
= 0;
55 //Input mapping : mesa_fp->Base.InputsRead set the flag, set in
56 //The flags parsed in parse_attrib_binding. FRAG_ATTRIB_COLx, FRAG_ATTRIB_TEXx, ...
57 //MUST match order in Map_Vertex_Output
58 unBit
= 1 << FRAG_ATTRIB_COL0
;
59 if(mesa_fp
->Base
.InputsRead
& unBit
)
61 pAsm
->uiFP_AttributeMap
[FRAG_ATTRIB_COL0
] = pAsm
->number_used_registers
++;
64 unBit
= 1 << FRAG_ATTRIB_COL1
;
65 if(mesa_fp
->Base
.InputsRead
& unBit
)
67 pAsm
->uiFP_AttributeMap
[FRAG_ATTRIB_COL1
] = pAsm
->number_used_registers
++;
70 unBit
= 1 << FRAG_ATTRIB_FOGC
;
71 if(mesa_fp
->Base
.InputsRead
& unBit
)
73 pAsm
->uiFP_AttributeMap
[FRAG_ATTRIB_FOGC
] = pAsm
->number_used_registers
++;
78 unBit
= 1 << (FRAG_ATTRIB_TEX0
+ i
);
79 if(mesa_fp
->Base
.InputsRead
& unBit
)
81 pAsm
->uiFP_AttributeMap
[FRAG_ATTRIB_TEX0
+ i
] = pAsm
->number_used_registers
++;
85 /* Map temporary registers (GPRs) */
86 pAsm
->starting_temp_register_number
= pAsm
->number_used_registers
;
88 if(mesa_fp
->Base
.NumNativeTemporaries
>= mesa_fp
->Base
.NumTemporaries
)
90 pAsm
->number_used_registers
+= mesa_fp
->Base
.NumNativeTemporaries
;
94 pAsm
->number_used_registers
+= mesa_fp
->Base
.NumTemporaries
;
98 pAsm
->number_of_exports
= 0;
99 pAsm
->number_of_colorandz_exports
= 0; /* don't include stencil and mask out. */
100 pAsm
->starting_export_register_number
= pAsm
->number_used_registers
;
101 unBit
= 1 << FRAG_RESULT_COLOR
;
102 if(mesa_fp
->Base
.OutputsWritten
& unBit
)
104 pAsm
->uiFP_OutputMap
[FRAG_RESULT_COLOR
] = pAsm
->number_used_registers
++;
105 pAsm
->number_of_exports
++;
106 pAsm
->number_of_colorandz_exports
++;
108 unBit
= 1 << FRAG_RESULT_DEPTH
;
109 if(mesa_fp
->Base
.OutputsWritten
& unBit
)
111 pAsm
->depth_export_register_number
= pAsm
->number_used_registers
;
112 pAsm
->uiFP_OutputMap
[FRAG_RESULT_DEPTH
] = pAsm
->number_used_registers
++;
113 pAsm
->number_of_exports
++;
114 pAsm
->number_of_colorandz_exports
++;
117 pAsm
->pucOutMask
= (unsigned char*) MALLOC(pAsm
->number_of_exports
);
118 for(ui
=0; ui
<pAsm
->number_of_exports
; ui
++)
120 pAsm
->pucOutMask
[ui
] = 0x0;
123 pAsm
->uFirstHelpReg
= pAsm
->number_used_registers
;
126 GLboolean
Find_Instruction_Dependencies_fp(struct r700_fragment_program
*fp
,
127 struct gl_fragment_program
*mesa_fp
)
130 GLint
* puiTEMPwrites
;
131 struct prog_instruction
* pILInst
;
133 struct prog_instruction
* texcoord_DepInst
;
136 puiTEMPwrites
= (GLint
*) MALLOC(sizeof(GLuint
)*mesa_fp
->Base
.NumTemporaries
);
137 for(i
=0; i
<mesa_fp
->Base
.NumTemporaries
; i
++)
139 puiTEMPwrites
[i
] = -1;
142 pInstDeps
= (InstDeps
*)MALLOC(sizeof(InstDeps
)*mesa_fp
->Base
.NumInstructions
);
144 for(i
=0; i
<mesa_fp
->Base
.NumInstructions
; i
++)
146 pInstDeps
[i
].nDstDep
= -1;
147 pILInst
= &(mesa_fp
->Base
.Instructions
[i
]);
150 if(pILInst
->DstReg
.File
== PROGRAM_TEMPORARY
)
152 //Set lastwrite for the temp
153 puiTEMPwrites
[pILInst
->DstReg
.Index
] = i
;
159 if(pILInst
->SrcReg
[j
].File
== PROGRAM_TEMPORARY
)
162 pInstDeps
[i
].nSrcDeps
[j
] = puiTEMPwrites
[pILInst
->SrcReg
[j
].Index
];
166 pInstDeps
[i
].nSrcDeps
[j
] = -1;
171 fp
->r700AsmCode
.pInstDeps
= pInstDeps
;
175 //Find dep for tex inst
176 for(i
=0; i
<mesa_fp
->Base
.NumInstructions
; i
++)
178 pILInst
= &(mesa_fp
->Base
.Instructions
[i
]);
180 if(GL_TRUE
== IsTex(pILInst
->Opcode
))
181 { //src0 is the tex coord register, src1 is texunit, src2 is textype
182 nDepInstID
= pInstDeps
[i
].nSrcDeps
[0];
185 texcoord_DepInst
= &(mesa_fp
->Base
.Instructions
[nDepInstID
]);
186 if(GL_TRUE
== IsAlu(texcoord_DepInst
->Opcode
) )
188 pInstDeps
[nDepInstID
].nDstDep
= i
;
189 pInstDeps
[i
].nDstDep
= i
;
191 else if(GL_TRUE
== IsTex(texcoord_DepInst
->Opcode
) )
193 pInstDeps
[i
].nDstDep
= i
;
205 GLboolean
r700TranslateFragmentShader(struct r700_fragment_program
*fp
,
206 struct gl_fragment_program
*mesa_fp
)
208 GLuint number_of_colors_exported
;
209 GLboolean z_enabled
= GL_FALSE
;
213 Init_r700_AssemblerBase( SPT_FP
, &(fp
->r700AsmCode
), &(fp
->r700Shader
) );
214 Map_Fragment_Program(&(fp
->r700AsmCode
), mesa_fp
);
216 if( GL_FALSE
== Find_Instruction_Dependencies_fp(fp
, mesa_fp
) )
221 if( GL_FALSE
== AssembleInstr(mesa_fp
->Base
.NumInstructions
,
222 &(mesa_fp
->Base
.Instructions
[0]),
223 &(fp
->r700AsmCode
)) )
228 if(GL_FALSE
== Process_Fragment_Exports(&(fp
->r700AsmCode
), mesa_fp
->Base
.OutputsWritten
) )
233 fp
->r700Shader
.nRegs
= (fp
->r700AsmCode
.number_used_registers
== 0) ? 0
234 : (fp
->r700AsmCode
.number_used_registers
- 1);
236 fp
->r700Shader
.nParamExports
= fp
->r700AsmCode
.number_of_exports
;
238 number_of_colors_exported
= fp
->r700AsmCode
.number_of_colorandz_exports
;
240 unBit
= 1 << FRAG_RESULT_DEPTH
;
241 if(mesa_fp
->Base
.OutputsWritten
& unBit
)
244 number_of_colors_exported
--;
247 fp
->r700Shader
.exportMode
= number_of_colors_exported
<< 1 | z_enabled
;
249 fp
->translated
= GL_TRUE
;
254 void * r700GetActiveFpShaderBo(GLcontext
* ctx
)
256 struct r700_fragment_program
*fp
= (struct r700_fragment_program
*)
257 (ctx
->FragmentProgram
._Current
);
262 GLboolean
r700SetupFragmentProgram(GLcontext
* ctx
)
264 context_t
*context
= R700_CONTEXT(ctx
);
265 BATCH_LOCALS(&context
->radeon
);
266 R700_CHIP_CONTEXT
*r700
= (R700_CHIP_CONTEXT
*)(&context
->hw
);
268 struct r700_fragment_program
*fp
= (struct r700_fragment_program
*)
269 (ctx
->FragmentProgram
._Current
);
270 r700_AssemblerBase
*pAsm
= &(fp
->r700AsmCode
);
271 struct gl_fragment_program
*mesa_fp
= &(fp
->mesa_program
);
272 struct gl_program_parameter_list
*paramList
;
273 unsigned int unNumParamData
;
275 unsigned int unNumOfReg
;
278 if(GL_FALSE
== fp
->loaded
)
280 if(fp
->r700Shader
.bNeedsAssembly
== GL_TRUE
)
282 Assemble( &(fp
->r700Shader
) );
288 (GLvoid
*)(fp
->r700Shader
.pProgram
),
289 fp
->r700Shader
.uShaderBinaryDWORDSize
,
292 fp
->loaded
= GL_TRUE
;
295 DumpHwBinary(DUMP_PIXEL_SHADER
, (GLvoid
*)(fp
->r700Shader
.pProgram
),
296 fp
->r700Shader
.uShaderBinaryDWORDSize
);
298 /* TODO : enable this after MemUse fixed *=
299 (context->chipobj.MemUse)(context, fp->shadercode.buf->id);
302 r700
->ps
.SQ_PGM_START_PS
.u32All
= 0; /* set from buffer obj */
304 unNumOfReg
= fp
->r700Shader
.nRegs
+ 1;
306 ui
= (r700
->SPI_PS_IN_CONTROL_0
.u32All
& NUM_INTERP_mask
) / (1 << NUM_INTERP_shift
);
308 ui
= (unNumOfReg
< ui
) ? ui
: unNumOfReg
;
310 SETfield(r700
->ps
.SQ_PGM_RESOURCES_PS
.u32All
, ui
, NUM_GPRS_shift
, NUM_GPRS_mask
);
312 CLEARbit(r700
->ps
.SQ_PGM_RESOURCES_PS
.u32All
, UNCACHED_FIRST_INST_bit
);
314 if(fp
->r700Shader
.uStackSize
) /* we don't use branch for now, it should be zero. */
316 SETfield(r700
->ps
.SQ_PGM_RESOURCES_PS
.u32All
, fp
->r700Shader
.uStackSize
,
317 STACK_SIZE_shift
, STACK_SIZE_mask
);
320 SETfield(r700
->ps
.SQ_PGM_EXPORTS_PS
.u32All
, fp
->r700Shader
.exportMode
,
321 EXPORT_MODE_shift
, EXPORT_MODE_mask
);
323 if(fp
->r700Shader
.killIsUsed
)
325 SETbit(r700
->DB_SHADER_CONTROL
.u32All
, KILL_ENABLE_bit
);
329 CLEARbit(r700
->DB_SHADER_CONTROL
.u32All
, KILL_ENABLE_bit
);
332 if(fp
->r700Shader
.depthIsExported
)
334 SETbit(r700
->DB_SHADER_CONTROL
.u32All
, Z_EXPORT_ENABLE_bit
);
338 CLEARbit(r700
->DB_SHADER_CONTROL
.u32All
, Z_EXPORT_ENABLE_bit
);
341 /* sent out shader constants. */
343 paramList
= fp
->mesa_program
.Base
.Parameters
;
345 if(NULL
!= paramList
)
347 _mesa_load_state_parameters(ctx
, paramList
);
349 unNumParamData
= paramList
->NumParameters
* 4;
351 BEGIN_BATCH_NO_AUTOSTATE(2 + unNumParamData
);
353 R600_OUT_BATCH(CP_PACKET3(R600_IT_SET_ALU_CONST
, unNumParamData
));
355 /* assembler map const from very beginning. */
356 R600_OUT_BATCH(SQ_ALU_CONSTANT_PS_OFFSET
* 4);
358 unNumParamData
= paramList
->NumParameters
;
360 for(ui
=0; ui
<unNumParamData
; ui
++)
362 R600_OUT_BATCH(*((unsigned int*)&(paramList
->ParameterValues
[ui
][0])));
363 R600_OUT_BATCH(*((unsigned int*)&(paramList
->ParameterValues
[ui
][1])));
364 R600_OUT_BATCH(*((unsigned int*)&(paramList
->ParameterValues
[ui
][2])));
365 R600_OUT_BATCH(*((unsigned int*)&(paramList
->ParameterValues
[ui
][3])));
372 unBit
= 1 << FRAG_ATTRIB_COL0
;
373 if(mesa_fp
->Base
.InputsRead
& unBit
)
375 ui
= pAsm
->uiFP_AttributeMap
[FRAG_ATTRIB_COL0
];
376 SETbit(r700
->SPI_PS_INPUT_CNTL
[ui
].u32All
, SEL_CENTROID_bit
);
377 SETfield(r700
->SPI_PS_INPUT_CNTL
[ui
].u32All
, ui
,
378 SEMANTIC_shift
, SEMANTIC_mask
);
379 if (r700
->SPI_INTERP_CONTROL_0
.u32All
& FLAT_SHADE_ENA_bit
)
380 SETbit(r700
->SPI_PS_INPUT_CNTL
[ui
].u32All
, FLAT_SHADE_bit
);
382 CLEARbit(r700
->SPI_PS_INPUT_CNTL
[ui
].u32All
, FLAT_SHADE_bit
);
385 unBit
= 1 << FRAG_ATTRIB_COL1
;
386 if(mesa_fp
->Base
.InputsRead
& unBit
)
388 ui
= pAsm
->uiFP_AttributeMap
[FRAG_ATTRIB_COL1
];
389 SETbit(r700
->SPI_PS_INPUT_CNTL
[ui
].u32All
, SEL_CENTROID_bit
);
390 SETfield(r700
->SPI_PS_INPUT_CNTL
[ui
].u32All
, ui
,
391 SEMANTIC_shift
, SEMANTIC_mask
);
392 if (r700
->SPI_INTERP_CONTROL_0
.u32All
& FLAT_SHADE_ENA_bit
)
393 SETbit(r700
->SPI_PS_INPUT_CNTL
[ui
].u32All
, FLAT_SHADE_bit
);
395 CLEARbit(r700
->SPI_PS_INPUT_CNTL
[ui
].u32All
, FLAT_SHADE_bit
);
398 unBit
= 1 << FRAG_ATTRIB_FOGC
;
399 if(mesa_fp
->Base
.InputsRead
& unBit
)
401 ui
= pAsm
->uiFP_AttributeMap
[FRAG_ATTRIB_FOGC
];
402 SETbit(r700
->SPI_PS_INPUT_CNTL
[ui
].u32All
, SEL_CENTROID_bit
);
403 SETfield(r700
->SPI_PS_INPUT_CNTL
[ui
].u32All
, ui
,
404 SEMANTIC_shift
, SEMANTIC_mask
);
405 if (r700
->SPI_INTERP_CONTROL_0
.u32All
& FLAT_SHADE_ENA_bit
)
406 SETbit(r700
->SPI_PS_INPUT_CNTL
[ui
].u32All
, FLAT_SHADE_bit
);
408 CLEARbit(r700
->SPI_PS_INPUT_CNTL
[ui
].u32All
, FLAT_SHADE_bit
);
413 unBit
= 1 << (FRAG_ATTRIB_TEX0
+ i
);
414 if(mesa_fp
->Base
.InputsRead
& unBit
)
416 ui
= pAsm
->uiFP_AttributeMap
[FRAG_ATTRIB_TEX0
+ i
];
417 SETbit(r700
->SPI_PS_INPUT_CNTL
[ui
].u32All
, SEL_CENTROID_bit
);
418 SETfield(r700
->SPI_PS_INPUT_CNTL
[ui
].u32All
, ui
,
419 SEMANTIC_shift
, SEMANTIC_mask
);
420 CLEARbit(r700
->SPI_PS_INPUT_CNTL
[ui
].u32All
, FLAT_SHADE_bit
);