HRESULT WINAPI NineTexture9_AddDirtyRect( struct NineTexture9 *This, const RECT *pDirtyRect ) { DBG("This=%p pDirtyRect=%p[(%u,%u)-(%u,%u)]\n", This, pDirtyRect, pDirtyRect ? pDirtyRect->left : 0, pDirtyRect ? pDirtyRect->top : 0, pDirtyRect ? pDirtyRect->right : 0, pDirtyRect ? pDirtyRect->bottom : 0); /* Tracking dirty regions on DEFAULT or SYSTEMMEM resources is pointless, * because we always write to the final storage. Just marked it dirty in * case we need to generate mip maps. */ if (This->base.base.pool != D3DPOOL_MANAGED) { if (This->base.base.usage & D3DUSAGE_AUTOGENMIPMAP) This->base.dirty_mip = TRUE; return D3D_OK; } This->base.managed.dirty = TRUE; BASETEX_REGISTER_UPDATE(&This->base); if (!pDirtyRect) { u_box_origin_2d(This->base.base.info.width0, This->base.base.info.height0, &This->dirty_rect); } else { struct pipe_box box; rect_to_pipe_box_clamp(&box, pDirtyRect); u_box_union_2d(&This->dirty_rect, &This->dirty_rect, &box); (void) u_box_clip_2d(&This->dirty_rect, &This->dirty_rect, This->base.base.info.width0, This->base.base.info.height0); } return D3D_OK; }
/** * Schedule a copy swap from the back to the front buffer using the * native display's copy context. */ boolean resource_surface_copy_swap(struct resource_surface *rsurf, struct native_display *ndpy) { struct pipe_resource *ftex; struct pipe_resource *btex; struct pipe_context *pipe; struct pipe_box src_box; boolean ret = FALSE; pipe = ndpy_get_copy_context(ndpy); if (!pipe) return FALSE; ftex = resource_surface_get_single_resource(rsurf, NATIVE_ATTACHMENT_FRONT_LEFT); if (!ftex) goto out_no_ftex; btex = resource_surface_get_single_resource(rsurf, NATIVE_ATTACHMENT_BACK_LEFT); if (!btex) goto out_no_btex; u_box_origin_2d(ftex->width0, ftex->height0, &src_box); pipe->resource_copy_region(pipe, ftex, 0, 0, 0, 0, btex, 0, &src_box); ret = TRUE; out_no_btex: pipe_resource_reference(&btex, NULL); out_no_ftex: pipe_resource_reference(&ftex, NULL); return ret; }
void NineSurface9_CopyDefaultToMem( struct NineSurface9 *This, struct NineSurface9 *From ) { struct pipe_context *pipe = This->pipe; struct pipe_resource *r_src = From->base.resource; struct pipe_transfer *transfer; struct pipe_box src_box; uint8_t *p_dst; const uint8_t *p_src; assert(This->base.pool == D3DPOOL_SYSTEMMEM && From->base.pool == D3DPOOL_DEFAULT); assert(This->desc.Width == From->desc.Width); assert(This->desc.Height == From->desc.Height); u_box_origin_2d(This->desc.Width, This->desc.Height, &src_box); src_box.z = From->layer; p_src = pipe->transfer_map(pipe, r_src, From->level, PIPE_TRANSFER_READ, &src_box, &transfer); p_dst = NineSurface9_GetSystemMemPointer(This, 0, 0); assert (p_src && p_dst); util_copy_rect(p_dst, This->base.info.format, This->stride, 0, 0, This->desc.Width, This->desc.Height, p_src, transfer->stride, 0, 0); pipe->transfer_unmap(pipe, transfer); }
static void vl_dri3_flush_frontbuffer(struct pipe_screen *screen, struct pipe_resource *resource, unsigned level, unsigned layer, void *context_private, struct pipe_box *sub_box) { struct vl_dri3_screen *scrn = (struct vl_dri3_screen *)context_private; uint32_t options = XCB_PRESENT_OPTION_NONE; struct vl_dri3_buffer *back; struct pipe_box src_box; xcb_xfixes_region_t region; xcb_rectangle_t rectangle; back = scrn->back_buffers[scrn->cur_back]; if (!back) return; while (scrn->special_event && scrn->recv_sbc < scrn->send_sbc) if (!dri3_wait_present_events(scrn)) return; rectangle.x = 0; rectangle.y = 0; rectangle.width = (scrn->output_texture) ? scrn->clip_width : scrn->width; rectangle.height = (scrn->output_texture) ? scrn->clip_height : scrn->height; region = xcb_generate_id(scrn->conn); xcb_xfixes_create_region(scrn->conn, region, 2, &rectangle); if (scrn->is_different_gpu) { u_box_origin_2d(back->width, back->height, &src_box); scrn->pipe->resource_copy_region(scrn->pipe, back->linear_texture, 0, 0, 0, 0, back->texture, 0, &src_box); scrn->pipe->flush(scrn->pipe, NULL, 0); } xshmfence_reset(back->shm_fence); back->busy = true; xcb_present_pixmap(scrn->conn, scrn->drawable, back->pixmap, (uint32_t)(++scrn->send_sbc), 0, region, 0, 0, None, None, back->sync_fence, options, scrn->next_msc, 0, 0, 0, NULL); xcb_flush(scrn->conn); return; }
static void vg_context_update_surface_mask_view(struct vg_context *ctx, uint width, uint height) { struct st_framebuffer *stfb = ctx->draw_buffer; struct pipe_sampler_view *old_sampler_view = stfb->surface_mask_view; struct pipe_context *pipe = ctx->pipe; if (old_sampler_view && old_sampler_view->texture->width0 == width && old_sampler_view->texture->height0 == height) return; /* we use PIPE_FORMAT_B8G8R8A8_UNORM because we want to render to this texture and use it as a sampler, so while this wastes some space it makes both of those a lot simpler */ stfb->surface_mask_view = create_tex_and_view(pipe, PIPE_FORMAT_B8G8R8A8_UNORM, width, height); if (!stfb->surface_mask_view) { if (old_sampler_view) pipe_sampler_view_reference(&old_sampler_view, NULL); return; } /* XXX could this call be avoided? */ vg_validate_state(ctx); /* alpha mask starts with 1.f alpha */ mask_fill(0, 0, width, height, 1.f); /* if we had an old surface copy it over */ if (old_sampler_view) { struct pipe_box src_box; u_box_origin_2d(MIN2(old_sampler_view->texture->width0, stfb->surface_mask_view->texture->width0), MIN2(old_sampler_view->texture->height0, stfb->surface_mask_view->texture->height0), &src_box); pipe->resource_copy_region(pipe, stfb->surface_mask_view->texture, 0, 0, 0, 0, old_sampler_view->texture, 0, &src_box); } /* Free the old texture */ if (old_sampler_view) pipe_sampler_view_reference(&old_sampler_view, NULL); }
/* Copy a detiled texture to a tiled one. */ static void r300_copy_into_tiled_texture(struct pipe_context *ctx, struct r300_transfer *r300transfer) { struct pipe_transfer *transfer = (struct pipe_transfer*)r300transfer; struct pipe_resource *tex = transfer->resource; struct pipe_box src_box; u_box_origin_2d(transfer->box.width, transfer->box.height, &src_box); ctx->resource_copy_region(ctx, tex, transfer->level, transfer->box.x, transfer->box.y, transfer->box.z, &r300transfer->linear_texture->b.b.b, 0, &src_box); /* XXX remove this. */ r300_flush(ctx, 0, NULL); }
static void copy_resources(struct native_display *ndpy, struct pipe_resource *src, struct pipe_resource *dst) { struct pipe_context *pipe; struct pipe_box box; pipe = ndpy_get_copy_context(ndpy); if (!pipe) return; u_box_origin_2d(src->width0, src->height0, &box); pipe->resource_copy_region(pipe, dst, 0, 0, 0, 0, src, 0, &box); pipe->flush(pipe, NULL); }
boolean native_display_copy_to_pixmap(struct native_display *ndpy, EGLNativePixmapType pix, struct pipe_resource *src) { struct pipe_context *pipe; struct native_surface *nsurf; struct pipe_resource *dst; struct pipe_resource *tmp[NUM_NATIVE_ATTACHMENTS]; const enum native_attachment natt = NATIVE_ATTACHMENT_FRONT_LEFT; pipe = ndpy_get_copy_context(ndpy); if (!pipe) return FALSE; nsurf = ndpy->create_pixmap_surface(ndpy, pix, NULL); if (!nsurf) return FALSE; /* get the texutre */ tmp[natt] = NULL; nsurf->validate(nsurf, 1 << natt, NULL, tmp, NULL, NULL); dst = tmp[natt]; if (dst && dst->format == src->format) { struct native_present_control ctrl; struct pipe_box src_box; u_box_origin_2d(src->width0, src->height0, &src_box); pipe->resource_copy_region(pipe, dst, 0, 0, 0, 0, src, 0, &src_box); pipe->flush(pipe, NULL, 0); memset(&ctrl, 0, sizeof(ctrl)); ctrl.natt = natt; nsurf->present(nsurf, &ctrl); } if (dst) pipe_resource_reference(&dst, NULL); nsurf->destroy(nsurf); return TRUE; }
HRESULT NINE_WINAPI NineSurface9_UnlockRect( struct NineSurface9 *This ) { DBG("This=%p lock_count=%u\n", This, This->lock_count); user_assert(This->lock_count, D3DERR_INVALIDCALL); if (This->transfer) { This->pipe->transfer_unmap(This->pipe, This->transfer); This->transfer = NULL; } --This->lock_count; if (This->data_conversion) { struct pipe_transfer *transfer; uint8_t *dst = This->data; struct pipe_box box; u_box_origin_2d(This->desc.Width, This->desc.Height, &box); if (!dst) { dst = This->pipe->transfer_map(This->pipe, This->base.resource, This->level, PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE, &box, &transfer); if (!dst) return D3D_OK; } (void) util_format_translate(This->base.info.format, dst, This->data ? This->stride : transfer->stride, 0, 0, This->format_conversion, This->data_conversion, This->stride_conversion, 0, 0, This->desc.Width, This->desc.Height); if (!This->data) pipe_transfer_unmap(This->pipe, transfer); } return D3D_OK; }
HRESULT NINE_WINAPI NineCubeTexture9_AddDirtyRect( struct NineCubeTexture9 *This, D3DCUBEMAP_FACES FaceType, const RECT *pDirtyRect ) { DBG("This=%p FaceType=%d pDirtyRect=%p\n", This, FaceType, pDirtyRect); user_assert(FaceType < 6, D3DERR_INVALIDCALL); if (This->base.base.pool != D3DPOOL_MANAGED) { if (This->base.base.usage & D3DUSAGE_AUTOGENMIPMAP) { This->base.dirty_mip = TRUE; BASETEX_REGISTER_UPDATE(&This->base); } return D3D_OK; } if (This->base.base.pool == D3DPOOL_MANAGED) { This->base.managed.dirty = TRUE; BASETEX_REGISTER_UPDATE(&This->base); } if (!pDirtyRect) { u_box_origin_2d(This->base.base.info.width0, This->base.base.info.height0, &This->dirty_rect[FaceType]); } else { struct pipe_box box; rect_to_pipe_box_clamp(&box, pDirtyRect); u_box_union_2d(&This->dirty_rect[FaceType], &This->dirty_rect[FaceType], &box); (void) u_box_clip_2d(&This->dirty_rect[FaceType], &This->dirty_rect[FaceType], This->base.base.info.width0, This->base.base.info.height0); } return D3D_OK; }
/** * Create the texture map we'll use for antialiasing the lines. */ static boolean aaline_create_texture(struct aaline_stage *aaline) { struct pipe_context *pipe = aaline->stage.draw->pipe; struct pipe_screen *screen = pipe->screen; struct pipe_resource texTemp; struct pipe_sampler_view viewTempl; uint level; memset(&texTemp, 0, sizeof(texTemp)); texTemp.target = PIPE_TEXTURE_2D; texTemp.format = PIPE_FORMAT_A8_UNORM; /* XXX verify supported by driver! */ texTemp.last_level = MAX_TEXTURE_LEVEL; texTemp.width0 = 1 << MAX_TEXTURE_LEVEL; texTemp.height0 = 1 << MAX_TEXTURE_LEVEL; texTemp.depth0 = 1; texTemp.array_size = 1; texTemp.bind = PIPE_BIND_SAMPLER_VIEW; aaline->texture = screen->resource_create(screen, &texTemp); if (!aaline->texture) return FALSE; u_sampler_view_default_template(&viewTempl, aaline->texture, aaline->texture->format); aaline->sampler_view = pipe->create_sampler_view(pipe, aaline->texture, &viewTempl); if (!aaline->sampler_view) { return FALSE; } /* Fill in mipmap images. * Basically each level is solid opaque, except for the outermost * texels which are zero. Special case the 1x1 and 2x2 levels * (though, those levels shouldn't be used - see the max_lod setting). */ for (level = 0; level <= MAX_TEXTURE_LEVEL; level++) { struct pipe_transfer *transfer; struct pipe_box box; const uint size = u_minify(aaline->texture->width0, level); ubyte *data; uint i, j; assert(aaline->texture->width0 == aaline->texture->height0); u_box_origin_2d( size, size, &box ); /* This texture is new, no need to flush. */ transfer = pipe->get_transfer(pipe, aaline->texture, level, PIPE_TRANSFER_WRITE, &box); data = pipe->transfer_map(pipe, transfer); if (data == NULL) return FALSE; for (i = 0; i < size; i++) { for (j = 0; j < size; j++) { ubyte d; if (size == 1) { d = 255; } else if (size == 2) { d = 200; /* tuneable */ } else if (i == 0 || j == 0 || i == size - 1 || j == size - 1) { d = 0; } else { d = 255; } data[i * transfer->stride + j] = d; } } /* unmap */ pipe->transfer_unmap(pipe, transfer); pipe->transfer_destroy(pipe, transfer); } return TRUE; }
HRESULT WINAPI NineSurface9_LockRect( struct NineSurface9 *This, D3DLOCKED_RECT *pLockedRect, const RECT *pRect, DWORD Flags ) { struct pipe_resource *resource = This->base.resource; struct pipe_box box; unsigned usage; DBG("This=%p pLockedRect=%p pRect=%p[%u..%u,%u..%u] Flags=%s\n", This, pLockedRect, pRect, pRect ? pRect->left : 0, pRect ? pRect->right : 0, pRect ? pRect->top : 0, pRect ? pRect->bottom : 0, nine_D3DLOCK_to_str(Flags)); NineSurface9_Dump(This); #ifdef NINE_STRICT user_assert(This->base.pool != D3DPOOL_DEFAULT || (resource && (resource->flags & NINE_RESOURCE_FLAG_LOCKABLE)), D3DERR_INVALIDCALL); #endif user_assert(!(Flags & ~(D3DLOCK_DISCARD | D3DLOCK_DONOTWAIT | D3DLOCK_NO_DIRTY_UPDATE | D3DLOCK_NOOVERWRITE | D3DLOCK_NOSYSLOCK | /* ignored */ D3DLOCK_READONLY)), D3DERR_INVALIDCALL); user_assert(!((Flags & D3DLOCK_DISCARD) && (Flags & D3DLOCK_READONLY)), D3DERR_INVALIDCALL); /* check if it's already locked */ user_assert(This->lock_count == 0, D3DERR_INVALIDCALL); user_assert(pLockedRect, E_POINTER); user_assert(This->desc.MultiSampleType == D3DMULTISAMPLE_NONE, D3DERR_INVALIDCALL); if (pRect && This->base.pool == D3DPOOL_DEFAULT && util_format_is_compressed(This->base.info.format)) { const unsigned w = util_format_get_blockwidth(This->base.info.format); const unsigned h = util_format_get_blockheight(This->base.info.format); user_assert(!(pRect->left % w) && !(pRect->right % w) && !(pRect->top % h) && !(pRect->bottom % h), D3DERR_INVALIDCALL); } if (Flags & D3DLOCK_DISCARD) { usage = PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD_RANGE; } else { usage = (Flags & D3DLOCK_READONLY) ? PIPE_TRANSFER_READ : PIPE_TRANSFER_READ_WRITE; } if (Flags & D3DLOCK_DONOTWAIT) usage |= PIPE_TRANSFER_DONTBLOCK; if (pRect) { rect_to_pipe_box(&box, pRect); if (u_box_clip_2d(&box, &box, This->desc.Width, This->desc.Height) < 0) { DBG("pRect clipped by Width=%u Height=%u\n", This->desc.Width, This->desc.Height); return D3DERR_INVALIDCALL; } } else { u_box_origin_2d(This->desc.Width, This->desc.Height, &box); } user_warn(This->desc.Format == D3DFMT_NULL); if (This->data) { DBG("returning system memory\n"); /* ATI1 and ATI2 need special handling, because of d3d9 bug. * We must advertise to the application as if it is uncompressed * and bpp 8, and the app has a workaround to work with the fact * that it is actually compressed. */ if (is_ATI1_ATI2(This->base.info.format)) { pLockedRect->Pitch = This->desc.Height; pLockedRect->pBits = This->data + box.y * This->desc.Height + box.x; } else { pLockedRect->Pitch = This->stride; pLockedRect->pBits = NineSurface9_GetSystemMemPointer(This, box.x, box.y); } } else { DBG("mapping pipe_resource %p (level=%u usage=%x)\n", resource, This->level, usage); pLockedRect->pBits = This->pipe->transfer_map(This->pipe, resource, This->level, usage, &box, &This->transfer); if (!This->transfer) { DBG("transfer_map failed\n"); if (Flags & D3DLOCK_DONOTWAIT) return D3DERR_WASSTILLDRAWING; return D3DERR_INVALIDCALL; } pLockedRect->Pitch = This->transfer->stride; } if (!(Flags & (D3DLOCK_NO_DIRTY_UPDATE | D3DLOCK_READONLY))) { NineSurface9_MarkContainerDirty(This); NineSurface9_AddDirtyRect(This, &box); } ++This->lock_count; return D3D_OK; }