void NineSurface9_Dump( struct NineSurface9 *This ) { struct NineBaseTexture9 *tex; GUID id = IID_IDirect3DBaseTexture9; REFIID ref = &id; DBG("\nNineSurface9(%p->%p/%p): Pool=%s Type=%s Usage=%s\n" "Dims=%ux%u Format=%s Stride=%u Lockable=%i\n" "Level=%u(%u), Layer=%u\n", This, This->base.resource, This->data, nine_D3DPOOL_to_str(This->desc.Pool), nine_D3DRTYPE_to_str(This->desc.Type), nine_D3DUSAGE_to_str(This->desc.Usage), This->desc.Width, This->desc.Height, d3dformat_to_string(This->desc.Format), This->stride, This->base.resource && (This->base.resource->flags & NINE_RESOURCE_FLAG_LOCKABLE), This->level, This->level_actual, This->layer); if (!This->base.base.container) return; NineUnknown_QueryInterface(This->base.base.container, ref, (void **)&tex); if (tex) { NineBaseTexture9_Dump(tex); NineUnknown_Release(NineUnknown(tex)); } }
void NineBaseTexture9_Dump( struct NineBaseTexture9 *This ) { DBG("\nNineBaseTexture9(%p->NULL/%p): Pool=%s Type=%s Usage=%s\n" "Format=%s Dims=%ux%ux%u/%u LastLevel=%u Lod=%u(%u)\n", This, This->base.resource, nine_D3DPOOL_to_str(This->base.pool), nine_D3DRTYPE_to_str(This->base.type), nine_D3DUSAGE_to_str(This->base.usage), d3dformat_to_string(This->format), This->base.info.width0, This->base.info.height0, This->base.info.depth0, This->base.info.array_size, This->base.info.last_level, This->managed.lod, This->managed.lod_resident); }
static HRESULT NineTexture9_ctor( struct NineTexture9 *This, struct NineUnknownParams *pParams, UINT Width, UINT Height, UINT Levels, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, HANDLE *pSharedHandle ) { struct pipe_screen *screen = pParams->device->screen; struct pipe_resource *info = &This->base.base.info; enum pipe_format pf; unsigned *level_offsets; unsigned l; D3DSURFACE_DESC sfdesc; HRESULT hr; void *user_buffer = NULL, *user_buffer_for_level; DBG("(%p) Width=%u Height=%u Levels=%u Usage=%s Format=%s Pool=%s " "pSharedHandle=%p\n", This, Width, Height, Levels, nine_D3DUSAGE_to_str(Usage), d3dformat_to_string(Format), nine_D3DPOOL_to_str(Pool), pSharedHandle); user_assert(Width && Height, D3DERR_INVALIDCALL); /* pSharedHandle: can be non-null for ex only. * D3DPOOL_SYSTEMMEM: Levels must be 1 * D3DPOOL_DEFAULT: no restriction for Levels * Other Pools are forbidden. */ user_assert(!pSharedHandle || pParams->device->ex, D3DERR_INVALIDCALL); user_assert(!pSharedHandle || (Pool == D3DPOOL_SYSTEMMEM && Levels == 1) || Pool == D3DPOOL_DEFAULT, D3DERR_INVALIDCALL); user_assert(!(Usage & D3DUSAGE_AUTOGENMIPMAP) || (Pool != D3DPOOL_SYSTEMMEM && Pool != D3DPOOL_SCRATCH && Levels <= 1), D3DERR_INVALIDCALL); /* TODO: implement pSharedHandle for D3DPOOL_DEFAULT (cross process * buffer sharing). * * Gem names may have fit but they're depreciated and won't work on render-nodes. * One solution is to use shm buffers. We would use a /dev/shm file, fill the first * values to tell it is a nine buffer, the size, which function created it, etc, * and then it would contain the data. The handle would be a number, corresponding to * the file to read (/dev/shm/nine-share-4 for example would be 4). * * Wine just ignores the argument, which works only if the app creates the handle * and won't use it. Instead of failing, we support that situation by putting an * invalid handle, that we would fail to import. Please note that we don't advertise * the flag indicating the support for that feature, but apps seem to not care. */ if (pSharedHandle && Pool == D3DPOOL_DEFAULT) { if (!*pSharedHandle) { DBG("Creating Texture with invalid handle. Importing will fail\n."); *pSharedHandle = (HANDLE)1; /* Wine would keep it NULL */ pSharedHandle = NULL; } else { ERR("Application tries to use cross-process sharing feature. Nine " "doesn't support it"); return D3DERR_INVALIDCALL; } } if (Usage & D3DUSAGE_AUTOGENMIPMAP) Levels = 0; pf = d3d9_to_pipe_format_checked(screen, Format, PIPE_TEXTURE_2D, 0, PIPE_BIND_SAMPLER_VIEW, FALSE, Pool == D3DPOOL_SCRATCH); if (Format != D3DFMT_NULL && pf == PIPE_FORMAT_NONE) return D3DERR_INVALIDCALL; if (compressed_format(Format)) { const unsigned w = util_format_get_blockwidth(pf); const unsigned h = util_format_get_blockheight(pf); user_assert(!(Width % w) && !(Height % h), D3DERR_INVALIDCALL); } info->screen = screen; info->target = PIPE_TEXTURE_2D; info->format = pf; info->width0 = Width; info->height0 = Height; info->depth0 = 1; if (Levels) info->last_level = Levels - 1; else info->last_level = util_logbase2(MAX2(Width, Height)); info->array_size = 1; info->nr_samples = 0; info->nr_storage_samples = 0; info->bind = PIPE_BIND_SAMPLER_VIEW; info->usage = PIPE_USAGE_DEFAULT; info->flags = 0; if (Usage & D3DUSAGE_RENDERTARGET) info->bind |= PIPE_BIND_RENDER_TARGET; if (Usage & D3DUSAGE_DEPTHSTENCIL) info->bind |= PIPE_BIND_DEPTH_STENCIL; if (Usage & D3DUSAGE_DYNAMIC) { info->usage = PIPE_USAGE_DYNAMIC; } if (Usage & D3DUSAGE_SOFTWAREPROCESSING) DBG("Application asked for Software Vertex Processing, " "but this is unimplemented\n"); if (pSharedHandle && *pSharedHandle) { /* Pool == D3DPOOL_SYSTEMMEM */ user_buffer = (void *)*pSharedHandle; level_offsets = alloca(sizeof(unsigned) * (info->last_level + 1)); (void) nine_format_get_size_and_offsets(pf, level_offsets, Width, Height, info->last_level); } else if (Pool != D3DPOOL_DEFAULT) { /* TODO: For D3DUSAGE_AUTOGENMIPMAP, it is likely we only have to * allocate only for the first level, since it is the only lockable * level. Check apps don't crash if we allocate smaller buffer (some * apps access sublevels of texture even if they locked only first * level) */ level_offsets = alloca(sizeof(unsigned) * (info->last_level + 1)); user_buffer = align_calloc( nine_format_get_size_and_offsets(pf, level_offsets, Width, Height, info->last_level), 32); This->managed_buffer = user_buffer; if (!This->managed_buffer) return E_OUTOFMEMORY; } This->surfaces = CALLOC(info->last_level + 1, sizeof(*This->surfaces)); if (!This->surfaces) return E_OUTOFMEMORY; hr = NineBaseTexture9_ctor(&This->base, pParams, NULL, D3DRTYPE_TEXTURE, Format, Pool, Usage); if (FAILED(hr)) return hr; This->base.pstype = (Height == 1) ? 1 : 0; /* Create all the surfaces right away. * They manage backing storage, and transfers (LockRect) are deferred * to them. */ sfdesc.Format = Format; sfdesc.Type = D3DRTYPE_SURFACE; sfdesc.Usage = Usage; sfdesc.Pool = Pool; sfdesc.MultiSampleType = D3DMULTISAMPLE_NONE; sfdesc.MultiSampleQuality = 0; for (l = 0; l <= info->last_level; ++l) { sfdesc.Width = u_minify(Width, l); sfdesc.Height = u_minify(Height, l); /* Some apps expect the memory to be allocated in * continous blocks */ user_buffer_for_level = user_buffer ? user_buffer + level_offsets[l] : NULL; hr = NineSurface9_new(This->base.base.base.device, NineUnknown(This), This->base.base.resource, user_buffer_for_level, D3DRTYPE_TEXTURE, l, 0, &sfdesc, &This->surfaces[l]); if (FAILED(hr)) return hr; } /* Textures start initially dirty */ This->dirty_rect.width = Width; This->dirty_rect.height = Height; This->dirty_rect.depth = 1; /* widht == 0 means empty, depth stays 1 */ if (pSharedHandle && !*pSharedHandle) {/* Pool == D3DPOOL_SYSTEMMEM */ *pSharedHandle = This->surfaces[0]->data; } return D3D_OK; }