1 /* 2 * Copyright 2006 VMware, Inc. 3 * All Rights Reserved. 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the 7 * "Software"), to deal in the Software without restriction, including 8 * without limitation the rights to use, copy, modify, merge, publish, 9 * distribute, sublicense, and/or sell copies of the Software, and to 10 * permit persons to whom the Software is furnished to do so, subject to 11 * the following conditions: 12 * 13 * The above copyright notice and this permission notice (including the 14 * next paragraph) shall be included in all copies or substantial portionsalloc 15 * of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 21 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 22 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 23 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 */ 25 26 #include "main/enums.h" 27 #include "main/image.h" 28 #include "main/glformats.h" 29 #include "main/mtypes.h" 30 #include "main/condrender.h" 31 #include "main/fbobject.h" 32 #include "main/teximage.h" 33 #include "main/texobj.h" 34 #include "main/texstate.h" 35 #include "main/bufferobj.h" 36 #include "swrast/swrast.h" 37 #include "drivers/common/meta.h" 38 39 #include "brw_context.h" 40 #include "intel_screen.h" 41 #include "intel_blit.h" 42 #include "intel_buffers.h" 43 #include "intel_fbo.h" 44 #include "intel_mipmap_tree.h" 45 #include "intel_pixel.h" 46 #include "intel_buffer_objects.h" 47 48 #define FILE_DEBUG_FLAG DEBUG_PIXEL 49 50 static bool 51 do_blit_drawpixels(struct gl_context * ctx, 52 GLint x, GLint y, GLsizei width, GLsizei height, 53 GLenum format, GLenum type, 54 const struct gl_pixelstore_attrib *unpack, 55 const GLvoid * pixels) 56 { 57 struct brw_context *brw = brw_context(ctx); 58 struct intel_buffer_object *src = intel_buffer_object(unpack->BufferObj); 59 GLuint src_offset; 60 drm_intel_bo *src_buffer; 61 62 DBG("%s\n", __func__); 63 64 if (!intel_check_blit_fragment_ops(ctx, false)) 65 return false; 66 67 if (ctx->DrawBuffer->_NumColorDrawBuffers != 1) { 68 DBG("%s: fallback due to MRT\n", __func__); 69 return false; 70 } 71 72 intel_prepare_render(brw); 73 74 struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0]; 75 struct intel_renderbuffer *irb = intel_renderbuffer(rb); 76 77 mesa_format src_format = _mesa_format_from_format_and_type(format, type); 78 if (_mesa_format_is_mesa_array_format(src_format)) 79 src_format = _mesa_format_from_array_format(src_format); 80 mesa_format dst_format = irb->mt->format; 81 82 /* We can safely discard sRGB encode/decode for the DrawPixels interface */ 83 src_format = _mesa_get_srgb_format_linear(src_format); 84 dst_format = _mesa_get_srgb_format_linear(dst_format); 85 86 if (!intel_miptree_blit_compatible_formats(src_format, dst_format)) { 87 DBG("%s: bad format for blit\n", __func__); 88 return false; 89 } 90 91 if (unpack->SwapBytes || unpack->LsbFirst || 92 unpack->SkipPixels || unpack->SkipRows) { 93 DBG("%s: bad packing params\n", __func__); 94 return false; 95 } 96 97 int src_stride = _mesa_image_row_stride(unpack, width, format, type); 98 bool src_flip = false; 99 /* Mesa flips the src_stride for unpack->Invert, but we want our mt to have 100 * a normal src_stride. 101 */ 102 if (unpack->Invert) { 103 src_stride = -src_stride; 104 src_flip = true; 105 } 106 107 src_offset = (GLintptr)pixels; 108 src_offset += _mesa_image_offset(2, unpack, width, height, 109 format, type, 0, 0, 0); 110 111 src_buffer = intel_bufferobj_buffer(brw, src, src_offset, 112 height * src_stride); 113 114 struct intel_mipmap_tree *pbo_mt = 115 intel_miptree_create_for_bo(brw, 116 src_buffer, 117 irb->mt->format, 118 src_offset, 119 width, height, 1, 120 src_stride, 121 0); 122 if (!pbo_mt) 123 return false; 124 125 if (!intel_miptree_blit(brw, 126 pbo_mt, 0, 0, 127 0, 0, src_flip, 128 irb->mt, irb->mt_level, irb->mt_layer, 129 x, y, _mesa_is_winsys_fbo(ctx->DrawBuffer), 130 width, height, GL_COPY)) { 131 DBG("%s: blit failed\n", __func__); 132 intel_miptree_release(&pbo_mt); 133 return false; 134 } 135 136 intel_miptree_release(&pbo_mt); 137 138 if (ctx->Query.CurrentOcclusionObject) 139 ctx->Query.CurrentOcclusionObject->Result += width * height; 140 141 DBG("%s: success\n", __func__); 142 return true; 143 } 144 145 void 146 intelDrawPixels(struct gl_context * ctx, 147 GLint x, GLint y, 148 GLsizei width, GLsizei height, 149 GLenum format, 150 GLenum type, 151 const struct gl_pixelstore_attrib *unpack, 152 const GLvoid * pixels) 153 { 154 struct brw_context *brw = brw_context(ctx); 155 156 if (!_mesa_check_conditional_render(ctx)) 157 return; 158 159 if (format == GL_STENCIL_INDEX) { 160 _swrast_DrawPixels(ctx, x, y, width, height, format, type, 161 unpack, pixels); 162 return; 163 } 164 165 if (_mesa_is_bufferobj(unpack->BufferObj)) { 166 if (do_blit_drawpixels(ctx, x, y, width, height, format, type, unpack, 167 pixels)) { 168 return; 169 } 170 171 perf_debug("%s: fallback to generic code in PBO case\n", __func__); 172 } 173 174 _mesa_meta_DrawPixels(ctx, x, y, width, height, format, type, 175 unpack, pixels); 176 } 177