Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Copyright 2011 Joakim Sindholt <opensource@zhasha.com>
  3.  *
  4.  * Permission is hereby granted, free of charge, to any person obtaining a
  5.  * copy of this software and associated documentation files (the "Software"),
  6.  * to deal in the Software without restriction, including without limitation
  7.  * on the rights to use, copy, modify, merge, publish, distribute, sub
  8.  * license, and/or sell copies of the Software, and to permit persons to whom
  9.  * the Software is furnished to do so, subject to the following conditions:
  10.  *
  11.  * The above copyright notice and this permission notice (including the next
  12.  * paragraph) shall be included in all copies or substantial portions of the
  13.  * Software.
  14.  *
  15.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17.  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
  18.  * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
  19.  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
  20.  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
  21.  * USE OR OTHER DEALINGS IN THE SOFTWARE. */
  22.  
  23. #include "device9.h"
  24. #include "volumetexture9.h"
  25. #include "nine_helpers.h"
  26. #include "nine_pipe.h"
  27.  
  28. #define DBG_CHANNEL DBG_VOLUMETEXTURE
  29.  
  30. static HRESULT
  31. NineVolumeTexture9_ctor( struct NineVolumeTexture9 *This,
  32.                          struct NineUnknownParams *pParams,
  33.                          UINT Width, UINT Height, UINT Depth, UINT Levels,
  34.                          DWORD Usage,
  35.                          D3DFORMAT Format,
  36.                          D3DPOOL Pool,
  37.                          HANDLE *pSharedHandle )
  38. {
  39.     struct pipe_resource *info = &This->base.base.info;
  40.     struct pipe_screen *screen = pParams->device->screen;
  41.     enum pipe_format pf;
  42.     unsigned l;
  43.     D3DVOLUME_DESC voldesc;
  44.     HRESULT hr;
  45.  
  46.     DBG("This=%p pParams=%p Width=%u Height=%u Depth=%u Levels=%u "
  47.         "Usage=%d Format=%d Pool=%d pSharedHandle=%p\n",
  48.         This, pParams, Width, Height, Depth, Levels,
  49.         Usage, Format, Pool, pSharedHandle);
  50.  
  51.     /* An IDirect3DVolume9 cannot be bound as a render target can it ? */
  52.     user_assert(!(Usage & (D3DUSAGE_RENDERTARGET | D3DUSAGE_DEPTHSTENCIL)),
  53.                 D3DERR_INVALIDCALL);
  54.     user_assert(!(Usage & D3DUSAGE_AUTOGENMIPMAP), D3DERR_INVALIDCALL);
  55.  
  56.     user_assert(!pSharedHandle, D3DERR_INVALIDCALL); /* TODO */
  57.  
  58.     pf = d3d9_to_pipe_format_checked(screen, Format, PIPE_TEXTURE_3D, 0,
  59.                                      PIPE_BIND_SAMPLER_VIEW, FALSE);
  60.     if (pf == PIPE_FORMAT_NONE)
  61.         return D3DERR_INVALIDCALL;
  62.  
  63.     /* We support ATI1 and ATI2 hacks only for 2D textures */
  64.     if (Format == D3DFMT_ATI1 || Format == D3DFMT_ATI2)
  65.         return D3DERR_INVALIDCALL;
  66.  
  67.     info->screen = pParams->device->screen;
  68.     info->target = PIPE_TEXTURE_3D;
  69.     info->format = pf;
  70.     info->width0 = Width;
  71.     info->height0 = Height;
  72.     info->depth0 = Depth;
  73.     if (Levels)
  74.         info->last_level = Levels - 1;
  75.     else
  76.         info->last_level = util_logbase2(MAX2(MAX2(Width, Height), Depth));
  77.     info->array_size = 1;
  78.     info->nr_samples = 0;
  79.     info->bind = PIPE_BIND_SAMPLER_VIEW;
  80.     info->usage = PIPE_USAGE_DEFAULT;
  81.     info->flags = 0;
  82.  
  83.     if (Usage & D3DUSAGE_DYNAMIC) {
  84.         info->usage = PIPE_USAGE_DYNAMIC;
  85.         info->bind |=
  86.             PIPE_BIND_TRANSFER_READ |
  87.             PIPE_BIND_TRANSFER_WRITE;
  88.     }
  89.     if (Usage & D3DUSAGE_SOFTWAREPROCESSING)
  90.         DBG("Application asked for Software Vertex Processing, "
  91.             "but this is unimplemented\n");
  92.  
  93.     This->volumes = CALLOC(info->last_level + 1, sizeof(*This->volumes));
  94.     if (!This->volumes)
  95.         return E_OUTOFMEMORY;
  96.     This->base.pstype = 3;
  97.  
  98.     hr = NineBaseTexture9_ctor(&This->base, pParams, NULL,
  99.                                D3DRTYPE_VOLUMETEXTURE, Format, Pool, Usage);
  100.     if (FAILED(hr))
  101.         return hr;
  102.  
  103.     voldesc.Format = Format;
  104.     voldesc.Type = D3DRTYPE_VOLUME;
  105.     voldesc.Usage = Usage;
  106.     voldesc.Pool = Pool;
  107.     for (l = 0; l <= info->last_level; ++l) {
  108.         voldesc.Width = u_minify(Width, l);
  109.         voldesc.Height = u_minify(Height, l);
  110.         voldesc.Depth = u_minify(Depth, l);
  111.  
  112.         hr = NineVolume9_new(This->base.base.base.device, NineUnknown(This),
  113.                              This->base.base.resource, l,
  114.                              &voldesc, &This->volumes[l]);
  115.         if (FAILED(hr))
  116.             return hr;
  117.     }
  118.  
  119.     return D3D_OK;
  120. }
  121.  
  122. static void
  123. NineVolumeTexture9_dtor( struct NineVolumeTexture9 *This )
  124. {
  125.     unsigned l;
  126.  
  127.     DBG("This=%p\n", This);
  128.  
  129.     if (This->volumes) {
  130.         for (l = 0; l < This->base.base.info.last_level; ++l)
  131.             NineUnknown_Destroy(&This->volumes[l]->base);
  132.         FREE(This->volumes);
  133.     }
  134.  
  135.     NineBaseTexture9_dtor(&This->base);
  136. }
  137.  
  138. HRESULT WINAPI
  139. NineVolumeTexture9_GetLevelDesc( struct NineVolumeTexture9 *This,
  140.                                  UINT Level,
  141.                                  D3DVOLUME_DESC *pDesc )
  142. {
  143.     user_assert(Level <= This->base.base.info.last_level, D3DERR_INVALIDCALL);
  144.  
  145.     *pDesc = This->volumes[Level]->desc;
  146.  
  147.     return D3D_OK;
  148. }
  149.  
  150. HRESULT WINAPI
  151. NineVolumeTexture9_GetVolumeLevel( struct NineVolumeTexture9 *This,
  152.                                    UINT Level,
  153.                                    IDirect3DVolume9 **ppVolumeLevel )
  154. {
  155.     user_assert(Level <= This->base.base.info.last_level, D3DERR_INVALIDCALL);
  156.  
  157.     NineUnknown_AddRef(NineUnknown(This->volumes[Level]));
  158.     *ppVolumeLevel = (IDirect3DVolume9 *)This->volumes[Level];
  159.  
  160.     return D3D_OK;
  161. }
  162.  
  163. HRESULT WINAPI
  164. NineVolumeTexture9_LockBox( struct NineVolumeTexture9 *This,
  165.                             UINT Level,
  166.                             D3DLOCKED_BOX *pLockedVolume,
  167.                             const D3DBOX *pBox,
  168.                             DWORD Flags )
  169. {
  170.     DBG("This=%p Level=%u pLockedVolume=%p pBox=%p Flags=%d\n",
  171.         This, Level, pLockedVolume, pBox, Flags);
  172.  
  173.     user_assert(Level <= This->base.base.info.last_level, D3DERR_INVALIDCALL);
  174.  
  175.     return NineVolume9_LockBox(This->volumes[Level], pLockedVolume, pBox,
  176.                                Flags);
  177. }
  178.  
  179. HRESULT WINAPI
  180. NineVolumeTexture9_UnlockBox( struct NineVolumeTexture9 *This,
  181.                               UINT Level )
  182. {
  183.     DBG("This=%p Level=%u\n", This, Level);
  184.  
  185.     user_assert(Level <= This->base.base.info.last_level, D3DERR_INVALIDCALL);
  186.  
  187.     return NineVolume9_UnlockBox(This->volumes[Level]);
  188. }
  189.  
  190. HRESULT WINAPI
  191. NineVolumeTexture9_AddDirtyBox( struct NineVolumeTexture9 *This,
  192.                                 const D3DBOX *pDirtyBox )
  193. {
  194.     DBG("This=%p pDirtybox=%p\n", This, pDirtyBox);
  195.  
  196.     if (This->base.base.pool != D3DPOOL_MANAGED) {
  197.         return D3D_OK;
  198.     }
  199.     This->base.managed.dirty = TRUE;
  200.  
  201.     BASETEX_REGISTER_UPDATE(&This->base);
  202.  
  203.     if (!pDirtyBox) {
  204.         This->dirty_box.x = 0;
  205.         This->dirty_box.y = 0;
  206.         This->dirty_box.z = 0;
  207.         This->dirty_box.width = This->base.base.info.width0;
  208.         This->dirty_box.height = This->base.base.info.height0;
  209.         This->dirty_box.depth = This->base.base.info.depth0;
  210.     } else {
  211.         struct pipe_box box;
  212.         d3dbox_to_pipe_box(&box, pDirtyBox);
  213.         u_box_union_3d(&This->dirty_box, &This->dirty_box, &box);
  214.         This->dirty_box.x = MAX2(This->dirty_box.x, 0);
  215.         This->dirty_box.y = MAX2(This->dirty_box.y, 0);
  216.         This->dirty_box.z = MAX2(This->dirty_box.z, 0);
  217.         This->dirty_box.width = MIN2(This->dirty_box.width,
  218.                                      This->base.base.info.width0 - This->dirty_box.x);
  219.         This->dirty_box.height = MIN2(This->dirty_box.height,
  220.                                      This->base.base.info.height0 - This->dirty_box.y);
  221.         This->dirty_box.depth = MIN2(This->dirty_box.depth,
  222.                                      This->base.base.info.depth0 - This->dirty_box.z);
  223.     }
  224.     return D3D_OK;
  225. }
  226.  
  227. IDirect3DVolumeTexture9Vtbl NineVolumeTexture9_vtable = {
  228.     (void *)NineUnknown_QueryInterface,
  229.     (void *)NineUnknown_AddRef,
  230.     (void *)NineUnknown_Release,
  231.     (void *)NineUnknown_GetDevice, /* actually part of Resource9 iface */
  232.     (void *)NineResource9_SetPrivateData,
  233.     (void *)NineResource9_GetPrivateData,
  234.     (void *)NineResource9_FreePrivateData,
  235.     (void *)NineResource9_SetPriority,
  236.     (void *)NineResource9_GetPriority,
  237.     (void *)NineBaseTexture9_PreLoad,
  238.     (void *)NineResource9_GetType,
  239.     (void *)NineBaseTexture9_SetLOD,
  240.     (void *)NineBaseTexture9_GetLOD,
  241.     (void *)NineBaseTexture9_GetLevelCount,
  242.     (void *)NineBaseTexture9_SetAutoGenFilterType,
  243.     (void *)NineBaseTexture9_GetAutoGenFilterType,
  244.     (void *)NineBaseTexture9_GenerateMipSubLevels,
  245.     (void *)NineVolumeTexture9_GetLevelDesc,
  246.     (void *)NineVolumeTexture9_GetVolumeLevel,
  247.     (void *)NineVolumeTexture9_LockBox,
  248.     (void *)NineVolumeTexture9_UnlockBox,
  249.     (void *)NineVolumeTexture9_AddDirtyBox
  250. };
  251.  
  252. static const GUID *NineVolumeTexture9_IIDs[] = {
  253.     &IID_IDirect3DVolumeTexture9,
  254.     &IID_IDirect3DBaseTexture9,
  255.     &IID_IDirect3DResource9,
  256.     &IID_IUnknown,
  257.     NULL
  258. };
  259.  
  260. HRESULT
  261. NineVolumeTexture9_new( struct NineDevice9 *pDevice,
  262.                         UINT Width, UINT Height, UINT Depth, UINT Levels,
  263.                         DWORD Usage,
  264.                         D3DFORMAT Format,
  265.                         D3DPOOL Pool,
  266.                         struct NineVolumeTexture9 **ppOut,
  267.                         HANDLE *pSharedHandle )
  268. {
  269.     NINE_DEVICE_CHILD_NEW(VolumeTexture9, ppOut, pDevice,
  270.                           Width, Height, Depth, Levels,
  271.                           Usage, Format, Pool, pSharedHandle);
  272. }
  273.  
  274.