1/************************************************************************** 2 * 3 * Copyright 2003 VMware, Inc. 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 VMWARE 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#include "main/glheader.h" 29#include "main/image.h" 30#include "main/state.h" 31#include "main/mtypes.h" 32#include "main/condrender.h" 33#include "main/fbobject.h" 34#include "drivers/common/meta.h" 35 36#include "intel_context.h" 37#include "intel_buffers.h" 38#include "intel_mipmap_tree.h" 39#include "intel_regions.h" 40#include "intel_pixel.h" 41#include "intel_fbo.h" 42#include "intel_blit.h" 43 44#define FILE_DEBUG_FLAG DEBUG_PIXEL 45 46/** 47 * CopyPixels with the blitter. Don't support zooming, pixel transfer, etc. 48 */ 49static bool 50do_blit_copypixels(struct gl_context * ctx, 51 GLint srcx, GLint srcy, 52 GLsizei width, GLsizei height, 53 GLint dstx, GLint dsty, GLenum type) 54{ 55 struct intel_context *intel = intel_context(ctx); 56 struct gl_framebuffer *fb = ctx->DrawBuffer; 57 struct gl_framebuffer *read_fb = ctx->ReadBuffer; 58 GLint orig_dstx; 59 GLint orig_dsty; 60 GLint orig_srcx; 61 GLint orig_srcy; 62 struct intel_renderbuffer *draw_irb = NULL; 63 struct intel_renderbuffer *read_irb = NULL; 64 65 /* Update draw buffer bounds */ 66 _mesa_update_state(ctx); 67 68 switch (type) { 69 case GL_COLOR: 70 if (fb->_NumColorDrawBuffers != 1) { 71 perf_debug("glCopyPixels() fallback: MRT\n"); 72 return false; 73 } 74 75 draw_irb = intel_renderbuffer(fb->_ColorDrawBuffers[0]); 76 read_irb = intel_renderbuffer(read_fb->_ColorReadBuffer); 77 break; 78 case GL_DEPTH_STENCIL_EXT: 79 draw_irb = intel_renderbuffer(fb->Attachment[BUFFER_DEPTH].Renderbuffer); 80 read_irb = 81 intel_renderbuffer(read_fb->Attachment[BUFFER_DEPTH].Renderbuffer); 82 break; 83 case GL_DEPTH: 84 perf_debug("glCopyPixels() fallback: GL_DEPTH\n"); 85 return false; 86 case GL_STENCIL: 87 perf_debug("glCopyPixels() fallback: GL_STENCIL\n"); 88 return false; 89 default: 90 perf_debug("glCopyPixels(): Unknown type\n"); 91 return false; 92 } 93 94 if (!draw_irb) { 95 perf_debug("glCopyPixels() fallback: missing draw buffer\n"); 96 return false; 97 } 98 99 if (!read_irb) { 100 perf_debug("glCopyPixels() fallback: missing read buffer\n"); 101 return false; 102 } 103 104 if (ctx->_ImageTransferState) { 105 perf_debug("glCopyPixels(): Unsupported image transfer state\n"); 106 return false; 107 } 108 109 if (ctx->Depth.Test) { 110 perf_debug("glCopyPixels(): Unsupported depth test state\n"); 111 return false; 112 } 113 114 if (ctx->Stencil._Enabled) { 115 perf_debug("glCopyPixels(): Unsupported stencil test state\n"); 116 return false; 117 } 118 119 if (ctx->Fog.Enabled || 120 ctx->Texture._MaxEnabledTexImageUnit != -1 || 121 ctx->FragmentProgram._Enabled) { 122 perf_debug("glCopyPixels(): Unsupported fragment shader state\n"); 123 return false; 124 } 125 126 if (ctx->Color.AlphaEnabled || 127 ctx->Color.BlendEnabled) { 128 perf_debug("glCopyPixels(): Unsupported blend state\n"); 129 return false; 130 } 131 132 if (!ctx->Color.ColorMask[0][0] || 133 !ctx->Color.ColorMask[0][1] || 134 !ctx->Color.ColorMask[0][2] || 135 !ctx->Color.ColorMask[0][3]) { 136 perf_debug("glCopyPixels(): Unsupported color mask state\n"); 137 return false; 138 } 139 140 if (ctx->Pixel.ZoomX != 1.0F || ctx->Pixel.ZoomY != 1.0F) { 141 perf_debug("glCopyPixels(): Unsupported pixel zoom\n"); 142 return false; 143 } 144 145 intel_prepare_render(intel); 146 147 intel_flush(&intel->ctx); 148 149 /* Clip to destination buffer. */ 150 orig_dstx = dstx; 151 orig_dsty = dsty; 152 if (!_mesa_clip_to_region(fb->_Xmin, fb->_Ymin, 153 fb->_Xmax, fb->_Ymax, 154 &dstx, &dsty, &width, &height)) 155 goto out; 156 /* Adjust src coords for our post-clipped destination origin */ 157 srcx += dstx - orig_dstx; 158 srcy += dsty - orig_dsty; 159 160 /* Clip to source buffer. */ 161 orig_srcx = srcx; 162 orig_srcy = srcy; 163 if (!_mesa_clip_to_region(0, 0, 164 read_fb->Width, read_fb->Height, 165 &srcx, &srcy, &width, &height)) 166 goto out; 167 /* Adjust dst coords for our post-clipped source origin */ 168 dstx += srcx - orig_srcx; 169 dsty += srcy - orig_srcy; 170 171 if (!intel_miptree_blit(intel, 172 read_irb->mt, read_irb->mt_level, read_irb->mt_layer, 173 srcx, srcy, _mesa_is_winsys_fbo(read_fb), 174 draw_irb->mt, draw_irb->mt_level, draw_irb->mt_layer, 175 dstx, dsty, _mesa_is_winsys_fbo(fb), 176 width, height, 177 (ctx->Color.ColorLogicOpEnabled ? 178 ctx->Color.LogicOp : GL_COPY))) { 179 DBG("%s: blit failure\n", __func__); 180 return false; 181 } 182 183 if (ctx->Query.CurrentOcclusionObject) 184 ctx->Query.CurrentOcclusionObject->Result += width * height; 185 186out: 187 intel_check_front_buffer_rendering(intel); 188 189 DBG("%s: success\n", __func__); 190 return true; 191} 192 193 194void 195intelCopyPixels(struct gl_context * ctx, 196 GLint srcx, GLint srcy, 197 GLsizei width, GLsizei height, 198 GLint destx, GLint desty, GLenum type) 199{ 200 DBG("%s\n", __func__); 201 202 if (!_mesa_check_conditional_render(ctx)) 203 return; 204 205 if (do_blit_copypixels(ctx, srcx, srcy, width, height, destx, desty, type)) 206 return; 207 208 /* this will use swrast if needed */ 209 _mesa_meta_CopyPixels(ctx, srcx, srcy, width, height, destx, desty, type); 210} 211