static unsigned nvfx_miptree_layout(struct nvfx_miptree *mt) { struct pipe_resource* pt = &mt->base.base; uint offset = 0; if(!nvfx_screen(pt->screen)->is_nv4x) { assert(pt->target == PIPE_TEXTURE_RECT || (util_is_power_of_two(pt->width0) && util_is_power_of_two(pt->height0))); } for (unsigned l = 0; l <= pt->last_level; l++) { unsigned size; mt->level_offset[l] = offset; if(mt->linear_pitch) size = mt->linear_pitch; else size = util_format_get_stride(pt->format, u_minify(pt->width0, l)); size = util_format_get_2d_size(pt->format, size, u_minify(pt->height0, l)); if(pt->target == PIPE_TEXTURE_3D) size *= u_minify(pt->depth0, l); offset += size; } offset = align(offset, 128); mt->face_size = offset; if(mt->base.base.target == PIPE_TEXTURE_CUBE) offset += 5 * mt->face_size; return offset; }
/** * gl_renderbuffer::AllocStorage() * This is called to allocate the original drawing surface, and * during window resize. */ static GLboolean st_renderbuffer_alloc_storage(struct gl_context * ctx, struct gl_renderbuffer *rb, GLenum internalFormat, GLuint width, GLuint height) { struct st_context *st = st_context(ctx); struct pipe_context *pipe = st->pipe; struct pipe_screen *screen = st->pipe->screen; struct st_renderbuffer *strb = st_renderbuffer(rb); enum pipe_format format; struct pipe_surface surf_tmpl; format = st_choose_renderbuffer_format(screen, internalFormat, rb->NumSamples); if (format == PIPE_FORMAT_NONE) { return FALSE; } /* init renderbuffer fields */ strb->Base.Width = width; strb->Base.Height = height; strb->Base.Format = st_pipe_format_to_mesa_format(format); strb->Base._BaseFormat = _mesa_base_fbo_format(ctx, internalFormat); strb->Base.DataType = st_format_datatype(format); strb->format = format; strb->defined = GL_FALSE; /* undefined contents now */ if (strb->software) { size_t size; free(strb->data); assert(strb->format != PIPE_FORMAT_NONE); strb->stride = util_format_get_stride(strb->format, width); size = util_format_get_2d_size(strb->format, strb->stride, height); strb->data = malloc(size); return strb->data != NULL; } else { struct pipe_resource template; /* Free the old surface and texture */ pipe_surface_reference( &strb->surface, NULL ); pipe_resource_reference( &strb->texture, NULL ); pipe_sampler_view_reference(&strb->sampler_view, NULL); /* Setup new texture template. */ memset(&template, 0, sizeof(template));
static uint32_t vtest_get_transfer_size(struct virgl_hw_res *res, const struct pipe_box *box, uint32_t stride, uint32_t layer_stride, uint32_t level, uint32_t *valid_stride_p) { uint32_t valid_stride, valid_layer_stride; valid_stride = util_format_get_stride(res->format, box->width); if (stride) { if (box->height > 1) valid_stride = stride; } valid_layer_stride = util_format_get_2d_size(res->format, valid_stride, box->height); if (layer_stride) { if (box->depth > 1) valid_layer_stride = layer_stride; } *valid_stride_p = valid_stride; return valid_layer_stride * box->depth; }
static HRESULT NineVolume9_ctor( struct NineVolume9 *This, struct NineUnknownParams *pParams, struct NineUnknown *pContainer, struct pipe_resource *pResource, unsigned Level, D3DVOLUME_DESC *pDesc ) { HRESULT hr; assert(pContainer); /* stand-alone volumes can't be created */ DBG("This=%p pContainer=%p pDevice=%p pResource=%p Level=%u pDesc=%p\n", This, pContainer, pParams->device, pResource, Level, pDesc); /* Mark this as a special surface held by another internal resource. */ pParams->container = pContainer; user_assert(!(pDesc->Usage & D3DUSAGE_DYNAMIC) || (pDesc->Pool != D3DPOOL_MANAGED), D3DERR_INVALIDCALL); assert(pResource || pDesc->Pool != D3DPOOL_DEFAULT); hr = NineUnknown_ctor(&This->base, pParams); if (FAILED(hr)) return hr; This->pdata = util_hash_table_create(ht_guid_hash, ht_guid_compare); if (!This->pdata) return E_OUTOFMEMORY; pipe_resource_reference(&This->resource, pResource); This->pipe = pParams->device->pipe; This->transfer = NULL; This->lock_count = 0; This->level = Level; This->level_actual = Level; This->desc = *pDesc; This->info.screen = pParams->device->screen; This->info.target = PIPE_TEXTURE_3D; This->info.width0 = pDesc->Width; This->info.height0 = pDesc->Height; This->info.depth0 = pDesc->Depth; This->info.last_level = 0; This->info.array_size = 1; This->info.nr_samples = 0; This->info.usage = PIPE_USAGE_DEFAULT; This->info.bind = PIPE_BIND_SAMPLER_VIEW; This->info.flags = 0; This->info.format = d3d9_to_pipe_format_checked(This->info.screen, pDesc->Format, This->info.target, This->info.nr_samples, This->info.bind, FALSE); if (This->info.format == PIPE_FORMAT_NONE) return D3DERR_DRIVERINTERNALERROR; This->stride = util_format_get_stride(This->info.format, pDesc->Width); This->stride = align(This->stride, 4); This->layer_stride = util_format_get_2d_size(This->info.format, This->stride, pDesc->Height); if (pDesc->Pool == D3DPOOL_SYSTEMMEM) This->info.usage = PIPE_USAGE_STAGING; if (!This->resource) { hr = NineVolume9_AllocateData(This); if (FAILED(hr)) return hr; } return D3D_OK; }
static void * fd_resource_transfer_map(struct pipe_context *pctx, struct pipe_resource *prsc, unsigned level, unsigned usage, const struct pipe_box *box, struct pipe_transfer **pptrans) { struct fd_context *ctx = fd_context(pctx); struct fd_resource *rsc = fd_resource(prsc); struct fd_resource_slice *slice = fd_resource_slice(rsc, level); struct fd_transfer *trans; struct pipe_transfer *ptrans; enum pipe_format format = prsc->format; uint32_t op = 0; uint32_t offset; char *buf; int ret = 0; DBG("prsc=%p, level=%u, usage=%x, box=%dx%d+%d,%d", prsc, level, usage, box->width, box->height, box->x, box->y); ptrans = util_slab_alloc(&ctx->transfer_pool); if (!ptrans) return NULL; /* util_slab_alloc() doesn't zero: */ trans = fd_transfer(ptrans); memset(trans, 0, sizeof(*trans)); pipe_resource_reference(&ptrans->resource, prsc); ptrans->level = level; ptrans->usage = usage; ptrans->box = *box; ptrans->stride = util_format_get_nblocksx(format, slice->pitch) * rsc->cpp; ptrans->layer_stride = rsc->layer_first ? rsc->layer_size : slice->size0; if (usage & PIPE_TRANSFER_READ) op |= DRM_FREEDRENO_PREP_READ; if (usage & PIPE_TRANSFER_WRITE) op |= DRM_FREEDRENO_PREP_WRITE; if (usage & PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE) { realloc_bo(rsc, fd_bo_size(rsc->bo)); if (rsc->stencil) realloc_bo(rsc->stencil, fd_bo_size(rsc->stencil->bo)); fd_invalidate_resource(ctx, prsc); } else if ((usage & PIPE_TRANSFER_WRITE) && prsc->target == PIPE_BUFFER && !util_ranges_intersect(&rsc->valid_buffer_range, box->x, box->x + box->width)) { /* We are trying to write to a previously uninitialized range. No need * to wait. */ } else if (!(usage & PIPE_TRANSFER_UNSYNCHRONIZED)) { /* If the GPU is writing to the resource, or if it is reading from the * resource and we're trying to write to it, flush the renders. */ if (((ptrans->usage & PIPE_TRANSFER_WRITE) && pending(rsc, FD_PENDING_READ | FD_PENDING_WRITE)) || pending(rsc, FD_PENDING_WRITE)) fd_context_render(pctx); /* The GPU keeps track of how the various bo's are being used, and * will wait if necessary for the proper operation to have * completed. */ ret = fd_bo_cpu_prep(rsc->bo, ctx->screen->pipe, op); if (ret) goto fail; } buf = fd_bo_map(rsc->bo); if (!buf) goto fail; offset = slice->offset + box->y / util_format_get_blockheight(format) * ptrans->stride + box->x / util_format_get_blockwidth(format) * rsc->cpp + fd_resource_layer_offset(rsc, slice, box->z); if (prsc->format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT || prsc->format == PIPE_FORMAT_X32_S8X24_UINT) { assert(trans->base.box.depth == 1); trans->base.stride = trans->base.box.width * rsc->cpp * 2; trans->staging = malloc(trans->base.stride * trans->base.box.height); if (!trans->staging) goto fail; /* if we're not discarding the whole range (or resource), we must copy * the real data in. */ if (!(usage & (PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE | PIPE_TRANSFER_DISCARD_RANGE))) { struct fd_resource_slice *sslice = fd_resource_slice(rsc->stencil, level); void *sbuf = fd_bo_map(rsc->stencil->bo); if (!sbuf) goto fail; float *depth = (float *)(buf + slice->offset + fd_resource_layer_offset(rsc, slice, box->z) + box->y * slice->pitch * 4 + box->x * 4); uint8_t *stencil = sbuf + sslice->offset + fd_resource_layer_offset(rsc->stencil, sslice, box->z) + box->y * sslice->pitch + box->x; if (format != PIPE_FORMAT_X32_S8X24_UINT) util_format_z32_float_s8x24_uint_pack_z_float( trans->staging, trans->base.stride, depth, slice->pitch * 4, box->width, box->height); util_format_z32_float_s8x24_uint_pack_s_8uint( trans->staging, trans->base.stride, stencil, sslice->pitch, box->width, box->height); } buf = trans->staging; offset = 0; } else if (rsc->internal_format != format && util_format_description(format)->layout == UTIL_FORMAT_LAYOUT_RGTC) { assert(trans->base.box.depth == 1); trans->base.stride = util_format_get_stride( format, trans->base.box.width); trans->staging = malloc( util_format_get_2d_size(format, trans->base.stride, trans->base.box.height)); if (!trans->staging) goto fail; /* if we're not discarding the whole range (or resource), we must copy * the real data in. */ if (!(usage & (PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE | PIPE_TRANSFER_DISCARD_RANGE))) { uint8_t *rgba8 = (uint8_t *)buf + slice->offset + fd_resource_layer_offset(rsc, slice, box->z) + box->y * slice->pitch * rsc->cpp + box->x * rsc->cpp; switch (format) { case PIPE_FORMAT_RGTC1_UNORM: case PIPE_FORMAT_RGTC1_SNORM: case PIPE_FORMAT_LATC1_UNORM: case PIPE_FORMAT_LATC1_SNORM: util_format_rgtc1_unorm_pack_rgba_8unorm( trans->staging, trans->base.stride, rgba8, slice->pitch * rsc->cpp, box->width, box->height); break; case PIPE_FORMAT_RGTC2_UNORM: case PIPE_FORMAT_RGTC2_SNORM: case PIPE_FORMAT_LATC2_UNORM: case PIPE_FORMAT_LATC2_SNORM: util_format_rgtc2_unorm_pack_rgba_8unorm( trans->staging, trans->base.stride, rgba8, slice->pitch * rsc->cpp, box->width, box->height); break; default: assert(!"Unexpected format"); break; } } buf = trans->staging; offset = 0; } *pptrans = ptrans; return buf + offset; fail: fd_resource_transfer_unmap(pctx, ptrans); return NULL; }