Fix pow <small> and a very stypid bug with dummy srcs(0 equals to tmp0.x)</small...
[mesa.git] / src / mesa / main / texrender.c
1
2 #include "context.h"
3 #include "fbobject.h"
4 #include "texrender.h"
5 #include "renderbuffer.h"
6
7
8 /*
9 * Render-to-texture code for GL_EXT_framebuffer_object
10 */
11
12
13 /**
14 * Derived from gl_renderbuffer class
15 */
16 struct texture_renderbuffer
17 {
18 struct gl_renderbuffer Base; /* Base class object */
19 struct gl_texture_image *TexImage;
20 StoreTexelFunc Store;
21 GLint Zoffset;
22 };
23
24
25
26 static void
27 texture_get_row(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
28 GLint x, GLint y, void *values)
29 {
30 const struct texture_renderbuffer *trb
31 = (const struct texture_renderbuffer *) rb;
32 const GLint z = trb->Zoffset;
33 GLchan *rgbaOut = (GLchan *) values;
34 GLuint i;
35 for (i = 0; i < count; i++) {
36 trb->TexImage->FetchTexelc(trb->TexImage, x + i, y, z, rgbaOut + 4 * i);
37 }
38 }
39
40 static void
41 texture_get_values(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
42 const GLint x[], const GLint y[], void *values)
43 {
44 const struct texture_renderbuffer *trb
45 = (const struct texture_renderbuffer *) rb;
46 const GLint z = trb->Zoffset;
47 GLchan *rgbaOut = (GLchan *) values;
48 GLuint i;
49 for (i = 0; i < count; i++) {
50 trb->TexImage->FetchTexelc(trb->TexImage, x[i], y[i], z,
51 rgbaOut + 4 * i);
52 }
53 }
54
55 static void
56 texture_put_row(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
57 GLint x, GLint y, const void *values, const GLubyte *mask)
58 {
59 const struct texture_renderbuffer *trb
60 = (const struct texture_renderbuffer *) rb;
61 const GLint z = trb->Zoffset;
62 const GLchan *rgba = (const GLchan *) values;
63 GLuint i;
64 for (i = 0; i < count; i++) {
65 if (!mask || mask[i]) {
66 trb->Store(trb->TexImage, x + i, y, z, rgba);
67 }
68 rgba += 4;
69 }
70 }
71
72 static void
73 texture_put_mono_row(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
74 GLint x, GLint y, const void *value, const GLubyte *mask)
75 {
76 const struct texture_renderbuffer *trb
77 = (const struct texture_renderbuffer *) rb;
78 const GLint z = trb->Zoffset;
79 const GLchan *rgba = (const GLchan *) value;
80 GLuint i;
81 for (i = 0; i < count; i++) {
82 if (!mask || mask[i]) {
83 trb->Store(trb->TexImage, x + i, y, z, rgba);
84 }
85 }
86 }
87
88 static void
89 texture_put_values(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
90 const GLint x[], const GLint y[], const void *values,
91 const GLubyte *mask)
92 {
93 const struct texture_renderbuffer *trb
94 = (const struct texture_renderbuffer *) rb;
95 const GLint z = trb->Zoffset;
96 const GLchan *rgba = (const GLchan *) values;
97 GLuint i;
98 for (i = 0; i < count; i++) {
99 if (!mask || mask[i]) {
100 trb->Store(trb->TexImage, x[i], y[i], z, rgba);
101 }
102 rgba += 4;
103 }
104 }
105
106 static void
107 texture_put_mono_values(GLcontext *ctx, struct gl_renderbuffer *rb,
108 GLuint count, const GLint x[], const GLint y[],
109 const void *value, const GLubyte *mask)
110 {
111 const struct texture_renderbuffer *trb
112 = (const struct texture_renderbuffer *) rb;
113 const GLint z = trb->Zoffset;
114 const GLchan *rgba = (const GLchan *) value;
115 GLuint i;
116 for (i = 0; i < count; i++) {
117 if (!mask || mask[i]) {
118 trb->Store(trb->TexImage, x[i], y[i], z, rgba);
119 }
120 }
121 }
122
123
124 static void
125 delete_texture_wrapper(struct gl_renderbuffer *rb)
126 {
127 ASSERT(rb->RefCount == 0);
128 _mesa_free(rb);
129 }
130
131
132 /**
133 * If a render buffer attachment specifies a texture image, we'll use
134 * this function to make a gl_renderbuffer wrapper around the texture image.
135 * This allows other parts of Mesa to access the texture image as if it
136 * was a renderbuffer.
137 */
138 static void
139 wrap_texture(GLcontext *ctx, struct gl_renderbuffer_attachment *att)
140 {
141 struct texture_renderbuffer *trb;
142 const GLuint name = 0;
143
144 ASSERT(att->Type == GL_TEXTURE);
145 ASSERT(att->Renderbuffer == NULL);
146 /*
147 ASSERT(att->Complete);
148 */
149
150 trb = CALLOC_STRUCT(texture_renderbuffer);
151 if (!trb) {
152 _mesa_error(ctx, GL_OUT_OF_MEMORY, "wrap_texture");
153 return;
154 }
155
156 _mesa_init_renderbuffer(&trb->Base, name);
157
158 trb->TexImage = att->Texture->Image[att->CubeMapFace][att->TextureLevel];
159 assert(trb->TexImage);
160
161 trb->Store = trb->TexImage->TexFormat->StoreTexel;
162 assert(trb->Store);
163
164 trb->Zoffset = att->Zoffset;
165
166 trb->Base.RefCount = 1;
167 trb->Base.Width = trb->TexImage->Width;
168 trb->Base.Height = trb->TexImage->Height;
169 trb->Base.InternalFormat = trb->TexImage->InternalFormat; /* XXX fix? */
170 trb->Base._BaseFormat = trb->TexImage->TexFormat->BaseFormat;
171 #if 0
172 /* fix/avoid this assertion someday */
173 assert(trb->Base._BaseFormat == GL_RGB ||
174 trb->Base._BaseFormat == GL_RGBA ||
175 trb->Base._BaseFormat == GL_DEPTH_COMPONENT);
176 #endif
177 trb->Base.DataType = GL_UNSIGNED_BYTE; /* XXX fix! */
178 trb->Base.Data = trb->TexImage->Data;
179
180 trb->Base.GetRow = texture_get_row;
181 trb->Base.GetValues = texture_get_values;
182 trb->Base.PutRow = texture_put_row;
183 trb->Base.PutMonoRow = texture_put_mono_row;
184 trb->Base.PutValues = texture_put_values;
185 trb->Base.PutMonoValues = texture_put_mono_values;
186
187 trb->Base.Delete = delete_texture_wrapper;
188 trb->Base.AllocStorage = NULL; /* illegal! */
189
190 /* XXX fix these */
191 trb->Base.RedBits = trb->TexImage->TexFormat->RedBits;
192 trb->Base.GreenBits = trb->TexImage->TexFormat->GreenBits;
193 trb->Base.BlueBits = trb->TexImage->TexFormat->BlueBits;
194 trb->Base.AlphaBits = trb->TexImage->TexFormat->AlphaBits;
195 trb->Base.DepthBits = trb->TexImage->TexFormat->DepthBits;
196
197 att->Renderbuffer = &(trb->Base);
198 }
199
200
201
202 /**
203 * Software fallback for ctx->Driver.RenderbufferTexture.
204 * This is called via the glRenderbufferTexture1D/2D/3D() functions.
205 * If we're unbinding a texture, texObj will be NULL.
206 * The framebuffer of interest is ctx->DrawBuffer.
207 * \sa _mesa_framebuffer_renderbuffer
208 */
209 void
210 _mesa_renderbuffer_texture(GLcontext *ctx,
211 struct gl_renderbuffer_attachment *att,
212 struct gl_texture_object *texObj,
213 GLenum texTarget, GLuint level, GLuint zoffset)
214 {
215 if (texObj) {
216 _mesa_set_texture_attachment(ctx, att, texObj,
217 texTarget, level, zoffset);
218 if (!att->Renderbuffer)
219 wrap_texture(ctx, att);
220 }
221 else {
222 _mesa_remove_attachment(ctx, att);
223 }
224 }