Home | History | Annotate | Download | only in i965
      1 /*
      2  Copyright (C) Intel Corp.  2006.  All Rights Reserved.
      3  Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
      4  develop this 3D driver.
      5 
      6  Permission is hereby granted, free of charge, to any person obtaining
      7  a 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, sublicense, 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
     16  portions of the Software.
     17 
     18  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
     19  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     20  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
     21  IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
     22  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
     23  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
     24  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     25 
     26  **********************************************************************/
     27  /*
     28   * Authors:
     29   *   Keith Whitwell <keith (at) tungstengraphics.com>
     30   */
     31 
     32 
     33 #include "main/imports.h"
     34 #include "main/macros.h"
     35 #include "main/simple_list.h"
     36 
     37 #include "vbo/vbo_context.h"
     38 
     39 #include "brw_context.h"
     40 #include "brw_defines.h"
     41 #include "brw_draw.h"
     42 #include "brw_state.h"
     43 
     44 #include "intel_fbo.h"
     45 #include "intel_mipmap_tree.h"
     46 #include "intel_regions.h"
     47 #include "intel_span.h"
     48 #include "intel_tex.h"
     49 #include "intel_tex_obj.h"
     50 
     51 #include "tnl/t_pipeline.h"
     52 #include "glsl/ralloc.h"
     53 
     54 /***************************************
     55  * Mesa's Driver Functions
     56  ***************************************/
     57 
     58 static void brwInitDriverFunctions(struct intel_screen *screen,
     59 				   struct dd_function_table *functions)
     60 {
     61    intelInitDriverFunctions( functions );
     62 
     63    brwInitFragProgFuncs( functions );
     64    brw_init_queryobj_functions(functions);
     65 
     66    functions->BeginTransformFeedback = brw_begin_transform_feedback;
     67 
     68    if (screen->gen >= 7)
     69       functions->EndTransformFeedback = gen7_end_transform_feedback;
     70    else
     71       functions->EndTransformFeedback = brw_end_transform_feedback;
     72 }
     73 
     74 bool
     75 brwCreateContext(int api,
     76 	         const struct gl_config *mesaVis,
     77 		 __DRIcontext *driContextPriv,
     78                  unsigned major_version,
     79                  unsigned minor_version,
     80                  uint32_t flags,
     81                  unsigned *error,
     82 	         void *sharedContextPrivate)
     83 {
     84    __DRIscreen *sPriv = driContextPriv->driScreenPriv;
     85    struct intel_screen *screen = sPriv->driverPrivate;
     86    struct dd_function_table functions;
     87    const unsigned req_version = major_version * 10 + minor_version;
     88    unsigned max_supported_version = 0;
     89    unsigned i;
     90 
     91 #ifdef TEXTURE_FLOAT_ENABLED
     92    bool has_texture_float = true;
     93 #else
     94    bool has_texture_float = false;
     95 #endif
     96 
     97    bool supports_gl30 = has_texture_float &&
     98                         (screen->gen == 6 ||
     99                          (screen->gen == 7 &&
    100                           screen->kernel_has_gen7_sol_reset));
    101 
    102    /* Determine max_supported_version. */
    103    switch (api) {
    104    case API_OPENGL:
    105       max_supported_version = supports_gl30 ? 30 : 21;
    106       break;
    107    case API_OPENGLES:
    108       max_supported_version = 11;
    109       break;
    110    case API_OPENGLES2:
    111       max_supported_version = 20;
    112       break;
    113    case API_OPENGL_CORE:
    114       max_supported_version = supports_gl30 ? 31 : 0;
    115       break;
    116    default:
    117       break;
    118    }
    119 
    120    if (max_supported_version == 0) {
    121       *error = __DRI_CTX_ERROR_BAD_API;
    122       return false;
    123    } else if (req_version > max_supported_version) {
    124       *error = __DRI_CTX_ERROR_BAD_VERSION;
    125       return false;
    126    }
    127 
    128    struct brw_context *brw = rzalloc(NULL, struct brw_context);
    129    if (!brw) {
    130       printf("%s: failed to alloc context\n", __FUNCTION__);
    131       *error = __DRI_CTX_ERROR_NO_MEMORY;
    132       return false;
    133    }
    134 
    135    /* brwInitVtbl needs to know the chipset generation so that it can set the
    136     * right pointers.
    137     */
    138    brw->intel.gen = screen->gen;
    139 
    140    brwInitVtbl( brw );
    141 
    142    brwInitDriverFunctions(screen, &functions);
    143 
    144    struct intel_context *intel = &brw->intel;
    145    struct gl_context *ctx = &intel->ctx;
    146 
    147    if (!intelInitContext( intel, api, mesaVis, driContextPriv,
    148 			  sharedContextPrivate, &functions )) {
    149       printf("%s: failed to init intel context\n", __FUNCTION__);
    150       *error = __DRI_CTX_ERROR_NO_MEMORY;
    151       return false;
    152    }
    153 
    154    brw_init_surface_formats(brw);
    155 
    156    /* Initialize swrast, tnl driver tables: */
    157    intelInitSpanFuncs(ctx);
    158 
    159    TNLcontext *tnl = TNL_CONTEXT(ctx);
    160    if (tnl)
    161       tnl->Driver.RunPipeline = _tnl_run_pipeline;
    162 
    163    ctx->Const.MaxDualSourceDrawBuffers = 1;
    164    ctx->Const.MaxDrawBuffers = BRW_MAX_DRAW_BUFFERS;
    165    ctx->Const.MaxTextureImageUnits = BRW_MAX_TEX_UNIT;
    166    ctx->Const.MaxTextureCoordUnits = 8; /* Mesa limit */
    167    ctx->Const.MaxTextureUnits = MIN2(ctx->Const.MaxTextureCoordUnits,
    168                                      ctx->Const.MaxTextureImageUnits);
    169    ctx->Const.MaxVertexTextureImageUnits = BRW_MAX_TEX_UNIT;
    170    ctx->Const.MaxCombinedTextureImageUnits =
    171       ctx->Const.MaxVertexTextureImageUnits +
    172       ctx->Const.MaxTextureImageUnits;
    173 
    174    ctx->Const.MaxTextureLevels = 14; /* 8192 */
    175    if (ctx->Const.MaxTextureLevels > MAX_TEXTURE_LEVELS)
    176 	   ctx->Const.MaxTextureLevels = MAX_TEXTURE_LEVELS;
    177    ctx->Const.Max3DTextureLevels = 9;
    178    ctx->Const.MaxCubeTextureLevels = 12;
    179 
    180    if (intel->gen >= 7)
    181       ctx->Const.MaxArrayTextureLayers = 2048;
    182    else
    183       ctx->Const.MaxArrayTextureLayers = 512;
    184 
    185    ctx->Const.MaxTextureRectSize = (1<<12);
    186 
    187    ctx->Const.MaxTextureMaxAnisotropy = 16.0;
    188 
    189    /* Hardware only supports a limited number of transform feedback buffers.
    190     * So we need to override the Mesa default (which is based only on software
    191     * limits).
    192     */
    193    ctx->Const.MaxTransformFeedbackBuffers = BRW_MAX_SOL_BUFFERS;
    194 
    195    /* On Gen6, in the worst case, we use up one binding table entry per
    196     * transform feedback component (see comments above the definition of
    197     * BRW_MAX_SOL_BINDINGS, in brw_context.h), so we need to advertise a value
    198     * for MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS equal to
    199     * BRW_MAX_SOL_BINDINGS.
    200     *
    201     * In "separate components" mode, we need to divide this value by
    202     * BRW_MAX_SOL_BUFFERS, so that the total number of binding table entries
    203     * used up by all buffers will not exceed BRW_MAX_SOL_BINDINGS.
    204     */
    205    ctx->Const.MaxTransformFeedbackInterleavedComponents = BRW_MAX_SOL_BINDINGS;
    206    ctx->Const.MaxTransformFeedbackSeparateComponents =
    207       BRW_MAX_SOL_BINDINGS / BRW_MAX_SOL_BUFFERS;
    208 
    209    if (intel->gen == 6)
    210       ctx->Const.MaxSamples = 4;
    211    else if (intel->gen >= 7)
    212       ctx->Const.MaxSamples = 8;
    213 
    214    /* if conformance mode is set, swrast can handle any size AA point */
    215    ctx->Const.MaxPointSizeAA = 255.0;
    216 
    217    /* We want the GLSL compiler to emit code that uses condition codes */
    218    for (i = 0; i <= MESA_SHADER_FRAGMENT; i++) {
    219       ctx->ShaderCompilerOptions[i].MaxIfDepth = intel->gen < 6 ? 16 : UINT_MAX;
    220       ctx->ShaderCompilerOptions[i].EmitCondCodes = true;
    221       ctx->ShaderCompilerOptions[i].EmitNVTempInitialization = true;
    222       ctx->ShaderCompilerOptions[i].EmitNoNoise = true;
    223       ctx->ShaderCompilerOptions[i].EmitNoMainReturn = true;
    224       ctx->ShaderCompilerOptions[i].EmitNoIndirectInput = true;
    225       ctx->ShaderCompilerOptions[i].EmitNoIndirectOutput = true;
    226 
    227       ctx->ShaderCompilerOptions[i].EmitNoIndirectUniform =
    228 	 (i == MESA_SHADER_FRAGMENT);
    229       ctx->ShaderCompilerOptions[i].EmitNoIndirectTemp =
    230 	 (i == MESA_SHADER_FRAGMENT);
    231       ctx->ShaderCompilerOptions[i].LowerClipDistance = true;
    232    }
    233 
    234    ctx->Const.VertexProgram.MaxNativeInstructions = (16 * 1024);
    235    ctx->Const.VertexProgram.MaxAluInstructions = 0;
    236    ctx->Const.VertexProgram.MaxTexInstructions = 0;
    237    ctx->Const.VertexProgram.MaxTexIndirections = 0;
    238    ctx->Const.VertexProgram.MaxNativeAluInstructions = 0;
    239    ctx->Const.VertexProgram.MaxNativeTexInstructions = 0;
    240    ctx->Const.VertexProgram.MaxNativeTexIndirections = 0;
    241    ctx->Const.VertexProgram.MaxNativeAttribs = 16;
    242    ctx->Const.VertexProgram.MaxNativeTemps = 256;
    243    ctx->Const.VertexProgram.MaxNativeAddressRegs = 1;
    244    ctx->Const.VertexProgram.MaxNativeParameters = 1024;
    245    ctx->Const.VertexProgram.MaxEnvParams =
    246       MIN2(ctx->Const.VertexProgram.MaxNativeParameters,
    247 	   ctx->Const.VertexProgram.MaxEnvParams);
    248 
    249    ctx->Const.FragmentProgram.MaxNativeInstructions = (16 * 1024);
    250    ctx->Const.FragmentProgram.MaxNativeAluInstructions = (16 * 1024);
    251    ctx->Const.FragmentProgram.MaxNativeTexInstructions = (16 * 1024);
    252    ctx->Const.FragmentProgram.MaxNativeTexIndirections = (16 * 1024);
    253    ctx->Const.FragmentProgram.MaxNativeAttribs = 12;
    254    ctx->Const.FragmentProgram.MaxNativeTemps = 256;
    255    ctx->Const.FragmentProgram.MaxNativeAddressRegs = 0;
    256    ctx->Const.FragmentProgram.MaxNativeParameters = 1024;
    257    ctx->Const.FragmentProgram.MaxEnvParams =
    258       MIN2(ctx->Const.FragmentProgram.MaxNativeParameters,
    259 	   ctx->Const.FragmentProgram.MaxEnvParams);
    260 
    261    /* Fragment shaders use real, 32-bit twos-complement integers for all
    262     * integer types.
    263     */
    264    ctx->Const.FragmentProgram.LowInt.RangeMin = 31;
    265    ctx->Const.FragmentProgram.LowInt.RangeMax = 30;
    266    ctx->Const.FragmentProgram.LowInt.Precision = 0;
    267    ctx->Const.FragmentProgram.HighInt = ctx->Const.FragmentProgram.MediumInt
    268       = ctx->Const.FragmentProgram.LowInt;
    269 
    270    /* Gen6 converts quads to polygon in beginning of 3D pipeline,
    271       but we're not sure how it's actually done for vertex order,
    272       that affect provoking vertex decision. Always use last vertex
    273       convention for quad primitive which works as expected for now. */
    274    if (intel->gen >= 6)
    275        ctx->Const.QuadsFollowProvokingVertexConvention = false;
    276 
    277    ctx->Const.QueryCounterBits.Timestamp = 36;
    278 
    279    if (intel->is_g4x || intel->gen >= 5) {
    280       brw->CMD_VF_STATISTICS = GM45_3DSTATE_VF_STATISTICS;
    281       brw->CMD_PIPELINE_SELECT = CMD_PIPELINE_SELECT_GM45;
    282       brw->has_surface_tile_offset = true;
    283       if (intel->gen < 6)
    284 	  brw->has_compr4 = true;
    285       brw->has_aa_line_parameters = true;
    286       brw->has_pln = true;
    287   } else {
    288       brw->CMD_VF_STATISTICS = GEN4_3DSTATE_VF_STATISTICS;
    289       brw->CMD_PIPELINE_SELECT = CMD_PIPELINE_SELECT_965;
    290    }
    291 
    292    /* WM maximum threads is number of EUs times number of threads per EU. */
    293    assert(intel->gen <= 7);
    294 
    295    if (intel->is_haswell) {
    296       if (intel->gt == 1) {
    297 	 brw->max_wm_threads = 102;
    298 	 brw->max_vs_threads = 70;
    299 	 brw->urb.size = 128;
    300 	 brw->urb.max_vs_entries = 640;
    301 	 brw->urb.max_gs_entries = 256;
    302       } else if (intel->gt == 2) {
    303 	 brw->max_wm_threads = 204;
    304 	 brw->max_vs_threads = 280;
    305 	 brw->urb.size = 256;
    306 	 brw->urb.max_vs_entries = 1664;
    307 	 brw->urb.max_gs_entries = 640;
    308       }
    309    } else if (intel->gen == 7) {
    310       if (intel->gt == 1) {
    311 	 brw->max_wm_threads = 48;
    312 	 brw->max_vs_threads = 36;
    313 	 brw->max_gs_threads = 36;
    314 	 brw->urb.size = 128;
    315 	 brw->urb.max_vs_entries = 512;
    316 	 brw->urb.max_gs_entries = 192;
    317       } else if (intel->gt == 2) {
    318 	 brw->max_wm_threads = 172;
    319 	 brw->max_vs_threads = 128;
    320 	 brw->max_gs_threads = 128;
    321 	 brw->urb.size = 256;
    322 	 brw->urb.max_vs_entries = 704;
    323 	 brw->urb.max_gs_entries = 320;
    324       } else {
    325 	 assert(!"Unknown gen7 device.");
    326       }
    327    } else if (intel->gen == 6) {
    328       if (intel->gt == 2) {
    329 	 brw->max_wm_threads = 80;
    330 	 brw->max_vs_threads = 60;
    331 	 brw->max_gs_threads = 60;
    332 	 brw->urb.size = 64;            /* volume 5c.5 section 5.1 */
    333 	 brw->urb.max_vs_entries = 256; /* volume 2a (see 3DSTATE_URB) */
    334 	 brw->urb.max_gs_entries = 256;
    335       } else {
    336 	 brw->max_wm_threads = 40;
    337 	 brw->max_vs_threads = 24;
    338 	 brw->max_gs_threads = 21; /* conservative; 24 if rendering disabled */
    339 	 brw->urb.size = 32;            /* volume 5c.5 section 5.1 */
    340 	 brw->urb.max_vs_entries = 256; /* volume 2a (see 3DSTATE_URB) */
    341 	 brw->urb.max_gs_entries = 256;
    342       }
    343       brw->urb.gen6_gs_previously_active = false;
    344    } else if (intel->gen == 5) {
    345       brw->urb.size = 1024;
    346       brw->max_vs_threads = 72;
    347       brw->max_gs_threads = 32;
    348       brw->max_wm_threads = 12 * 6;
    349    } else if (intel->is_g4x) {
    350       brw->urb.size = 384;
    351       brw->max_vs_threads = 32;
    352       brw->max_gs_threads = 2;
    353       brw->max_wm_threads = 10 * 5;
    354    } else if (intel->gen < 6) {
    355       brw->urb.size = 256;
    356       brw->max_vs_threads = 16;
    357       brw->max_gs_threads = 2;
    358       brw->max_wm_threads = 8 * 4;
    359       brw->has_negative_rhw_bug = true;
    360    }
    361 
    362    if (intel->gen <= 7) {
    363       brw->needs_unlit_centroid_workaround = true;
    364    }
    365 
    366    brw->prim_restart.in_progress = false;
    367    brw->prim_restart.enable_cut_index = false;
    368    intel->hw_ctx = drm_intel_gem_context_create(intel->bufmgr);
    369 
    370    brw_init_state( brw );
    371 
    372    brw->curbe.last_buf = calloc(1, 4096);
    373    brw->curbe.next_buf = calloc(1, 4096);
    374 
    375    brw->state.dirty.mesa = ~0;
    376    brw->state.dirty.brw = ~0;
    377 
    378    brw->emit_state_always = 0;
    379 
    380    intel->batch.need_workaround_flush = true;
    381 
    382    ctx->VertexProgram._MaintainTnlProgram = true;
    383    ctx->FragmentProgram._MaintainTexEnvProgram = true;
    384 
    385    brw_draw_init( brw );
    386 
    387    brw->precompile = driQueryOptionb(&intel->optionCache, "shader_precompile");
    388 
    389    ctx->Const.NativeIntegers = true;
    390    ctx->Const.UniformBooleanTrue = 1;
    391 
    392    ctx->Const.ForceGLSLExtensionsWarn = driQueryOptionb(&intel->optionCache, "force_glsl_extensions_warn");
    393 
    394    ctx->Const.ContextFlags = 0;
    395    if ((flags & __DRI_CTX_FLAG_FORWARD_COMPATIBLE) != 0)
    396       ctx->Const.ContextFlags |= GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT;
    397 
    398    if ((flags & __DRI_CTX_FLAG_DEBUG) != 0)
    399       ctx->Const.ContextFlags |= GL_CONTEXT_FLAG_DEBUG_BIT;
    400 
    401    return true;
    402 }
    403 
    404