Home | History | Annotate | Download | only in i965
      1 /**************************************************************************
      2  *
      3  * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
      4  * Copyright 2011 Intel Corporation
      5  * All Rights Reserved.
      6  *
      7  * Permission is hereby granted, free of charge, to any person obtaining a
      8  * copy of this software and associated documentation files (the
      9  * "Software"), to deal in the Software without restriction, including
     10  * without limitation the rights to use, copy, modify, merge, publish,
     11  * distribute, sub license, and/or sell copies of the Software, and to
     12  * permit persons to whom the Software is furnished to do so, subject to
     13  * the following conditions:
     14  *
     15  * The above copyright notice and this permission notice (including the
     16  * next paragraph) shall be included in all copies or substantial portions
     17  * of the Software.
     18  *
     19  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
     20  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     21  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
     22  * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
     23  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
     24  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
     25  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     26  *
     27  * Authors:
     28  *     Chad Versace <chad (at) chad-versace.us>
     29  *
     30  **************************************************************************/
     31 
     32 #include <stdbool.h>
     33 #include <stdint.h>
     34 #include "main/glheader.h"
     35 #include "main/macros.h"
     36 #include "main/mtypes.h"
     37 #include "main/colormac.h"
     38 #include "main/renderbuffer.h"
     39 
     40 #include "intel_buffers.h"
     41 #include "intel_fbo.h"
     42 #include "intel_mipmap_tree.h"
     43 #include "intel_screen.h"
     44 #include "intel_span.h"
     45 #include "intel_regions.h"
     46 #include "intel_tex.h"
     47 
     48 #include "swrast/swrast.h"
     49 #include "swrast/s_renderbuffer.h"
     50 
     51 /**
     52  * \brief Get pointer offset into stencil buffer.
     53  *
     54  * The stencil buffer is W tiled. Since the GTT is incapable of W fencing, we
     55  * must decode the tile's layout in software.
     56  *
     57  * See
     58  *   - PRM, 2011 Sandy Bridge, Volume 1, Part 2, Section 4.5.2.1 W-Major Tile
     59  *     Format.
     60  *   - PRM, 2011 Sandy Bridge, Volume 1, Part 2, Section 4.5.3 Tiling Algorithm
     61  *
     62  * Even though the returned offset is always positive, the return type is
     63  * signed due to
     64  *    commit e8b1c6d6f55f5be3bef25084fdd8b6127517e137
     65  *    mesa: Fix return type of  _mesa_get_format_bytes() (#37351)
     66  */
     67 intptr_t
     68 intel_offset_S8(uint32_t stride, uint32_t x, uint32_t y, bool swizzled)
     69 {
     70    uint32_t tile_size = 4096;
     71    uint32_t tile_width = 64;
     72    uint32_t tile_height = 64;
     73    uint32_t row_size = 64 * stride;
     74 
     75    uint32_t tile_x = x / tile_width;
     76    uint32_t tile_y = y / tile_height;
     77 
     78    /* The byte's address relative to the tile's base addres. */
     79    uint32_t byte_x = x % tile_width;
     80    uint32_t byte_y = y % tile_height;
     81 
     82    uintptr_t u = tile_y * row_size
     83                + tile_x * tile_size
     84                + 512 * (byte_x / 8)
     85                +  64 * (byte_y / 8)
     86                +  32 * ((byte_y / 4) % 2)
     87                +  16 * ((byte_x / 4) % 2)
     88                +   8 * ((byte_y / 2) % 2)
     89                +   4 * ((byte_x / 2) % 2)
     90                +   2 * (byte_y % 2)
     91                +   1 * (byte_x % 2);
     92 
     93    if (swizzled) {
     94       /* adjust for bit6 swizzling */
     95       if (((byte_x / 8) % 2) == 1) {
     96 	 if (((byte_y / 8) % 2) == 0) {
     97 	    u += 64;
     98 	 } else {
     99 	    u -= 64;
    100 	 }
    101       }
    102    }
    103 
    104    return u;
    105 }
    106 
    107 /**
    108  * Map the regions needed by intelSpanRenderStart().
    109  */
    110 static void
    111 intel_span_map_buffers(struct intel_context *intel)
    112 {
    113    struct gl_context *ctx = &intel->ctx;
    114    struct intel_texture_object *tex_obj;
    115 
    116    for (int i = 0; i < ctx->Const.MaxTextureImageUnits; i++) {
    117       if (!ctx->Texture.Unit[i]._ReallyEnabled)
    118 	 continue;
    119       tex_obj = intel_texture_object(ctx->Texture.Unit[i]._Current);
    120       intel_finalize_mipmap_tree(intel, i);
    121       intel_tex_map_images(intel, tex_obj,
    122 			   GL_MAP_READ_BIT | GL_MAP_WRITE_BIT);
    123    }
    124 
    125    _swrast_map_renderbuffers(ctx);
    126 }
    127 
    128 /**
    129  * Prepare for software rendering.  Map current read/draw framebuffers'
    130  * renderbuffes and all currently bound texture objects.
    131  *
    132  * Old note: Moved locking out to get reasonable span performance.
    133  */
    134 void
    135 intelSpanRenderStart(struct gl_context * ctx)
    136 {
    137    struct intel_context *intel = intel_context(ctx);
    138 
    139    intel_flush(ctx);
    140    intel_prepare_render(intel);
    141    intel_flush(ctx);
    142    intel_span_map_buffers(intel);
    143 }
    144 
    145 /**
    146  * Called when done software rendering.  Unmap the buffers we mapped in
    147  * the above function.
    148  */
    149 void
    150 intelSpanRenderFinish(struct gl_context * ctx)
    151 {
    152    struct intel_context *intel = intel_context(ctx);
    153    GLuint i;
    154 
    155    _swrast_flush(ctx);
    156 
    157    for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++) {
    158       if (ctx->Texture.Unit[i]._ReallyEnabled) {
    159          struct gl_texture_object *texObj = ctx->Texture.Unit[i]._Current;
    160          intel_tex_unmap_images(intel, intel_texture_object(texObj));
    161       }
    162    }
    163 
    164    _swrast_unmap_renderbuffers(ctx);
    165 }
    166 
    167 
    168 void
    169 intelInitSpanFuncs(struct gl_context * ctx)
    170 {
    171    struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference(ctx);
    172    if (swdd) {
    173       swdd->SpanRenderStart = intelSpanRenderStart;
    174       swdd->SpanRenderFinish = intelSpanRenderFinish;
    175    }
    176 }
    177 
    178 void
    179 intel_map_vertex_shader_textures(struct gl_context *ctx)
    180 {
    181    struct intel_context *intel = intel_context(ctx);
    182    int i;
    183 
    184    if (ctx->VertexProgram._Current == NULL)
    185       return;
    186 
    187    for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++) {
    188       if (ctx->Texture.Unit[i]._ReallyEnabled &&
    189 	  ctx->VertexProgram._Current->Base.TexturesUsed[i] != 0) {
    190          struct gl_texture_object *texObj = ctx->Texture.Unit[i]._Current;
    191 
    192          intel_tex_map_images(intel, intel_texture_object(texObj),
    193                               GL_MAP_READ_BIT | GL_MAP_WRITE_BIT);
    194       }
    195    }
    196 }
    197 
    198 void
    199 intel_unmap_vertex_shader_textures(struct gl_context *ctx)
    200 {
    201    struct intel_context *intel = intel_context(ctx);
    202    int i;
    203 
    204    if (ctx->VertexProgram._Current == NULL)
    205       return;
    206 
    207    for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++) {
    208       if (ctx->Texture.Unit[i]._ReallyEnabled &&
    209 	  ctx->VertexProgram._Current->Base.TexturesUsed[i] != 0) {
    210          struct gl_texture_object *texObj = ctx->Texture.Unit[i]._Current;
    211 
    212          intel_tex_unmap_images(intel, intel_texture_object(texObj));
    213       }
    214    }
    215 }
    216