2 * Copyright 2011 Joakim Sindholt <opensource@zhasha.com>
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:
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
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. */
24 #include "cubetexture9.h"
25 #include "nine_helpers.h"
26 #include "nine_pipe.h"
28 #define DBG_CHANNEL DBG_CUBETEXTURE
32 NineCubeTexture9_ctor( struct NineCubeTexture9
*This
,
33 struct NineUnknownParams
*pParams
,
34 UINT EdgeLength
, UINT Levels
,
38 HANDLE
*pSharedHandle
)
40 struct pipe_resource
*info
= &This
->base
.base
.info
;
42 D3DSURFACE_DESC sfdesc
;
45 user_assert(!(Usage
& D3DUSAGE_AUTOGENMIPMAP
) ||
46 (Pool
!= D3DPOOL_SYSTEMMEM
&& Levels
<= 1), D3DERR_INVALIDCALL
);
48 user_assert(!pSharedHandle
, D3DERR_INVALIDCALL
); /* TODO */
50 if (Usage
& D3DUSAGE_AUTOGENMIPMAP
)
53 This
->base
.format
= Format
;
54 This
->base
.base
.usage
= Usage
;
56 info
->screen
= pParams
->device
->screen
;
57 info
->target
= PIPE_TEXTURE_CUBE
;
58 info
->format
= d3d9_to_pipe_format(Format
);
59 info
->width0
= EdgeLength
;
60 info
->height0
= EdgeLength
;
63 info
->last_level
= Levels
- 1;
65 info
->last_level
= util_logbase2(EdgeLength
);
68 info
->bind
= PIPE_BIND_SAMPLER_VIEW
;
69 info
->usage
= PIPE_USAGE_DEFAULT
;
72 if (Usage
& D3DUSAGE_RENDERTARGET
)
73 info
->bind
|= PIPE_BIND_RENDER_TARGET
;
74 if (Usage
& D3DUSAGE_DEPTHSTENCIL
)
75 info
->bind
|= PIPE_BIND_DEPTH_STENCIL
;
77 if (Usage
& D3DUSAGE_DYNAMIC
) {
78 info
->usage
= PIPE_USAGE_DYNAMIC
;
80 PIPE_BIND_TRANSFER_READ
|
81 PIPE_BIND_TRANSFER_WRITE
;
84 This
->surfaces
= CALLOC(6 * (info
->last_level
+ 1), sizeof(*This
->surfaces
));
88 hr
= NineBaseTexture9_ctor(&This
->base
, pParams
, D3DRTYPE_CUBETEXTURE
,
92 This
->base
.pstype
= 2;
94 /* Create all the surfaces right away.
95 * They manage backing storage, and transfers (LockRect) are deferred
98 sfdesc
.Format
= Format
;
99 sfdesc
.Type
= D3DRTYPE_SURFACE
;
100 sfdesc
.Usage
= Usage
;
102 sfdesc
.MultiSampleType
= D3DMULTISAMPLE_NONE
;
103 sfdesc
.MultiSampleQuality
= 0;
104 for (i
= 0; i
< (info
->last_level
+ 1) * 6; ++i
) {
105 sfdesc
.Width
= sfdesc
.Height
= u_minify(EdgeLength
, i
/ 6);
107 hr
= NineSurface9_new(This
->base
.base
.base
.device
, NineUnknown(This
),
108 This
->base
.base
.resource
, D3DRTYPE_CUBETEXTURE
,
110 &sfdesc
, &This
->surfaces
[i
]);
114 for (i
= 0; i
< 6; ++i
) /* width = 0 means empty, depth stays 1 */
115 This
->dirty_rect
[i
].depth
= 1;
121 NineCubeTexture9_dtor( struct NineCubeTexture9
*This
)
125 DBG("This=%p\n", This
);
127 if (This
->surfaces
) {
128 for (i
= 0; i
< This
->base
.base
.info
.last_level
* 6; ++i
)
129 NineUnknown_Destroy(&This
->surfaces
[i
]->base
.base
);
130 FREE(This
->surfaces
);
133 NineBaseTexture9_dtor(&This
->base
);
137 NineCubeTexture9_GetLevelDesc( struct NineCubeTexture9
*This
,
139 D3DSURFACE_DESC
*pDesc
)
141 user_assert(Level
<= This
->base
.base
.info
.last_level
, D3DERR_INVALIDCALL
);
142 user_assert(Level
== 0 || !(This
->base
.base
.usage
& D3DUSAGE_AUTOGENMIPMAP
),
145 *pDesc
= This
->surfaces
[Level
]->desc
;
151 NineCubeTexture9_GetCubeMapSurface( struct NineCubeTexture9
*This
,
152 D3DCUBEMAP_FACES FaceType
,
154 IDirect3DSurface9
**ppCubeMapSurface
)
156 const unsigned s
= Level
* 6 + FaceType
;
158 user_assert(Level
<= This
->base
.base
.info
.last_level
, D3DERR_INVALIDCALL
);
159 user_assert(Level
== 0 || !(This
->base
.base
.usage
& D3DUSAGE_AUTOGENMIPMAP
),
161 user_assert(FaceType
< 6, D3DERR_INVALIDCALL
);
163 NineUnknown_AddRef(NineUnknown(This
->surfaces
[s
]));
164 *ppCubeMapSurface
= (IDirect3DSurface9
*)This
->surfaces
[s
];
170 NineCubeTexture9_LockRect( struct NineCubeTexture9
*This
,
171 D3DCUBEMAP_FACES FaceType
,
173 D3DLOCKED_RECT
*pLockedRect
,
177 const unsigned s
= Level
* 6 + FaceType
;
179 user_assert(Level
<= This
->base
.base
.info
.last_level
, D3DERR_INVALIDCALL
);
180 user_assert(Level
== 0 || !(This
->base
.base
.usage
& D3DUSAGE_AUTOGENMIPMAP
),
182 user_assert(FaceType
< 6, D3DERR_INVALIDCALL
);
184 return NineSurface9_LockRect(This
->surfaces
[s
], pLockedRect
, pRect
, Flags
);
188 NineCubeTexture9_UnlockRect( struct NineCubeTexture9
*This
,
189 D3DCUBEMAP_FACES FaceType
,
192 const unsigned s
= Level
* 6 + FaceType
;
194 user_assert(Level
<= This
->base
.base
.info
.last_level
, D3DERR_INVALIDCALL
);
195 user_assert(FaceType
< 6, D3DERR_INVALIDCALL
);
197 return NineSurface9_UnlockRect(This
->surfaces
[s
]);
201 NineCubeTexture9_AddDirtyRect( struct NineCubeTexture9
*This
,
202 D3DCUBEMAP_FACES FaceType
,
203 const RECT
*pDirtyRect
)
205 user_assert(FaceType
< 6, D3DERR_INVALIDCALL
);
207 if (This
->base
.base
.pool
!= D3DPOOL_MANAGED
) {
208 if (This
->base
.base
.usage
& D3DUSAGE_AUTOGENMIPMAP
)
209 This
->base
.dirty_mip
= TRUE
;
212 This
->base
.dirty
= TRUE
;
214 BASETEX_REGISTER_UPDATE(&This
->base
);
217 u_box_origin_2d(This
->base
.base
.info
.width0
,
218 This
->base
.base
.info
.height0
,
219 &This
->dirty_rect
[FaceType
]);
222 rect_to_pipe_box_clamp(&box
, pDirtyRect
);
223 u_box_union_2d(&This
->dirty_rect
[FaceType
], &This
->dirty_rect
[FaceType
],
229 IDirect3DCubeTexture9Vtbl NineCubeTexture9_vtable
= {
230 (void *)NineUnknown_QueryInterface
,
231 (void *)NineUnknown_AddRef
,
232 (void *)NineUnknown_Release
,
233 (void *)NineUnknown_GetDevice
, /* actually part of Resource9 iface */
234 (void *)NineResource9_SetPrivateData
,
235 (void *)NineResource9_GetPrivateData
,
236 (void *)NineResource9_FreePrivateData
,
237 (void *)NineResource9_SetPriority
,
238 (void *)NineResource9_GetPriority
,
239 (void *)NineBaseTexture9_PreLoad
,
240 (void *)NineResource9_GetType
,
241 (void *)NineBaseTexture9_SetLOD
,
242 (void *)NineBaseTexture9_GetLOD
,
243 (void *)NineBaseTexture9_GetLevelCount
,
244 (void *)NineBaseTexture9_SetAutoGenFilterType
,
245 (void *)NineBaseTexture9_GetAutoGenFilterType
,
246 (void *)NineBaseTexture9_GenerateMipSubLevels
,
247 (void *)NineCubeTexture9_GetLevelDesc
,
248 (void *)NineCubeTexture9_GetCubeMapSurface
,
249 (void *)NineCubeTexture9_LockRect
,
250 (void *)NineCubeTexture9_UnlockRect
,
251 (void *)NineCubeTexture9_AddDirtyRect
254 static const GUID
*NineCubeTexture9_IIDs
[] = {
255 &IID_IDirect3DCubeTexture9
,
256 &IID_IDirect3DBaseTexture9
,
257 &IID_IDirect3DResource9
,
263 NineCubeTexture9_new( struct NineDevice9
*pDevice
,
264 UINT EdgeLength
, UINT Levels
,
268 struct NineCubeTexture9
**ppOut
,
269 HANDLE
*pSharedHandle
)
271 NINE_DEVICE_CHILD_NEW(CubeTexture9
, ppOut
, pDevice
,
273 Usage
, Format
, Pool
, pSharedHandle
);