Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1901 serge 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
 
37
#include "st_debug.h"
38
#include "st_context.h"
39
#include "st_cb_accum.h"
40
#include "st_cb_fbo.h"
41
#include "st_texture.h"
42
#include "pipe/p_context.h"
43
#include "pipe/p_defines.h"
44
#include "util/u_inlines.h"
45
#include "util/u_tile.h"
46
 
47
 
48
#if FEATURE_accum
49
 
50
/**
51
 * For hardware that supports deep color buffers, we could accelerate
52
 * most/all the accum operations with blending/texturing.
53
 * For now, just use the get/put_tile() functions and do things in software.
54
 */
55
 
56
 
57
void
58
st_clear_accum_buffer(struct gl_context *ctx, struct gl_renderbuffer *rb)
59
{
60
   struct st_renderbuffer *acc_strb = st_renderbuffer(rb);
61
   const GLint xpos = ctx->DrawBuffer->_Xmin;
62
   const GLint ypos = ctx->DrawBuffer->_Ymin;
63
   const GLint width = ctx->DrawBuffer->_Xmax - xpos;
64
   const GLint height = ctx->DrawBuffer->_Ymax - ypos;
65
   size_t stride = acc_strb->stride;
66
   GLubyte *data = acc_strb->data;
67
 
68
   if(!data)
69
      return;
70
 
71
   switch (acc_strb->format) {
72
   case PIPE_FORMAT_R16G16B16A16_SNORM:
73
      {
74
         GLshort r = FLOAT_TO_SHORT(ctx->Accum.ClearColor[0]);
75
         GLshort g = FLOAT_TO_SHORT(ctx->Accum.ClearColor[1]);
76
         GLshort b = FLOAT_TO_SHORT(ctx->Accum.ClearColor[2]);
77
         GLshort a = FLOAT_TO_SHORT(ctx->Accum.ClearColor[3]);
78
         int i, j;
79
         for (i = 0; i < height; i++) {
80
            GLshort *dst = (GLshort *) (data + (ypos + i) * stride + xpos * 8);
81
            for (j = 0; j < width; j++) {
82
               dst[0] = r;
83
               dst[1] = g;
84
               dst[2] = b;
85
               dst[3] = a;
86
               dst += 4;
87
            }
88
         }
89
      }
90
      break;
91
   default:
92
      _mesa_problem(ctx, "unexpected format in st_clear_accum_buffer()");
93
   }
94
}
95
 
96
 
97
/** For ADD/MULT */
98
static void
99
accum_mad(struct gl_context *ctx, GLfloat scale, GLfloat bias,
100
          GLint xpos, GLint ypos, GLint width, GLint height,
101
          struct st_renderbuffer *acc_strb)
102
{
103
   size_t stride = acc_strb->stride;
104
   GLubyte *data = acc_strb->data;
105
 
106
   switch (acc_strb->format) {
107
   case PIPE_FORMAT_R16G16B16A16_SNORM:
108
      {
109
         int i, j;
110
         for (i = 0; i < height; i++) {
111
            GLshort *acc = (GLshort *) (data + (ypos + i) * stride + xpos * 8);
112
            for (j = 0; j < width * 4; j++) {
113
               float val = SHORT_TO_FLOAT(*acc) * scale + bias;
114
               *acc++ = FLOAT_TO_SHORT(val);
115
            }
116
         }
117
      }
118
      break;
119
   default:
120
      _mesa_problem(NULL, "unexpected format in st_clear_accum_buffer()");
121
   }
122
}
123
 
124
 
125
static void
126
accum_accum(struct st_context *st, GLfloat value,
127
            GLint xpos, GLint ypos, GLint width, GLint height,
128
            struct st_renderbuffer *acc_strb,
129
            struct st_renderbuffer *color_strb)
130
{
131
   struct pipe_context *pipe = st->pipe;
132
   struct pipe_transfer *color_trans;
133
   size_t stride = acc_strb->stride;
134
   GLubyte *data = acc_strb->data;
135
   GLfloat *buf;
136
 
137
   if (ST_DEBUG & DEBUG_FALLBACK)
138
      debug_printf("%s: fallback processing\n", __FUNCTION__);
139
 
140
   color_trans = pipe_get_transfer(st->pipe,
141
                                   color_strb->texture,
142
                                   0, 0,
143
                                   PIPE_TRANSFER_READ, xpos, ypos,
144
                                   width, height);
145
 
146
   buf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat));
147
 
148
   pipe_get_tile_rgba(pipe, color_trans, 0, 0, width, height, buf);
149
 
150
   switch (acc_strb->format) {
151
   case PIPE_FORMAT_R16G16B16A16_SNORM:
152
      {
153
         const GLfloat *color = buf;
154
         int i, j;
155
         for (i = 0; i < height; i++) {
156
            GLshort *acc = (GLshort *) (data + (ypos + i) * stride + xpos * 8);
157
            for (j = 0; j < width * 4; j++) {
158
               float val = *color++ * value;
159
               *acc++ += FLOAT_TO_SHORT(val);
160
            }
161
         }
162
      }
163
      break;
164
   default:
165
      _mesa_problem(NULL, "unexpected format in st_clear_accum_buffer()");
166
   }
167
 
168
   free(buf);
169
   pipe->transfer_destroy(pipe, color_trans);
170
}
171
 
172
 
173
static void
174
accum_load(struct st_context *st, GLfloat value,
175
           GLint xpos, GLint ypos, GLint width, GLint height,
176
           struct st_renderbuffer *acc_strb,
177
           struct st_renderbuffer *color_strb)
178
{
179
   struct pipe_context *pipe = st->pipe;
180
   struct pipe_transfer *color_trans;
181
   size_t stride = acc_strb->stride;
182
   GLubyte *data = acc_strb->data;
183
   GLfloat *buf;
184
 
185
 
186
   if (ST_DEBUG & DEBUG_FALLBACK)
187
      debug_printf("%s: fallback processing\n", __FUNCTION__);
188
 
189
   color_trans = pipe_get_transfer(st->pipe, color_strb->texture,
190
                                   0, 0,
191
                                   PIPE_TRANSFER_READ, xpos, ypos,
192
                                   width, height);
193
 
194
   buf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat));
195
 
196
   pipe_get_tile_rgba(pipe, color_trans, 0, 0, width, height, buf);
197
 
198
   switch (acc_strb->format) {
199
   case PIPE_FORMAT_R16G16B16A16_SNORM:
200
      {
201
         const GLfloat *color = buf;
202
         int i, j;
203
         for (i = 0; i < height; i++) {
204
            GLshort *acc = (GLshort *) (data + (ypos + i) * stride + xpos * 8);
205
            for (j = 0; j < width * 4; j++) {
206
               float val = *color++ * value;
207
               *acc++ = FLOAT_TO_SHORT(val);
208
            }
209
         }
210
      }
211
      break;
212
   default:
213
      _mesa_problem(NULL, "unexpected format in st_clear_accum_buffer()");
214
   }
215
 
216
   free(buf);
217
   pipe->transfer_destroy(pipe, color_trans);
218
}
219
 
220
 
221
static void
222
accum_return(struct gl_context *ctx, GLfloat value,
223
             GLint xpos, GLint ypos, GLint width, GLint height,
224
             struct st_renderbuffer *acc_strb,
225
             struct st_renderbuffer *color_strb)
226
{
227
   struct pipe_context *pipe = st_context(ctx)->pipe;
228
   const GLubyte *colormask = ctx->Color.ColorMask[0];
229
   enum pipe_transfer_usage usage;
230
   struct pipe_transfer *color_trans;
231
   size_t stride = acc_strb->stride;
232
   const GLubyte *data = acc_strb->data;
233
   GLfloat *buf;
234
 
235
   if (ST_DEBUG & DEBUG_FALLBACK)
236
      debug_printf("%s: fallback processing\n", __FUNCTION__);
237
 
238
   buf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat));
239
 
240
   if (!colormask[0] || !colormask[1] || !colormask[2] || !colormask[3])
241
      usage = PIPE_TRANSFER_READ_WRITE;
242
   else
243
      usage = PIPE_TRANSFER_WRITE;
244
 
245
   color_trans = pipe_get_transfer(st_context(ctx)->pipe,
246
                                   color_strb->texture, 0, 0,
247
                                   usage,
248
                                   xpos, ypos,
249
                                   width, height);
250
 
251
   if (usage & PIPE_TRANSFER_READ)
252
      pipe_get_tile_rgba(pipe, color_trans, 0, 0, width, height, buf);
253
 
254
   switch (acc_strb->format) {
255
   case PIPE_FORMAT_R16G16B16A16_SNORM:
256
      {
257
         GLfloat *color = buf;
258
         int i, j, ch;
259
         for (i = 0; i < height; i++) {
260
            const GLshort *acc = (const GLshort *) (data + (ypos + i) * stride + xpos * 8);
261
            for (j = 0; j < width; j++) {
262
               for (ch = 0; ch < 4; ch++) {
263
                  if (colormask[ch]) {
264
                     GLfloat val = SHORT_TO_FLOAT(*acc * value);
265
                     *color = CLAMP(val, 0.0f, 1.0f);
266
                  }
267
                  else {
268
                     /* No change */
269
                  }
270
                  ++acc;
271
                  ++color;
272
               }
273
            }
274
         }
275
      }
276
      break;
277
   default:
278
      _mesa_problem(NULL, "unexpected format in st_clear_accum_buffer()");
279
   }
280
 
281
   pipe_put_tile_rgba(pipe, color_trans, 0, 0, width, height, buf);
282
 
283
   free(buf);
284
   pipe->transfer_destroy(pipe, color_trans);
285
}
286
 
287
 
288
static void
289
st_Accum(struct gl_context *ctx, GLenum op, GLfloat value)
290
{
291
   struct st_context *st = st_context(ctx);
292
   struct st_renderbuffer *acc_strb
293
     = st_renderbuffer(ctx->DrawBuffer->Attachment[BUFFER_ACCUM].Renderbuffer);
294
   struct st_renderbuffer *color_strb
295
      = st_renderbuffer(ctx->ReadBuffer->_ColorReadBuffer);
296
 
297
   const GLint xpos = ctx->DrawBuffer->_Xmin;
298
   const GLint ypos = ctx->DrawBuffer->_Ymin;
299
   const GLint width = ctx->DrawBuffer->_Xmax - xpos;
300
   const GLint height = ctx->DrawBuffer->_Ymax - ypos;
301
 
302
   if(!acc_strb->data)
303
      return;
304
 
305
   switch (op) {
306
   case GL_ADD:
307
      if (value != 0.0F) {
308
         accum_mad(ctx, 1.0, value, xpos, ypos, width, height, acc_strb);
309
      }
310
      break;
311
   case GL_MULT:
312
      if (value != 1.0F) {
313
         accum_mad(ctx, value, 0.0, xpos, ypos, width, height, acc_strb);
314
      }
315
      break;
316
   case GL_ACCUM:
317
      if (value != 0.0F) {
318
         accum_accum(st, value, xpos, ypos, width, height, acc_strb, color_strb);
319
      }
320
      break;
321
   case GL_LOAD:
322
      accum_load(st, value, xpos, ypos, width, height, acc_strb, color_strb);
323
      break;
324
   case GL_RETURN:
325
      accum_return(ctx, value, xpos, ypos, width, height, acc_strb, color_strb);
326
      break;
327
   default:
328
      assert(0);
329
   }
330
}
331
 
332
 
333
 
334
void st_init_accum_functions(struct dd_function_table *functions)
335
{
336
   functions->Accum = st_Accum;
337
}
338
 
339
#endif /* FEATURE_accum */