static int intel_dri3_fd_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, CARD16 *stride, CARD32 *size) { struct intel_uxa_pixmap *priv; int fd; priv = intel_uxa_get_pixmap_private(pixmap); if (!priv) return -1; if (intel_pixmap_pitch(pixmap) > UINT16_MAX) return -1; if (drm_intel_bo_gem_export_to_prime(priv->bo, &fd) < 0) return -1; priv->pinned |= PIN_DRI3; *stride = intel_pixmap_pitch(pixmap); *size = priv->bo->size; return fd; }
static void intel_uxa_solid(PixmapPtr pixmap, int x1, int y1, int x2, int y2) { ScrnInfoPtr scrn = xf86Screens[pixmap->drawable.pScreen->myNum]; intel_screen_private *intel = intel_get_screen_private(scrn); unsigned long pitch; uint32_t cmd; if (x1 < 0) x1 = 0; if (y1 < 0) y1 = 0; if (x2 > pixmap->drawable.width) x2 = pixmap->drawable.width; if (y2 > pixmap->drawable.height) y2 = pixmap->drawable.height; if (x2 <= x1 || y2 <= y1) return; pitch = intel_pixmap_pitch(pixmap); { BEGIN_BATCH_BLT(6); cmd = XY_COLOR_BLT_CMD; if (pixmap->drawable.bitsPerPixel == 32) cmd |= XY_COLOR_BLT_WRITE_ALPHA | XY_COLOR_BLT_WRITE_RGB; if (INTEL_INFO(intel)->gen >= 40 && intel_pixmap_tiled(pixmap)) { assert((pitch % 512) == 0); pitch >>= 2; cmd |= XY_COLOR_BLT_TILED; } OUT_BATCH(cmd); OUT_BATCH(intel->BR[13] | pitch); OUT_BATCH((y1 << 16) | (x1 & 0xffff)); OUT_BATCH((y2 << 16) | (x2 & 0xffff)); OUT_RELOC_PIXMAP_FENCED(pixmap, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0); OUT_BATCH(intel->BR[16]); ADVANCE_BATCH(); }
static void i915_emit_composite_setup(ScrnInfoPtr scrn) { intel_screen_private *intel = intel_get_screen_private(scrn); int op = intel->i915_render_state.op; PicturePtr mask_picture = intel->render_mask_picture; PicturePtr dest_picture = intel->render_dest_picture; PixmapPtr mask = intel->render_mask; PixmapPtr dest = intel->render_dest; Bool is_solid_src, is_solid_mask; int tex_count, t; intel->needs_render_state_emit = FALSE; IntelEmitInvarientState(scrn); intel->last_3d = LAST_3D_RENDER; is_solid_src = intel->render_source_is_solid; is_solid_mask = intel->render_mask_is_solid; tex_count = 0; tex_count += ! is_solid_src; tex_count += mask && ! is_solid_mask; assert(intel->in_batch_atomic); if (tex_count != 0) { OUT_BATCH(_3DSTATE_MAP_STATE | (3 * tex_count)); OUT_BATCH((1 << tex_count) - 1); for (t = 0; t < tex_count; t++) { OUT_RELOC_PIXMAP(intel->texture[t], I915_GEM_DOMAIN_SAMPLER, 0, 0); OUT_BATCH(intel->mapstate[3*t + 1]); OUT_BATCH(intel->mapstate[3*t + 2]); } OUT_BATCH(_3DSTATE_SAMPLER_STATE | (3 * tex_count)); OUT_BATCH((1 << tex_count) - 1); for (t = 0; t < tex_count; t++) { OUT_BATCH(intel->samplerstate[3*t + 0]); OUT_BATCH(intel->samplerstate[3*t + 1]); OUT_BATCH(intel->samplerstate[3*t + 2]); } } if (is_solid_src) { OUT_BATCH (_3DSTATE_DFLT_DIFFUSE_CMD); OUT_BATCH (intel->render_source_solid); } if (mask && is_solid_mask) { OUT_BATCH (_3DSTATE_DFLT_SPEC_CMD); OUT_BATCH (intel->render_mask_solid); } /* BUF_INFO is an implicit flush, so avoid if the target has not changed. * XXX However for reasons unfathomed, correct rendering in KDE requires * at least a MI_FLUSH | INHIBIT_RENDER_CACHE_FLUSH here. */ if (1 || dest != intel->render_current_dest) { uint32_t tiling_bits; intel_batch_do_flush(scrn); if (intel_pixmap_tiled(dest)) { tiling_bits = BUF_3D_TILED_SURFACE; if (intel_get_pixmap_private(dest)->tiling == I915_TILING_Y) tiling_bits |= BUF_3D_TILE_WALK_Y; } else tiling_bits = 0; OUT_BATCH(_3DSTATE_BUF_INFO_CMD); OUT_BATCH(BUF_3D_ID_COLOR_BACK | tiling_bits | BUF_3D_PITCH(intel_pixmap_pitch(dest))); OUT_RELOC_PIXMAP(dest, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0); OUT_BATCH(_3DSTATE_DST_BUF_VARS_CMD); OUT_BATCH(intel->i915_render_state.dst_format); /* draw rect is unconditional */ OUT_BATCH(_3DSTATE_DRAW_RECT_CMD); OUT_BATCH(0x00000000); OUT_BATCH(0x00000000); /* ymin, xmin */ OUT_BATCH(DRAW_YMAX(dest->drawable.height - 1) | DRAW_XMAX(dest->drawable.width - 1)); /* yorig, xorig (relate to color buffer?) */ OUT_BATCH(0x00000000); intel->render_current_dest = dest; } { uint32_t ss2; ss2 = ~0; t = 0; if (! is_solid_src) { ss2 &= ~S2_TEXCOORD_FMT(t, TEXCOORDFMT_NOT_PRESENT); ss2 |= S2_TEXCOORD_FMT(t, intel_transform_is_affine(intel->transform[t]) ? TEXCOORDFMT_2D : TEXCOORDFMT_4D); t++; } if (mask && ! is_solid_mask) { ss2 &= ~S2_TEXCOORD_FMT(t, TEXCOORDFMT_NOT_PRESENT); ss2 |= S2_TEXCOORD_FMT(t, intel_transform_is_affine(intel->transform[t]) ? TEXCOORDFMT_2D : TEXCOORDFMT_4D); t++; } if (intel->needs_render_ca_pass) { OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(2) | 0); OUT_BATCH(ss2); } else { OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(2) | I1_LOAD_S(6) | 1); OUT_BATCH(ss2); OUT_BATCH(i915_get_blend_cntl(op, mask_picture, dest_picture->format)); } } if (! intel->needs_render_ca_pass) i915_composite_emit_shader(intel, op); }
static Bool i915_texture_setup(PicturePtr picture, PixmapPtr pixmap, int unit) { ScrnInfoPtr scrn = xf86Screens[picture->pDrawable->pScreen->myNum]; intel_screen_private *intel = intel_get_screen_private(scrn); uint32_t format, pitch, filter; uint32_t wrap_mode, tiling_bits; int i; pitch = intel_pixmap_pitch(pixmap); intel->scale_units[unit][0] = 1. / pixmap->drawable.width; intel->scale_units[unit][1] = 1. / pixmap->drawable.height; for (i = 0; i < sizeof(i915_tex_formats) / sizeof(i915_tex_formats[0]); i++) { if (i915_tex_formats[i].fmt == picture->format) break; } if (i == sizeof(i915_tex_formats) / sizeof(i915_tex_formats[0])) { intel_debug_fallback(scrn, "unknown texture format\n"); return FALSE; } format = i915_tex_formats[i].card_fmt; switch (picture->repeatType) { case RepeatNone: wrap_mode = TEXCOORDMODE_CLAMP_BORDER; break; case RepeatNormal: wrap_mode = TEXCOORDMODE_WRAP; break; case RepeatPad: wrap_mode = TEXCOORDMODE_CLAMP_EDGE; break; case RepeatReflect: wrap_mode = TEXCOORDMODE_MIRROR; break; default: FatalError("Unknown repeat type %d\n", picture->repeatType); } switch (picture->filter) { case PictFilterNearest: filter = (FILTER_NEAREST << SS2_MAG_FILTER_SHIFT) | (FILTER_NEAREST << SS2_MIN_FILTER_SHIFT); break; case PictFilterBilinear: filter = (FILTER_LINEAR << SS2_MAG_FILTER_SHIFT) | (FILTER_LINEAR << SS2_MIN_FILTER_SHIFT); break; default: filter = 0; intel_debug_fallback(scrn, "Bad filter 0x%x\n", picture->filter); return FALSE; } /* offset filled in at emit time */ if (intel_pixmap_tiled(pixmap)) { tiling_bits = MS3_TILED_SURFACE; if (intel_get_pixmap_private(pixmap)->tiling == I915_TILING_Y) tiling_bits |= MS3_TILE_WALK; } else tiling_bits = 0; intel->texture[unit] = pixmap; intel->mapstate[unit * 3 + 0] = 0; intel->mapstate[unit * 3 + 1] = format | tiling_bits | ((pixmap->drawable.height - 1) << MS3_HEIGHT_SHIFT) | ((pixmap->drawable.width - 1) << MS3_WIDTH_SHIFT); intel->mapstate[unit * 3 + 2] = ((pitch / 4) - 1) << MS4_PITCH_SHIFT; intel->samplerstate[unit * 3 + 0] = (MIPFILTER_NONE << SS2_MIP_FILTER_SHIFT); intel->samplerstate[unit * 3 + 0] |= filter; intel->samplerstate[unit * 3 + 1] = SS3_NORMALIZED_COORDS; intel->samplerstate[unit * 3 + 1] |= wrap_mode << SS3_TCX_ADDR_MODE_SHIFT; intel->samplerstate[unit * 3 + 1] |= wrap_mode << SS3_TCY_ADDR_MODE_SHIFT; intel->samplerstate[unit * 3 + 1] |= unit << SS3_TEXTUREMAP_INDEX_SHIFT; intel->samplerstate[unit * 3 + 2] = 0x00000000; /* border color */ intel->transform[unit] = picture->transform; return TRUE; }
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 i830_emit_composite_state(ScrnInfoPtr scrn) { intel_screen_private *intel = intel_get_screen_private(scrn); uint32_t vf2, tiling_bits; uint32_t texcoordfmt = 0; intel->needs_render_state_emit = FALSE; IntelEmitInvarientState(scrn); intel->last_3d = LAST_3D_RENDER; assert(intel->in_batch_atomic); if (intel_pixmap_tiled(intel->render_dest)) { tiling_bits = BUF_3D_TILED_SURFACE; if (intel_get_pixmap_private(intel->render_dest)->tiling == I915_TILING_Y) tiling_bits |= BUF_3D_TILE_WALK_Y; } else tiling_bits = 0; OUT_BATCH(_3DSTATE_BUF_INFO_CMD); OUT_BATCH(BUF_3D_ID_COLOR_BACK | tiling_bits | BUF_3D_PITCH(intel_pixmap_pitch(intel->render_dest))); OUT_RELOC_PIXMAP(intel->render_dest, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0); OUT_BATCH(_3DSTATE_DST_BUF_VARS_CMD); OUT_BATCH(intel->render_dest_format); OUT_BATCH(_3DSTATE_DRAW_RECT_CMD); OUT_BATCH(0); OUT_BATCH(0); /* ymin, xmin */ OUT_BATCH(DRAW_YMAX(intel->render_dest->drawable.height - 1) | DRAW_XMAX(intel->render_dest->drawable.width - 1)); OUT_BATCH(0); /* yorig, xorig */ OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(2) | I1_LOAD_S(3) | I1_LOAD_S(8) | 2); if (intel->render_mask) vf2 = 2 << 12; /* 2 texture coord sets */ else vf2 = 1 << 12; OUT_BATCH(vf2); /* number of coordinate sets */ OUT_BATCH(S3_CULLMODE_NONE | S3_VERTEXHAS_XY); OUT_BATCH(S8_ENABLE_COLOR_BLEND | S8_BLENDFUNC_ADD | intel-> s8_blendctl | S8_ENABLE_COLOR_BUFFER_WRITE); OUT_BATCH(_3DSTATE_INDPT_ALPHA_BLEND_CMD | DISABLE_INDPT_ALPHA_BLEND); OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_2 | LOAD_TEXTURE_BLEND_STAGE(0) | 1); OUT_BATCH(intel->cblend); OUT_BATCH(intel->ablend); OUT_BATCH(_3DSTATE_ENABLES_1_CMD | DISABLE_LOGIC_OP | DISABLE_STENCIL_TEST | DISABLE_DEPTH_BIAS | DISABLE_SPEC_ADD | DISABLE_FOG | DISABLE_ALPHA_TEST | ENABLE_COLOR_BLEND | DISABLE_DEPTH_TEST); /* We have to explicitly say we don't want write disabled */ OUT_BATCH(_3DSTATE_ENABLES_2_CMD | ENABLE_COLOR_MASK | DISABLE_STENCIL_WRITE | ENABLE_TEX_CACHE | DISABLE_DITHER | ENABLE_COLOR_WRITE | DISABLE_DEPTH_WRITE); if (intel_transform_is_affine(intel->render_source_picture->transform)) texcoordfmt |= (TEXCOORDFMT_2D << 0); else texcoordfmt |= (TEXCOORDFMT_3D << 0); if (intel->render_mask) { if (intel_transform_is_affine (intel->render_mask_picture->transform)) texcoordfmt |= (TEXCOORDFMT_2D << 2); else texcoordfmt |= (TEXCOORDFMT_3D << 2); } OUT_BATCH(_3DSTATE_VERTEX_FORMAT_2_CMD | texcoordfmt); i830_texture_setup(intel->render_source_picture, intel->render_source, 0); if (intel->render_mask) { i830_texture_setup(intel->render_mask_picture, intel->render_mask, 1); } }
static void i830_texture_setup(PicturePtr picture, PixmapPtr pixmap, int unit) { ScrnInfoPtr scrn = xf86Screens[picture->pDrawable->pScreen->myNum]; intel_screen_private *intel = intel_get_screen_private(scrn); uint32_t format, tiling_bits, pitch, filter; uint32_t wrap_mode; uint32_t texcoordtype; pitch = intel_pixmap_pitch(pixmap); intel->scale_units[unit][0] = pixmap->drawable.width; intel->scale_units[unit][1] = pixmap->drawable.height; intel->transform[unit] = picture->transform; if (intel_transform_is_affine(intel->transform[unit])) texcoordtype = TEXCOORDTYPE_CARTESIAN; else texcoordtype = TEXCOORDTYPE_HOMOGENEOUS; switch (picture->repeatType) { case RepeatNone: wrap_mode = TEXCOORDMODE_CLAMP_BORDER; break; case RepeatNormal: wrap_mode = TEXCOORDMODE_WRAP; break; case RepeatPad: wrap_mode = TEXCOORDMODE_CLAMP; break; case RepeatReflect: wrap_mode = TEXCOORDMODE_MIRROR; break; default: FatalError("Unknown repeat type %d\n", picture->repeatType); } switch (picture->filter) { case PictFilterNearest: filter = ((FILTER_NEAREST << TM0S3_MAG_FILTER_SHIFT) | (FILTER_NEAREST << TM0S3_MIN_FILTER_SHIFT)); break; case PictFilterBilinear: filter = ((FILTER_LINEAR << TM0S3_MAG_FILTER_SHIFT) | (FILTER_LINEAR << TM0S3_MIN_FILTER_SHIFT)); break; default: filter = 0; FatalError("Bad filter 0x%x\n", picture->filter); } filter |= (MIPFILTER_NONE << TM0S3_MIP_FILTER_SHIFT); if (intel_pixmap_tiled(pixmap)) { tiling_bits = TM0S1_TILED_SURFACE; if (intel_get_pixmap_private(pixmap)->tiling == I915_TILING_Y) tiling_bits |= TM0S1_TILE_WALK; } else tiling_bits = 0; format = i8xx_get_card_format(intel, picture); assert(intel->in_batch_atomic); OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_2 | LOAD_TEXTURE_MAP(unit) | 4); OUT_RELOC_PIXMAP(pixmap, I915_GEM_DOMAIN_SAMPLER, 0, 0); OUT_BATCH(((pixmap->drawable.height - 1) << TM0S1_HEIGHT_SHIFT) | ((pixmap->drawable.width - 1) << TM0S1_WIDTH_SHIFT) | format | tiling_bits); OUT_BATCH((pitch / 4 - 1) << TM0S2_PITCH_SHIFT | TM0S2_MAP_2D); OUT_BATCH(filter); OUT_BATCH(0); /* default color */ OUT_BATCH(_3DSTATE_MAP_COORD_SET_CMD | TEXCOORD_SET(unit) | ENABLE_TEXCOORD_PARAMS | TEXCOORDS_ARE_NORMAL | texcoordtype | ENABLE_ADDR_V_CNTL | TEXCOORD_ADDR_V_MODE(wrap_mode) | ENABLE_ADDR_U_CNTL | TEXCOORD_ADDR_U_MODE(wrap_mode)); /* map texel stream */ OUT_BATCH(_3DSTATE_MAP_COORD_SETBIND_CMD); if (unit == 0) OUT_BATCH(TEXBIND_SET0(TEXCOORDSRC_VTXSET_0) | TEXBIND_SET1(TEXCOORDSRC_KEEP) | TEXBIND_SET2(TEXCOORDSRC_KEEP) | TEXBIND_SET3(TEXCOORDSRC_KEEP)); else OUT_BATCH(TEXBIND_SET0(TEXCOORDSRC_VTXSET_0) | TEXBIND_SET1(TEXCOORDSRC_VTXSET_1) | TEXBIND_SET2(TEXCOORDSRC_KEEP) | TEXBIND_SET3(TEXCOORDSRC_KEEP)); OUT_BATCH(_3DSTATE_MAP_TEX_STREAM_CMD | (unit << 16) | DISABLE_TEX_STREAM_BUMP | ENABLE_TEX_STREAM_COORD_SET | TEX_STREAM_COORD_SET(unit) | ENABLE_TEX_STREAM_MAP_IDX | TEX_STREAM_MAP_IDX(unit)); }