static void upload_te_state(struct brw_context *brw) { /* BRW_NEW_TESS_EVAL_PROGRAM */ bool active = brw->tess_eval_program; if (active) assert(brw->tess_ctrl_program); const struct brw_tes_prog_data *tes_prog_data = brw->tes.prog_data; if (active) { BEGIN_BATCH(4); OUT_BATCH(_3DSTATE_TE << 16 | (4 - 2)); OUT_BATCH((tes_prog_data->partitioning << GEN7_TE_PARTITIONING_SHIFT) | (tes_prog_data->output_topology << GEN7_TE_OUTPUT_TOPOLOGY_SHIFT) | (tes_prog_data->domain << GEN7_TE_DOMAIN_SHIFT) | GEN7_TE_ENABLE); OUT_BATCH_F(63.0); OUT_BATCH_F(64.0); ADVANCE_BATCH(); } else { BEGIN_BATCH(4); OUT_BATCH(_3DSTATE_TE << 16 | (4 - 2)); OUT_BATCH(0); OUT_BATCH_F(0); OUT_BATCH_F(0); ADVANCE_BATCH(); } }
static void gen8_blorp_emit_raster_state(struct brw_context *brw) { BEGIN_BATCH(5); OUT_BATCH(_3DSTATE_RASTER << 16 | (5 - 2)); OUT_BATCH(GEN8_RASTER_CULL_NONE); OUT_BATCH_F(0); OUT_BATCH_F(0); OUT_BATCH_F(0); ADVANCE_BATCH(); }
static void upload_blend_constant_color(struct brw_context *brw) { struct gl_context *ctx = &brw->ctx; BEGIN_BATCH(5); OUT_BATCH(_3DSTATE_BLEND_CONSTANT_COLOR << 16 | (5-2)); OUT_BATCH_F(ctx->Color.BlendColorUnclamped[0]); OUT_BATCH_F(ctx->Color.BlendColorUnclamped[1]); OUT_BATCH_F(ctx->Color.BlendColorUnclamped[2]); OUT_BATCH_F(ctx->Color.BlendColorUnclamped[3]); CACHED_BATCH(); }
void brw_upload_invariant_state(struct brw_context *brw) { /* 3DSTATE_SIP, 3DSTATE_MULTISAMPLE, etc. are nonpipelined. */ if (brw->gen == 6) intel_emit_post_sync_nonzero_flush(brw); /* Select the 3D pipeline (as opposed to media) */ BEGIN_BATCH(1); OUT_BATCH(brw->CMD_PIPELINE_SELECT << 16 | 0); ADVANCE_BATCH(); if (brw->gen < 6) { /* Disable depth offset clamping. */ BEGIN_BATCH(2); OUT_BATCH(_3DSTATE_GLOBAL_DEPTH_OFFSET_CLAMP << 16 | (2 - 2)); OUT_BATCH_F(0.0); ADVANCE_BATCH(); } BEGIN_BATCH(2); OUT_BATCH(CMD_STATE_SIP << 16 | (2 - 2)); OUT_BATCH(0); ADVANCE_BATCH(); BEGIN_BATCH(1); OUT_BATCH(brw->CMD_VF_STATISTICS << 16 | (unlikely(INTEL_DEBUG & DEBUG_STATS) ? 1 : 0)); ADVANCE_BATCH(); }
static void upload_invariant_state( struct brw_context *brw ) { struct intel_context *intel = &brw->intel; /* 3DSTATE_SIP, 3DSTATE_MULTISAMPLE, etc. are nonpipelined. */ if (intel->gen == 6) intel_emit_post_sync_nonzero_flush(intel); /* Select the 3D pipeline (as opposed to media) */ BEGIN_BATCH(1); OUT_BATCH(brw->CMD_PIPELINE_SELECT << 16 | 0); ADVANCE_BATCH(); if (intel->gen < 6) { /* Disable depth offset clamping. */ BEGIN_BATCH(2); OUT_BATCH(_3DSTATE_GLOBAL_DEPTH_OFFSET_CLAMP << 16 | (2 - 2)); OUT_BATCH_F(0.0); ADVANCE_BATCH(); } if (intel->gen == 6) { int i; for (i = 0; i < 4; i++) { BEGIN_BATCH(4); OUT_BATCH(_3DSTATE_GS_SVB_INDEX << 16 | (4 - 2)); OUT_BATCH(i << SVB_INDEX_SHIFT); OUT_BATCH(0); OUT_BATCH(0xffffffff); ADVANCE_BATCH(); } } BEGIN_BATCH(2); OUT_BATCH(CMD_STATE_SIP << 16 | (2 - 2)); OUT_BATCH(0); ADVANCE_BATCH(); BEGIN_BATCH(1); OUT_BATCH(brw->CMD_VF_STATISTICS << 16 | (unlikely(INTEL_DEBUG & DEBUG_STATS) ? 1 : 0)); ADVANCE_BATCH(); }
void brw_upload_invariant_state(struct brw_context *brw) { const bool is_965 = brw->gen == 4 && !brw->is_g4x; /* 3DSTATE_SIP, 3DSTATE_MULTISAMPLE, etc. are nonpipelined. */ if (brw->gen == 6) intel_emit_post_sync_nonzero_flush(brw); /* Select the 3D pipeline (as opposed to media) */ const uint32_t _3DSTATE_PIPELINE_SELECT = is_965 ? CMD_PIPELINE_SELECT_965 : CMD_PIPELINE_SELECT_GM45; BEGIN_BATCH(1); OUT_BATCH(_3DSTATE_PIPELINE_SELECT << 16 | 0); ADVANCE_BATCH(); if (brw->gen < 6) { /* Disable depth offset clamping. */ BEGIN_BATCH(2); OUT_BATCH(_3DSTATE_GLOBAL_DEPTH_OFFSET_CLAMP << 16 | (2 - 2)); OUT_BATCH_F(0.0); ADVANCE_BATCH(); } if (brw->gen >= 8) { BEGIN_BATCH(3); OUT_BATCH(CMD_STATE_SIP << 16 | (3 - 2)); OUT_BATCH(0); OUT_BATCH(0); ADVANCE_BATCH(); } else { BEGIN_BATCH(2); OUT_BATCH(CMD_STATE_SIP << 16 | (2 - 2)); OUT_BATCH(0); ADVANCE_BATCH(); } const uint32_t _3DSTATE_VF_STATISTICS = is_965 ? GEN4_3DSTATE_VF_STATISTICS : GM45_3DSTATE_VF_STATISTICS; BEGIN_BATCH(1); OUT_BATCH(_3DSTATE_VF_STATISTICS << 16 | (unlikely(INTEL_DEBUG & DEBUG_STATS) ? 1 : 0)); ADVANCE_BATCH(); }
static void upload_raster(struct brw_context *brw) { struct gl_context *ctx = &brw->ctx; uint32_t dw1 = 0; /* _NEW_BUFFERS */ bool render_to_fbo = _mesa_is_user_fbo(brw->ctx.DrawBuffer); /* _NEW_POLYGON */ if (ctx->Polygon._FrontBit == render_to_fbo) dw1 |= GEN8_RASTER_FRONT_WINDING_CCW; if (ctx->Polygon.CullFlag) { switch (ctx->Polygon.CullFaceMode) { case GL_FRONT: dw1 |= GEN8_RASTER_CULL_FRONT; break; case GL_BACK: dw1 |= GEN8_RASTER_CULL_BACK; break; case GL_FRONT_AND_BACK: dw1 |= GEN8_RASTER_CULL_BOTH; break; default: unreachable("not reached"); } } else { dw1 |= GEN8_RASTER_CULL_NONE; } /* _NEW_POINT */ if (ctx->Point.SmoothFlag) dw1 |= GEN8_RASTER_SMOOTH_POINT_ENABLE; if (_mesa_is_multisample_enabled(ctx)) dw1 |= GEN8_RASTER_API_MULTISAMPLE_ENABLE; if (ctx->Polygon.OffsetFill) dw1 |= GEN6_SF_GLOBAL_DEPTH_OFFSET_SOLID; if (ctx->Polygon.OffsetLine) dw1 |= GEN6_SF_GLOBAL_DEPTH_OFFSET_WIREFRAME; if (ctx->Polygon.OffsetPoint) dw1 |= GEN6_SF_GLOBAL_DEPTH_OFFSET_POINT; switch (ctx->Polygon.FrontMode) { case GL_FILL: dw1 |= GEN6_SF_FRONT_SOLID; break; case GL_LINE: dw1 |= GEN6_SF_FRONT_WIREFRAME; break; case GL_POINT: dw1 |= GEN6_SF_FRONT_POINT; break; default: unreachable("not reached"); } switch (ctx->Polygon.BackMode) { case GL_FILL: dw1 |= GEN6_SF_BACK_SOLID; break; case GL_LINE: dw1 |= GEN6_SF_BACK_WIREFRAME; break; case GL_POINT: dw1 |= GEN6_SF_BACK_POINT; break; default: unreachable("not reached"); } /* _NEW_LINE */ if (ctx->Line.SmoothFlag) dw1 |= GEN8_RASTER_LINE_AA_ENABLE; /* _NEW_SCISSOR */ if (ctx->Scissor.EnableFlags) dw1 |= GEN8_RASTER_SCISSOR_ENABLE; /* _NEW_TRANSFORM */ if (!ctx->Transform.DepthClamp) { if (brw->gen >= 9) { dw1 |= GEN9_RASTER_VIEWPORT_Z_NEAR_CLIP_TEST_ENABLE | GEN9_RASTER_VIEWPORT_Z_FAR_CLIP_TEST_ENABLE; } else { dw1 |= GEN8_RASTER_VIEWPORT_Z_CLIP_TEST_ENABLE; } } BEGIN_BATCH(5); OUT_BATCH(_3DSTATE_RASTER << 16 | (5 - 2)); OUT_BATCH(dw1); OUT_BATCH_F(ctx->Polygon.OffsetUnits * 2); /* constant. copied from gen4 */ OUT_BATCH_F(ctx->Polygon.OffsetFactor); /* scale */ OUT_BATCH_F(ctx->Polygon.OffsetClamp); /* global depth offset clamp */ ADVANCE_BATCH(); }
static void upload_sf_state(struct brw_context *brw) { struct gl_context *ctx = &brw->ctx; /* CACHE_NEW_WM_PROG */ uint32_t num_outputs = brw->wm.prog_data->num_varying_inputs; uint32_t dw1, dw2, dw3, dw4; uint32_t point_sprite_enables; uint32_t flat_enables; int i; /* _NEW_BUFFER */ bool render_to_fbo = _mesa_is_user_fbo(ctx->DrawBuffer); bool multisampled_fbo = ctx->DrawBuffer->Visual.samples > 1; const int urb_entry_read_offset = BRW_SF_URB_ENTRY_READ_OFFSET; float point_size; uint16_t attr_overrides[16]; uint32_t point_sprite_origin; dw1 = GEN6_SF_SWIZZLE_ENABLE | num_outputs << GEN6_SF_NUM_OUTPUTS_SHIFT; dw2 = GEN6_SF_STATISTICS_ENABLE | GEN6_SF_VIEWPORT_TRANSFORM_ENABLE; dw3 = 0; dw4 = 0; /* _NEW_POLYGON */ if ((ctx->Polygon.FrontFace == GL_CCW) ^ render_to_fbo) dw2 |= GEN6_SF_WINDING_CCW; if (ctx->Polygon.OffsetFill) dw2 |= GEN6_SF_GLOBAL_DEPTH_OFFSET_SOLID; if (ctx->Polygon.OffsetLine) dw2 |= GEN6_SF_GLOBAL_DEPTH_OFFSET_WIREFRAME; if (ctx->Polygon.OffsetPoint) dw2 |= GEN6_SF_GLOBAL_DEPTH_OFFSET_POINT; switch (ctx->Polygon.FrontMode) { case GL_FILL: dw2 |= GEN6_SF_FRONT_SOLID; break; case GL_LINE: dw2 |= GEN6_SF_FRONT_WIREFRAME; break; case GL_POINT: dw2 |= GEN6_SF_FRONT_POINT; break; default: assert(0); break; } switch (ctx->Polygon.BackMode) { case GL_FILL: dw2 |= GEN6_SF_BACK_SOLID; break; case GL_LINE: dw2 |= GEN6_SF_BACK_WIREFRAME; break; case GL_POINT: dw2 |= GEN6_SF_BACK_POINT; break; default: assert(0); break; } /* _NEW_SCISSOR */ if (ctx->Scissor.Enabled) dw3 |= GEN6_SF_SCISSOR_ENABLE; /* _NEW_POLYGON */ if (ctx->Polygon.CullFlag) { switch (ctx->Polygon.CullFaceMode) { case GL_FRONT: dw3 |= GEN6_SF_CULL_FRONT; break; case GL_BACK: dw3 |= GEN6_SF_CULL_BACK; break; case GL_FRONT_AND_BACK: dw3 |= GEN6_SF_CULL_BOTH; break; default: assert(0); break; } } else { dw3 |= GEN6_SF_CULL_NONE; } /* _NEW_LINE */ { uint32_t line_width_u3_7 = U_FIXED(CLAMP(ctx->Line.Width, 0.0, 7.99), 7); /* TODO: line width of 0 is not allowed when MSAA enabled */ if (line_width_u3_7 == 0) line_width_u3_7 = 1; dw3 |= line_width_u3_7 << GEN6_SF_LINE_WIDTH_SHIFT; } if (ctx->Line.SmoothFlag) { dw3 |= GEN6_SF_LINE_AA_ENABLE; dw3 |= GEN6_SF_LINE_AA_MODE_TRUE; dw3 |= GEN6_SF_LINE_END_CAP_WIDTH_1_0; } /* _NEW_MULTISAMPLE */ if (multisampled_fbo && ctx->Multisample.Enabled) dw3 |= GEN6_SF_MSRAST_ON_PATTERN; /* _NEW_PROGRAM | _NEW_POINT */ if (!(ctx->VertexProgram.PointSizeEnabled || ctx->Point._Attenuated)) dw4 |= GEN6_SF_USE_STATE_POINT_WIDTH; /* Clamp to ARB_point_parameters user limits */ point_size = CLAMP(ctx->Point.Size, ctx->Point.MinSize, ctx->Point.MaxSize); /* Clamp to the hardware limits and convert to fixed point */ dw4 |= U_FIXED(CLAMP(point_size, 0.125, 255.875), 3); /* * Window coordinates in an FBO are inverted, which means point * sprite origin must be inverted, too. */ if ((ctx->Point.SpriteOrigin == GL_LOWER_LEFT) != render_to_fbo) { point_sprite_origin = GEN6_SF_POINT_SPRITE_LOWERLEFT; } else { point_sprite_origin = GEN6_SF_POINT_SPRITE_UPPERLEFT; } dw1 |= point_sprite_origin; /* _NEW_LIGHT */ if (ctx->Light.ProvokingVertex != GL_FIRST_VERTEX_CONVENTION) { dw4 |= (2 << GEN6_SF_TRI_PROVOKE_SHIFT) | (2 << GEN6_SF_TRIFAN_PROVOKE_SHIFT) | (1 << GEN6_SF_LINE_PROVOKE_SHIFT); } else { dw4 |= (1 << GEN6_SF_TRIFAN_PROVOKE_SHIFT); } /* BRW_NEW_VUE_MAP_GEOM_OUT | _NEW_POINT | _NEW_LIGHT | _NEW_PROGRAM | * CACHE_NEW_WM_PROG */ uint32_t urb_entry_read_length; calculate_attr_overrides(brw, attr_overrides, &point_sprite_enables, &flat_enables, &urb_entry_read_length); dw1 |= (urb_entry_read_length << GEN6_SF_URB_ENTRY_READ_LENGTH_SHIFT | urb_entry_read_offset << GEN6_SF_URB_ENTRY_READ_OFFSET_SHIFT); BEGIN_BATCH(20); OUT_BATCH(_3DSTATE_SF << 16 | (20 - 2)); OUT_BATCH(dw1); OUT_BATCH(dw2); OUT_BATCH(dw3); OUT_BATCH(dw4); OUT_BATCH_F(ctx->Polygon.OffsetUnits * 2); /* constant. copied from gen4 */ OUT_BATCH_F(ctx->Polygon.OffsetFactor); /* scale */ OUT_BATCH_F(0.0); /* XXX: global depth offset clamp */ for (i = 0; i < 8; i++) { OUT_BATCH(attr_overrides[i * 2] | attr_overrides[i * 2 + 1] << 16); } OUT_BATCH(point_sprite_enables); /* dw16 */ OUT_BATCH(flat_enables); OUT_BATCH(0); /* wrapshortest enables 0-7 */ OUT_BATCH(0); /* wrapshortest enables 8-15 */ ADVANCE_BATCH(); }
static void upload_sf_state(struct brw_context *brw) { struct intel_context *intel = &brw->intel; struct gl_context *ctx = &intel->ctx; uint32_t dw1, dw2, dw3; float point_size; /* _NEW_BUFFERS */ bool render_to_fbo = _mesa_is_user_fbo(brw->intel.ctx.DrawBuffer); bool multisampled_fbo = ctx->DrawBuffer->Visual.samples > 1; dw1 = GEN6_SF_STATISTICS_ENABLE | GEN6_SF_VIEWPORT_TRANSFORM_ENABLE; /* _NEW_BUFFERS */ dw1 |= (brw_depthbuffer_format(brw) << GEN7_SF_DEPTH_BUFFER_SURFACE_FORMAT_SHIFT); /* _NEW_POLYGON */ if ((ctx->Polygon.FrontFace == GL_CCW) ^ render_to_fbo) dw1 |= GEN6_SF_WINDING_CCW; if (ctx->Polygon.OffsetFill) dw1 |= GEN6_SF_GLOBAL_DEPTH_OFFSET_SOLID; if (ctx->Polygon.OffsetLine) dw1 |= GEN6_SF_GLOBAL_DEPTH_OFFSET_WIREFRAME; if (ctx->Polygon.OffsetPoint) dw1 |= GEN6_SF_GLOBAL_DEPTH_OFFSET_POINT; switch (ctx->Polygon.FrontMode) { case GL_FILL: dw1 |= GEN6_SF_FRONT_SOLID; break; case GL_LINE: dw1 |= GEN6_SF_FRONT_WIREFRAME; break; case GL_POINT: dw1 |= GEN6_SF_FRONT_POINT; break; default: assert(0); break; } switch (ctx->Polygon.BackMode) { case GL_FILL: dw1 |= GEN6_SF_BACK_SOLID; break; case GL_LINE: dw1 |= GEN6_SF_BACK_WIREFRAME; break; case GL_POINT: dw1 |= GEN6_SF_BACK_POINT; break; default: assert(0); break; } dw2 = 0; if (ctx->Polygon.CullFlag) { switch (ctx->Polygon.CullFaceMode) { case GL_FRONT: dw2 |= GEN6_SF_CULL_FRONT; break; case GL_BACK: dw2 |= GEN6_SF_CULL_BACK; break; case GL_FRONT_AND_BACK: dw2 |= GEN6_SF_CULL_BOTH; break; default: assert(0); break; } } else { dw2 |= GEN6_SF_CULL_NONE; } /* _NEW_SCISSOR */ if (ctx->Scissor.Enabled) dw2 |= GEN6_SF_SCISSOR_ENABLE; /* _NEW_LINE */ { uint32_t line_width_u3_7 = U_FIXED(CLAMP(ctx->Line.Width, 0.0, 7.99), 7); /* TODO: line width of 0 is not allowed when MSAA enabled */ if (line_width_u3_7 == 0) line_width_u3_7 = 1; dw2 |= line_width_u3_7 << GEN6_SF_LINE_WIDTH_SHIFT; } if (ctx->Line.SmoothFlag) { dw2 |= GEN6_SF_LINE_AA_ENABLE; dw2 |= GEN6_SF_LINE_END_CAP_WIDTH_1_0; } if (ctx->Line.StippleFlag && intel->is_haswell) { dw2 |= HSW_SF_LINE_STIPPLE_ENABLE; } /* _NEW_MULTISAMPLE */ if (multisampled_fbo && ctx->Multisample.Enabled) dw2 |= GEN6_SF_MSRAST_ON_PATTERN; /* FINISHME: Last Pixel Enable? Vertex Sub Pixel Precision Select? */ dw3 = GEN6_SF_LINE_AA_MODE_TRUE; /* _NEW_PROGRAM | _NEW_POINT */ if (!(ctx->VertexProgram.PointSizeEnabled || ctx->Point._Attenuated)) dw3 |= GEN6_SF_USE_STATE_POINT_WIDTH; /* Clamp to ARB_point_parameters user limits */ point_size = CLAMP(ctx->Point.Size, ctx->Point.MinSize, ctx->Point.MaxSize); /* Clamp to the hardware limits and convert to fixed point */ dw3 |= U_FIXED(CLAMP(point_size, 0.125, 255.875), 3); /* _NEW_LIGHT */ if (ctx->Light.ProvokingVertex != GL_FIRST_VERTEX_CONVENTION) { dw3 |= (2 << GEN6_SF_TRI_PROVOKE_SHIFT) | (2 << GEN6_SF_TRIFAN_PROVOKE_SHIFT) | (1 << GEN6_SF_LINE_PROVOKE_SHIFT); } else { dw3 |= (1 << GEN6_SF_TRIFAN_PROVOKE_SHIFT); } BEGIN_BATCH(7); OUT_BATCH(_3DSTATE_SF << 16 | (7 - 2)); OUT_BATCH(dw1); OUT_BATCH(dw2); OUT_BATCH(dw3); OUT_BATCH_F(ctx->Polygon.OffsetUnits * 2); /* constant. copied from gen4 */ OUT_BATCH_F(ctx->Polygon.OffsetFactor); /* scale */ OUT_BATCH_F(0.0); /* XXX: global depth offset clamp */ ADVANCE_BATCH(); }
void I915DisplayVideoTextured(ScrnInfoPtr scrn, intel_adaptor_private *adaptor_priv, int id, RegionPtr dstRegion, short width, short height, int video_pitch, int video_pitch2, short src_w, short src_h, short drw_w, short drw_h, PixmapPtr pixmap) { intel_screen_private *intel = intel_get_screen_private(scrn); uint32_t format, ms3, s5, tiling; BoxPtr pbox = REGION_RECTS(dstRegion); int nbox_total = REGION_NUM_RECTS(dstRegion); int nbox_this_time; int dxo, dyo, pix_xoff, pix_yoff; PixmapPtr target; #if 0 ErrorF("I915DisplayVideo: %dx%d (pitch %d)\n", width, height, video_pitch); #endif dxo = dstRegion->extents.x1; dyo = dstRegion->extents.y1; if (pixmap->drawable.width > 2048 || pixmap->drawable.height > 2048 || !intel_uxa_check_pitch_3d(pixmap)) { ScreenPtr screen = pixmap->drawable.pScreen; target = screen->CreatePixmap(screen, dstRegion->extents.x2 - dxo, dstRegion->extents.y2 - dyo, pixmap->drawable.depth, CREATE_PIXMAP_USAGE_SCRATCH); if (target == NULL) return; if (intel_uxa_get_pixmap_bo(target) == NULL) { screen->DestroyPixmap(target); return; } pix_xoff = -dxo; pix_yoff = -dyo; } else { target = pixmap; /* Set up the offset for translating from the given region * (in screen coordinates) to the backing pixmap. */ #ifdef COMPOSITE pix_xoff = -target->screen_x + target->drawable.x; pix_yoff = -target->screen_y + target->drawable.y; #else pix_xoff = 0; pix_yoff = 0; #endif } #define BYTES_FOR_BOXES(n) ((200 + (n) * 20) * 4) #define BOXES_IN_BYTES(s) ((((s)/4) - 200) / 20) #define BATCH_BYTES(p) ((p)->batch_bo->size - 16) while (nbox_total) { nbox_this_time = nbox_total; if (BYTES_FOR_BOXES(nbox_this_time) > BATCH_BYTES(intel)) nbox_this_time = BOXES_IN_BYTES(BATCH_BYTES(intel)); nbox_total -= nbox_this_time; intel_batch_start_atomic(scrn, 200 + 20 * nbox_this_time); IntelEmitInvarientState(scrn); intel->last_3d = LAST_3D_VIDEO; /* draw rect -- just clipping */ OUT_BATCH(_3DSTATE_DRAW_RECT_CMD); OUT_BATCH(DRAW_DITHER_OFS_X(pixmap->drawable.x & 3) | DRAW_DITHER_OFS_Y(pixmap->drawable.y & 3)); OUT_BATCH(0x00000000); /* ymin, xmin */ /* ymax, xmax */ OUT_BATCH((target->drawable.width - 1) | (target->drawable.height - 1) << 16); OUT_BATCH(0x00000000); /* yorigin, xorigin */ OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(2) | I1_LOAD_S(5) | I1_LOAD_S(6) | 2); OUT_BATCH(S2_TEXCOORD_FMT(0, TEXCOORDFMT_2D) | S2_TEXCOORD_FMT(1, TEXCOORDFMT_NOT_PRESENT) | S2_TEXCOORD_FMT(2, TEXCOORDFMT_NOT_PRESENT) | S2_TEXCOORD_FMT(3, TEXCOORDFMT_NOT_PRESENT) | S2_TEXCOORD_FMT(4, TEXCOORDFMT_NOT_PRESENT) | S2_TEXCOORD_FMT(5, TEXCOORDFMT_NOT_PRESENT) | S2_TEXCOORD_FMT(6, TEXCOORDFMT_NOT_PRESENT) | S2_TEXCOORD_FMT(7, TEXCOORDFMT_NOT_PRESENT)); s5 = 0x0; if (intel->cpp == 2) s5 |= S5_COLOR_DITHER_ENABLE; OUT_BATCH(s5); /* S5 - enable bits */ OUT_BATCH((2 << S6_DEPTH_TEST_FUNC_SHIFT) | (2 << S6_CBUF_SRC_BLEND_FACT_SHIFT) | (1 << S6_CBUF_DST_BLEND_FACT_SHIFT) | S6_COLOR_WRITE_ENABLE | (2 << S6_TRISTRIP_PV_SHIFT)); OUT_BATCH(_3DSTATE_CONST_BLEND_COLOR_CMD); OUT_BATCH(0x00000000); OUT_BATCH(_3DSTATE_DST_BUF_VARS_CMD); if (intel->cpp == 2) format = COLR_BUF_RGB565; else format = COLR_BUF_ARGB8888 | DEPTH_FRMT_24_FIXED_8_OTHER; OUT_BATCH(LOD_PRECLAMP_OGL | DSTORG_HORT_BIAS(0x8) | DSTORG_VERT_BIAS(0x8) | format); /* front buffer, pitch, offset */ if (intel_uxa_pixmap_tiled(target)) { tiling = BUF_3D_TILED_SURFACE; if (intel_uxa_get_pixmap_private(target)->tiling == I915_TILING_Y) tiling |= BUF_3D_TILE_WALK_Y; } else tiling = 0; OUT_BATCH(_3DSTATE_BUF_INFO_CMD); OUT_BATCH(BUF_3D_ID_COLOR_BACK | tiling | BUF_3D_PITCH(intel_pixmap_pitch(target))); OUT_RELOC_PIXMAP(target, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0); if (!is_planar_fourcc(id)) { FS_LOCALS(); OUT_BATCH(_3DSTATE_PIXEL_SHADER_CONSTANTS | 4); OUT_BATCH(0x0000001); /* constant 0 */ /* constant 0: brightness/contrast */ OUT_BATCH_F(adaptor_priv->brightness / 128.0); OUT_BATCH_F(adaptor_priv->contrast / 255.0); OUT_BATCH_F(0.0); OUT_BATCH_F(0.0); OUT_BATCH(_3DSTATE_SAMPLER_STATE | 3); OUT_BATCH(0x00000001); OUT_BATCH(SS2_COLORSPACE_CONVERSION | (FILTER_LINEAR << SS2_MAG_FILTER_SHIFT) | (FILTER_LINEAR << SS2_MIN_FILTER_SHIFT)); OUT_BATCH((TEXCOORDMODE_CLAMP_EDGE << SS3_TCX_ADDR_MODE_SHIFT) | (TEXCOORDMODE_CLAMP_EDGE << SS3_TCY_ADDR_MODE_SHIFT) | (0 << SS3_TEXTUREMAP_INDEX_SHIFT) | SS3_NORMALIZED_COORDS); OUT_BATCH(0x00000000); OUT_BATCH(_3DSTATE_MAP_STATE | 3); OUT_BATCH(0x00000001); /* texture map #1 */ if (adaptor_priv->buf) OUT_RELOC(adaptor_priv->buf, I915_GEM_DOMAIN_SAMPLER, 0, adaptor_priv->YBufOffset); else OUT_BATCH(adaptor_priv->YBufOffset); ms3 = MAPSURF_422; switch (id) { case FOURCC_YUY2: ms3 |= MT_422_YCRCB_NORMAL; break; case FOURCC_UYVY: ms3 |= MT_422_YCRCB_SWAPY; break; } ms3 |= (height - 1) << MS3_HEIGHT_SHIFT; ms3 |= (width - 1) << MS3_WIDTH_SHIFT; OUT_BATCH(ms3); OUT_BATCH(((video_pitch / 4) - 1) << MS4_PITCH_SHIFT); FS_BEGIN(); i915_fs_dcl(FS_S0); i915_fs_dcl(FS_T0); i915_fs_texld(FS_OC, FS_S0, FS_T0); if (adaptor_priv->brightness != 0) { i915_fs_add(FS_OC, i915_fs_operand_reg(FS_OC), i915_fs_operand(FS_C0, X, X, X, ZERO)); } FS_END(); } else { FS_LOCALS(); /* For the planar formats, we set up three samplers -- * one for each plane, in a Y8 format. Because I * couldn't get the special PLANAR_TO_PACKED * shader setup to work, I did the manual pixel shader: * * y' = y - .0625 * u' = u - .5 * v' = v - .5; * * r = 1.1643 * y' + 0.0 * u' + 1.5958 * v' * g = 1.1643 * y' - 0.39173 * u' - 0.81290 * v' * b = 1.1643 * y' + 2.017 * u' + 0.0 * v' * * register assignment: * r0 = (y',u',v',0) * r1 = (y,y,y,y) * r2 = (u,u,u,u) * r3 = (v,v,v,v) * OC = (r,g,b,1) */ OUT_BATCH(_3DSTATE_PIXEL_SHADER_CONSTANTS | (22 - 2)); OUT_BATCH(0x000001f); /* constants 0-4 */ /* constant 0: normalization offsets */ OUT_BATCH_F(-0.0625); OUT_BATCH_F(-0.5); OUT_BATCH_F(-0.5); OUT_BATCH_F(0.0); /* constant 1: r coefficients */ OUT_BATCH_F(1.1643); OUT_BATCH_F(0.0); OUT_BATCH_F(1.5958); OUT_BATCH_F(0.0); /* constant 2: g coefficients */ OUT_BATCH_F(1.1643); OUT_BATCH_F(-0.39173); OUT_BATCH_F(-0.81290); OUT_BATCH_F(0.0); /* constant 3: b coefficients */ OUT_BATCH_F(1.1643); OUT_BATCH_F(2.017); OUT_BATCH_F(0.0); OUT_BATCH_F(0.0); /* constant 4: brightness/contrast */ OUT_BATCH_F(adaptor_priv->brightness / 128.0); OUT_BATCH_F(adaptor_priv->contrast / 255.0); OUT_BATCH_F(0.0); OUT_BATCH_F(0.0); OUT_BATCH(_3DSTATE_SAMPLER_STATE | 9); OUT_BATCH(0x00000007); /* sampler 0 */ OUT_BATCH((FILTER_LINEAR << SS2_MAG_FILTER_SHIFT) | (FILTER_LINEAR << SS2_MIN_FILTER_SHIFT)); OUT_BATCH((TEXCOORDMODE_CLAMP_EDGE << SS3_TCX_ADDR_MODE_SHIFT) | (TEXCOORDMODE_CLAMP_EDGE << SS3_TCY_ADDR_MODE_SHIFT) | (0 << SS3_TEXTUREMAP_INDEX_SHIFT) | SS3_NORMALIZED_COORDS); OUT_BATCH(0x00000000); /* sampler 1 */ OUT_BATCH((FILTER_LINEAR << SS2_MAG_FILTER_SHIFT) | (FILTER_LINEAR << SS2_MIN_FILTER_SHIFT)); OUT_BATCH((TEXCOORDMODE_CLAMP_EDGE << SS3_TCX_ADDR_MODE_SHIFT) | (TEXCOORDMODE_CLAMP_EDGE << SS3_TCY_ADDR_MODE_SHIFT) | (1 << SS3_TEXTUREMAP_INDEX_SHIFT) | SS3_NORMALIZED_COORDS); OUT_BATCH(0x00000000); /* sampler 2 */ OUT_BATCH((FILTER_LINEAR << SS2_MAG_FILTER_SHIFT) | (FILTER_LINEAR << SS2_MIN_FILTER_SHIFT)); OUT_BATCH((TEXCOORDMODE_CLAMP_EDGE << SS3_TCX_ADDR_MODE_SHIFT) | (TEXCOORDMODE_CLAMP_EDGE << SS3_TCY_ADDR_MODE_SHIFT) | (2 << SS3_TEXTUREMAP_INDEX_SHIFT) | SS3_NORMALIZED_COORDS); OUT_BATCH(0x00000000); OUT_BATCH(_3DSTATE_MAP_STATE | 9); OUT_BATCH(0x00000007); if (adaptor_priv->buf) OUT_RELOC(adaptor_priv->buf, I915_GEM_DOMAIN_SAMPLER, 0, adaptor_priv->YBufOffset); else OUT_BATCH(adaptor_priv->YBufOffset); ms3 = MAPSURF_8BIT | MT_8BIT_I8; ms3 |= (height - 1) << MS3_HEIGHT_SHIFT; ms3 |= (width - 1) << MS3_WIDTH_SHIFT; OUT_BATCH(ms3); /* check to see if Y has special pitch than normal * double u/v pitch, e.g i915 XvMC hw requires at * least 1K alignment, so Y pitch might * be same as U/V's.*/ if (video_pitch2) OUT_BATCH(((video_pitch2 / 4) - 1) << MS4_PITCH_SHIFT); else OUT_BATCH(((video_pitch * 2 / 4) - 1) << MS4_PITCH_SHIFT); if (adaptor_priv->buf) OUT_RELOC(adaptor_priv->buf, I915_GEM_DOMAIN_SAMPLER, 0, adaptor_priv->UBufOffset); else OUT_BATCH(adaptor_priv->UBufOffset); ms3 = MAPSURF_8BIT | MT_8BIT_I8; ms3 |= (height / 2 - 1) << MS3_HEIGHT_SHIFT; ms3 |= (width / 2 - 1) << MS3_WIDTH_SHIFT; OUT_BATCH(ms3); OUT_BATCH(((video_pitch / 4) - 1) << MS4_PITCH_SHIFT); if (adaptor_priv->buf) OUT_RELOC(adaptor_priv->buf, I915_GEM_DOMAIN_SAMPLER, 0, adaptor_priv->VBufOffset); else OUT_BATCH(adaptor_priv->VBufOffset); ms3 = MAPSURF_8BIT | MT_8BIT_I8; ms3 |= (height / 2 - 1) << MS3_HEIGHT_SHIFT; ms3 |= (width / 2 - 1) << MS3_WIDTH_SHIFT; OUT_BATCH(ms3); OUT_BATCH(((video_pitch / 4) - 1) << MS4_PITCH_SHIFT); FS_BEGIN(); /* Declare samplers */ i915_fs_dcl(FS_S0); /* Y */ i915_fs_dcl(FS_S1); /* U */ i915_fs_dcl(FS_S2); /* V */ i915_fs_dcl(FS_T0); /* normalized coords */ /* Load samplers to temporaries. */ i915_fs_texld(FS_R1, FS_S0, FS_T0); i915_fs_texld(FS_R2, FS_S1, FS_T0); i915_fs_texld(FS_R3, FS_S2, FS_T0); /* Move the sampled YUV data in R[123] to the first * 3 channels of R0. */ i915_fs_mov_masked(FS_R0, MASK_X, i915_fs_operand_reg(FS_R1)); i915_fs_mov_masked(FS_R0, MASK_Y, i915_fs_operand_reg(FS_R2)); i915_fs_mov_masked(FS_R0, MASK_Z, i915_fs_operand_reg(FS_R3)); /* Normalize the YUV data */ i915_fs_add(FS_R0, i915_fs_operand_reg(FS_R0), i915_fs_operand_reg(FS_C0)); /* dot-product the YUV data in R0 by the vectors of * coefficients for calculating R, G, and B, storing * the results in the R, G, or B channels of the output * color. The OC results are implicitly clamped * at the end of the program. */ i915_fs_dp3(FS_OC, MASK_X, i915_fs_operand_reg(FS_R0), i915_fs_operand_reg(FS_C1)); i915_fs_dp3(FS_OC, MASK_Y, i915_fs_operand_reg(FS_R0), i915_fs_operand_reg(FS_C2)); i915_fs_dp3(FS_OC, MASK_Z, i915_fs_operand_reg(FS_R0), i915_fs_operand_reg(FS_C3)); /* Set alpha of the output to 1.0, by wiring W to 1 * and not actually using the source. */ i915_fs_mov_masked(FS_OC, MASK_W, i915_fs_operand_one()); if (adaptor_priv->brightness != 0) { i915_fs_add(FS_OC, i915_fs_operand_reg(FS_OC), i915_fs_operand(FS_C4, X, X, X, ZERO)); } FS_END(); } OUT_BATCH(PRIM3D_RECTLIST | (12 * nbox_this_time - 1)); while (nbox_this_time--) { int box_x1 = pbox->x1; int box_y1 = pbox->y1; int box_x2 = pbox->x2; int box_y2 = pbox->y2; float src_scale_x, src_scale_y; pbox++; src_scale_x = ((float)src_w / width) / drw_w; src_scale_y = ((float)src_h / height) / drw_h; /* vertex data - rect list consists of bottom right, * bottom left, and top left vertices. */ /* bottom right */ OUT_BATCH_F(box_x2 + pix_xoff); OUT_BATCH_F(box_y2 + pix_yoff); OUT_BATCH_F((box_x2 - dxo) * src_scale_x); OUT_BATCH_F((box_y2 - dyo) * src_scale_y); /* bottom left */ OUT_BATCH_F(box_x1 + pix_xoff); OUT_BATCH_F(box_y2 + pix_yoff); OUT_BATCH_F((box_x1 - dxo) * src_scale_x); OUT_BATCH_F((box_y2 - dyo) * src_scale_y); /* top left */ OUT_BATCH_F(box_x1 + pix_xoff); OUT_BATCH_F(box_y1 + pix_yoff); OUT_BATCH_F((box_x1 - dxo) * src_scale_x); OUT_BATCH_F((box_y1 - dyo) * src_scale_y); } intel_batch_end_atomic(scrn); } if (target != pixmap) { GCPtr gc; gc = GetScratchGC(pixmap->drawable.depth, pixmap->drawable.pScreen); if (gc) { gc->subWindowMode = ClipByChildren; if (REGION_NUM_RECTS(dstRegion) > 1) { RegionPtr tmp; tmp = REGION_CREATE(pixmap->drawable.pScreen, NULL, 0); if (tmp) { REGION_COPY(pixmap->drawable.pScreen, tmp, dstRegion); gc->funcs->ChangeClip(gc, CT_REGION, tmp, 0); } } ValidateGC(&pixmap->drawable, gc); gc->ops->CopyArea(&target->drawable, &pixmap->drawable, gc, 0, 0, target->drawable.width, target->drawable.height, -pix_xoff, -pix_yoff); FreeScratchGC(gc); } target->drawable.pScreen->DestroyPixmap(target); } intel_uxa_debug_flush(scrn); }
static void upload_sf_state(struct brw_context *brw) { struct intel_context *intel = &brw->intel; struct gl_context *ctx = &intel->ctx; uint32_t urb_entry_read_length; /* BRW_NEW_FRAGMENT_PROGRAM */ uint32_t num_outputs = _mesa_bitcount_64(brw->fragment_program->Base.InputsRead); /* _NEW_LIGHT */ bool shade_model_flat = ctx->Light.ShadeModel == GL_FLAT; uint32_t dw1, dw2, dw3, dw4, dw16, dw17; int i; /* _NEW_BUFFER */ bool render_to_fbo = brw->intel.ctx.DrawBuffer->Name != 0; int attr = 0, input_index = 0; int urb_entry_read_offset = 1; float point_size; uint16_t attr_overrides[FRAG_ATTRIB_MAX]; uint32_t point_sprite_origin; /* CACHE_NEW_VS_PROG */ urb_entry_read_length = ((brw->vs.prog_data->vue_map.num_slots + 1) / 2 - urb_entry_read_offset); if (urb_entry_read_length == 0) { /* Setting the URB entry read length to 0 causes undefined behavior, so * if we have no URB data to read, set it to 1. */ urb_entry_read_length = 1; } dw1 = GEN6_SF_SWIZZLE_ENABLE | num_outputs << GEN6_SF_NUM_OUTPUTS_SHIFT | urb_entry_read_length << GEN6_SF_URB_ENTRY_READ_LENGTH_SHIFT | urb_entry_read_offset << GEN6_SF_URB_ENTRY_READ_OFFSET_SHIFT; dw2 = GEN6_SF_STATISTICS_ENABLE | GEN6_SF_VIEWPORT_TRANSFORM_ENABLE; dw3 = 0; dw4 = 0; dw16 = 0; dw17 = 0; /* _NEW_POLYGON */ if ((ctx->Polygon.FrontFace == GL_CCW) ^ render_to_fbo) dw2 |= GEN6_SF_WINDING_CCW; if (ctx->Polygon.OffsetFill) dw2 |= GEN6_SF_GLOBAL_DEPTH_OFFSET_SOLID; if (ctx->Polygon.OffsetLine) dw2 |= GEN6_SF_GLOBAL_DEPTH_OFFSET_WIREFRAME; if (ctx->Polygon.OffsetPoint) dw2 |= GEN6_SF_GLOBAL_DEPTH_OFFSET_POINT; switch (ctx->Polygon.FrontMode) { case GL_FILL: dw2 |= GEN6_SF_FRONT_SOLID; break; case GL_LINE: dw2 |= GEN6_SF_FRONT_WIREFRAME; break; case GL_POINT: dw2 |= GEN6_SF_FRONT_POINT; break; default: assert(0); break; } switch (ctx->Polygon.BackMode) { case GL_FILL: dw2 |= GEN6_SF_BACK_SOLID; break; case GL_LINE: dw2 |= GEN6_SF_BACK_WIREFRAME; break; case GL_POINT: dw2 |= GEN6_SF_BACK_POINT; break; default: assert(0); break; } /* _NEW_SCISSOR */ if (ctx->Scissor.Enabled) dw3 |= GEN6_SF_SCISSOR_ENABLE; /* _NEW_POLYGON */ if (ctx->Polygon.CullFlag) { switch (ctx->Polygon.CullFaceMode) { case GL_FRONT: dw3 |= GEN6_SF_CULL_FRONT; break; case GL_BACK: dw3 |= GEN6_SF_CULL_BACK; break; case GL_FRONT_AND_BACK: dw3 |= GEN6_SF_CULL_BOTH; break; default: assert(0); break; } } else { dw3 |= GEN6_SF_CULL_NONE; } /* _NEW_LINE */ dw3 |= U_FIXED(CLAMP(ctx->Line.Width, 0.0, 7.99), 7) << GEN6_SF_LINE_WIDTH_SHIFT; if (ctx->Line.SmoothFlag) { dw3 |= GEN6_SF_LINE_AA_ENABLE; dw3 |= GEN6_SF_LINE_AA_MODE_TRUE; dw3 |= GEN6_SF_LINE_END_CAP_WIDTH_1_0; } /* _NEW_PROGRAM | _NEW_POINT */ if (!(ctx->VertexProgram.PointSizeEnabled || ctx->Point._Attenuated)) dw4 |= GEN6_SF_USE_STATE_POINT_WIDTH; /* Clamp to ARB_point_parameters user limits */ point_size = CLAMP(ctx->Point.Size, ctx->Point.MinSize, ctx->Point.MaxSize); /* Clamp to the hardware limits and convert to fixed point */ dw4 |= U_FIXED(CLAMP(point_size, 0.125, 255.875), 3); /* * Window coordinates in an FBO are inverted, which means point * sprite origin must be inverted, too. */ if ((ctx->Point.SpriteOrigin == GL_LOWER_LEFT) != render_to_fbo) { point_sprite_origin = GEN6_SF_POINT_SPRITE_LOWERLEFT; } else { point_sprite_origin = GEN6_SF_POINT_SPRITE_UPPERLEFT; } dw1 |= point_sprite_origin; /* _NEW_LIGHT */ if (ctx->Light.ProvokingVertex != GL_FIRST_VERTEX_CONVENTION) { dw4 |= (2 << GEN6_SF_TRI_PROVOKE_SHIFT) | (2 << GEN6_SF_TRIFAN_PROVOKE_SHIFT) | (1 << GEN6_SF_LINE_PROVOKE_SHIFT); } else { dw4 |= (1 << GEN6_SF_TRIFAN_PROVOKE_SHIFT); } /* Create the mapping from the FS inputs we produce to the VS outputs * they source from. */ for (; attr < FRAG_ATTRIB_MAX; attr++) { enum glsl_interp_qualifier interp_qualifier = brw->fragment_program->InterpQualifier[attr]; bool is_gl_Color = attr == FRAG_ATTRIB_COL0 || attr == FRAG_ATTRIB_COL1; if (!(brw->fragment_program->Base.InputsRead & BITFIELD64_BIT(attr))) continue; /* _NEW_POINT */ if (ctx->Point.PointSprite && (attr >= FRAG_ATTRIB_TEX0 && attr <= FRAG_ATTRIB_TEX7) && ctx->Point.CoordReplace[attr - FRAG_ATTRIB_TEX0]) { dw16 |= (1 << input_index); } if (attr == FRAG_ATTRIB_PNTC) dw16 |= (1 << input_index); /* flat shading */ if (interp_qualifier == INTERP_QUALIFIER_FLAT || (shade_model_flat && is_gl_Color && interp_qualifier == INTERP_QUALIFIER_NONE)) dw17 |= (1 << input_index); /* The hardware can only do the overrides on 16 overrides at a * time, and the other up to 16 have to be lined up so that the * input index = the output index. We'll need to do some * tweaking to make sure that's the case. */ assert(input_index < 16 || attr == input_index); /* CACHE_NEW_VS_PROG | _NEW_LIGHT | _NEW_PROGRAM */ attr_overrides[input_index++] = get_attr_override(&brw->vs.prog_data->vue_map, urb_entry_read_offset, attr, ctx->VertexProgram._TwoSideEnabled); } for (; input_index < FRAG_ATTRIB_MAX; input_index++) attr_overrides[input_index] = 0; BEGIN_BATCH(20); OUT_BATCH(_3DSTATE_SF << 16 | (20 - 2)); OUT_BATCH(dw1); OUT_BATCH(dw2); OUT_BATCH(dw3); OUT_BATCH(dw4); OUT_BATCH_F(ctx->Polygon.OffsetUnits * 2); /* constant. copied from gen4 */ OUT_BATCH_F(ctx->Polygon.OffsetFactor); /* scale */ OUT_BATCH_F(0.0); /* XXX: global depth offset clamp */ for (i = 0; i < 8; i++) { OUT_BATCH(attr_overrides[i * 2] | attr_overrides[i * 2 + 1] << 16); } OUT_BATCH(dw16); /* point sprite texcoord bitmask */ OUT_BATCH(dw17); /* constant interp bitmask */ OUT_BATCH(0); /* wrapshortest enables 0-7 */ OUT_BATCH(0); /* wrapshortest enables 8-15 */ ADVANCE_BATCH(); }
static void upload_sf_state(struct brw_context *brw) { struct gl_context *ctx = &brw->ctx; uint32_t dw1, dw2, dw3; float point_size; /* _NEW_BUFFERS */ bool render_to_fbo = _mesa_is_user_fbo(ctx->DrawBuffer); const bool multisampled_fbo = _mesa_geometric_samples(ctx->DrawBuffer) > 1; dw1 = GEN6_SF_STATISTICS_ENABLE; if (brw->sf.viewport_transform_enable) dw1 |= GEN6_SF_VIEWPORT_TRANSFORM_ENABLE; /* _NEW_BUFFERS */ dw1 |= (brw_depthbuffer_format(brw) << GEN7_SF_DEPTH_BUFFER_SURFACE_FORMAT_SHIFT); /* _NEW_POLYGON */ if (ctx->Polygon._FrontBit == render_to_fbo) dw1 |= GEN6_SF_WINDING_CCW; if (ctx->Polygon.OffsetFill) dw1 |= GEN6_SF_GLOBAL_DEPTH_OFFSET_SOLID; if (ctx->Polygon.OffsetLine) dw1 |= GEN6_SF_GLOBAL_DEPTH_OFFSET_WIREFRAME; if (ctx->Polygon.OffsetPoint) dw1 |= GEN6_SF_GLOBAL_DEPTH_OFFSET_POINT; switch (ctx->Polygon.FrontMode) { case GL_FILL: dw1 |= GEN6_SF_FRONT_SOLID; break; case GL_LINE: dw1 |= GEN6_SF_FRONT_WIREFRAME; break; case GL_POINT: dw1 |= GEN6_SF_FRONT_POINT; break; default: unreachable("not reached"); } switch (ctx->Polygon.BackMode) { case GL_FILL: dw1 |= GEN6_SF_BACK_SOLID; break; case GL_LINE: dw1 |= GEN6_SF_BACK_WIREFRAME; break; case GL_POINT: dw1 |= GEN6_SF_BACK_POINT; break; default: unreachable("not reached"); } dw2 = 0; if (ctx->Polygon.CullFlag) { switch (ctx->Polygon.CullFaceMode) { case GL_FRONT: dw2 |= GEN6_SF_CULL_FRONT; break; case GL_BACK: dw2 |= GEN6_SF_CULL_BACK; break; case GL_FRONT_AND_BACK: dw2 |= GEN6_SF_CULL_BOTH; break; default: unreachable("not reached"); } } else { dw2 |= GEN6_SF_CULL_NONE; } /* _NEW_SCISSOR _NEW_POLYGON BRW_NEW_GEOMETRY_PROGRAM BRW_NEW_PRIMITIVE */ if (ctx->Scissor.EnableFlags || is_drawing_points(brw) || is_drawing_lines(brw)) dw2 |= GEN6_SF_SCISSOR_ENABLE; /* _NEW_LINE */ { uint32_t line_width_u3_7 = brw_get_line_width(brw); dw2 |= line_width_u3_7 << GEN6_SF_LINE_WIDTH_SHIFT; } if (ctx->Line.SmoothFlag) { dw2 |= GEN6_SF_LINE_AA_ENABLE; dw2 |= GEN6_SF_LINE_END_CAP_WIDTH_1_0; } if (ctx->Line.StippleFlag && brw->is_haswell) { dw2 |= HSW_SF_LINE_STIPPLE_ENABLE; } /* _NEW_MULTISAMPLE */ if (multisampled_fbo && ctx->Multisample.Enabled) dw2 |= GEN6_SF_MSRAST_ON_PATTERN; /* FINISHME: Last Pixel Enable? Vertex Sub Pixel Precision Select? */ dw3 = GEN6_SF_LINE_AA_MODE_TRUE; /* _NEW_PROGRAM | _NEW_POINT */ if (!(ctx->VertexProgram.PointSizeEnabled || ctx->Point._Attenuated)) dw3 |= GEN6_SF_USE_STATE_POINT_WIDTH; /* Clamp to ARB_point_parameters user limits */ point_size = CLAMP(ctx->Point.Size, ctx->Point.MinSize, ctx->Point.MaxSize); /* Clamp to the hardware limits and convert to fixed point */ dw3 |= U_FIXED(CLAMP(point_size, 0.125f, 255.875f), 3); /* _NEW_LIGHT */ if (ctx->Light.ProvokingVertex != GL_FIRST_VERTEX_CONVENTION) { dw3 |= (2 << GEN6_SF_TRI_PROVOKE_SHIFT) | (2 << GEN6_SF_TRIFAN_PROVOKE_SHIFT) | (1 << GEN6_SF_LINE_PROVOKE_SHIFT); } else { dw3 |= (1 << GEN6_SF_TRIFAN_PROVOKE_SHIFT); } BEGIN_BATCH(7); OUT_BATCH(_3DSTATE_SF << 16 | (7 - 2)); OUT_BATCH(dw1); OUT_BATCH(dw2); OUT_BATCH(dw3); OUT_BATCH_F(ctx->Polygon.OffsetUnits * 2); /* constant. copied from gen4 */ OUT_BATCH_F(ctx->Polygon.OffsetFactor); /* scale */ OUT_BATCH_F(ctx->Polygon.OffsetClamp); /* global depth offset clamp */ ADVANCE_BATCH(); }
/* Emit the vertices for a single composite rectangle. * * This function is no longer shared between i830 and i915 generation code. */ static void i830_emit_composite_primitive(PixmapPtr dest, int srcX, int srcY, int maskX, int maskY, int dstX, int dstY, int w, int h) { ScrnInfoPtr scrn = xf86Screens[dest->drawable.pScreen->myNum]; intel_screen_private *intel = intel_get_screen_private(scrn); Bool is_affine_src, is_affine_mask = TRUE; int per_vertex; float src_x[3], src_y[3], src_w[3], mask_x[3], mask_y[3], mask_w[3]; per_vertex = 2; /* dest x/y */ { float x = srcX, y = srcY; is_affine_src = intel_transform_is_affine(intel->transform[0]); if (is_affine_src) { if (!intel_get_transformed_coordinates(x, y, intel-> transform[0], &src_x[0], &src_y[0])) return; if (!intel_get_transformed_coordinates(x, y + h, intel-> transform[0], &src_x[1], &src_y[1])) return; if (!intel_get_transformed_coordinates(x + w, y + h, intel-> transform[0], &src_x[2], &src_y[2])) return; per_vertex += 2; /* src x/y */ } else { if (!intel_get_transformed_coordinates_3d(x, y, intel-> transform[0], &src_x[0], &src_y[0], &src_w[0])) return; if (!intel_get_transformed_coordinates_3d(x, y + h, intel-> transform[0], &src_x[1], &src_y[1], &src_w[1])) return; if (!intel_get_transformed_coordinates_3d(x + w, y + h, intel-> transform[0], &src_x[2], &src_y[2], &src_w[2])) return; per_vertex += 3; /* src x/y/w */ } } if (intel->render_mask) { float x = maskX, y = maskY; is_affine_mask = intel_transform_is_affine(intel->transform[1]); if (is_affine_mask) { if (!intel_get_transformed_coordinates(x, y, intel-> transform[1], &mask_x[0], &mask_y[0])) return; if (!intel_get_transformed_coordinates(x, y + h, intel-> transform[1], &mask_x[1], &mask_y[1])) return; if (!intel_get_transformed_coordinates(x + w, y + h, intel-> transform[1], &mask_x[2], &mask_y[2])) return; per_vertex += 2; /* mask x/y */ } else { if (!intel_get_transformed_coordinates_3d(x, y, intel-> transform[1], &mask_x[0], &mask_y[0], &mask_w[0])) return; if (!intel_get_transformed_coordinates_3d(x, y + h, intel-> transform[1], &mask_x[1], &mask_y[1], &mask_w[1])) return; if (!intel_get_transformed_coordinates_3d(x + w, y + h, intel-> transform[1], &mask_x[2], &mask_y[2], &mask_w[2])) return; per_vertex += 3; /* mask x/y/w */ } } if (intel->vertex_count == 0) { intel->vertex_index = intel->batch_used; OUT_BATCH(PRIM3D_INLINE | PRIM3D_RECTLIST); } OUT_BATCH_F(dstX + w); OUT_BATCH_F(dstY + h); OUT_BATCH_F(src_x[2] / intel->scale_units[0][0]); OUT_BATCH_F(src_y[2] / intel->scale_units[0][1]); if (!is_affine_src) { OUT_BATCH_F(src_w[2]); } if (intel->render_mask) { OUT_BATCH_F(mask_x[2] / intel->scale_units[1][0]); OUT_BATCH_F(mask_y[2] / intel->scale_units[1][1]); if (!is_affine_mask) { OUT_BATCH_F(mask_w[2]); } } OUT_BATCH_F(dstX); OUT_BATCH_F(dstY + h); OUT_BATCH_F(src_x[1] / intel->scale_units[0][0]); OUT_BATCH_F(src_y[1] / intel->scale_units[0][1]); if (!is_affine_src) { OUT_BATCH_F(src_w[1]); } if (intel->render_mask) { OUT_BATCH_F(mask_x[1] / intel->scale_units[1][0]); OUT_BATCH_F(mask_y[1] / intel->scale_units[1][1]); if (!is_affine_mask) { OUT_BATCH_F(mask_w[1]); } } OUT_BATCH_F(dstX); OUT_BATCH_F(dstY); OUT_BATCH_F(src_x[0] / intel->scale_units[0][0]); OUT_BATCH_F(src_y[0] / intel->scale_units[0][1]); if (!is_affine_src) { OUT_BATCH_F(src_w[0]); } if (intel->render_mask) { OUT_BATCH_F(mask_x[0] / intel->scale_units[1][0]); OUT_BATCH_F(mask_y[0] / intel->scale_units[1][1]); if (!is_affine_mask) { OUT_BATCH_F(mask_w[0]); } } intel->vertex_count += 3 * per_vertex; }
void i915_clear_emit(struct pipe_context *pipe, unsigned buffers, const float *rgba, double depth, unsigned stencil, unsigned destx, unsigned desty, unsigned width, unsigned height) { struct i915_context *i915 = i915_context(pipe); uint32_t clear_params, clear_color, clear_depth, clear_stencil, clear_color8888, packed_z_stencil; union util_color u_color; float f_depth = depth; struct i915_texture *cbuf_tex, *depth_tex; cbuf_tex = depth_tex = NULL; clear_params = 0; if (buffers & PIPE_CLEAR_COLOR) { struct pipe_surface *cbuf = i915->framebuffer.cbufs[0]; clear_params |= CLEARPARAM_WRITE_COLOR; cbuf_tex = i915_texture(cbuf->texture); util_pack_color(rgba, cbuf->format, &u_color); if (util_format_get_blocksize(cbuf_tex->b.b.format) == 4) clear_color = u_color.ui; else clear_color = (u_color.ui & 0xffff) | (u_color.ui << 16); util_pack_color(rgba, cbuf->format, &u_color); clear_color8888 = u_color.ui; } else clear_color = clear_color8888 = 0; clear_depth = clear_stencil = 0; if (buffers & PIPE_CLEAR_DEPTH) { struct pipe_surface *zbuf = i915->framebuffer.zsbuf; clear_params |= CLEARPARAM_WRITE_DEPTH; depth_tex = i915_texture(zbuf->texture); packed_z_stencil = util_pack_z_stencil(depth_tex->b.b.format, depth, stencil); if (util_format_get_blocksize(depth_tex->b.b.format) == 4) { /* Avoid read-modify-write if there's no stencil. */ if (buffers & PIPE_CLEAR_STENCIL || depth_tex->b.b.format != PIPE_FORMAT_Z24_UNORM_S8_USCALED) { clear_params |= CLEARPARAM_WRITE_STENCIL; clear_stencil = packed_z_stencil & 0xff; clear_depth = packed_z_stencil; } else clear_depth = packed_z_stencil & 0xffffff00; } else { clear_depth = (clear_depth & 0xffff) | (clear_depth << 16); } } if (i915->hardware_dirty) i915_emit_hardware_state(i915); if (!BEGIN_BATCH(7 + 7)) { FLUSH_BATCH(NULL); i915_emit_hardware_state(i915); i915->vbo_flushed = 1; assert(BEGIN_BATCH(7 + 7)); } OUT_BATCH(_3DSTATE_CLEAR_PARAMETERS); OUT_BATCH(clear_params | CLEARPARAM_CLEAR_RECT); OUT_BATCH(clear_color); OUT_BATCH(clear_depth); OUT_BATCH(clear_color8888); OUT_BATCH_F(f_depth); OUT_BATCH(clear_stencil); OUT_BATCH(_3DPRIMITIVE | PRIM3D_CLEAR_RECT | 5); OUT_BATCH_F(destx + width); OUT_BATCH_F(desty + height); OUT_BATCH_F(destx); OUT_BATCH_F(desty + height); OUT_BATCH_F(destx); OUT_BATCH_F(desty); /* Flush after clear, its expected to be a costly operation. * This is not required, just a heuristic */ FLUSH_BATCH(NULL); }
static void upload_sf_state(struct brw_context *brw) { struct intel_context *intel = &brw->intel; struct gl_context *ctx = &intel->ctx; /* BRW_NEW_FRAGMENT_PROGRAM */ uint32_t num_outputs = _mesa_bitcount_64(brw->fragment_program->Base.InputsRead); /* _NEW_LIGHT */ bool shade_model_flat = ctx->Light.ShadeModel == GL_FLAT; uint32_t dw1, dw2, dw3, dw4, dw16, dw17; int i; /* _NEW_BUFFER */ bool render_to_fbo = _mesa_is_user_fbo(brw->intel.ctx.DrawBuffer); bool multisampled_fbo = ctx->DrawBuffer->Visual.samples > 1; int attr = 0, input_index = 0; int urb_entry_read_offset = 1; float point_size; uint16_t attr_overrides[FRAG_ATTRIB_MAX]; uint32_t point_sprite_origin; dw1 = GEN6_SF_SWIZZLE_ENABLE | num_outputs << GEN6_SF_NUM_OUTPUTS_SHIFT; dw2 = GEN6_SF_STATISTICS_ENABLE | GEN6_SF_VIEWPORT_TRANSFORM_ENABLE; dw3 = 0; dw4 = 0; dw16 = 0; dw17 = 0; /* _NEW_POLYGON */ if ((ctx->Polygon.FrontFace == GL_CCW) ^ render_to_fbo) dw2 |= GEN6_SF_WINDING_CCW; if (ctx->Polygon.OffsetFill) dw2 |= GEN6_SF_GLOBAL_DEPTH_OFFSET_SOLID; if (ctx->Polygon.OffsetLine) dw2 |= GEN6_SF_GLOBAL_DEPTH_OFFSET_WIREFRAME; if (ctx->Polygon.OffsetPoint) dw2 |= GEN6_SF_GLOBAL_DEPTH_OFFSET_POINT; switch (ctx->Polygon.FrontMode) { case GL_FILL: dw2 |= GEN6_SF_FRONT_SOLID; break; case GL_LINE: dw2 |= GEN6_SF_FRONT_WIREFRAME; break; case GL_POINT: dw2 |= GEN6_SF_FRONT_POINT; break; default: assert(0); break; } switch (ctx->Polygon.BackMode) { case GL_FILL: dw2 |= GEN6_SF_BACK_SOLID; break; case GL_LINE: dw2 |= GEN6_SF_BACK_WIREFRAME; break; case GL_POINT: dw2 |= GEN6_SF_BACK_POINT; break; default: assert(0); break; } /* _NEW_SCISSOR */ if (ctx->Scissor.Enabled) dw3 |= GEN6_SF_SCISSOR_ENABLE; /* _NEW_POLYGON */ if (ctx->Polygon.CullFlag) { switch (ctx->Polygon.CullFaceMode) { case GL_FRONT: dw3 |= GEN6_SF_CULL_FRONT; break; case GL_BACK: dw3 |= GEN6_SF_CULL_BACK; break; case GL_FRONT_AND_BACK: dw3 |= GEN6_SF_CULL_BOTH; break; default: assert(0); break; } } else { dw3 |= GEN6_SF_CULL_NONE; } /* _NEW_LINE */ { uint32_t line_width_u3_7 = U_FIXED(CLAMP(ctx->Line.Width, 0.0, 7.99), 7); /* TODO: line width of 0 is not allowed when MSAA enabled */ if (line_width_u3_7 == 0) line_width_u3_7 = 1; dw3 |= line_width_u3_7 << GEN6_SF_LINE_WIDTH_SHIFT; } if (ctx->Line.SmoothFlag) { dw3 |= GEN6_SF_LINE_AA_ENABLE; dw3 |= GEN6_SF_LINE_AA_MODE_TRUE; dw3 |= GEN6_SF_LINE_END_CAP_WIDTH_1_0; } /* _NEW_MULTISAMPLE */ if (multisampled_fbo && ctx->Multisample.Enabled) dw3 |= GEN6_SF_MSRAST_ON_PATTERN; /* _NEW_PROGRAM | _NEW_POINT */ if (!(ctx->VertexProgram.PointSizeEnabled || ctx->Point._Attenuated)) dw4 |= GEN6_SF_USE_STATE_POINT_WIDTH; /* Clamp to ARB_point_parameters user limits */ point_size = CLAMP(ctx->Point.Size, ctx->Point.MinSize, ctx->Point.MaxSize); /* Clamp to the hardware limits and convert to fixed point */ dw4 |= U_FIXED(CLAMP(point_size, 0.125, 255.875), 3); /* * Window coordinates in an FBO are inverted, which means point * sprite origin must be inverted, too. */ if ((ctx->Point.SpriteOrigin == GL_LOWER_LEFT) != render_to_fbo) { point_sprite_origin = GEN6_SF_POINT_SPRITE_LOWERLEFT; } else { point_sprite_origin = GEN6_SF_POINT_SPRITE_UPPERLEFT; } dw1 |= point_sprite_origin; /* _NEW_LIGHT */ if (ctx->Light.ProvokingVertex != GL_FIRST_VERTEX_CONVENTION) { dw4 |= (2 << GEN6_SF_TRI_PROVOKE_SHIFT) | (2 << GEN6_SF_TRIFAN_PROVOKE_SHIFT) | (1 << GEN6_SF_LINE_PROVOKE_SHIFT); } else { dw4 |= (1 << GEN6_SF_TRIFAN_PROVOKE_SHIFT); } /* Create the mapping from the FS inputs we produce to the VS outputs * they source from. */ uint32_t max_source_attr = 0; for (; attr < FRAG_ATTRIB_MAX; attr++) { enum glsl_interp_qualifier interp_qualifier = brw->fragment_program->InterpQualifier[attr]; bool is_gl_Color = attr == FRAG_ATTRIB_COL0 || attr == FRAG_ATTRIB_COL1; if (!(brw->fragment_program->Base.InputsRead & BITFIELD64_BIT(attr))) continue; /* _NEW_POINT */ if (ctx->Point.PointSprite && (attr >= FRAG_ATTRIB_TEX0 && attr <= FRAG_ATTRIB_TEX7) && ctx->Point.CoordReplace[attr - FRAG_ATTRIB_TEX0]) { dw16 |= (1 << input_index); } if (attr == FRAG_ATTRIB_PNTC) dw16 |= (1 << input_index); /* flat shading */ if (interp_qualifier == INTERP_QUALIFIER_FLAT || (shade_model_flat && is_gl_Color && interp_qualifier == INTERP_QUALIFIER_NONE)) dw17 |= (1 << input_index); /* The hardware can only do the overrides on 16 overrides at a * time, and the other up to 16 have to be lined up so that the * input index = the output index. We'll need to do some * tweaking to make sure that's the case. */ assert(input_index < 16 || attr == input_index); /* CACHE_NEW_VS_PROG | _NEW_LIGHT | _NEW_PROGRAM */ attr_overrides[input_index++] = get_attr_override(&brw->vs.prog_data->vue_map, urb_entry_read_offset, attr, ctx->VertexProgram._TwoSideEnabled, &max_source_attr); } for (; input_index < FRAG_ATTRIB_MAX; input_index++) attr_overrides[input_index] = 0; /* From the Sandy Bridge PRM, Volume 2, Part 1, documentation for * 3DSTATE_SF DWord 1 bits 15:11, "Vertex URB Entry Read Length": * * "This field should be set to the minimum length required to read the * maximum source attribute. The maximum source attribute is indicated * by the maximum value of the enabled Attribute # Source Attribute if * Attribute Swizzle Enable is set, Number of Output Attributes-1 if * enable is not set. * read_length = ceiling((max_source_attr + 1) / 2) * * [errata] Corruption/Hang possible if length programmed larger than * recommended" */ uint32_t urb_entry_read_length = ALIGN(max_source_attr + 1, 2) / 2; dw1 |= urb_entry_read_length << GEN6_SF_URB_ENTRY_READ_LENGTH_SHIFT | urb_entry_read_offset << GEN6_SF_URB_ENTRY_READ_OFFSET_SHIFT; BEGIN_BATCH(20); OUT_BATCH(_3DSTATE_SF << 16 | (20 - 2)); OUT_BATCH(dw1); OUT_BATCH(dw2); OUT_BATCH(dw3); OUT_BATCH(dw4); OUT_BATCH_F(ctx->Polygon.OffsetUnits * 2); /* constant. copied from gen4 */ OUT_BATCH_F(ctx->Polygon.OffsetFactor); /* scale */ OUT_BATCH_F(0.0); /* XXX: global depth offset clamp */ for (i = 0; i < 8; i++) { OUT_BATCH(attr_overrides[i * 2] | attr_overrides[i * 2 + 1] << 16); } OUT_BATCH(dw16); /* point sprite texcoord bitmask */ OUT_BATCH(dw17); /* constant interp bitmask */ OUT_BATCH(0); /* wrapshortest enables 0-7 */ OUT_BATCH(0); /* wrapshortest enables 8-15 */ ADVANCE_BATCH(); }
static void upload_sf_state(struct brw_context *brw) { struct intel_context *intel = &brw->intel; GLcontext *ctx = &intel->ctx; /* CACHE_NEW_VS_PROG */ uint32_t num_inputs = brw_count_bits(brw->vs.prog_data->outputs_written); uint32_t num_outputs = brw_count_bits(brw->fragment_program->Base.InputsRead); uint32_t dw1, dw2, dw3, dw4, dw16; int i; /* _NEW_BUFFER */ GLboolean render_to_fbo = brw->intel.ctx.DrawBuffer->Name != 0; int attr = 0; dw1 = num_outputs << GEN6_SF_NUM_OUTPUTS_SHIFT | (num_inputs + 1) / 2 << GEN6_SF_URB_ENTRY_READ_LENGTH_SHIFT | 1 << GEN6_SF_URB_ENTRY_READ_OFFSET_SHIFT; dw2 = GEN6_SF_VIEWPORT_TRANSFORM_ENABLE | GEN6_SF_STATISTICS_ENABLE; dw3 = 0; dw4 = 0; dw16 = 0; /* _NEW_POLYGON */ if ((ctx->Polygon.FrontFace == GL_CCW) ^ render_to_fbo) dw2 |= GEN6_SF_WINDING_CCW; if (ctx->Polygon.OffsetFill) dw2 |= GEN6_SF_GLOBAL_DEPTH_OFFSET_SOLID; /* _NEW_SCISSOR */ if (ctx->Scissor.Enabled) dw3 |= GEN6_SF_SCISSOR_ENABLE; /* _NEW_POLYGON */ if (ctx->Polygon.CullFlag) { switch (ctx->Polygon.CullFaceMode) { case GL_FRONT: dw3 |= GEN6_SF_CULL_FRONT; break; case GL_BACK: dw3 |= GEN6_SF_CULL_BACK; break; case GL_FRONT_AND_BACK: dw3 |= GEN6_SF_CULL_BOTH; break; default: assert(0); break; } } else { dw3 |= GEN6_SF_CULL_NONE; } /* _NEW_LINE */ dw3 |= U_FIXED(CLAMP(ctx->Line.Width, 0.0, 7.99), 7) << GEN6_SF_LINE_WIDTH_SHIFT; if (ctx->Line.SmoothFlag) { dw3 |= GEN6_SF_LINE_AA_ENABLE; dw3 |= GEN6_SF_LINE_AA_MODE_TRUE; dw3 |= GEN6_SF_LINE_END_CAP_WIDTH_1_0; } /* _NEW_POINT */ if (ctx->Point._Attenuated) dw4 |= GEN6_SF_USE_STATE_POINT_WIDTH; dw4 |= U_FIXED(CLAMP(ctx->Point.Size, 0.125, 225.875), 3) << GEN6_SF_POINT_WIDTH_SHIFT; if (ctx->Point.SpriteOrigin == GL_LOWER_LEFT) dw1 |= GEN6_SF_POINT_SPRITE_LOWERLEFT; /* _NEW_LIGHT */ if (ctx->Light.ProvokingVertex != GL_FIRST_VERTEX_CONVENTION) { dw4 |= (2 << GEN6_SF_TRI_PROVOKE_SHIFT) | (2 << GEN6_SF_TRIFAN_PROVOKE_SHIFT) | (1 << GEN6_SF_LINE_PROVOKE_SHIFT); } else { dw4 |= (1 << GEN6_SF_TRIFAN_PROVOKE_SHIFT); } if (ctx->Point.PointSprite) { for (i = 0; i < 8; i++) { if (ctx->Point.CoordReplace[i]) dw16 |= (1 << i); } } BEGIN_BATCH(20); OUT_BATCH(CMD_3D_SF_STATE << 16 | (20 - 2)); OUT_BATCH(dw1); OUT_BATCH(dw2); OUT_BATCH(dw3); OUT_BATCH(dw4); OUT_BATCH_F(ctx->Polygon.OffsetUnits * 2); /* constant. copied from gen4 */ OUT_BATCH_F(ctx->Polygon.OffsetFactor); /* scale */ OUT_BATCH_F(0.0); /* XXX: global depth offset clamp */ for (i = 0; i < 8; i++) { uint32_t attr_overrides = 0; for (; attr < 64; attr++) { if (brw->fragment_program->Base.InputsRead & BITFIELD64_BIT(attr)) { attr_overrides |= get_attr_override(brw, attr); attr++; break; } } for (; attr < 64; attr++) { if (brw->fragment_program->Base.InputsRead & BITFIELD64_BIT(attr)) { attr_overrides |= get_attr_override(brw, attr) << 16; attr++; break; } } OUT_BATCH(attr_overrides); } OUT_BATCH(dw16); /* point sprite texcoord bitmask */ OUT_BATCH(0); /* constant interp bitmask */ OUT_BATCH(0); /* wrapshortest enables 0-7 */ OUT_BATCH(0); /* wrapshortest enables 8-15 */ ADVANCE_BATCH(); intel_batchbuffer_emit_mi_flush(intel->batch); }