+ /* Fragment shaders use real, 32-bit twos-complement integers for all
+ * integer types.
+ */
+ ctx->Const.FragmentProgram.LowInt.RangeMin = 31;
+ ctx->Const.FragmentProgram.LowInt.RangeMax = 30;
+ ctx->Const.FragmentProgram.LowInt.Precision = 0;
+ ctx->Const.FragmentProgram.HighInt = ctx->Const.FragmentProgram.LowInt;
+ ctx->Const.FragmentProgram.MediumInt = ctx->Const.FragmentProgram.LowInt;
+
+ /* Gen6 converts quads to polygon in beginning of 3D pipeline,
+ * but we're not sure how it's actually done for vertex order,
+ * that affect provoking vertex decision. Always use last vertex
+ * convention for quad primitive which works as expected for now.
+ */
+ if (brw->gen >= 6)
+ ctx->Const.QuadsFollowProvokingVertexConvention = false;
+
+ ctx->Const.NativeIntegers = true;
+ ctx->Const.UniformBooleanTrue = 1;
+
+ /* From the gen4 PRM, volume 4 page 127:
+ *
+ * "For SURFTYPE_BUFFER non-rendertarget surfaces, this field specifies
+ * the base address of the first element of the surface, computed in
+ * software by adding the surface base address to the byte offset of
+ * the element in the buffer."
+ *
+ * However, unaligned accesses are slower, so enforce buffer alignment.
+ */
+ ctx->Const.UniformBufferOffsetAlignment = 16;
+ ctx->Const.TextureBufferOffsetAlignment = 16;
+
+ if (brw->gen >= 6) {
+ ctx->Const.MaxVarying = 32;
+ ctx->Const.VertexProgram.MaxOutputComponents = 128;
+ ctx->Const.GeometryProgram.MaxInputComponents = 128;
+ ctx->Const.GeometryProgram.MaxOutputComponents = 128;
+ ctx->Const.FragmentProgram.MaxInputComponents = 128;
+ }
+
+ /* We want the GLSL compiler to emit code that uses condition codes */
+ for (int i = 0; i < MESA_SHADER_TYPES; i++) {
+ ctx->ShaderCompilerOptions[i].MaxIfDepth = brw->gen < 6 ? 16 : UINT_MAX;
+ ctx->ShaderCompilerOptions[i].EmitCondCodes = true;
+ ctx->ShaderCompilerOptions[i].EmitNoNoise = true;
+ ctx->ShaderCompilerOptions[i].EmitNoMainReturn = true;
+ ctx->ShaderCompilerOptions[i].EmitNoIndirectInput = true;
+ ctx->ShaderCompilerOptions[i].EmitNoIndirectOutput = true;
+
+ ctx->ShaderCompilerOptions[i].EmitNoIndirectUniform =
+ (i == MESA_SHADER_FRAGMENT);
+ ctx->ShaderCompilerOptions[i].EmitNoIndirectTemp =
+ (i == MESA_SHADER_FRAGMENT);
+ ctx->ShaderCompilerOptions[i].LowerClipDistance = true;
+ }
+
+ ctx->ShaderCompilerOptions[MESA_SHADER_VERTEX].PreferDP4 = true;
+}
+
+/**
+ * Process driconf (drirc) options, setting appropriate context flags.
+ *
+ * intelInitExtensions still pokes at optionCache directly, in order to
+ * avoid advertising various extensions. No flags are set, so it makes
+ * sense to continue doing that there.
+ */
+static void
+brw_process_driconf_options(struct brw_context *brw)
+{
+ struct gl_context *ctx = &brw->ctx;
+
+ driOptionCache *options = &brw->optionCache;
+ driParseConfigFiles(options, &brw->intelScreen->optionCache,
+ brw->driContext->driScreenPriv->myNum, "i965");
+
+ int bo_reuse_mode = driQueryOptioni(options, "bo_reuse");
+ switch (bo_reuse_mode) {
+ case DRI_CONF_BO_REUSE_DISABLED:
+ break;
+ case DRI_CONF_BO_REUSE_ALL:
+ intel_bufmgr_gem_enable_reuse(brw->bufmgr);
+ break;
+ }
+
+ if (!driQueryOptionb(options, "hiz")) {
+ brw->has_hiz = false;
+ /* On gen6, you can only do separate stencil with HIZ. */
+ if (brw->gen == 6)
+ brw->has_separate_stencil = false;
+ }
+
+ if (driQueryOptionb(options, "always_flush_batch")) {
+ fprintf(stderr, "flushing batchbuffer before/after each draw call\n");
+ brw->always_flush_batch = true;
+ }
+
+ if (driQueryOptionb(options, "always_flush_cache")) {
+ fprintf(stderr, "flushing GPU caches before/after each draw call\n");
+ brw->always_flush_cache = true;
+ }
+
+ if (driQueryOptionb(options, "disable_throttling")) {
+ fprintf(stderr, "disabling flush throttling\n");
+ brw->disable_throttling = true;
+ }
+
+ brw->disable_derivative_optimization =
+ driQueryOptionb(&brw->optionCache, "disable_derivative_optimization");
+
+ brw->precompile = driQueryOptionb(&brw->optionCache, "shader_precompile");
+
+ ctx->Const.ForceGLSLExtensionsWarn =
+ driQueryOptionb(options, "force_glsl_extensions_warn");
+
+ ctx->Const.DisableGLSLLineContinuations =
+ driQueryOptionb(options, "disable_glsl_line_continuations");
+}
+
+bool
+brwCreateContext(gl_api api,
+ const struct gl_config *mesaVis,
+ __DRIcontext *driContextPriv,
+ unsigned major_version,
+ unsigned minor_version,
+ uint32_t flags,
+ unsigned *dri_ctx_error,
+ void *sharedContextPrivate)
+{
+ __DRIscreen *sPriv = driContextPriv->driScreenPriv;
+ struct gl_context *shareCtx = (struct gl_context *) sharedContextPrivate;
+ struct intel_screen *screen = sPriv->driverPrivate;
+ const struct brw_device_info *devinfo = screen->devinfo;
+ struct dd_function_table functions;
+ struct gl_config visual;
+
+ struct brw_context *brw = rzalloc(NULL, struct brw_context);
+ if (!brw) {
+ printf("%s: failed to alloc context\n", __FUNCTION__);
+ *dri_ctx_error = __DRI_CTX_ERROR_NO_MEMORY;
+ return false;
+ }
+
+ driContextPriv->driverPrivate = brw;
+ brw->driContext = driContextPriv;
+ brw->intelScreen = screen;
+ brw->bufmgr = screen->bufmgr;
+
+ brw->gen = devinfo->gen;
+ brw->gt = devinfo->gt;
+ brw->is_g4x = devinfo->is_g4x;
+ brw->is_baytrail = devinfo->is_baytrail;
+ brw->is_haswell = devinfo->is_haswell;
+ brw->has_llc = devinfo->has_llc;
+ brw->has_hiz = devinfo->has_hiz_and_separate_stencil;
+ brw->has_separate_stencil = devinfo->has_hiz_and_separate_stencil;
+ brw->has_pln = devinfo->has_pln;
+ brw->has_compr4 = devinfo->has_compr4;
+ brw->has_surface_tile_offset = devinfo->has_surface_tile_offset;
+ brw->has_negative_rhw_bug = devinfo->has_negative_rhw_bug;
+ brw->needs_unlit_centroid_workaround =
+ devinfo->needs_unlit_centroid_workaround;
+
+ brw->must_use_separate_stencil = screen->hw_must_use_separate_stencil;
+ brw->has_swizzling = screen->hw_has_swizzling;
+
+ if (brw->gen >= 7) {
+ gen7_init_vtable_surface_functions(brw);
+ gen7_init_vtable_sampler_functions(brw);
+ brw->vtbl.emit_depth_stencil_hiz = gen7_emit_depth_stencil_hiz;
+ } else {
+ gen4_init_vtable_surface_functions(brw);
+ gen4_init_vtable_sampler_functions(brw);
+ brw->vtbl.emit_depth_stencil_hiz = brw_emit_depth_stencil_hiz;
+ }
+
+ brw_init_driver_functions(brw, &functions);
+
+ struct gl_context *ctx = &brw->ctx;
+
+ if (mesaVis == NULL) {
+ memset(&visual, 0, sizeof visual);
+ mesaVis = &visual;
+ }
+
+ if (!_mesa_initialize_context(ctx, api, mesaVis, shareCtx, &functions)) {
+ *dri_ctx_error = __DRI_CTX_ERROR_NO_MEMORY;
+ printf("%s: failed to init mesa context\n", __FUNCTION__);
+ intelDestroyContext(driContextPriv);
+ return false;
+ }
+
+ /* Initialize the software rasterizer and helper modules.
+ *
+ * As of GL 3.1 core, the gen4+ driver doesn't need the swrast context for
+ * software fallbacks (which we have to support on legacy GL to do weird
+ * glDrawPixels(), glBitmap(), and other functions).
+ */
+ if (api != API_OPENGL_CORE && api != API_OPENGLES2) {
+ _swrast_CreateContext(ctx);
+ }
+
+ _vbo_CreateContext(ctx);
+ if (ctx->swrast_context) {
+ _tnl_CreateContext(ctx);
+ TNL_CONTEXT(ctx)->Driver.RunPipeline = _tnl_run_pipeline;
+ _swsetup_CreateContext(ctx);
+
+ /* Configure swrast to match hardware characteristics: */
+ _swrast_allow_pixel_fog(ctx, false);
+ _swrast_allow_vertex_fog(ctx, true);
+ }
+
+ _mesa_meta_init(ctx);
+
+ brw_process_driconf_options(brw);
+ brw_process_intel_debug_variable(brw);
+ brw_initialize_context_constants(brw);
+
+ /* Reinitialize the context point state. It depends on ctx->Const values. */
+ _mesa_init_point(ctx);
+
+ intelInitExtensions(ctx);
+
+ intel_batchbuffer_init(brw);
+
+ intel_fbo_init(brw);
+
+ if (brw->gen >= 6) {
+ /* Create a new hardware context. Using a hardware context means that
+ * our GPU state will be saved/restored on context switch, allowing us
+ * to assume that the GPU is in the same state we left it in.
+ *
+ * This is required for transform feedback buffer offsets, query objects,
+ * and also allows us to reduce how much state we have to emit.
+ */
+ brw->hw_ctx = drm_intel_gem_context_create(brw->bufmgr);
+
+ if (!brw->hw_ctx) {
+ fprintf(stderr, "Gen6+ requires Kernel 3.6 or later.\n");
+ intelDestroyContext(driContextPriv);
+ return false;
+ }
+ }
+
+ brw_init_surface_formats(brw);
+
+ if (brw->is_g4x || brw->gen >= 5) {
+ brw->CMD_VF_STATISTICS = GM45_3DSTATE_VF_STATISTICS;