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_context.h"
38
#include "st_texture.h"
39
#include "st_cb_blit.h"
40
#include "st_cb_fbo.h"
41
 
42
#include "util/u_blit.h"
43
#include "util/u_inlines.h"
44
 
45
 
46
void
47
st_init_blit(struct st_context *st)
48
{
49
   st->blit = util_create_blit(st->pipe, st->cso_context);
50
}
51
 
52
 
53
void
54
st_destroy_blit(struct st_context *st)
55
{
56
   util_destroy_blit(st->blit);
57
   st->blit = NULL;
58
}
59
 
60
 
61
#if FEATURE_EXT_framebuffer_blit
62
 
63
static void
64
st_BlitFramebuffer(struct gl_context *ctx,
65
                   GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
66
                   GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
67
                   GLbitfield mask, GLenum filter)
68
{
69
   const GLbitfield depthStencil = (GL_DEPTH_BUFFER_BIT |
70
                                    GL_STENCIL_BUFFER_BIT);
71
   struct st_context *st = st_context(ctx);
72
   const uint pFilter = ((filter == GL_NEAREST)
73
                         ? PIPE_TEX_MIPFILTER_NEAREST
74
                         : PIPE_TEX_MIPFILTER_LINEAR);
75
   struct gl_framebuffer *readFB = ctx->ReadBuffer;
76
   struct gl_framebuffer *drawFB = ctx->DrawBuffer;
77
 
78
   if (!_mesa_clip_blit(ctx, &srcX0, &srcY0, &srcX1, &srcY1,
79
                        &dstX0, &dstY0, &dstX1, &dstY1)) {
80
      return; /* nothing to draw/blit */
81
   }
82
 
83
   if (st_fb_orientation(drawFB) == Y_0_TOP) {
84
      /* invert Y for dest */
85
      dstY0 = drawFB->Height - dstY0;
86
      dstY1 = drawFB->Height - dstY1;
87
   }
88
 
89
   if (st_fb_orientation(readFB) == Y_0_TOP) {
90
      /* invert Y for src */
91
      srcY0 = readFB->Height - srcY0;
92
      srcY1 = readFB->Height - srcY1;
93
   }
94
 
95
   if (srcY0 > srcY1 && dstY0 > dstY1) {
96
      /* Both src and dst are upside down.  Swap Y to make it
97
       * right-side up to increase odds of using a fast path.
98
       * Recall that all Gallium raster coords have Y=0=top.
99
       */
100
      GLint tmp;
101
      tmp = srcY0;
102
      srcY0 = srcY1;
103
      srcY1 = tmp;
104
      tmp = dstY0;
105
      dstY0 = dstY1;
106
      dstY1 = tmp;
107
   }
108
 
109
   if (mask & GL_COLOR_BUFFER_BIT) {
110
      struct gl_renderbuffer_attachment *srcAtt =
111
         &readFB->Attachment[readFB->_ColorReadBufferIndex];
112
 
113
      if(srcAtt->Type == GL_TEXTURE) {
114
         struct st_texture_object *srcObj =
115
            st_texture_object(srcAtt->Texture);
116
         struct st_renderbuffer *dstRb =
117
            st_renderbuffer(drawFB->_ColorDrawBuffers[0]);
118
         struct pipe_surface *dstSurf = dstRb->surface;
119
 
120
         if (!srcObj->pt)
121
            return;
122
 
123
         util_blit_pixels(st->blit, srcObj->pt, srcAtt->TextureLevel,
124
                          srcX0, srcY0, srcX1, srcY1,
125
                          srcAtt->Zoffset + srcAtt->CubeMapFace,
126
                          dstSurf, dstX0, dstY0, dstX1, dstY1,
127
                          0.0, pFilter);
128
      }
129
      else {
130
         struct st_renderbuffer *srcRb =
131
            st_renderbuffer(readFB->_ColorReadBuffer);
132
         struct st_renderbuffer *dstRb =
133
            st_renderbuffer(drawFB->_ColorDrawBuffers[0]);
134
         struct pipe_surface *srcSurf = srcRb->surface;
135
         struct pipe_surface *dstSurf = dstRb->surface;
136
 
137
         util_blit_pixels(st->blit,
138
                          srcRb->texture, srcSurf->u.tex.level,
139
                          srcX0, srcY0, srcX1, srcY1,
140
                          srcSurf->u.tex.first_layer,
141
                          dstSurf, dstX0, dstY0, dstX1, dstY1,
142
                          0.0, pFilter);
143
      }
144
   }
145
 
146
   if (mask & depthStencil) {
147
      /* depth and/or stencil blit */
148
 
149
      /* get src/dst depth surfaces */
150
      struct gl_renderbuffer_attachment *srcDepth =
151
         &readFB->Attachment[BUFFER_DEPTH];
152
      struct gl_renderbuffer_attachment *dstDepth =
153
         &drawFB->Attachment[BUFFER_DEPTH];
154
      struct gl_renderbuffer_attachment *srcStencil =
155
         &readFB->Attachment[BUFFER_STENCIL];
156
      struct gl_renderbuffer_attachment *dstStencil =
157
         &drawFB->Attachment[BUFFER_STENCIL];
158
 
159
      struct st_renderbuffer *srcDepthRb =
160
         st_renderbuffer(readFB->Attachment[BUFFER_DEPTH].Renderbuffer);
161
      struct st_renderbuffer *dstDepthRb =
162
         st_renderbuffer(drawFB->Attachment[BUFFER_DEPTH].Renderbuffer);
163
      struct pipe_surface *dstDepthSurf =
164
         dstDepthRb ? dstDepthRb->surface : NULL;
165
 
166
      if ((mask & depthStencil) == depthStencil &&
167
          st_is_depth_stencil_combined(srcDepth, srcStencil) &&
168
          st_is_depth_stencil_combined(dstDepth, dstStencil)) {
169
 
170
         /* Blitting depth and stencil values between combined
171
          * depth/stencil buffers.  This is the ideal case for such buffers.
172
          */
173
         util_blit_pixels(st->blit,
174
                          srcDepthRb->texture,
175
                          srcDepthRb->surface->u.tex.level,
176
                          srcX0, srcY0, srcX1, srcY1,
177
                          srcDepthRb->surface->u.tex.first_layer,
178
                          dstDepthSurf, dstX0, dstY0, dstX1, dstY1,
179
                          0.0, pFilter);
180
      }
181
      else {
182
         /* blitting depth and stencil separately */
183
 
184
         if (mask & GL_DEPTH_BUFFER_BIT) {
185
            util_blit_pixels(st->blit, srcDepthRb->texture,
186
                             srcDepthRb->surface->u.tex.level,
187
                             srcX0, srcY0, srcX1, srcY1,
188
                             srcDepthRb->surface->u.tex.first_layer,
189
                             dstDepthSurf, dstX0, dstY0, dstX1, dstY1,
190
                             0.0, pFilter);
191
         }
192
 
193
         if (mask & GL_STENCIL_BUFFER_BIT) {
194
            /* blit stencil only */
195
            _mesa_problem(ctx, "st_BlitFramebuffer(STENCIL) not completed");
196
         }
197
      }
198
   }
199
}
200
 
201
 
202
void
203
st_init_blit_functions(struct dd_function_table *functions)
204
{
205
   functions->BlitFramebuffer = st_BlitFramebuffer;
206
}
207
 
208
#endif /* FEATURE_EXT_framebuffer_blit */