static void bad_blit(drm_intel_bo *src_bo, uint32_t devid) { uint32_t src_pitch = 512, dst_pitch = 512; uint32_t cmd_bits = 0; if (IS_965(devid)) { src_pitch /= 4; cmd_bits |= XY_SRC_COPY_BLT_SRC_TILED; } if (IS_965(devid)) { dst_pitch /= 4; cmd_bits |= XY_SRC_COPY_BLT_DST_TILED; } BEGIN_BATCH(8); OUT_BATCH(XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA | XY_SRC_COPY_BLT_WRITE_RGB | cmd_bits); OUT_BATCH((3 << 24) | /* 32 bits */ (0xcc << 16) | /* copy ROP */ dst_pitch); OUT_BATCH(0); /* dst x1,y1 */ OUT_BATCH((64 << 16) | 64); /* 64x64 blit */ OUT_BATCH(BAD_GTT_DEST); OUT_BATCH(0); /* src x1,y1 */ OUT_BATCH(src_pitch); OUT_RELOC(src_bo, I915_GEM_DOMAIN_RENDER, 0, 0); ADVANCE_BATCH(); intel_batchbuffer_flush(batch); }
static GLboolean intelCreateContext(gl_api api, const struct gl_config * mesaVis, __DRIcontext * driContextPriv, unsigned major_version, unsigned minor_version, uint32_t flags, unsigned *error, void *sharedContextPrivate) { __DRIscreen *sPriv = driContextPriv->driScreenPriv; struct intel_screen *intelScreen = sPriv->driverPrivate; bool success = false; #ifdef I915 if (IS_9XX(intelScreen->deviceID)) { if (!IS_965(intelScreen->deviceID)) { success = i915CreateContext(api, mesaVis, driContextPriv, sharedContextPrivate); } } else { intelScreen->no_vbo = true; success = i830CreateContext(mesaVis, driContextPriv, sharedContextPrivate); } #else if (IS_965(intelScreen->deviceID)) success = brwCreateContext(api, mesaVis, driContextPriv, sharedContextPrivate); #endif if (success) { struct gl_context *ctx = (struct gl_context *) driContextPriv->driverPrivate; _mesa_compute_version(ctx); if (ctx->Version >= major_version * 10 + minor_version) { return true; } *error = __DRI_CTX_ERROR_BAD_VERSION; intelDestroyContext(driContextPriv); } else { *error = __DRI_CTX_ERROR_NO_MEMORY; fprintf(stderr, "Unrecognized deviceID 0x%x\n", intelScreen->deviceID); } return false; }
static void emit_blt(drm_intel_bo *src_bo, uint32_t src_tiling, unsigned src_pitch, unsigned src_x, unsigned src_y, unsigned w, unsigned h, drm_intel_bo *dst_bo, uint32_t dst_tiling, unsigned dst_pitch, unsigned dst_x, unsigned dst_y) { uint32_t cmd_bits = 0; if (IS_965(devid) && src_tiling) { src_pitch /= 4; cmd_bits |= XY_SRC_COPY_BLT_SRC_TILED; } if (IS_965(devid) && dst_tiling) { dst_pitch /= 4; cmd_bits |= XY_SRC_COPY_BLT_DST_TILED; } /* copy lower half to upper half */ BEGIN_BATCH(8); OUT_BATCH(XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA | XY_SRC_COPY_BLT_WRITE_RGB | cmd_bits); OUT_BATCH((3 << 24) | /* 32 bits */ (0xcc << 16) | /* copy ROP */ dst_pitch); OUT_BATCH(dst_y << 16 | dst_x); OUT_BATCH((dst_y+h) << 16 | (dst_x+w)); OUT_RELOC_FENCED(dst_bo, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0); OUT_BATCH(src_y << 16 | src_x); OUT_BATCH(src_pitch); OUT_RELOC_FENCED(src_bo, I915_GEM_DOMAIN_RENDER, 0, 0); ADVANCE_BATCH(); if (IS_GEN6(devid) || IS_GEN7(devid)) { BEGIN_BATCH(3); OUT_BATCH(XY_SETUP_CLIP_BLT_CMD); OUT_BATCH(0); OUT_BATCH(0); ADVANCE_BATCH(); } }
static void emit_dummy_load(void) { int i; uint32_t tile_flags = 0; uint32_t tiling_mode = I915_TILING_X; unsigned long pitch; drm_intel_bo *dummy_bo; dummy_bo = drm_intel_bo_alloc_tiled(bufmgr, "tiled dummy_bo", 2048, 2048, 4, &tiling_mode, &pitch, 0); if (IS_965(devid)) { pitch /= 4; tile_flags = XY_SRC_COPY_BLT_SRC_TILED | XY_SRC_COPY_BLT_DST_TILED; } for (i = 0; i < 5; i++) { BLIT_COPY_BATCH_START(tile_flags); OUT_BATCH((3 << 24) | /* 32 bits */ (0xcc << 16) | /* copy ROP */ pitch); OUT_BATCH(0 << 16 | 1024); OUT_BATCH((2048) << 16 | (2048)); OUT_RELOC_FENCED(dummy_bo, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0); OUT_BATCH(0 << 16 | 0); OUT_BATCH(pitch); OUT_RELOC_FENCED(dummy_bo, I915_GEM_DOMAIN_RENDER, 0, 0); ADVANCE_BATCH(); if (batch->gen >= 6) { BEGIN_BATCH(3, 0); OUT_BATCH(XY_SETUP_CLIP_BLT_CMD); OUT_BATCH(0); OUT_BATCH(0); ADVANCE_BATCH(); } } intel_batchbuffer_flush(batch); drm_intel_bo_unreference(dummy_bo); }
/** * Initializes potential list of extensions if ctx == NULL, or actually enables * extensions for a context. */ void intelInitExtensions(GLcontext *ctx, GLboolean enable_imaging) { struct intel_context *intel = ctx?intel_context(ctx):NULL; /* Disable imaging extension until convolution is working in teximage paths. */ enable_imaging = GL_FALSE; driInitExtensions(ctx, card_extensions, enable_imaging); if (intel == NULL || intel->ttm) driInitExtensions(ctx, ttm_extensions, GL_FALSE); if (intel == NULL || IS_965(intel->intelScreen->deviceID)) driInitExtensions(ctx, brw_extensions, GL_FALSE); if (intel == NULL || IS_915(intel->intelScreen->deviceID) || IS_945(intel->intelScreen->deviceID)) driInitExtensions(ctx, i915_extensions, GL_FALSE); }
GLboolean intelInitContext(struct intel_context *intel, const __GLcontextModes * mesaVis, __DRIcontext * driContextPriv, void *sharedContextPrivate, struct dd_function_table *functions) { GLcontext *ctx = &intel->ctx; GLcontext *shareCtx = (GLcontext *) sharedContextPrivate; __DRIscreen *sPriv = driContextPriv->driScreenPriv; struct intel_screen *intelScreen = sPriv->private; int bo_reuse_mode; /* we can't do anything without a connection to the device */ if (intelScreen->bufmgr == NULL) return GL_FALSE; if (!_mesa_initialize_context(&intel->ctx, mesaVis, shareCtx, functions, (void *) intel)) { printf("%s: failed to init mesa context\n", __FUNCTION__); return GL_FALSE; } driContextPriv->driverPrivate = intel; intel->intelScreen = intelScreen; intel->driScreen = sPriv; intel->driContext = driContextPriv; intel->driFd = sPriv->fd; intel->has_xrgb_textures = GL_TRUE; if (IS_GEN6(intel->intelScreen->deviceID)) { intel->gen = 6; intel->needs_ff_sync = GL_TRUE; intel->has_luminance_srgb = GL_TRUE; } else if (IS_GEN5(intel->intelScreen->deviceID)) { intel->gen = 5; intel->needs_ff_sync = GL_TRUE; intel->has_luminance_srgb = GL_TRUE; } else if (IS_965(intel->intelScreen->deviceID)) { intel->gen = 4; if (IS_G4X(intel->intelScreen->deviceID)) { intel->has_luminance_srgb = GL_TRUE; intel->is_g4x = GL_TRUE; } } else if (IS_9XX(intel->intelScreen->deviceID)) { intel->gen = 3; if (IS_945(intel->intelScreen->deviceID)) { intel->is_945 = GL_TRUE; } } else { intel->gen = 2; if (intel->intelScreen->deviceID == PCI_CHIP_I830_M || intel->intelScreen->deviceID == PCI_CHIP_845_G) { intel->has_xrgb_textures = GL_FALSE; } } driParseConfigFiles(&intel->optionCache, &intelScreen->optionCache, intel->driScreen->myNum, (intel->gen >= 4) ? "i965" : "i915"); if (intelScreen->deviceID == PCI_CHIP_I865_G) intel->maxBatchSize = 4096; else intel->maxBatchSize = BATCH_SZ; intel->bufmgr = intelScreen->bufmgr; bo_reuse_mode = driQueryOptioni(&intel->optionCache, "bo_reuse"); switch (bo_reuse_mode) { case DRI_CONF_BO_REUSE_DISABLED: break; case DRI_CONF_BO_REUSE_ALL: intel_bufmgr_gem_enable_reuse(intel->bufmgr); break; } /* This doesn't yet catch all non-conformant rendering, but it's a * start. */ if (getenv("INTEL_STRICT_CONFORMANCE")) { unsigned int value = atoi(getenv("INTEL_STRICT_CONFORMANCE")); if (value > 0) { intel->conformance_mode = value; } else { intel->conformance_mode = 1; } } if (intel->conformance_mode > 0) { ctx->Const.MinLineWidth = 1.0; ctx->Const.MinLineWidthAA = 1.0; ctx->Const.MaxLineWidth = 1.0; ctx->Const.MaxLineWidthAA = 1.0; ctx->Const.LineWidthGranularity = 1.0; } else { ctx->Const.MinLineWidth = 1.0; ctx->Const.MinLineWidthAA = 1.0; ctx->Const.MaxLineWidth = 5.0; ctx->Const.MaxLineWidthAA = 5.0; ctx->Const.LineWidthGranularity = 0.5; } ctx->Const.MinPointSize = 1.0; ctx->Const.MinPointSizeAA = 1.0; ctx->Const.MaxPointSize = 255.0; ctx->Const.MaxPointSizeAA = 3.0; ctx->Const.PointSizeGranularity = 1.0; /* reinitialize the context point state. * It depend on constants in __GLcontextRec::Const */ _mesa_init_point(ctx); meta_init_metaops(ctx, &intel->meta); ctx->Const.MaxColorAttachments = 4; /* XXX FBO: review this */ if (intel->gen >= 4) { if (MAX_WIDTH > 8192) ctx->Const.MaxRenderbufferSize = 8192; } else { if (MAX_WIDTH > 2048) ctx->Const.MaxRenderbufferSize = 2048; } /* Initialize the software rasterizer and helper modules. */ _swrast_CreateContext(ctx); _vbo_CreateContext(ctx); _tnl_CreateContext(ctx); _swsetup_CreateContext(ctx); /* Configure swrast to match hardware characteristics: */ _swrast_allow_pixel_fog(ctx, GL_FALSE); _swrast_allow_vertex_fog(ctx, GL_TRUE); _mesa_meta_init(ctx); intel->hw_stencil = mesaVis->stencilBits && mesaVis->depthBits == 24; intel->hw_stipple = 1; /* XXX FBO: this doesn't seem to be used anywhere */ switch (mesaVis->depthBits) { case 0: /* what to do in this case? */ case 16: intel->polygon_offset_scale = 1.0; break; case 24: intel->polygon_offset_scale = 2.0; /* req'd to pass glean */ break; default: assert(0); break; } if (intel->gen >= 4) intel->polygon_offset_scale /= 0xffff; intel->RenderIndex = ~0; intelInitExtensions(ctx); INTEL_DEBUG = driParseDebugString(getenv("INTEL_DEBUG"), debug_control); if (INTEL_DEBUG & DEBUG_BUFMGR) dri_bufmgr_set_debug(intel->bufmgr, GL_TRUE); intel->batch = intel_batchbuffer_alloc(intel); intel_fbo_init(intel); if (intel->ctx.Mesa_DXTn) { _mesa_enable_extension(ctx, "GL_EXT_texture_compression_s3tc"); _mesa_enable_extension(ctx, "GL_S3_s3tc"); } else if (driQueryOptionb(&intel->optionCache, "force_s3tc_enable")) { _mesa_enable_extension(ctx, "GL_EXT_texture_compression_s3tc"); } intel->use_texture_tiling = driQueryOptionb(&intel->optionCache, "texture_tiling"); intel->use_early_z = driQueryOptionb(&intel->optionCache, "early_z"); intel->prim.primitive = ~0; /* Force all software fallbacks */ if (driQueryOptionb(&intel->optionCache, "no_rast")) { fprintf(stderr, "disabling 3D rasterization\n"); intel->no_rast = 1; } if (driQueryOptionb(&intel->optionCache, "always_flush_batch")) { fprintf(stderr, "flushing batchbuffer before/after each draw call\n"); intel->always_flush_batch = 1; } if (driQueryOptionb(&intel->optionCache, "always_flush_cache")) { fprintf(stderr, "flushing GPU caches before/after each draw call\n"); intel->always_flush_cache = 1; } /* Disable all hardware rendering (skip emitting batches and fences/waits * to the kernel) */ intel->no_hw = getenv("INTEL_NO_HW") != NULL; return GL_TRUE; }
static int print_clock_info(struct pci_device *pci_dev) { uint32_t devid = pci_dev->device_id; uint16_t gcfgc; if (IS_GM45(devid)) { int core_clock = -1; pci_device_cfg_read_u16(pci_dev, &gcfgc, I915_GCFGC); switch (gcfgc & 0xf) { case 8: core_clock = 266; break; case 9: core_clock = 320; break; case 11: core_clock = 400; break; case 13: core_clock = 533; break; } print_clock("core", core_clock); } else if (IS_965(devid) && IS_MOBILE(devid)) { int render_clock = -1, sampler_clock = -1; pci_device_cfg_read_u16(pci_dev, &gcfgc, I915_GCFGC); switch (gcfgc & 0xf) { case 2: render_clock = 250; sampler_clock = 267; break; case 3: render_clock = 320; sampler_clock = 333; break; case 4: render_clock = 400; sampler_clock = 444; break; case 5: render_clock = 500; sampler_clock = 533; break; } print_clock("render", render_clock); printf(" "); print_clock("sampler", sampler_clock); } else if (IS_945(devid) && IS_MOBILE(devid)) { int render_clock = -1, display_clock = -1; pci_device_cfg_read_u16(pci_dev, &gcfgc, I915_GCFGC); switch (gcfgc & 0x7) { case 0: render_clock = 166; break; case 1: render_clock = 200; break; case 3: render_clock = 250; break; case 5: render_clock = 400; break; } switch (gcfgc & 0x70) { case 0: display_clock = 200; break; case 4: display_clock = 320; break; } if (gcfgc & (1 << 7)) display_clock = 133; print_clock("render", render_clock); printf(" "); print_clock("display", display_clock); } else if (IS_915(devid) && IS_MOBILE(devid)) { int render_clock = -1, display_clock = -1; pci_device_cfg_read_u16(pci_dev, &gcfgc, I915_GCFGC); switch (gcfgc & 0x7) { case 0: render_clock = 160; break; case 1: render_clock = 190; break; case 4: render_clock = 333; break; } if (gcfgc & (1 << 13)) render_clock = 133; switch (gcfgc & 0x70) { case 0: display_clock = 190; break; case 4: display_clock = 333; break; } if (gcfgc & (1 << 7)) display_clock = 133; print_clock("render", render_clock); printf(" "); print_clock("display", display_clock); } printf("\n"); return -1; }
static GLboolean do_check_fallback(struct brw_context *brw) { struct intel_context *intel = &brw->intel; GLcontext *ctx = &brw->intel.ctx; GLuint i; if (brw->intel.no_rast) { DBG("FALLBACK: rasterization disabled\n"); return GL_TRUE; } /* _NEW_RENDERMODE */ if (ctx->RenderMode != GL_RENDER) { DBG("FALLBACK: render mode\n"); return GL_TRUE; } /* _NEW_TEXTURE: */ for (i = 0; i < BRW_MAX_TEX_UNIT; i++) { struct gl_texture_unit *texUnit = &ctx->Texture.Unit[i]; if (texUnit->_ReallyEnabled) { struct intel_texture_object *intelObj = intel_texture_object(texUnit->_Current); struct gl_texture_image *texImage = intelObj->base.Image[0][intelObj->firstLevel]; if (texImage->Border) { DBG("FALLBACK: texture border\n"); return GL_TRUE; } } } /* _NEW_STENCIL */ if (ctx->Stencil._Enabled && (ctx->DrawBuffer->Name == 0 && !brw->intel.hw_stencil)) { DBG("FALLBACK: stencil\n"); return GL_TRUE; } /* _NEW_BUFFERS */ if (IS_965(intel->intelScreen->deviceID) && !IS_G4X(intel->intelScreen->deviceID)) { for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) { struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[i]; struct intel_renderbuffer *irb = intel_renderbuffer(rb); /* The original gen4 hardware couldn't set up WM surfaces pointing * at an offset within a tile, which can happen when rendering to * anything but the base level of a texture or the +X face/0 depth. * This was fixed with the 4 Series hardware. * * For these original chips, you would have to make the depth and * color destination surfaces include information on the texture * type, LOD, face, and various limits to use them as a destination. * I would have done this, but there's also a nasty requirement that * the depth and the color surfaces all be of the same LOD, which * may be a worse requirement than this alignment. (Also, we may * want to just demote the texture to untiled, instead). */ if (irb->region && irb->region->tiling != I915_TILING_NONE && (irb->region->draw_offset & 4095)) { DBG("FALLBACK: non-tile-aligned destination for tiled FBO\n"); return GL_TRUE; } } } return GL_FALSE; }
/** * Called by ctx->Driver.Clear. */ static void intelClear(GLcontext *ctx, GLbitfield mask) { struct intel_context *intel = intel_context(ctx); const GLuint colorMask = *((GLuint *) & ctx->Color.ColorMask); GLbitfield tri_mask = 0; GLbitfield blit_mask = 0; GLbitfield swrast_mask = 0; struct gl_framebuffer *fb = ctx->DrawBuffer; GLuint i; if (0) fprintf(stderr, "%s\n", __FUNCTION__); /* HW color buffers (front, back, aux, generic FBO, etc) */ if (colorMask == ~0) { /* clear all R,G,B,A */ /* XXX FBO: need to check if colorbuffers are software RBOs! */ blit_mask |= (mask & BUFFER_BITS_COLOR); } else { /* glColorMask in effect */ tri_mask |= (mask & (BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT)); } /* HW stencil */ if (mask & BUFFER_BIT_STENCIL) { const struct intel_region *stencilRegion = intel_get_rb_region(fb, BUFFER_STENCIL); if (stencilRegion) { /* have hw stencil */ if (IS_965(intel->intelScreen->deviceID) || (ctx->Stencil.WriteMask[0] & 0xff) != 0xff) { /* We have to use the 3D engine if we're clearing a partial mask * of the stencil buffer, or if we're on a 965 which has a tiled * depth/stencil buffer in a layout we can't blit to. */ tri_mask |= BUFFER_BIT_STENCIL; } else { /* clearing all stencil bits, use blitting */ blit_mask |= BUFFER_BIT_STENCIL; } } } /* HW depth */ if (mask & BUFFER_BIT_DEPTH) { /* clear depth with whatever method is used for stencil (see above) */ if (IS_965(intel->intelScreen->deviceID) || tri_mask & BUFFER_BIT_STENCIL) tri_mask |= BUFFER_BIT_DEPTH; else blit_mask |= BUFFER_BIT_DEPTH; } /* If we're doing a tri pass for depth/stencil, include a likely color * buffer with it. */ if (mask & (BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL)) { int color_bit = _mesa_ffs(mask & TRI_CLEAR_COLOR_BITS); if (color_bit != 0) { tri_mask |= blit_mask & (1 << (color_bit - 1)); blit_mask &= ~(1 << (color_bit - 1)); } } /* SW fallback clearing */ swrast_mask = mask & ~tri_mask & ~blit_mask; for (i = 0; i < BUFFER_COUNT; i++) { GLuint bufBit = 1 << i; if ((blit_mask | tri_mask) & bufBit) { if (!fb->Attachment[i].Renderbuffer->ClassID) { blit_mask &= ~bufBit; tri_mask &= ~bufBit; swrast_mask |= bufBit; } } } if (blit_mask) { if (INTEL_DEBUG & DEBUG_BLIT) { DBG("blit clear:"); for (i = 0; i < BUFFER_COUNT; i++) { if (blit_mask & (1 << i)) DBG(" %s", buffer_names[i]); } DBG("\n"); } intelClearWithBlit(ctx, blit_mask); } if (tri_mask) { if (INTEL_DEBUG & DEBUG_BLIT) { DBG("tri clear:"); for (i = 0; i < BUFFER_COUNT; i++) { if (tri_mask & (1 << i)) DBG(" %s", buffer_names[i]); } DBG("\n"); } intel_clear_tris(ctx, tri_mask); } if (swrast_mask) { if (INTEL_DEBUG & DEBUG_BLIT) { DBG("swrast clear:"); for (i = 0; i < BUFFER_COUNT; i++) { if (swrast_mask & (1 << i)) DBG(" %s", buffer_names[i]); } DBG("\n"); } _swrast_Clear(ctx, swrast_mask); } }
static struct intel_region * intel_recreate_static(struct intel_context *intel, const char *name, struct intel_region *region, intelRegion *region_desc) { intelScreenPrivate *intelScreen = intel->intelScreen; int ret; if (region == NULL) { region = calloc(sizeof(*region), 1); region->refcount = 1; } if (intel->ctx.Visual.rgbBits == 24) region->cpp = 4; else region->cpp = intel->ctx.Visual.rgbBits / 8; region->pitch = intelScreen->pitch; region->width = intelScreen->width; region->height = intelScreen->height; if (region->buffer != NULL) { dri_bo_unreference(region->buffer); region->buffer = NULL; } if (intel->ttm) { assert(region_desc->bo_handle != -1); region->buffer = intel_bo_gem_create_from_name(intel->bufmgr, name, region_desc->bo_handle); ret = dri_bo_get_tiling(region->buffer, ®ion->tiling, ®ion->bit_6_swizzle); if (ret != 0) { fprintf(stderr, "Couldn't get tiling of buffer %d (%s): %s\n", region_desc->bo_handle, name, strerror(-ret)); intel_region_release(®ion); return NULL; } } else { if (region->classic_map != NULL) { drmUnmap(region->classic_map, region->pitch * region->cpp * region->height); region->classic_map = NULL; } ret = drmMap(intel->driFd, region_desc->handle, region->pitch * region->cpp * region->height, ®ion->classic_map); if (ret != 0) { fprintf(stderr, "Failed to drmMap %s buffer\n", name); free(region); return NULL; } region->buffer = intel_bo_fake_alloc_static(intel->bufmgr, name, region_desc->offset, region->pitch * region->cpp * region->height, region->classic_map); /* The sarea just gives us a boolean for whether it's tiled or not, * instead of which tiling mode it is. Guess. */ if (region_desc->tiled) { if (IS_965(intel->intelScreen->deviceID) && region_desc == &intelScreen->depth) region->tiling = I915_TILING_Y; else region->tiling = I915_TILING_X; } else { region->tiling = I915_TILING_NONE; } region->bit_6_swizzle = I915_BIT_6_SWIZZLE_NONE; } assert(region->buffer != NULL); return region; }
void intel_blt_copy(struct intel_batchbuffer *batch, drm_intel_bo *src_bo, int src_x1, int src_y1, int src_pitch, drm_intel_bo *dst_bo, int dst_x1, int dst_y1, int dst_pitch, int width, int height, int bpp) { uint32_t src_tiling, dst_tiling, swizzle; uint32_t cmd_bits = 0; uint32_t br13_bits; drm_intel_bo_get_tiling(src_bo, &src_tiling, &swizzle); drm_intel_bo_get_tiling(dst_bo, &dst_tiling, &swizzle); if (IS_965(batch->devid) && src_tiling != I915_TILING_NONE) { src_pitch /= 4; cmd_bits |= XY_SRC_COPY_BLT_SRC_TILED; } if (IS_965(batch->devid) && dst_tiling != I915_TILING_NONE) { dst_pitch /= 4; cmd_bits |= XY_SRC_COPY_BLT_DST_TILED; } br13_bits = 0; switch (bpp) { case 8: break; case 16: /* supporting only RGB565, not ARGB1555 */ br13_bits |= 1 << 24; break; case 32: br13_bits |= 3 << 24; cmd_bits |= XY_SRC_COPY_BLT_WRITE_ALPHA | XY_SRC_COPY_BLT_WRITE_RGB; break; default: abort(); } #define CHECK_RANGE(x) ((x) >= 0 && (x) < (1 << 15)) assert(CHECK_RANGE(src_x1) && CHECK_RANGE(src_y1) && CHECK_RANGE(dst_x1) && CHECK_RANGE(dst_y1) && CHECK_RANGE(width) && CHECK_RANGE(height) && CHECK_RANGE(src_x1 + width) && CHECK_RANGE(src_y1 + height) && CHECK_RANGE(dst_x1 + width) && CHECK_RANGE(dst_y1 + height) && CHECK_RANGE(src_pitch) && CHECK_RANGE(dst_pitch)); #undef CHECK_RANGE BEGIN_BATCH(8); OUT_BATCH(XY_SRC_COPY_BLT_CMD | cmd_bits); OUT_BATCH((br13_bits) | (0xcc << 16) | /* copy ROP */ dst_pitch); OUT_BATCH((dst_y1 << 16) | dst_x1); /* dst x1,y1 */ OUT_BATCH(((dst_y1 + height) << 16) | (dst_x1 + width)); /* dst x2,y2 */ OUT_RELOC(dst_bo, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0); OUT_BATCH((src_y1 << 16) | src_x1); /* src x1,y1 */ OUT_BATCH(src_pitch); OUT_RELOC(src_bo, I915_GEM_DOMAIN_RENDER, 0, 0); ADVANCE_BATCH(); intel_batchbuffer_flush(batch); }