/** * \brief Query DRI2 to obtain a DRIdrawable's buffers. * * To determine which DRI buffers to request, examine the renderbuffers * attached to the drawable's framebuffer. Then request the buffers with * DRI2GetBuffers() or DRI2GetBuffersWithFormat(). * * This is called from intel_update_renderbuffers(). * * \param drawable Drawable whose buffers are queried. * \param buffers [out] List of buffers returned by DRI2 query. * \param buffer_count [out] Number of buffers returned. * * \see intel_update_renderbuffers() * \see DRI2GetBuffers() * \see DRI2GetBuffersWithFormat() */ static void intel_query_dri2_buffers(struct brw_context *brw, __DRIdrawable *drawable, __DRIbuffer **buffers, int *buffer_count) { __DRIscreen *screen = brw->intelScreen->driScrnPriv; struct gl_framebuffer *fb = drawable->driverPrivate; int i = 0; unsigned attachments[8]; struct intel_renderbuffer *front_rb; struct intel_renderbuffer *back_rb; front_rb = intel_get_renderbuffer(fb, BUFFER_FRONT_LEFT); back_rb = intel_get_renderbuffer(fb, BUFFER_BACK_LEFT); memset(attachments, 0, sizeof(attachments)); if ((brw_is_front_buffer_drawing(fb) || brw_is_front_buffer_reading(fb) || !back_rb) && front_rb) { /* If a fake front buffer is in use, then querying for * __DRI_BUFFER_FRONT_LEFT will cause the server to copy the image from * the real front buffer to the fake front buffer. So before doing the * query, we need to make sure all the pending drawing has landed in the * real front buffer. */ intel_batchbuffer_flush(brw); intel_flush_front(&brw->ctx); attachments[i++] = __DRI_BUFFER_FRONT_LEFT; attachments[i++] = intel_bits_per_pixel(front_rb); } else if (front_rb && brw->front_buffer_dirty) { /* We have pending front buffer rendering, but we aren't querying for a * front buffer. If the front buffer we have is a fake front buffer, * the X server is going to throw it away when it processes the query. * So before doing the query, make sure all the pending drawing has * landed in the real front buffer. */ intel_batchbuffer_flush(brw); intel_flush_front(&brw->ctx); } if (back_rb) { attachments[i++] = __DRI_BUFFER_BACK_LEFT; attachments[i++] = intel_bits_per_pixel(back_rb); } assert(i <= ARRAY_SIZE(attachments)); *buffers = screen->dri2.loader->getBuffersWithFormat(drawable, &drawable->w, &drawable->h, attachments, i / 2, buffer_count, drawable->loaderPrivate); }
/** * Allocates a block of space in the batchbuffer for indirect state. * * We don't want to allocate separate BOs for every bit of indirect * state in the driver. It means overallocating by a significant * margin (4096 bytes, even if the object is just a 20-byte surface * state), and more buffers to walk and count for aperture size checking. * * However, due to the restrictions imposed by the aperture size * checking performance hacks, we can't have the batch point at a * separate indirect state buffer, because once the batch points at * it, no more relocations can be added to it. So, we sneak these * buffers in at the top of the batchbuffer. */ void * brw_state_batch(struct brw_context *brw, int size, int alignment, uint32_t *out_offset) { struct intel_batchbuffer *batch = &brw->batch; uint32_t offset; assert(size < batch->bo->size); offset = ROUND_DOWN_TO(batch->state_batch_offset - size, alignment); /* If allocating from the top would wrap below the batchbuffer, or * if the batch's used space (plus the reserved pad) collides with our * space, then flush and try again. */ if (batch->state_batch_offset < size || offset < 4 * USED_BATCH(*batch) + batch->reserved_space) { intel_batchbuffer_flush(brw); offset = ROUND_DOWN_TO(batch->state_batch_offset - size, alignment); } batch->state_batch_offset = offset; if (unlikely(INTEL_DEBUG & DEBUG_BATCH)) { _mesa_hash_table_insert(batch->state_batch_sizes, (void *) (uintptr_t) offset, (void *) (uintptr_t) size); } *out_offset = offset; return batch->map + (offset>>2); }
static void intel_dri2_flush_with_flags(__DRIcontext *cPriv, __DRIdrawable *dPriv, unsigned flags, enum __DRI2throttleReason reason) { struct brw_context *brw = cPriv->driverPrivate; if (!brw) return; struct gl_context *ctx = &brw->ctx; FLUSH_VERTICES(ctx, 0); if (flags & __DRI2_FLUSH_DRAWABLE) intel_resolve_for_dri2_flush(brw, dPriv); if (reason == __DRI2_THROTTLE_SWAPBUFFER) brw->need_swap_throttle = true; if (reason == __DRI2_THROTTLE_FLUSHFRONT) brw->need_flush_throttle = true; intel_batchbuffer_flush(brw); if (INTEL_DEBUG & DEBUG_AUB) { aub_dump_bmp(ctx); } }
void brw_blorp_exec(struct brw_context *brw, const brw_blorp_params *params) { switch (brw->gen) { case 6: gen6_blorp_exec(brw, params); break; case 7: gen7_blorp_exec(brw, params); break; default: /* BLORP is not supported before Gen6. */ assert(false); break; } if (unlikely(brw->always_flush_batch)) intel_batchbuffer_flush(brw); /* We've smashed all state compared to what the normal 3D pipeline * rendering tracks for GL. */ brw->state.dirty.brw = ~0; brw->state.dirty.cache = ~0; brw->state_batch_count = 0; brw->batch.need_workaround_flush = true; brw->ib.type = -1; intel_batchbuffer_clear_cache(brw); /* Flush the sampler cache so any texturing from the destination is * coherent. */ intel_batchbuffer_emit_mi_flush(brw); }
static void gpu_blit(struct igt_fb *dst_fb, struct igt_fb *src_fb) { drm_intel_bo *dst_bo; drm_intel_bo *src_bo; int bpp; igt_assert(dst_fb->drm_format == src_fb->drm_format); igt_assert(src_fb->drm_format == DRM_FORMAT_RGB565 || igt_drm_format_to_bpp(src_fb->drm_format) != 16); bpp = igt_drm_format_to_bpp(src_fb->drm_format); dst_bo = gem_handle_to_libdrm_bo(bufmgr, drm_fd, "destination", dst_fb->gem_handle); igt_assert(dst_bo); src_bo = gem_handle_to_libdrm_bo(bufmgr, drm_fd, "source", src_fb->gem_handle); igt_assert(src_bo); intel_blt_copy(batch, src_bo, 0, 0, src_fb->width * bpp / 8, dst_bo, 0, 0, dst_fb->width * bpp / 8, src_fb->width, src_fb->height, bpp); intel_batchbuffer_flush(batch); gem_quiescent_gpu(drm_fd); drm_intel_bo_unreference(src_bo); drm_intel_bo_unreference(dst_bo); }
static void intel_flush_front(struct gl_context *ctx) { struct brw_context *brw = brw_context(ctx); __DRIcontext *driContext = brw->driContext; __DRIdrawable *driDrawable = driContext->driDrawablePriv; __DRIscreen *const screen = brw->intelScreen->driScrnPriv; if (brw->front_buffer_dirty && _mesa_is_winsys_fbo(ctx->DrawBuffer)) { if (flushFront(screen) && driDrawable && driDrawable->loaderPrivate) { /* Resolve before flushing FAKE_FRONT_LEFT to FRONT_LEFT. * * This potentially resolves both front and back buffer. It * is unnecessary to resolve the back, but harms nothing except * performance. And no one cares about front-buffer render * performance. */ intel_resolve_for_dri2_flush(brw, driDrawable); intel_batchbuffer_flush(brw); flushFront(screen)(driDrawable, driDrawable->loaderPrivate); /* We set the dirty bit in intel_prepare_render() if we're * front buffer rendering once we get there. */ brw->front_buffer_dirty = false; } } }
static void blitter_copyfunc(struct scratch_buf *src, unsigned src_x, unsigned src_y, struct scratch_buf *dst, unsigned dst_x, unsigned dst_y, unsigned logical_tile_no) { static unsigned keep_gpu_busy_counter = 0; /* check both edges of the fence usage */ if (keep_gpu_busy_counter & 1 && !fence_storm) keep_gpu_busy(); emit_blt(src->bo, src->tiling, src->stride, src_x, src_y, options.tile_size, options.tile_size, dst->bo, dst->tiling, dst->stride, dst_x, dst_y); if (!(keep_gpu_busy_counter & 1) && !fence_storm) keep_gpu_busy(); keep_gpu_busy_counter++; if (src->tiling) fence_storm--; if (dst->tiling) fence_storm--; if (fence_storm <= 1) { fence_storm = 0; intel_batchbuffer_flush(batch); } }
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); }
/** * Allocates a block of space in the batchbuffer for indirect state. * * We don't want to allocate separate BOs for every bit of indirect * state in the driver. It means overallocating by a significant * margin (4096 bytes, even if the object is just a 20-byte surface * state), and more buffers to walk and count for aperture size checking. * * However, due to the restrictions inposed by the aperture size * checking performance hacks, we can't have the batch point at a * separate indirect state buffer, because once the batch points at * it, no more relocations can be added to it. So, we sneak these * buffers in at the top of the batchbuffer. */ void * brw_state_batch(struct brw_context *brw, enum state_struct_type type, int size, int alignment, uint32_t *out_offset) { struct intel_batchbuffer *batch = &brw->intel.batch; uint32_t offset; assert(size < batch->bo->size); offset = ROUND_DOWN_TO(batch->state_batch_offset - size, alignment); /* If allocating from the top would wrap below the batchbuffer, or * if the batch's used space (plus the reserved pad) collides with our * space, then flush and try again. */ if (batch->state_batch_offset < size || offset < 4*batch->used + batch->reserved_space) { intel_batchbuffer_flush(&brw->intel); offset = ROUND_DOWN_TO(batch->state_batch_offset - size, alignment); } batch->state_batch_offset = offset; if (unlikely(INTEL_DEBUG & (DEBUG_BATCH | DEBUG_AUB))) brw_track_state_batch(brw, type, offset, size); *out_offset = offset; return batch->map + (offset>>2); }
/** * Allocates a block of space in the batchbuffer for indirect state. * * We don't want to allocate separate BOs for every bit of indirect * state in the driver. It means overallocating by a significant * margin (4096 bytes, even if the object is just a 20-byte surface * state), and more buffers to walk and count for aperture size checking. * * However, due to the restrictions inposed by the aperture size * checking performance hacks, we can't have the batch point at a * separate indirect state buffer, because once the batch points at * it, no more relocations can be added to it. So, we sneak these * buffers in at the top of the batchbuffer. */ void * brw_state_batch(struct brw_context *brw, int size, int alignment, drm_intel_bo **out_bo, uint32_t *out_offset) { struct intel_batchbuffer *batch = brw->intel.batch; uint32_t offset; assert(size < batch->buf->size); offset = ROUND_DOWN_TO(batch->state_batch_offset - size, alignment); /* If allocating from the top would wrap below the batchbuffer, or * if the batch's used space (plus the reserved pad) collides with our * space, then flush and try again. */ if (batch->state_batch_offset < size || offset < batch->ptr - batch->map + batch->reserved_space) { intel_batchbuffer_flush(batch); offset = ROUND_DOWN_TO(batch->state_batch_offset - size, alignment); } batch->state_batch_offset = offset; if (*out_bo != batch->buf) { drm_intel_bo_unreference(*out_bo); drm_intel_bo_reference(batch->buf); *out_bo = batch->buf; } *out_offset = offset; return batch->map + offset; }
void intelDestroyContext(__DRIcontext * driContextPriv) { struct brw_context *brw = (struct brw_context *) driContextPriv->driverPrivate; struct gl_context *ctx = &brw->ctx; assert(brw); /* should never be null */ if (!brw) return; /* Dump a final BMP in case the application doesn't call SwapBuffers */ if (INTEL_DEBUG & DEBUG_AUB) { intel_batchbuffer_flush(brw); aub_dump_bmp(&brw->ctx); } _mesa_meta_free(&brw->ctx); if (INTEL_DEBUG & DEBUG_SHADER_TIME) { /* Force a report. */ brw->shader_time.report_time = 0; brw_collect_and_report_shader_time(brw); brw_destroy_shader_time(brw); } brw_destroy_state(brw); brw_draw_destroy(brw); drm_intel_bo_unreference(brw->curbe.curbe_bo); free(brw->curbe.last_buf); free(brw->curbe.next_buf); drm_intel_gem_context_destroy(brw->hw_ctx); if (ctx->swrast_context) { _swsetup_DestroyContext(&brw->ctx); _tnl_DestroyContext(&brw->ctx); } _vbo_DestroyContext(&brw->ctx); if (ctx->swrast_context) _swrast_DestroyContext(&brw->ctx); intel_batchbuffer_free(brw); drm_intel_bo_unreference(brw->first_post_swapbuffers_batch); brw->first_post_swapbuffers_batch = NULL; driDestroyOptionCache(&brw->optionCache); /* free the Mesa context */ _mesa_free_context_data(&brw->ctx); ralloc_free(brw); driContextPriv->driverPrivate = NULL; }
void intel_batchbuffer_finish(struct intel_batchbuffer *batch) { struct _DriFenceObject *fence = intel_batchbuffer_flush(batch); driFenceReference(fence); driFenceFinish(fence, 3, GL_FALSE); driFenceUnReference(fence); }
void gen7_begin_transform_feedback(struct gl_context *ctx, GLenum mode, struct gl_transform_feedback_object *obj) { struct brw_context *brw = brw_context(ctx); intel_batchbuffer_flush(brw); brw->batch.needs_sol_reset = true; }
/** * Used to initialize the alpha value of an ARGB8888 miptree after copying * into it from an XRGB8888 source. * * This is very common with glCopyTexImage2D(). Note that the coordinates are * relative to the start of the miptree, not relative to a slice within the * miptree. */ static void intel_miptree_set_alpha_to_one(struct brw_context *brw, struct intel_mipmap_tree *mt, int x, int y, int width, int height) { uint32_t BR13, CMD; int pitch, cpp; drm_intel_bo *aper_array[2]; pitch = mt->pitch; cpp = mt->cpp; DBG("%s dst:buf(%p)/%d %d,%d sz:%dx%d\n", __FUNCTION__, mt->bo, pitch, x, y, width, height); BR13 = br13_for_cpp(cpp) | 0xf0 << 16; CMD = XY_COLOR_BLT_CMD; CMD |= XY_BLT_WRITE_ALPHA; if (mt->tiling != I915_TILING_NONE) { CMD |= XY_DST_TILED; pitch /= 4; } BR13 |= pitch; /* do space check before going any further */ aper_array[0] = brw->batch.bo; aper_array[1] = mt->bo; if (drm_intel_bufmgr_check_aperture_space(aper_array, ARRAY_SIZE(aper_array)) != 0) { intel_batchbuffer_flush(brw); } unsigned length = brw->gen >= 8 ? 7 : 6; bool dst_y_tiled = mt->tiling == I915_TILING_Y; BEGIN_BATCH_BLT_TILED(length, dst_y_tiled, false); OUT_BATCH(CMD | (length - 2)); OUT_BATCH(BR13); OUT_BATCH(SET_FIELD(y, BLT_Y) | SET_FIELD(x, BLT_X)); OUT_BATCH(SET_FIELD(y + height, BLT_Y) | SET_FIELD(x + width, BLT_X)); if (brw->gen >= 8) { OUT_RELOC64(mt->bo, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0); } else { OUT_RELOC(mt->bo, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0); } OUT_BATCH(0xffffffff); /* white, but only alpha gets written */ ADVANCE_BATCH_TILED(dst_y_tiled, false); intel_batchbuffer_emit_mi_flush(brw); }
static void intel_glFlush(struct gl_context *ctx) { struct brw_context *brw = brw_context(ctx); intel_batchbuffer_flush(brw); intel_flush_front(ctx); if (brw->is_front_buffer_rendering) brw->need_throttle = true; }
static void intel_glFlush(struct gl_context *ctx) { struct brw_context *brw = brw_context(ctx); intel_batchbuffer_flush(brw); intel_flush_front(ctx); if (brw_is_front_buffer_drawing(ctx->DrawBuffer)) brw->need_throttle = true; }
void intelWrapInlinePrimitive(struct intel_context *intel) { GLuint prim = intel->prim.primitive; GLuint batchflags = intel->batch->flags; intel_flush_inline_primitive(intel); intel_batchbuffer_flush(intel->batch); intelStartInlinePrimitive(intel, prim, batchflags); /* ??? */ }
static void bad_batch(void) { BEGIN_BATCH(2, 0); OUT_BATCH(MI_BATCH_BUFFER_START); OUT_BATCH(0); ADVANCE_BATCH(); intel_batchbuffer_flush(batch); }
void intel_batchbuffer_require_space(struct intel_batchbuffer *batch, unsigned int size) { assert(size < batch->size - 8); if (intel_batchbuffer_space(batch) < size) { intel_batchbuffer_flush(batch); } }
/* XXX: Do this for TexSubImage also: */ static GLboolean try_pbo_upload(struct intel_context *intel, struct intel_texture_image *intelImage, const struct gl_pixelstore_attrib *unpack, GLint internalFormat, GLint width, GLint height, GLenum format, GLenum type, const void *pixels) { struct intel_buffer_object *pbo = intel_buffer_object(unpack->BufferObj); GLuint src_offset, src_stride; GLuint dst_offset, dst_stride; if (!pbo || intel->ctx._ImageTransferState || unpack->SkipPixels || unpack->SkipRows) { _mesa_printf("%s: failure 1\n", __FUNCTION__); return GL_FALSE; } src_offset = (GLuint) pixels; if (unpack->RowLength > 0) src_stride = unpack->RowLength; else src_stride = width; dst_offset = intel_miptree_image_offset(intelImage->mt, intelImage->face, intelImage->level); dst_stride = intelImage->mt->pitch; intelFlush(&intel->ctx); LOCK_HARDWARE(intel); { struct _DriBufferObject *src_buffer = intel_bufferobj_buffer(intel, pbo, INTEL_READ); struct _DriBufferObject *dst_buffer = intel_region_buffer(intel->intelScreen, intelImage->mt->region, INTEL_WRITE_FULL); intelEmitCopyBlit(intel, intelImage->mt->cpp, src_stride, src_buffer, src_offset, dst_stride, dst_buffer, dst_offset, 0, 0, 0, 0, width, height, GL_COPY); intel_batchbuffer_flush(intel->batch); } UNLOCK_HARDWARE(intel); return GL_TRUE; }
static void brw_fence_insert(struct brw_context *brw, struct brw_fence *fence) { assert(!fence->batch_bo); assert(!fence->signalled); brw_emit_mi_flush(brw); fence->batch_bo = brw->batch.bo; drm_intel_bo_reference(fence->batch_bo); intel_batchbuffer_flush(brw); }
int main(int argc, char **argv) { int fd, i; fd = drm_open_any(); bufmgr = drm_intel_bufmgr_gem_init(fd, 4096); if (!bufmgr) { fprintf(stderr, "failed to init libdrm\n"); exit(-1); } /* don't enable buffer reuse!! */ //drm_intel_bufmgr_gem_enable_reuse(bufmgr); batch = intel_batchbuffer_alloc(bufmgr, intel_get_drm_devid(fd)); assert(batch); /* put some load onto the gpu to keep the light buffers active for long * enough */ for (i = 0; i < 1000; i++) { load_bo = drm_intel_bo_alloc(bufmgr, "target bo", 1024*4096, 4096); if (!load_bo) { fprintf(stderr, "failed to alloc target buffer\n"); exit(-1); } BEGIN_BATCH(8); OUT_BATCH(XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA | XY_SRC_COPY_BLT_WRITE_RGB); OUT_BATCH((3 << 24) | /* 32 bits */ (0xcc << 16) | /* copy ROP */ 4096); OUT_BATCH(0); /* dst x1,y1 */ OUT_BATCH((1024 << 16) | 512); OUT_RELOC(load_bo, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0); OUT_BATCH((0 << 16) | 512); /* src x1, y1 */ OUT_BATCH(4096); OUT_RELOC(load_bo, I915_GEM_DOMAIN_RENDER, 0, 0); ADVANCE_BATCH(); intel_batchbuffer_flush(batch); drm_intel_bo_disable_reuse(load_bo); drm_intel_bo_unreference(load_bo); } drm_intel_bufmgr_destroy(bufmgr); close(fd); return 0; }
void gen9_media_fillfunc(struct intel_batchbuffer *batch, struct igt_buf *dst, unsigned x, unsigned y, unsigned width, unsigned height, uint8_t color) { uint32_t curbe_buffer, interface_descriptor; uint32_t batch_end; intel_batchbuffer_flush(batch); /* setup states */ batch->ptr = &batch->buffer[BATCH_STATE_SPLIT]; curbe_buffer = gen8_fill_curbe_buffer_data(batch, color); interface_descriptor = gen8_fill_interface_descriptor(batch, dst); assert(batch->ptr < &batch->buffer[4095]); /* media pipeline */ batch->ptr = batch->buffer; OUT_BATCH(GEN8_PIPELINE_SELECT | PIPELINE_SELECT_MEDIA | GEN9_FORCE_MEDIA_AWAKE_ENABLE | GEN9_SAMPLER_DOP_GATE_DISABLE | GEN9_PIPELINE_SELECTION_MASK | GEN9_SAMPLER_DOP_GATE_MASK | GEN9_FORCE_MEDIA_AWAKE_MASK); gen9_emit_state_base_address(batch); gen8_emit_vfe_state(batch); gen8_emit_curbe_load(batch, curbe_buffer); gen8_emit_interface_descriptor_load(batch, interface_descriptor); gen8_emit_media_objects(batch, x, y, width, height); OUT_BATCH(GEN8_PIPELINE_SELECT | PIPELINE_SELECT_MEDIA | GEN9_FORCE_MEDIA_AWAKE_DISABLE | GEN9_SAMPLER_DOP_GATE_ENABLE | GEN9_PIPELINE_SELECTION_MASK | GEN9_SAMPLER_DOP_GATE_MASK | GEN9_FORCE_MEDIA_AWAKE_MASK); OUT_BATCH(MI_BATCH_BUFFER_END); batch_end = batch_align(batch, 8); assert(batch_end < BATCH_STATE_SPLIT); gen8_render_flush(batch, batch_end); intel_batchbuffer_reset(batch); }
static void draw_rect_blt(int fd, struct cmd_data *cmd_data, struct buf_data *buf, struct rect *rect, uint32_t color) { drm_intel_bo *dst; struct intel_batchbuffer *batch; int blt_cmd_len, blt_cmd_tiling, blt_cmd_depth; uint32_t devid = intel_get_drm_devid(fd); int gen = intel_gen(devid); uint32_t tiling, swizzle; int pitch; gem_get_tiling(fd, buf->handle, &tiling, &swizzle); dst = gem_handle_to_libdrm_bo(cmd_data->bufmgr, fd, "", buf->handle); igt_assert(dst); batch = intel_batchbuffer_alloc(cmd_data->bufmgr, devid); igt_assert(batch); switch (buf->bpp) { case 8: blt_cmd_depth = 0; break; case 16: /* we're assuming 565 */ blt_cmd_depth = 1 << 24; break; case 32: blt_cmd_depth = 3 << 24; break; default: igt_assert(false); } blt_cmd_len = (gen >= 8) ? 0x5 : 0x4; blt_cmd_tiling = (tiling) ? XY_COLOR_BLT_TILED : 0; pitch = (tiling) ? buf->stride / 4 : buf->stride; BEGIN_BATCH(6, 1); OUT_BATCH(XY_COLOR_BLT_CMD_NOLEN | XY_COLOR_BLT_WRITE_ALPHA | XY_COLOR_BLT_WRITE_RGB | blt_cmd_tiling | blt_cmd_len); OUT_BATCH(blt_cmd_depth | (0xF0 << 16) | pitch); OUT_BATCH((rect->y << 16) | rect->x); OUT_BATCH(((rect->y + rect->h) << 16) | (rect->x + rect->w)); OUT_RELOC_FENCED(dst, 0, I915_GEM_DOMAIN_RENDER, 0); OUT_BATCH(color); ADVANCE_BATCH(); intel_batchbuffer_flush(batch); intel_batchbuffer_free(batch); }
void intelDestroyContext(__DRIcontext * driContextPriv) { struct intel_context *intel = (struct intel_context *) driContextPriv->driverPrivate; struct gl_context *ctx = &intel->ctx; assert(intel); /* should never be null */ if (intel) { INTEL_FIREVERTICES(intel); /* Dump a final BMP in case the application doesn't call SwapBuffers */ if (INTEL_DEBUG & DEBUG_AUB) { intel_batchbuffer_flush(intel); aub_dump_bmp(&intel->ctx); } _mesa_meta_free(&intel->ctx); intel->vtbl.destroy(intel); if (ctx->swrast_context) { _swsetup_DestroyContext(&intel->ctx); _tnl_DestroyContext(&intel->ctx); } _vbo_DestroyContext(&intel->ctx); if (ctx->swrast_context) _swrast_DestroyContext(&intel->ctx); intel->Fallback = 0x0; /* don't call _swrast_Flush later */ intel_batchbuffer_free(intel); free(intel->prim.vb); intel->prim.vb = NULL; drm_intel_bo_unreference(intel->prim.vb_bo); intel->prim.vb_bo = NULL; drm_intel_bo_unreference(intel->first_post_swapbuffers_batch); intel->first_post_swapbuffers_batch = NULL; driDestroyOptionCache(&intel->optionCache); /* free the Mesa context */ _mesa_free_context_data(&intel->ctx); _math_matrix_dtr(&intel->ViewportMatrix); ralloc_free(intel); driContextPriv->driverPrivate = NULL; } }
void gen7_end_transform_feedback(struct gl_context *ctx, struct gl_transform_feedback_object *obj) { /* Because we have to rely on the kernel to reset our SO write offsets, and * we only get to do it once per batchbuffer, flush the batch after feedback * so another transform feedback can get the write offset reset it needs. * * This also covers any cache flushing required. */ struct brw_context *brw = brw_context(ctx); intel_batchbuffer_flush(brw); }
/** * Used to initialize the alpha value of an ARGB8888 miptree after copying * into it from an XRGB8888 source. * * This is very common with glCopyTexImage2D(). Note that the coordinates are * relative to the start of the miptree, not relative to a slice within the * miptree. */ static void intel_miptree_set_alpha_to_one(struct brw_context *brw, struct intel_mipmap_tree *mt, int x, int y, int width, int height) { struct intel_region *region = mt->region; uint32_t BR13, CMD; int pitch, cpp; drm_intel_bo *aper_array[2]; pitch = region->pitch; cpp = region->cpp; DBG("%s dst:buf(%p)/%d %d,%d sz:%dx%d\n", __FUNCTION__, region->bo, pitch, x, y, width, height); BR13 = br13_for_cpp(cpp) | 0xf0 << 16; CMD = XY_COLOR_BLT_CMD; CMD |= XY_BLT_WRITE_ALPHA; if (region->tiling != I915_TILING_NONE) { CMD |= XY_DST_TILED; pitch /= 4; } BR13 |= pitch; /* do space check before going any further */ aper_array[0] = brw->batch.bo; aper_array[1] = region->bo; if (drm_intel_bufmgr_check_aperture_space(aper_array, ARRAY_SIZE(aper_array)) != 0) { intel_batchbuffer_flush(brw); } bool dst_y_tiled = region->tiling == I915_TILING_Y; BEGIN_BATCH_BLT_TILED(6, dst_y_tiled, false); OUT_BATCH(CMD | (6 - 2)); OUT_BATCH(BR13); OUT_BATCH((y << 16) | x); OUT_BATCH(((y + height) << 16) | (x + width)); OUT_RELOC_FENCED(region->bo, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0); OUT_BATCH(0xffffffff); /* white, but only alpha gets written */ ADVANCE_BATCH_TILED(dst_y_tiled, false); intel_batchbuffer_emit_mi_flush(brw); }
static void dummy_reloc_loop(void) { int i, j; for (i = 0; i < 0x800; i++) { BEGIN_BATCH(8); OUT_BATCH(XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA | XY_SRC_COPY_BLT_WRITE_RGB); OUT_BATCH((3 << 24) | /* 32 bits */ (0xcc << 16) | /* copy ROP */ 4*4096); OUT_BATCH(2048 << 16 | 0); OUT_BATCH((4096) << 16 | (2048)); OUT_RELOC_FENCED(blt_bo, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0); OUT_BATCH(0 << 16 | 0); OUT_BATCH(4*4096); OUT_RELOC_FENCED(blt_bo, I915_GEM_DOMAIN_RENDER, 0, 0); ADVANCE_BATCH(); intel_batchbuffer_flush(batch); BEGIN_BATCH(4); OUT_BATCH(MI_FLUSH_DW | 1); OUT_BATCH(0); /* reserved */ OUT_RELOC(target_buffer, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0); OUT_BATCH(MI_NOOP | (1<<22) | (0xf)); ADVANCE_BATCH(); intel_batchbuffer_flush(batch); drm_intel_bo_map(target_buffer, 0); // map to force completion drm_intel_bo_unmap(target_buffer); } }
void intel_batchbuffer_check_batchbuffer_flag(struct intel_batchbuffer *batch, int flag) { if (flag != I915_EXEC_RENDER && flag != I915_EXEC_BLT && flag != I915_EXEC_BSD && flag != I915_EXEC_VEBOX) return; if (batch->flag == flag) return; intel_batchbuffer_flush(batch); batch->flag = flag; }
static void copy_tiles(unsigned *permutation) { unsigned src_tile, src_buf_idx, src_x, src_y; unsigned dst_tile, dst_buf_idx, dst_x, dst_y; struct scratch_buf *src_buf, *dst_buf; int i, idx; for (i = 0; i < num_total_tiles; i++) { /* tile_permutation is independent of current_permutation, so * abuse it to randomize the order of the src bos */ idx = tile_permutation[i]; src_buf_idx = idx / options.tiles_per_buf; src_tile = idx % options.tiles_per_buf; src_buf = &buffers[current_set][src_buf_idx]; tile2xy(src_buf, src_tile, &src_x, &src_y); dst_buf_idx = permutation[idx] / options.tiles_per_buf; dst_tile = permutation[idx] % options.tiles_per_buf; dst_buf = &buffers[target_set][dst_buf_idx]; tile2xy(dst_buf, dst_tile, &dst_x, &dst_y); if (options.trace_tile == i) printf("copying tile %i from %i (%i, %i) to %i (%i, %i)", i, tile_permutation[i], src_buf_idx, src_tile, permutation[idx], dst_buf_idx, dst_tile); if (options.no_hw) { cpucpy2d(src_buf->data, src_buf->stride / sizeof(uint32_t), src_x, src_y, dst_buf->data, dst_buf->stride / sizeof(uint32_t), dst_x, dst_y, i); } else { next_copyfunc(i); copyfunc(src_buf, src_x, src_y, dst_buf, dst_x, dst_y, i); } } intel_batchbuffer_flush(batch); }