static void xsp_flush_frontbuffer(struct pipe_winsys *pws, struct pipe_surface *surface, void *context_private) { struct xsp_pipe_winsys *xsp_winsys; struct xsp_context *xsp_context; assert(pws); assert(surface); assert(context_private); xsp_winsys = (struct xsp_pipe_winsys*)pws; xsp_context = (struct xsp_context*)context_private; xsp_winsys->fbimage->width = surface->width; xsp_winsys->fbimage->height = surface->height; xsp_winsys->fbimage->bytes_per_line = surface->width * (xsp_winsys->fbimage->bits_per_pixel >> 3); xsp_winsys->fbimage->data = (char*)((struct xsp_buffer *)softpipe_texture(surface->texture)->buffer)->data + surface->offset; XPutImage ( xsp_winsys->display, xsp_context->drawable, XDefaultGC(xsp_winsys->display, xsp_winsys->screen), xsp_winsys->fbimage, 0, 0, 0, 0, surface->width, surface->height ); XFlush(xsp_winsys->display); }
static void gdi_softpipe_present(struct pipe_screen *screen, struct pipe_surface *surface, HDC hDC) { struct softpipe_texture *texture; struct gdi_softpipe_buffer *buffer; BITMAPINFO bmi; texture = softpipe_texture(surface->texture); buffer = gdi_softpipe_buffer(texture->buffer); memset(&bmi, 0, sizeof(BITMAPINFO)); bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bmi.bmiHeader.biWidth = texture->stride[surface->level] / pf_get_size(surface->format); bmi.bmiHeader.biHeight= -(long)surface->height; bmi.bmiHeader.biPlanes = 1; bmi.bmiHeader.biBitCount = pf_get_bits(surface->format); bmi.bmiHeader.biCompression = BI_RGB; bmi.bmiHeader.biSizeImage = 0; bmi.bmiHeader.biXPelsPerMeter = 0; bmi.bmiHeader.biYPelsPerMeter = 0; bmi.bmiHeader.biClrUsed = 0; bmi.bmiHeader.biClrImportant = 0; StretchDIBits(hDC, 0, 0, surface->width, surface->height, 0, 0, surface->width, surface->height, buffer->data, &bmi, 0, SRCCOPY); }
static void softpipe_texture_destroy(struct pipe_texture *pt) { struct softpipe_texture *spt = softpipe_texture(pt); pipe_buffer_reference(&spt->buffer, NULL); FREE(spt); }
/** * Display/copy the image in the surface into the X window specified * by the XMesaBuffer. */ static void xlib_softpipe_display_surface(struct xmesa_buffer *b, struct pipe_surface *surf) { XImage *ximage; struct softpipe_texture *spt = softpipe_texture(surf->texture); struct xm_buffer *xm_buf = xm_buffer(spt->buffer); static boolean no_swap = 0; static boolean firsttime = 1; if (firsttime) { no_swap = getenv("SP_NO_RAST") != NULL; firsttime = 0; } if (no_swap) return; #ifdef USE_XSHM if (xm_buf->shm) { if (xm_buf->tempImage == NULL) { assert(surf->texture->block.width == 1); assert(surf->texture->block.height == 1); alloc_shm_ximage(xm_buf, b, spt->stride[surf->level] / surf->texture->block.size, surf->height); } ximage = xm_buf->tempImage; ximage->data = xm_buf->data; /* _debug_printf("XSHM\n"); */ XShmPutImage(b->xm_visual->display, b->drawable, b->gc, ximage, 0, 0, 0, 0, surf->width, surf->height, False); } else #endif { /* display image in Window */ ximage = b->tempImage; ximage->data = xm_buf->data; /* check that the XImage has been previously initialized */ assert(ximage->format); assert(ximage->bitmap_unit); /* update XImage's fields */ ximage->width = surf->width; ximage->height = surf->height; ximage->bytes_per_line = spt->stride[surf->level]; /* _debug_printf("XPUT\n"); */ XPutImage(b->xm_visual->display, b->drawable, b->gc, ximage, 0, 0, 0, 0, surf->width, surf->height); } }
static struct pipe_surface * softpipe_get_tex_surface(struct pipe_screen *screen, struct pipe_texture *pt, unsigned face, unsigned level, unsigned zslice, unsigned usage) { struct softpipe_texture *spt = softpipe_texture(pt); struct pipe_surface *ps; assert(level <= pt->last_level); ps = CALLOC_STRUCT(pipe_surface); if (ps) { pipe_reference_init(&ps->reference, 1); pipe_texture_reference(&ps->texture, pt); ps->format = pt->format; ps->width = pt->width[level]; ps->height = pt->height[level]; ps->offset = spt->level_offset[level]; ps->usage = usage; /* Because we are softpipe, anything that the state tracker * thought was going to be done with the GPU will actually get * done with the CPU. Let's adjust the flags to take that into * account. */ if (ps->usage & PIPE_BUFFER_USAGE_GPU_WRITE) { /* GPU_WRITE means "render" and that can involve reads (blending) */ ps->usage |= PIPE_BUFFER_USAGE_CPU_WRITE | PIPE_BUFFER_USAGE_CPU_READ; } if (ps->usage & PIPE_BUFFER_USAGE_GPU_READ) ps->usage |= PIPE_BUFFER_USAGE_CPU_READ; if (ps->usage & (PIPE_BUFFER_USAGE_CPU_WRITE | PIPE_BUFFER_USAGE_GPU_WRITE)) { /* Mark the surface as dirty. The tile cache will look for this. */ spt->modified = TRUE; } ps->face = face; ps->level = level; ps->zslice = zslice; if (pt->target == PIPE_TEXTURE_CUBE) { ps->offset += face * pt->nblocksy[level] * spt->stride[level]; } else if (pt->target == PIPE_TEXTURE_3D) { ps->offset += zslice * pt->nblocksy[level] * spt->stride[level]; } else { assert(face == 0); assert(zslice == 0); } } return ps; }
static void softpipe_transfer_unmap(struct pipe_screen *screen, struct pipe_transfer *transfer) { struct softpipe_texture *spt; assert(transfer->texture); spt = softpipe_texture(transfer->texture); pipe_buffer_unmap( screen, spt->buffer ); }
static void softpipe_texture_release(struct pipe_screen *screen, struct pipe_texture **pt) { if (!*pt) return; if (--(*pt)->refcount <= 0) { struct softpipe_texture *spt = softpipe_texture(*pt); pipe_buffer_reference(screen, &spt->buffer, NULL); FREE(spt); } *pt = NULL; }
static struct pipe_transfer * softpipe_get_tex_transfer(struct pipe_screen *screen, struct pipe_texture *texture, unsigned face, unsigned level, unsigned zslice, enum pipe_transfer_usage usage, unsigned x, unsigned y, unsigned w, unsigned h) { struct softpipe_texture *sptex = softpipe_texture(texture); struct softpipe_transfer *spt; assert(texture); assert(level <= texture->last_level); spt = CALLOC_STRUCT(softpipe_transfer); if (spt) { struct pipe_transfer *pt = &spt->base; pipe_texture_reference(&pt->texture, texture); pt->format = texture->format; pt->block = texture->block; pt->x = x; pt->y = y; pt->width = w; pt->height = h; pt->nblocksx = texture->nblocksx[level]; pt->nblocksy = texture->nblocksy[level]; pt->stride = sptex->stride[level]; pt->usage = usage; pt->face = face; pt->level = level; pt->zslice = zslice; spt->offset = sptex->level_offset[level]; if (texture->target == PIPE_TEXTURE_CUBE) { spt->offset += face * pt->nblocksy * pt->stride; } else if (texture->target == PIPE_TEXTURE_3D) { spt->offset += zslice * pt->nblocksy * pt->stride; } else { assert(face == 0); assert(zslice == 0); } return pt; } return NULL; }
static void * softpipe_transfer_map( struct pipe_screen *screen, struct pipe_transfer *transfer ) { ubyte *map, *xfer_map; struct softpipe_texture *spt; unsigned flags = 0; assert(transfer->texture); spt = softpipe_texture(transfer->texture); if (transfer->usage != PIPE_TRANSFER_READ) { flags |= PIPE_BUFFER_USAGE_CPU_WRITE; } if (transfer->usage != PIPE_TRANSFER_WRITE) { flags |= PIPE_BUFFER_USAGE_CPU_READ; } map = pipe_buffer_map(screen, spt->buffer, flags); if (map == NULL) return NULL; /* May want to different things here depending on read/write nature * of the map: */ if (transfer->texture && transfer->usage != PIPE_TRANSFER_READ) { /* Do something to notify sharing contexts of a texture change. * In softpipe, that would mean flushing the texture cache. */ softpipe_screen(screen)->timestamp++; } xfer_map = map + softpipe_transfer(transfer)->offset + transfer->y / transfer->block.height * transfer->stride + transfer->x / transfer->block.width * transfer->block.size; /*printf("map = %p xfer map = %p\n", map, xfer_map);*/ return xfer_map; }
/** * Find/create an sp_sampler_varient object for sampling the given texture, * sampler and tex unit. * * Note that the tex unit is significant. We can't re-use a sampler * varient for multiple texture units because the sampler varient contains * the texture object pointer. If the texture object pointer were stored * somewhere outside the sampler varient, we could re-use samplers for * multiple texture units. */ static struct sp_sampler_varient * get_sampler_varient( unsigned unit, struct sp_sampler *sampler, struct pipe_texture *texture, unsigned processor ) { struct softpipe_texture *sp_texture = softpipe_texture(texture); struct sp_sampler_varient *v = NULL; union sp_sampler_key key; /* if this fails, widen the key.unit field and update this assertion */ assert(PIPE_MAX_SAMPLERS <= 16); key.bits.target = sp_texture->base.target; key.bits.is_pot = sp_texture->pot; key.bits.processor = processor; key.bits.unit = unit; key.bits.pad = 0; if (sampler->current && key.value == sampler->current->key.value) { v = sampler->current; } if (v == NULL) { for (v = sampler->varients; v; v = v->next) if (v->key.value == key.value) break; if (v == NULL) { v = sp_create_sampler_varient( &sampler->base, key ); v->next = sampler->varients; sampler->varients = v; } } sampler->current = v; return v; }