Go to the source code of this file.
Functions | |
GLuint | st_translate_mesa_program (uint procType, const struct gl_program *program, GLuint numInputs, const GLuint inputMapping[], const ubyte inputSemanticName[], const ubyte inputSemanticIndex[], const GLuint interpMode[], const GLbitfield inputFlags[], GLuint numOutputs, const GLuint outputMapping[], const ubyte outputSemanticName[], const ubyte outputSemanticIndex[], const GLbitfield outputFlags[], struct tgsi_token *tokens, GLuint maxTokens) |
Translate Mesa program to TGSI format. |
GLuint st_translate_mesa_program | ( | uint | procType, | |
const struct gl_program * | program, | |||
GLuint | numInputs, | |||
const GLuint | inputMapping[], | |||
const ubyte | inputSemanticName[], | |||
const ubyte | inputSemanticIndex[], | |||
const GLuint | interpMode[], | |||
const GLbitfield | inputFlags[], | |||
GLuint | numOutputs, | |||
const GLuint | outputMapping[], | |||
const ubyte | outputSemanticName[], | |||
const ubyte | outputSemanticIndex[], | |||
const GLbitfield | outputFlags[], | |||
struct tgsi_token * | tokens, | |||
GLuint | maxTokens | |||
) |
Translate Mesa program to TGSI format.
program | the program to translate | |
numInputs | number of input registers used | |
inputMapping | maps Mesa fragment program inputs to TGSI generic input indexes | |
inputSemanticName | the TGSI_SEMANTIC flag for each input | |
inputSemanticIndex | the semantic index (ex: which texcoord) for each input | |
interpMode | the TGSI_INTERPOLATE_LINEAR/PERSP mode for each input | |
numOutputs | number of output registers used | |
outputMapping | maps Mesa fragment program outputs to TGSI generic outputs | |
outputSemanticName | the TGSI_SEMANTIC flag for each output | |
outputSemanticIndex | the semantic index (ex: which texcoord) for each output | |
tokens | array to store translated tokens in | |
maxTokens | size of the tokens array |
Definition at line 732 of file st_mesa_to_tgsi.c.
References assert, compile_instruction(), debug_printf(), find_temporaries(), make_addr_decl(), make_constant_decl(), make_immediate(), make_input_decl(), make_output_decl(), make_sampler_decl(), make_temp_decl(), tgsi_build_full_declaration(), tgsi_build_full_immediate(), tgsi_build_full_instruction(), tgsi_build_header(), tgsi_build_processor(), tgsi_build_version(), tgsi_dump(), TGSI_PROCESSOR_FRAGMENT, TGSI_PROCESSOR_VERTEX, tgsi_sanity_check(), TGSI_SEMANTIC_COLOR, TGSI_SEMANTIC_POSITION, TGSI_WRITEMASK_XYZW, and TGSI_WRITEMASK_Z.
00748 { 00749 GLuint i; 00750 GLuint ti; /* token index */ 00751 struct tgsi_header *header; 00752 struct tgsi_processor *processor; 00753 struct tgsi_full_instruction fullinst; 00754 GLuint preamble_size = 0; 00755 GLuint immediates[1000]; 00756 GLuint numImmediates = 0; 00757 GLboolean insideSubroutine = GL_FALSE; 00758 GLboolean indirectAccess = GL_FALSE; 00759 00760 assert(procType == TGSI_PROCESSOR_FRAGMENT || 00761 procType == TGSI_PROCESSOR_VERTEX); 00762 00763 *(struct tgsi_version *) &tokens[0] = tgsi_build_version(); 00764 00765 header = (struct tgsi_header *) &tokens[1]; 00766 *header = tgsi_build_header(); 00767 00768 processor = (struct tgsi_processor *) &tokens[2]; 00769 *processor = tgsi_build_processor( procType, header ); 00770 00771 ti = 3; 00772 00773 /* 00774 * Declare input attributes. 00775 */ 00776 if (procType == TGSI_PROCESSOR_FRAGMENT) { 00777 for (i = 0; i < numInputs; i++) { 00778 struct tgsi_full_declaration fulldecl; 00779 fulldecl = make_input_decl(i, 00780 GL_TRUE, interpMode[i], 00781 TGSI_WRITEMASK_XYZW, 00782 GL_TRUE, inputSemanticName[i], 00783 inputSemanticIndex[i], 00784 inputFlags[i]); 00785 ti += tgsi_build_full_declaration(&fulldecl, 00786 &tokens[ti], 00787 header, 00788 maxTokens - ti ); 00789 } 00790 } 00791 else { 00792 /* vertex prog */ 00793 /* XXX: this could probaby be merged with the clause above. 00794 * the only difference is the semantic tags. 00795 */ 00796 for (i = 0; i < numInputs; i++) { 00797 struct tgsi_full_declaration fulldecl; 00798 fulldecl = make_input_decl(i, 00799 GL_FALSE, 0, 00800 TGSI_WRITEMASK_XYZW, 00801 GL_FALSE, 0, 0, 00802 inputFlags[i]); 00803 ti += tgsi_build_full_declaration(&fulldecl, 00804 &tokens[ti], 00805 header, 00806 maxTokens - ti ); 00807 } 00808 } 00809 00810 /* 00811 * Declare output attributes. 00812 */ 00813 if (procType == TGSI_PROCESSOR_FRAGMENT) { 00814 for (i = 0; i < numOutputs; i++) { 00815 struct tgsi_full_declaration fulldecl; 00816 switch (outputSemanticName[i]) { 00817 case TGSI_SEMANTIC_POSITION: 00818 fulldecl = make_output_decl(i, 00819 TGSI_SEMANTIC_POSITION, /* Z / Depth */ 00820 outputSemanticIndex[i], 00821 TGSI_WRITEMASK_Z, 00822 outputFlags[i]); 00823 break; 00824 case TGSI_SEMANTIC_COLOR: 00825 fulldecl = make_output_decl(i, 00826 TGSI_SEMANTIC_COLOR, 00827 outputSemanticIndex[i], 00828 TGSI_WRITEMASK_XYZW, 00829 outputFlags[i]); 00830 break; 00831 default: 00832 assert(0); 00833 return 0; 00834 } 00835 ti += tgsi_build_full_declaration(&fulldecl, 00836 &tokens[ti], 00837 header, 00838 maxTokens - ti ); 00839 } 00840 } 00841 else { 00842 /* vertex prog */ 00843 for (i = 0; i < numOutputs; i++) { 00844 struct tgsi_full_declaration fulldecl; 00845 fulldecl = make_output_decl(i, 00846 outputSemanticName[i], 00847 outputSemanticIndex[i], 00848 TGSI_WRITEMASK_XYZW, 00849 outputFlags[i]); 00850 ti += tgsi_build_full_declaration(&fulldecl, 00851 &tokens[ti], 00852 header, 00853 maxTokens - ti ); 00854 } 00855 } 00856 00857 /* temporary decls */ 00858 { 00859 GLboolean tempsUsed[MAX_PROGRAM_TEMPS + 1]; 00860 GLboolean inside_range = GL_FALSE; 00861 GLuint start_range = 0; 00862 00863 find_temporaries(program, tempsUsed); 00864 tempsUsed[MAX_PROGRAM_TEMPS] = GL_FALSE; 00865 for (i = 0; i < MAX_PROGRAM_TEMPS + 1; i++) { 00866 if (tempsUsed[i] && !inside_range) { 00867 inside_range = GL_TRUE; 00868 start_range = i; 00869 } 00870 else if (!tempsUsed[i] && inside_range) { 00871 struct tgsi_full_declaration fulldecl; 00872 00873 inside_range = GL_FALSE; 00874 fulldecl = make_temp_decl( start_range, i - 1 ); 00875 ti += tgsi_build_full_declaration( 00876 &fulldecl, 00877 &tokens[ti], 00878 header, 00879 maxTokens - ti ); 00880 } 00881 } 00882 } 00883 00884 /* Declare address register. 00885 */ 00886 if (program->NumAddressRegs > 0) { 00887 struct tgsi_full_declaration fulldecl; 00888 00889 assert( program->NumAddressRegs == 1 ); 00890 00891 fulldecl = make_addr_decl( 0, 0 ); 00892 ti += tgsi_build_full_declaration( 00893 &fulldecl, 00894 &tokens[ti], 00895 header, 00896 maxTokens - ti ); 00897 00898 indirectAccess = GL_TRUE; 00899 } 00900 00901 /* immediates/literals */ 00902 memset(immediates, ~0, sizeof(immediates)); 00903 00904 /* Emit immediates only when there is no address register in use. 00905 * FIXME: Be smarter and recognize param arrays -- indirect addressing is 00906 * only valid within the referenced array. 00907 */ 00908 if (program->Parameters && !indirectAccess) { 00909 for (i = 0; i < program->Parameters->NumParameters; i++) { 00910 if (program->Parameters->Parameters[i].Type == PROGRAM_CONSTANT) { 00911 struct tgsi_full_immediate fullimm; 00912 00913 fullimm = make_immediate( program->Parameters->ParameterValues[i], 4 ); 00914 ti += tgsi_build_full_immediate( 00915 &fullimm, 00916 &tokens[ti], 00917 header, 00918 maxTokens - ti ); 00919 immediates[i] = numImmediates; 00920 numImmediates++; 00921 } 00922 } 00923 } 00924 00925 /* constant buffer refs */ 00926 if (program->Parameters) { 00927 GLint start = -1, end = -1; 00928 00929 for (i = 0; i < program->Parameters->NumParameters; i++) { 00930 GLboolean emit = (i == program->Parameters->NumParameters - 1); 00931 GLboolean matches; 00932 00933 switch (program->Parameters->Parameters[i].Type) { 00934 case PROGRAM_ENV_PARAM: 00935 case PROGRAM_STATE_VAR: 00936 case PROGRAM_NAMED_PARAM: 00937 case PROGRAM_UNIFORM: 00938 matches = GL_TRUE; 00939 break; 00940 case PROGRAM_CONSTANT: 00941 matches = indirectAccess; 00942 break; 00943 default: 00944 matches = GL_FALSE; 00945 } 00946 00947 if (matches) { 00948 if (start == -1) { 00949 /* begin a sequence */ 00950 start = i; 00951 end = i; 00952 } 00953 else { 00954 /* continue sequence */ 00955 end = i; 00956 } 00957 } 00958 else { 00959 if (start != -1) { 00960 /* end of sequence */ 00961 emit = GL_TRUE; 00962 } 00963 } 00964 00965 if (emit && start >= 0) { 00966 struct tgsi_full_declaration fulldecl; 00967 00968 fulldecl = make_constant_decl( start, end ); 00969 ti += tgsi_build_full_declaration( 00970 &fulldecl, 00971 &tokens[ti], 00972 header, 00973 maxTokens - ti ); 00974 start = end = -1; 00975 } 00976 } 00977 } 00978 00979 /* texture samplers */ 00980 for (i = 0; i < 8; i++) { 00981 if (program->SamplersUsed & (1 << i)) { 00982 struct tgsi_full_declaration fulldecl; 00983 00984 fulldecl = make_sampler_decl( i ); 00985 ti += tgsi_build_full_declaration( 00986 &fulldecl, 00987 &tokens[ti], 00988 header, 00989 maxTokens - ti ); 00990 } 00991 } 00992 00993 for (i = 0; i < program->NumInstructions; i++) { 00994 compile_instruction( 00995 &program->Instructions[i], 00996 &fullinst, 00997 inputMapping, 00998 outputMapping, 00999 immediates, 01000 indirectAccess, 01001 preamble_size, 01002 procType, 01003 &insideSubroutine ); 01004 01005 ti += tgsi_build_full_instruction( 01006 &fullinst, 01007 &tokens[ti], 01008 header, 01009 maxTokens - ti ); 01010 } 01011 01012 #if DEBUG 01013 if(!tgsi_sanity_check(tokens)) { 01014 debug_printf("Due to sanity check failure(s) above the following shader program is invalid:\n"); 01015 debug_printf("\nOriginal program:\n%s", program->String); 01016 debug_printf("\nMesa program:\n"); 01017 _mesa_print_program(program); 01018 debug_printf("\nTGSI program:\n"); 01019 tgsi_dump(tokens, 0); 01020 assert(0); 01021 } 01022 #endif 01023 01024 return ti; 01025 }