r300/vertprog: Cleanup source conflict handling
[mesa.git] / src / mesa / drivers / dri / r300 / compiler / radeon_program.h
1 /*
2 * Copyright (C) 2008 Nicolai Haehnle.
3 *
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining
7 * a copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sublicense, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial
16 * portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21 * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
22 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 */
27
28 #ifndef __RADEON_PROGRAM_H_
29 #define __RADEON_PROGRAM_H_
30
31 #include "main/glheader.h"
32 #include "main/macros.h"
33 #include "main/enums.h"
34 #include "shader/program.h"
35 #include "shader/prog_instruction.h"
36
37 struct radeon_compiler;
38 struct rc_instruction;
39
40 enum {
41 PROGRAM_BUILTIN = PROGRAM_FILE_MAX /**< not a real register, but a special swizzle constant */
42 };
43
44 enum {
45 OPCODE_REPL_ALPHA = MAX_OPCODE /**< used in paired instructions */
46 };
47
48 #define SWIZZLE_0000 MAKE_SWIZZLE4(SWIZZLE_ZERO, SWIZZLE_ZERO, SWIZZLE_ZERO, SWIZZLE_ZERO)
49 #define SWIZZLE_1111 MAKE_SWIZZLE4(SWIZZLE_ONE, SWIZZLE_ONE, SWIZZLE_ONE, SWIZZLE_ONE)
50
51 static inline GLuint get_swz(GLuint swz, GLuint idx)
52 {
53 if (idx & 0x4)
54 return idx;
55 return GET_SWZ(swz, idx);
56 }
57
58 static inline GLuint combine_swizzles4(GLuint src, GLuint swz_x, GLuint swz_y, GLuint swz_z, GLuint swz_w)
59 {
60 GLuint ret = 0;
61
62 ret |= get_swz(src, swz_x);
63 ret |= get_swz(src, swz_y) << 3;
64 ret |= get_swz(src, swz_z) << 6;
65 ret |= get_swz(src, swz_w) << 9;
66
67 return ret;
68 }
69
70 static inline GLuint combine_swizzles(GLuint src, GLuint swz)
71 {
72 GLuint ret = 0;
73
74 ret |= get_swz(src, GET_SWZ(swz, SWIZZLE_X));
75 ret |= get_swz(src, GET_SWZ(swz, SWIZZLE_Y)) << 3;
76 ret |= get_swz(src, GET_SWZ(swz, SWIZZLE_Z)) << 6;
77 ret |= get_swz(src, GET_SWZ(swz, SWIZZLE_W)) << 9;
78
79 return ret;
80 }
81
82 static INLINE void reset_srcreg(struct prog_src_register* reg)
83 {
84 _mesa_bzero(reg, sizeof(*reg));
85 reg->Swizzle = SWIZZLE_NOOP;
86 }
87
88
89 /**
90 * Transformation context that is passed to local transformations.
91 *
92 * Care must be taken with some operations during transformation,
93 * e.g. finding new temporary registers must use @ref radeonFindFreeTemporary
94 */
95 struct radeon_transform_context {
96 struct gl_program *Program;
97 struct prog_instruction *OldInstructions;
98 GLuint OldNumInstructions;
99 };
100
101 /**
102 * A transformation that can be passed to \ref radeonLocalTransform.
103 *
104 * The function will be called once for each instruction.
105 * It has to either emit the appropriate transformed code for the instruction
106 * and return GL_TRUE, or return GL_FALSE if it doesn't understand the
107 * instruction.
108 *
109 * The function gets passed the userData as last parameter.
110 */
111 struct radeon_program_transformation {
112 GLboolean (*function)(
113 struct radeon_transform_context*,
114 struct prog_instruction*,
115 void*);
116 void *userData;
117 };
118
119 void radeonLocalTransform(
120 struct gl_program *program,
121 int num_transformations,
122 struct radeon_program_transformation* transformations);
123
124 /**
125 * Find a usable free temporary register during program transformation
126 */
127 GLint radeonFindFreeTemporary(struct radeon_transform_context *ctx);
128
129 struct prog_instruction *radeonAppendInstructions(struct gl_program *program, int count);
130
131 GLint rc_find_free_temporary(struct radeon_compiler * c);
132
133 struct rc_instruction *rc_alloc_instruction(struct radeon_compiler * c);
134 struct rc_instruction *rc_insert_new_instruction(struct radeon_compiler * c, struct rc_instruction * after);
135
136 void rc_mesa_to_rc_program(struct radeon_compiler * c, struct gl_program * program);
137
138 #endif