Path: blob/21.2-virgl/src/gallium/frontends/nine/cubetexture9.c
4561 views
/*1* Copyright 2011 Joakim Sindholt <[email protected]>2*3* Permission is hereby granted, free of charge, to any person obtaining a4* copy of this software and associated documentation files (the "Software"),5* to deal in the Software without restriction, including without limitation6* on the rights to use, copy, modify, merge, publish, distribute, sub7* license, and/or sell copies of the Software, and to permit persons to whom8* the Software is furnished to do so, subject to the following conditions:9*10* The above copyright notice and this permission notice (including the next11* paragraph) shall be included in all copies or substantial portions of the12* Software.13*14* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL17* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,18* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR19* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE20* USE OR OTHER DEALINGS IN THE SOFTWARE. */2122#include "c99_alloca.h"2324#include "device9.h"25#include "cubetexture9.h"26#include "nine_memory_helper.h"27#include "nine_helpers.h"28#include "nine_pipe.h"2930#define DBG_CHANNEL DBG_CUBETEXTURE313233static HRESULT34NineCubeTexture9_ctor( struct NineCubeTexture9 *This,35struct NineUnknownParams *pParams,36UINT EdgeLength, UINT Levels,37DWORD Usage,38D3DFORMAT Format,39D3DPOOL Pool,40HANDLE *pSharedHandle )41{42struct pipe_resource *info = &This->base.base.info;43struct pipe_screen *screen = pParams->device->screen;44enum pipe_format pf;45unsigned i, l, f, offset, face_size = 0;46unsigned *level_offsets = NULL;47D3DSURFACE_DESC sfdesc;48struct nine_allocation *p;49HRESULT hr;5051DBG("This=%p pParams=%p EdgeLength=%u Levels=%u Usage=%d "52"Format=%d Pool=%d pSharedHandle=%p\n",53This, pParams, EdgeLength, Levels, Usage,54Format, Pool, pSharedHandle);5556This->base.base.base.device = pParams->device; /* Early fill this field in case of failure */5758user_assert(EdgeLength, D3DERR_INVALIDCALL);5960/* user_assert(!pSharedHandle || Pool == D3DPOOL_DEFAULT, D3DERR_INVALIDCALL); */61user_assert(!pSharedHandle, D3DERR_INVALIDCALL); /* TODO */6263user_assert(!(Usage & D3DUSAGE_AUTOGENMIPMAP) ||64(Pool != D3DPOOL_SYSTEMMEM && Levels <= 1), D3DERR_INVALIDCALL);6566if (Usage & D3DUSAGE_AUTOGENMIPMAP)67Levels = 0;6869pf = d3d9_to_pipe_format_checked(screen, Format, PIPE_TEXTURE_CUBE, 0,70PIPE_BIND_SAMPLER_VIEW, FALSE,71Pool == D3DPOOL_SCRATCH);7273if (pf == PIPE_FORMAT_NONE)74return D3DERR_INVALIDCALL;7576if (compressed_format(Format)) {77const unsigned w = util_format_get_blockwidth(pf);78const unsigned h = util_format_get_blockheight(pf);7980user_assert(!(EdgeLength % w) && !(EdgeLength % h), D3DERR_INVALIDCALL);81}8283info->screen = pParams->device->screen;84info->target = PIPE_TEXTURE_CUBE;85info->format = pf;86info->width0 = EdgeLength;87info->height0 = EdgeLength;88info->depth0 = 1;89if (Levels)90info->last_level = Levels - 1;91else92info->last_level = util_logbase2(EdgeLength);93info->array_size = 6;94info->nr_samples = 0;95info->nr_storage_samples = 0;96info->bind = PIPE_BIND_SAMPLER_VIEW;97info->usage = PIPE_USAGE_DEFAULT;98info->flags = 0;99100if (Usage & D3DUSAGE_RENDERTARGET)101info->bind |= PIPE_BIND_RENDER_TARGET;102if (Usage & D3DUSAGE_DEPTHSTENCIL)103info->bind |= PIPE_BIND_DEPTH_STENCIL;104105if (Usage & D3DUSAGE_DYNAMIC) {106info->usage = PIPE_USAGE_DYNAMIC;107}108if (Usage & D3DUSAGE_SOFTWAREPROCESSING)109DBG("Application asked for Software Vertex Processing, "110"but this is unimplemented\n");111112hr = NineBaseTexture9_ctor(&This->base, pParams, NULL, D3DRTYPE_CUBETEXTURE,113Format, Pool, Usage);114if (FAILED(hr))115return hr;116This->base.pstype = 2;117118if (Pool != D3DPOOL_DEFAULT) {119level_offsets = alloca(sizeof(unsigned) * This->base.level_count);120face_size = nine_format_get_size_and_offsets(pf, level_offsets,121EdgeLength, EdgeLength,122This->base.level_count-1);123This->managed_buffer = nine_allocate(pParams->device->allocator, 6 * face_size);124if (!This->managed_buffer)125return E_OUTOFMEMORY;126}127128This->surfaces = CALLOC(6 * This->base.level_count, sizeof(*This->surfaces));129if (!This->surfaces)130return E_OUTOFMEMORY;131132/* Create all the surfaces right away.133* They manage backing storage, and transfers (LockRect) are deferred134* to them.135*/136sfdesc.Format = Format;137sfdesc.Type = D3DRTYPE_SURFACE;138sfdesc.Usage = Usage;139sfdesc.Pool = Pool;140sfdesc.MultiSampleType = D3DMULTISAMPLE_NONE;141sfdesc.MultiSampleQuality = 0;142/* We allocate the memory for the surfaces as continous blocks.143* This is the expected behaviour, however we haven't tested for144* cube textures in which order the faces/levels should be in memory145*/146for (f = 0; f < 6; f++) {147offset = f * face_size;148for (l = 0; l < This->base.level_count; l++) {149sfdesc.Width = sfdesc.Height = u_minify(EdgeLength, l);150p = This->managed_buffer ?151nine_suballocate(pParams->device->allocator, This->managed_buffer, offset + level_offsets[l]) : NULL;152153hr = NineSurface9_new(This->base.base.base.device, NineUnknown(This),154This->base.base.resource, p, D3DRTYPE_CUBETEXTURE,155l, f, &sfdesc, &This->surfaces[f + 6 * l]);156if (FAILED(hr))157return hr;158}159}160161for (i = 0; i < 6; ++i) {162/* Textures start initially dirty */163This->dirty_rect[i].width = EdgeLength;164This->dirty_rect[i].height = EdgeLength;165This->dirty_rect[i].depth = 1;166}167168return D3D_OK;169}170171static void172NineCubeTexture9_dtor( struct NineCubeTexture9 *This )173{174unsigned i;175bool is_worker = nine_context_is_worker(This->base.base.base.device);176177DBG("This=%p\n", This);178179if (This->surfaces) {180for (i = 0; i < This->base.level_count * 6; ++i)181if (This->surfaces[i])182NineUnknown_Destroy(&This->surfaces[i]->base.base);183FREE(This->surfaces);184}185186if (This->managed_buffer) {187if (is_worker)188nine_free_worker(This->base.base.base.device->allocator, This->managed_buffer);189else190nine_free(This->base.base.base.device->allocator, This->managed_buffer);191}192193NineBaseTexture9_dtor(&This->base);194}195196HRESULT NINE_WINAPI197NineCubeTexture9_GetLevelDesc( struct NineCubeTexture9 *This,198UINT Level,199D3DSURFACE_DESC *pDesc )200{201DBG("This=%p Level=%u pDesc=%p\n", This, Level, pDesc);202203user_assert(Level < This->base.level_count, D3DERR_INVALIDCALL);204205*pDesc = This->surfaces[Level * 6]->desc;206207return D3D_OK;208}209210HRESULT NINE_WINAPI211NineCubeTexture9_GetCubeMapSurface( struct NineCubeTexture9 *This,212D3DCUBEMAP_FACES FaceType,213UINT Level,214IDirect3DSurface9 **ppCubeMapSurface )215{216const unsigned s = Level * 6 + FaceType;217218DBG("This=%p FaceType=%d Level=%u ppCubeMapSurface=%p\n",219This, FaceType, Level, ppCubeMapSurface);220221user_assert(Level < This->base.level_count, D3DERR_INVALIDCALL);222user_assert(FaceType < 6, D3DERR_INVALIDCALL);223224NineUnknown_AddRef(NineUnknown(This->surfaces[s]));225*ppCubeMapSurface = (IDirect3DSurface9 *)This->surfaces[s];226227return D3D_OK;228}229230HRESULT NINE_WINAPI231NineCubeTexture9_LockRect( struct NineCubeTexture9 *This,232D3DCUBEMAP_FACES FaceType,233UINT Level,234D3DLOCKED_RECT *pLockedRect,235const RECT *pRect,236DWORD Flags )237{238const unsigned s = Level * 6 + FaceType;239240DBG("This=%p FaceType=%d Level=%u pLockedRect=%p pRect=%p Flags=%d\n",241This, FaceType, Level, pLockedRect, pRect, Flags);242243user_assert(Level < This->base.level_count, D3DERR_INVALIDCALL);244user_assert(FaceType < 6, D3DERR_INVALIDCALL);245246return NineSurface9_LockRect(This->surfaces[s], pLockedRect, pRect, Flags);247}248249HRESULT NINE_WINAPI250NineCubeTexture9_UnlockRect( struct NineCubeTexture9 *This,251D3DCUBEMAP_FACES FaceType,252UINT Level )253{254const unsigned s = Level * 6 + FaceType;255256DBG("This=%p FaceType=%d Level=%u\n", This, FaceType, Level);257258user_assert(Level < This->base.level_count, D3DERR_INVALIDCALL);259user_assert(FaceType < 6, D3DERR_INVALIDCALL);260261return NineSurface9_UnlockRect(This->surfaces[s]);262}263264HRESULT NINE_WINAPI265NineCubeTexture9_AddDirtyRect( struct NineCubeTexture9 *This,266D3DCUBEMAP_FACES FaceType,267const RECT *pDirtyRect )268{269DBG("This=%p FaceType=%d pDirtyRect=%p\n", This, FaceType, pDirtyRect);270271user_assert(FaceType < 6, D3DERR_INVALIDCALL);272273if (This->base.base.pool != D3DPOOL_MANAGED) {274if (This->base.base.usage & D3DUSAGE_AUTOGENMIPMAP) {275This->base.dirty_mip = TRUE;276BASETEX_REGISTER_UPDATE(&This->base);277}278return D3D_OK;279}280281if (This->base.base.pool == D3DPOOL_MANAGED) {282This->base.managed.dirty = TRUE;283BASETEX_REGISTER_UPDATE(&This->base);284}285286if (!pDirtyRect) {287u_box_origin_2d(This->base.base.info.width0,288This->base.base.info.height0,289&This->dirty_rect[FaceType]);290} else {291if (This->dirty_rect[FaceType].width == 0) {292rect_to_pipe_box_clamp(&This->dirty_rect[FaceType], pDirtyRect);293} else {294struct pipe_box box;295rect_to_pipe_box_clamp(&box, pDirtyRect);296u_box_union_2d(&This->dirty_rect[FaceType], &This->dirty_rect[FaceType],297&box);298}299(void) u_box_clip_2d(&This->dirty_rect[FaceType],300&This->dirty_rect[FaceType],301This->base.base.info.width0,302This->base.base.info.height0);303}304return D3D_OK;305}306307IDirect3DCubeTexture9Vtbl NineCubeTexture9_vtable = {308(void *)NineUnknown_QueryInterface,309(void *)NineUnknown_AddRef,310(void *)NineUnknown_Release,311(void *)NineUnknown_GetDevice, /* actually part of Resource9 iface */312(void *)NineUnknown_SetPrivateData,313(void *)NineUnknown_GetPrivateData,314(void *)NineUnknown_FreePrivateData,315(void *)NineResource9_SetPriority,316(void *)NineResource9_GetPriority,317(void *)NineBaseTexture9_PreLoad,318(void *)NineResource9_GetType,319(void *)NineBaseTexture9_SetLOD,320(void *)NineBaseTexture9_GetLOD,321(void *)NineBaseTexture9_GetLevelCount,322(void *)NineBaseTexture9_SetAutoGenFilterType,323(void *)NineBaseTexture9_GetAutoGenFilterType,324(void *)NineBaseTexture9_GenerateMipSubLevels,325(void *)NineCubeTexture9_GetLevelDesc,326(void *)NineCubeTexture9_GetCubeMapSurface,327(void *)NineCubeTexture9_LockRect,328(void *)NineCubeTexture9_UnlockRect,329(void *)NineCubeTexture9_AddDirtyRect330};331332static const GUID *NineCubeTexture9_IIDs[] = {333&IID_IDirect3DCubeTexture9,334&IID_IDirect3DBaseTexture9,335&IID_IDirect3DResource9,336&IID_IUnknown,337NULL338};339340HRESULT341NineCubeTexture9_new( struct NineDevice9 *pDevice,342UINT EdgeLength, UINT Levels,343DWORD Usage,344D3DFORMAT Format,345D3DPOOL Pool,346struct NineCubeTexture9 **ppOut,347HANDLE *pSharedHandle )348{349NINE_DEVICE_CHILD_NEW(CubeTexture9, ppOut, pDevice,350EdgeLength, Levels,351Usage, Format, Pool, pSharedHandle);352}353354355