~ubuntu-branches/ubuntu/precise/mesa/precise-updates

« back to all changes in this revision

Viewing changes to src/mesa/state_tracker/st_cb_accum.c

  • Committer: Package Import Robot
  • Author(s): Robert Hooker
  • Date: 2012-02-02 12:05:48 UTC
  • mfrom: (1.7.1) (3.3.27 sid)
  • Revision ID: package-import@ubuntu.com-20120202120548-nvkma85jq0h4coix
Tags: 8.0~rc2-0ubuntu4
Drop drisearchdir handling, it is no longer needed with multiarch
and dri-alternates being removed.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/**************************************************************************
2
 
 * 
3
 
 * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
4
 
 * All Rights Reserved.
5
 
 * 
6
 
 * Permission is hereby granted, free of charge, to any person obtaining a
7
 
 * 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, sub license, 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 portions
16
 
 * of the Software.
17
 
 * 
18
 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19
 
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20
 
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21
 
 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22
 
 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23
 
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24
 
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25
 
 * 
26
 
 **************************************************************************/
27
 
 
28
 
 /*
29
 
  * Authors:
30
 
  *   Brian Paul
31
 
  */
32
 
 
33
 
#include "main/imports.h"
34
 
#include "main/image.h"
35
 
#include "main/macros.h"
36
 
#include "main/mfeatures.h"
37
 
 
38
 
#include "st_debug.h"
39
 
#include "st_context.h"
40
 
#include "st_cb_accum.h"
41
 
#include "st_cb_fbo.h"
42
 
#include "st_texture.h"
43
 
#include "pipe/p_context.h"
44
 
#include "pipe/p_defines.h"
45
 
#include "util/u_format.h"
46
 
#include "util/u_inlines.h"
47
 
#include "util/u_tile.h"
48
 
 
49
 
 
50
 
#if FEATURE_accum
51
 
 
52
 
/**
53
 
 * For hardware that supports deep color buffers, we could accelerate
54
 
 * most/all the accum operations with blending/texturing.
55
 
 * For now, just use the get/put_tile() functions and do things in software.
56
 
 */
57
 
 
58
 
 
59
 
void
60
 
st_clear_accum_buffer(struct gl_context *ctx, struct gl_renderbuffer *rb)
61
 
{
62
 
   struct st_renderbuffer *acc_strb = st_renderbuffer(rb);
63
 
   const GLint xpos = ctx->DrawBuffer->_Xmin;
64
 
   const GLint ypos = ctx->DrawBuffer->_Ymin;
65
 
   const GLint width = ctx->DrawBuffer->_Xmax - xpos;
66
 
   const GLint height = ctx->DrawBuffer->_Ymax - ypos;
67
 
   size_t stride = acc_strb->stride;
68
 
   GLubyte *data = acc_strb->data;
69
 
 
70
 
   if(!data)
71
 
      return;
72
 
   
73
 
   switch (acc_strb->format) {
74
 
   case PIPE_FORMAT_R16G16B16A16_SNORM:
75
 
      {
76
 
         GLshort r = FLOAT_TO_SHORT(ctx->Accum.ClearColor[0]);
77
 
         GLshort g = FLOAT_TO_SHORT(ctx->Accum.ClearColor[1]);
78
 
         GLshort b = FLOAT_TO_SHORT(ctx->Accum.ClearColor[2]);
79
 
         GLshort a = FLOAT_TO_SHORT(ctx->Accum.ClearColor[3]);
80
 
         int i, j;
81
 
         for (i = 0; i < height; i++) {
82
 
            GLshort *dst = (GLshort *) (data + (ypos + i) * stride + xpos * 8);
83
 
            for (j = 0; j < width; j++) {
84
 
               dst[0] = r;
85
 
               dst[1] = g;
86
 
               dst[2] = b;
87
 
               dst[3] = a;
88
 
               dst += 4;
89
 
            }
90
 
         }
91
 
      }
92
 
      break;
93
 
   default:
94
 
      _mesa_problem(ctx, "unexpected format in st_clear_accum_buffer()");
95
 
   }
96
 
}
97
 
 
98
 
 
99
 
/** For ADD/MULT */
100
 
static void
101
 
accum_mad(struct gl_context *ctx, GLfloat scale, GLfloat bias,
102
 
          GLint xpos, GLint ypos, GLint width, GLint height,
103
 
          struct st_renderbuffer *acc_strb)
104
 
{
105
 
   size_t stride = acc_strb->stride;
106
 
   GLubyte *data = acc_strb->data;
107
 
 
108
 
   switch (acc_strb->format) {
109
 
   case PIPE_FORMAT_R16G16B16A16_SNORM:
110
 
      {
111
 
         int i, j;
112
 
         for (i = 0; i < height; i++) {
113
 
            GLshort *acc = (GLshort *) (data + (ypos + i) * stride + xpos * 8);
114
 
            for (j = 0; j < width * 4; j++) {
115
 
               float val = SHORT_TO_FLOAT(*acc) * scale + bias;
116
 
               *acc++ = FLOAT_TO_SHORT(val);
117
 
            }
118
 
         }
119
 
      }
120
 
      break;
121
 
   default:
122
 
      _mesa_problem(NULL, "unexpected format in st_clear_accum_buffer()");
123
 
   }
124
 
}
125
 
 
126
 
 
127
 
static void
128
 
accum_accum(struct st_context *st, GLfloat value,
129
 
            GLint xpos, GLint ypos, GLint width, GLint height,
130
 
            struct st_renderbuffer *acc_strb,
131
 
            struct st_renderbuffer *color_strb)
132
 
{
133
 
   struct pipe_context *pipe = st->pipe;
134
 
   struct pipe_transfer *color_trans;
135
 
   size_t stride = acc_strb->stride;
136
 
   GLubyte *data = acc_strb->data;
137
 
   GLfloat *buf;
138
 
 
139
 
   if (ST_DEBUG & DEBUG_FALLBACK)
140
 
      debug_printf("%s: fallback processing\n", __FUNCTION__);
141
 
 
142
 
   color_trans = pipe_get_transfer(st->pipe,
143
 
                                   color_strb->texture,
144
 
                                   0, 0,
145
 
                                   PIPE_TRANSFER_READ, xpos, ypos,
146
 
                                   width, height);
147
 
 
148
 
   buf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat));
149
 
 
150
 
   pipe_get_tile_rgba_format(pipe, color_trans, 0, 0, width, height,
151
 
                             util_format_linear(color_strb->texture->format),
152
 
                             buf);
153
 
 
154
 
   switch (acc_strb->format) {
155
 
   case PIPE_FORMAT_R16G16B16A16_SNORM:
156
 
      {
157
 
         const GLfloat *color = buf;
158
 
         int i, j;
159
 
         for (i = 0; i < height; i++) {
160
 
            GLshort *acc = (GLshort *) (data + (ypos + i) * stride + xpos * 8);
161
 
            for (j = 0; j < width * 4; j++) {
162
 
               float val = *color++ * value;
163
 
               *acc++ += FLOAT_TO_SHORT(val);
164
 
            }
165
 
         }
166
 
      }
167
 
      break;
168
 
   default:
169
 
      _mesa_problem(NULL, "unexpected format in st_clear_accum_buffer()");
170
 
   }
171
 
 
172
 
   free(buf);
173
 
   pipe->transfer_destroy(pipe, color_trans);
174
 
}
175
 
 
176
 
 
177
 
static void
178
 
accum_load(struct st_context *st, GLfloat value,
179
 
           GLint xpos, GLint ypos, GLint width, GLint height,
180
 
           struct st_renderbuffer *acc_strb,
181
 
           struct st_renderbuffer *color_strb)
182
 
{
183
 
   struct pipe_context *pipe = st->pipe;
184
 
   struct pipe_transfer *color_trans;
185
 
   size_t stride = acc_strb->stride;
186
 
   GLubyte *data = acc_strb->data;
187
 
   GLfloat *buf;
188
 
 
189
 
   if (ST_DEBUG & DEBUG_FALLBACK)
190
 
      debug_printf("%s: fallback processing\n", __FUNCTION__);
191
 
 
192
 
   color_trans = pipe_get_transfer(st->pipe, color_strb->texture,
193
 
                                   0, 0,
194
 
                                   PIPE_TRANSFER_READ, xpos, ypos,
195
 
                                   width, height);
196
 
 
197
 
   buf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat));
198
 
 
199
 
   pipe_get_tile_rgba_format(pipe, color_trans, 0, 0, width, height,
200
 
                             util_format_linear(color_strb->texture->format),
201
 
                             buf);
202
 
 
203
 
   switch (acc_strb->format) {
204
 
   case PIPE_FORMAT_R16G16B16A16_SNORM:
205
 
      {
206
 
         const GLfloat *color = buf;
207
 
         int i, j;
208
 
         for (i = 0; i < height; i++) {
209
 
            GLshort *acc = (GLshort *) (data + (ypos + i) * stride + xpos * 8);
210
 
            for (j = 0; j < width * 4; j++) {
211
 
               float val = *color++ * value;
212
 
               *acc++ = FLOAT_TO_SHORT(val);
213
 
            }
214
 
         }
215
 
      }
216
 
      break;
217
 
   default:
218
 
      _mesa_problem(NULL, "unexpected format in st_clear_accum_buffer()");
219
 
   }
220
 
 
221
 
   free(buf);
222
 
   pipe->transfer_destroy(pipe, color_trans);
223
 
}
224
 
 
225
 
 
226
 
static void
227
 
accum_return(struct gl_context *ctx, GLfloat value,
228
 
             GLint xpos, GLint ypos, GLint width, GLint height,
229
 
             struct st_renderbuffer *acc_strb,
230
 
             struct st_renderbuffer *color_strb)
231
 
{
232
 
   struct pipe_context *pipe = st_context(ctx)->pipe;
233
 
   const GLubyte *colormask = ctx->Color.ColorMask[0];
234
 
   enum pipe_transfer_usage usage;
235
 
   struct pipe_transfer *color_trans;
236
 
   size_t stride = acc_strb->stride;
237
 
   const GLubyte *data = acc_strb->data;
238
 
   GLfloat *buf;
239
 
   enum pipe_format format = util_format_linear(color_strb->texture->format);
240
 
 
241
 
   if (ST_DEBUG & DEBUG_FALLBACK)
242
 
      debug_printf("%s: fallback processing\n", __FUNCTION__);
243
 
 
244
 
   buf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat));
245
 
 
246
 
   if (!colormask[0] || !colormask[1] || !colormask[2] || !colormask[3])
247
 
      usage = PIPE_TRANSFER_READ_WRITE;
248
 
   else
249
 
      usage = PIPE_TRANSFER_WRITE;
250
 
 
251
 
   color_trans = pipe_get_transfer(pipe,
252
 
                                   color_strb->texture, 0, 0,
253
 
                                   usage,
254
 
                                   xpos, ypos,
255
 
                                   width, height);
256
 
 
257
 
   if (usage & PIPE_TRANSFER_READ)
258
 
      pipe_get_tile_rgba_format(pipe, color_trans, 0, 0, width, height,
259
 
                                format, buf);
260
 
 
261
 
   switch (acc_strb->format) {
262
 
   case PIPE_FORMAT_R16G16B16A16_SNORM:
263
 
      {
264
 
         GLfloat *color = buf;
265
 
         int i, j, ch;
266
 
         for (i = 0; i < height; i++) {
267
 
            const GLshort *acc = (const GLshort *) (data + (ypos + i) * stride + xpos * 8);
268
 
            for (j = 0; j < width; j++) {
269
 
               for (ch = 0; ch < 4; ch++) {
270
 
                  if (colormask[ch]) {
271
 
                     GLfloat val = SHORT_TO_FLOAT(*acc * value);
272
 
                     *color = CLAMP(val, 0.0f, 1.0f);
273
 
                  }
274
 
                  else {
275
 
                     /* No change */
276
 
                  }
277
 
                  ++acc;
278
 
                  ++color;
279
 
               }
280
 
            }
281
 
         }
282
 
      }
283
 
      break;
284
 
   default:
285
 
      _mesa_problem(NULL, "unexpected format in st_clear_accum_buffer()");
286
 
   }
287
 
 
288
 
   pipe_put_tile_rgba_format(pipe, color_trans, 0, 0, width, height,
289
 
                             format, buf);
290
 
 
291
 
   free(buf);
292
 
   pipe->transfer_destroy(pipe, color_trans);
293
 
}
294
 
 
295
 
 
296
 
static void
297
 
st_Accum(struct gl_context *ctx, GLenum op, GLfloat value)
298
 
{
299
 
   struct st_context *st = st_context(ctx);
300
 
   struct st_renderbuffer *acc_strb
301
 
     = st_renderbuffer(ctx->DrawBuffer->Attachment[BUFFER_ACCUM].Renderbuffer);
302
 
   struct st_renderbuffer *color_strb
303
 
      = st_renderbuffer(ctx->ReadBuffer->_ColorReadBuffer);
304
 
 
305
 
   const GLint xpos = ctx->DrawBuffer->_Xmin;
306
 
   const GLint ypos = ctx->DrawBuffer->_Ymin;
307
 
   const GLint width = ctx->DrawBuffer->_Xmax - xpos;
308
 
   const GLint height = ctx->DrawBuffer->_Ymax - ypos;
309
 
 
310
 
   if(!acc_strb->data)
311
 
      return;
312
 
   
313
 
   switch (op) {
314
 
   case GL_ADD:
315
 
      if (value != 0.0F) {
316
 
         accum_mad(ctx, 1.0, value, xpos, ypos, width, height, acc_strb);
317
 
      }
318
 
      break;
319
 
   case GL_MULT:
320
 
      if (value != 1.0F) {
321
 
         accum_mad(ctx, value, 0.0, xpos, ypos, width, height, acc_strb);
322
 
      }
323
 
      break;
324
 
   case GL_ACCUM:
325
 
      if (value != 0.0F) {
326
 
         accum_accum(st, value, xpos, ypos, width, height, acc_strb, color_strb);
327
 
      }
328
 
      break;
329
 
   case GL_LOAD:
330
 
      accum_load(st, value, xpos, ypos, width, height, acc_strb, color_strb);
331
 
      break;
332
 
   case GL_RETURN:
333
 
      accum_return(ctx, value, xpos, ypos, width, height, acc_strb, color_strb);
334
 
      break;
335
 
   default:
336
 
      assert(0);
337
 
   }
338
 
}
339
 
 
340
 
 
341
 
 
342
 
void st_init_accum_functions(struct dd_function_table *functions)
343
 
{
344
 
   functions->Accum = st_Accum;
345
 
}
346
 
 
347
 
#endif /* FEATURE_accum */