VirtualBox

source: vbox/trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/texture.c@ 20817

Last change on this file since 20817 was 20612, checked in by vboxsync, 16 years ago

crOpenGL: update wine to 1.1.23

  • Property svn:eol-style set to native
File size: 23.5 KB
Line 
1/*
2 * IWineD3DTexture implementation
3 *
4 * Copyright 2002-2005 Jason Edmeades
5 * Copyright 2002-2005 Raphael Junqueira
6 * Copyright 2005 Oliver Stieber
7 * Copyright 2007-2008 Stefan Dösinger for CodeWeavers
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 */
23
24/*
25 * Sun LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
26 * other than GPL or LGPL is available it will apply instead, Sun elects to use only
27 * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
28 * a choice of LGPL license versions is made available with the language indicating
29 * that LGPLv2 or any later version may be used, or where a choice of which version
30 * of the LGPL is applied is otherwise unspecified.
31 */
32
33#include "config.h"
34#include "wined3d_private.h"
35
36WINE_DEFAULT_DEBUG_CHANNEL(d3d_texture);
37
38#define GLINFO_LOCATION (*gl_info)
39
40static void texture_internal_preload(IWineD3DBaseTexture *iface, enum WINED3DSRGB srgb)
41{
42 /* Override the IWineD3DResource PreLoad method. */
43 IWineD3DTextureImpl *This = (IWineD3DTextureImpl *)iface;
44 IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
45 unsigned int i;
46 BOOL srgb_mode;
47 BOOL *dirty;
48
49 TRACE("(%p) : About to load texture.\n", This);
50
51 switch (srgb)
52 {
53 case SRGB_RGB:
54 srgb_mode = FALSE;
55 break;
56
57 case SRGB_BOTH:
58 texture_internal_preload(iface, SRGB_RGB);
59 /* Fallthrough */
60
61 case SRGB_SRGB:
62 srgb_mode = TRUE;
63 break;
64
65 default:
66 srgb_mode = This->baseTexture.is_srgb;
67 break;
68 }
69 dirty = srgb_mode ? &This->baseTexture.srgbDirty : &This->baseTexture.dirty;
70
71 if (!device->isInDraw)
72 {
73 /* ActivateContext sets isInDraw to TRUE when loading a pbuffer into a texture,
74 * thus no danger of recursive calls. */
75 ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
76 }
77
78 if (This->resource.format_desc->format == WINED3DFMT_P8
79 || This->resource.format_desc->format == WINED3DFMT_A8P8)
80 {
81 for (i = 0; i < This->baseTexture.levels; ++i)
82 {
83 if (palette9_changed((IWineD3DSurfaceImpl *)This->surfaces[i]))
84 {
85 TRACE("Reloading surface because the d3d8/9 palette was changed.\n");
86 /* TODO: This is not necessarily needed with hw palettized texture support. */
87 IWineD3DSurface_LoadLocation(This->surfaces[i], SFLAG_INSYSMEM, NULL);
88 /* Make sure the texture is reloaded because of the palette change, this kills performance though :( */
89 IWineD3DSurface_ModifyLocation(This->surfaces[i], SFLAG_INTEXTURE, FALSE);
90 }
91 }
92 }
93
94 /* If the texture is marked dirty or the srgb sampler setting has changed
95 * since the last load then reload the surfaces. */
96 if (*dirty)
97 {
98 for (i = 0; i < This->baseTexture.levels; ++i)
99 {
100 IWineD3DSurface_LoadTexture(This->surfaces[i], srgb_mode);
101 }
102 }
103 else
104 {
105 TRACE("(%p) Texture not dirty, nothing to do.\n", iface);
106 }
107
108 /* No longer dirty. */
109 *dirty = FALSE;
110}
111
112static void texture_cleanup(IWineD3DTextureImpl *This, D3DCB_DESTROYSURFACEFN surface_destroy_cb)
113{
114 unsigned int i;
115
116 TRACE("(%p) : Cleaning up\n", This);
117
118 for (i = 0; i < This->baseTexture.levels; ++i)
119 {
120 if (This->surfaces[i])
121 {
122 /* Clean out the texture name we gave to the surface so that the
123 * surface doesn't try and release it */
124 surface_set_texture_name(This->surfaces[i], 0, TRUE);
125 surface_set_texture_name(This->surfaces[i], 0, FALSE);
126 surface_set_texture_target(This->surfaces[i], 0);
127 IWineD3DSurface_SetContainer(This->surfaces[i], 0);
128 surface_destroy_cb(This->surfaces[i]);
129 }
130 }
131
132 TRACE("(%p) : Cleaning up base texture\n", This);
133 basetexture_cleanup((IWineD3DBaseTexture *)This);
134}
135
136HRESULT texture_init(IWineD3DTextureImpl *texture, UINT width, UINT height, UINT levels,
137 IWineD3DDeviceImpl *device, DWORD usage, WINED3DFORMAT format, WINED3DPOOL pool, IUnknown *parent)
138{
139 const WineD3D_GL_Info *gl_info = &device->adapter->gl_info;
140 const struct GlPixelFormatDesc *format_desc = getFormatDescEntry(format, gl_info);
141 UINT pow2_width, pow2_height;
142 UINT tmp_w, tmp_h;
143 unsigned int i;
144 HRESULT hr;
145
146 /* TODO: It should only be possible to create textures for formats
147 * that are reported as supported. */
148 if (WINED3DFMT_UNKNOWN >= format)
149 {
150 WARN("(%p) : Texture cannot be created with a format of WINED3DFMT_UNKNOWN.\n", texture);
151 return WINED3DERR_INVALIDCALL;
152 }
153
154 /* Non-power2 support. */
155 if (GL_SUPPORT(ARB_TEXTURE_NON_POWER_OF_TWO))
156 {
157 pow2_width = width;
158 pow2_height = height;
159 }
160 else
161 {
162 /* Find the nearest pow2 match. */
163 pow2_width = pow2_height = 1;
164 while (pow2_width < width) pow2_width <<= 1;
165 while (pow2_height < height) pow2_height <<= 1;
166
167 if (pow2_width != width || pow2_height != height)
168 {
169 if (levels > 1)
170 {
171 WARN("Attempted to create a mipmapped np2 texture without unconditional np2 support.\n");
172 return WINED3DERR_INVALIDCALL;
173 }
174 levels = 1;
175 }
176 }
177
178 /* Calculate levels for mip mapping. */
179 if (usage & WINED3DUSAGE_AUTOGENMIPMAP)
180 {
181 if (!GL_SUPPORT(SGIS_GENERATE_MIPMAP))
182 {
183 WARN("No mipmap generation support, returning WINED3DERR_INVALIDCALL.\n");
184 return WINED3DERR_INVALIDCALL;
185 }
186
187 if (levels > 1)
188 {
189 WARN("D3DUSAGE_AUTOGENMIPMAP is set, and level count > 1, returning WINED3DERR_INVALIDCALL.\n");
190 return WINED3DERR_INVALIDCALL;
191 }
192
193 levels = 1;
194 }
195 else if (!levels)
196 {
197 levels = wined3d_log2i(max(width, height)) + 1;
198 TRACE("Calculated levels = %u.\n", levels);
199 }
200
201 hr = basetexture_init((IWineD3DBaseTextureImpl *)texture, levels,
202 WINED3DRTYPE_TEXTURE, device, 0, usage, format_desc, pool, parent);
203 if (FAILED(hr))
204 {
205 WARN("Failed to initialize basetexture, returning %#x.\n", hr);
206 return hr;
207 }
208
209 if (texture->resource.format_desc->Flags & WINED3DFMT_FLAG_FILTERING)
210 {
211 texture->baseTexture.minMipLookup = minMipLookup;
212 texture->baseTexture.magLookup = magLookup;
213 }
214 else
215 {
216 texture->baseTexture.minMipLookup = minMipLookup_noFilter;
217 texture->baseTexture.magLookup = magLookup_noFilter;
218 }
219
220 /* Precalculated scaling for 'faked' non power of two texture coords.
221 * Second also don't use ARB_TEXTURE_RECTANGLE in case the surface format is P8 and EXT_PALETTED_TEXTURE
222 * is used in combination with texture uploads (RTL_READTEX/RTL_TEXTEX). The reason is that EXT_PALETTED_TEXTURE
223 * doesn't work in combination with ARB_TEXTURE_RECTANGLE. */
224 if (GL_SUPPORT(WINE_NORMALIZED_TEXRECT) && (width != pow2_width || height != pow2_height))
225 {
226 texture->baseTexture.pow2Matrix[0] = 1.0;
227 texture->baseTexture.pow2Matrix[5] = 1.0;
228 texture->baseTexture.pow2Matrix[10] = 1.0;
229 texture->baseTexture.pow2Matrix[15] = 1.0;
230 texture->target = GL_TEXTURE_2D;
231 texture->cond_np2 = TRUE;
232 texture->baseTexture.minMipLookup = minMipLookup_noFilter;
233 }
234 else if (GL_SUPPORT(ARB_TEXTURE_RECTANGLE) && (width != pow2_width || height != pow2_height)
235 && !((format_desc->format == WINED3DFMT_P8) && GL_SUPPORT(EXT_PALETTED_TEXTURE)
236 && (wined3d_settings.rendertargetlock_mode == RTL_READTEX
237 || wined3d_settings.rendertargetlock_mode == RTL_TEXTEX)))
238 {
239 if ((width != 1) || (height != 1)) texture->baseTexture.pow2Matrix_identity = FALSE;
240
241 texture->baseTexture.pow2Matrix[0] = (float)width;
242 texture->baseTexture.pow2Matrix[5] = (float)height;
243 texture->baseTexture.pow2Matrix[10] = 1.0;
244 texture->baseTexture.pow2Matrix[15] = 1.0;
245 texture->target = GL_TEXTURE_RECTANGLE_ARB;
246 texture->cond_np2 = TRUE;
247 texture->baseTexture.minMipLookup = minMipLookup_noFilter;
248 }
249 else
250 {
251 if ((width != pow2_width) || (height != pow2_height))
252 {
253 texture->baseTexture.pow2Matrix_identity = FALSE;
254 texture->baseTexture.pow2Matrix[0] = (((float)width) / ((float)pow2_width));
255 texture->baseTexture.pow2Matrix[5] = (((float)height) / ((float)pow2_height));
256 }
257 else
258 {
259 texture->baseTexture.pow2Matrix[0] = 1.0;
260 texture->baseTexture.pow2Matrix[5] = 1.0;
261 }
262
263 texture->baseTexture.pow2Matrix[10] = 1.0;
264 texture->baseTexture.pow2Matrix[15] = 1.0;
265 texture->target = GL_TEXTURE_2D;
266 texture->cond_np2 = FALSE;
267 }
268 TRACE("xf(%f) yf(%f)\n", texture->baseTexture.pow2Matrix[0], texture->baseTexture.pow2Matrix[5]);
269
270 /* Generate all the surfaces. */
271 tmp_w = width;
272 tmp_h = height;
273 for (i = 0; i < texture->baseTexture.levels; ++i)
274 {
275 /* Use the callback to create the texture surface. */
276 hr = IWineD3DDeviceParent_CreateSurface(device->device_parent, parent, tmp_w, tmp_h, format_desc->format,
277 usage, pool, i, WINED3DCUBEMAP_FACE_POSITIVE_X, &texture->surfaces[i]);
278 if (FAILED(hr) || ((IWineD3DSurfaceImpl *)texture->surfaces[i])->Flags & SFLAG_OVERSIZE)
279 {
280 FIXME("Failed to create surface %p, hr %#x\n", texture, hr);
281 texture->surfaces[i] = NULL;
282 texture_cleanup(texture, D3DCB_DefaultDestroySurface);
283 return hr;
284 }
285
286 IWineD3DSurface_SetContainer(texture->surfaces[i], (IWineD3DBase *)texture);
287 TRACE("Created surface level %u @ %p.\n", i, texture->surfaces[i]);
288 surface_set_texture_target(texture->surfaces[i], texture->target);
289 /* Calculate the next mipmap level. */
290 tmp_w = max(1, tmp_w >> 1);
291 tmp_h = max(1, tmp_h >> 1);
292 }
293 texture->baseTexture.internal_preload = texture_internal_preload;
294
295 return WINED3D_OK;
296}
297
298#undef GLINFO_LOCATION
299
300/* *******************************************
301 IWineD3DTexture IUnknown parts follow
302 ******************************************* */
303
304#define GLINFO_LOCATION This->resource.wineD3DDevice->adapter->gl_info
305
306static HRESULT WINAPI IWineD3DTextureImpl_QueryInterface(IWineD3DTexture *iface, REFIID riid, LPVOID *ppobj)
307{
308 IWineD3DTextureImpl *This = (IWineD3DTextureImpl *)iface;
309 TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(riid),ppobj);
310 if (IsEqualGUID(riid, &IID_IUnknown)
311 || IsEqualGUID(riid, &IID_IWineD3DBase)
312 || IsEqualGUID(riid, &IID_IWineD3DResource)
313 || IsEqualGUID(riid, &IID_IWineD3DBaseTexture)
314 || IsEqualGUID(riid, &IID_IWineD3DTexture)){
315 IUnknown_AddRef(iface);
316 *ppobj = This;
317 return WINED3D_OK;
318 }
319 *ppobj = NULL;
320 return E_NOINTERFACE;
321}
322
323static ULONG WINAPI IWineD3DTextureImpl_AddRef(IWineD3DTexture *iface) {
324 IWineD3DTextureImpl *This = (IWineD3DTextureImpl *)iface;
325 TRACE("(%p) : AddRef increasing from %d\n", This, This->resource.ref);
326 return InterlockedIncrement(&This->resource.ref);
327}
328
329static ULONG WINAPI IWineD3DTextureImpl_Release(IWineD3DTexture *iface) {
330 IWineD3DTextureImpl *This = (IWineD3DTextureImpl *)iface;
331 ULONG ref;
332 TRACE("(%p) : Releasing from %d\n", This, This->resource.ref);
333 ref = InterlockedDecrement(&This->resource.ref);
334 if (ref == 0) {
335 IWineD3DTexture_Destroy(iface, D3DCB_DefaultDestroySurface);
336 }
337 return ref;
338}
339
340
341/* ****************************************************
342 IWineD3DTexture IWineD3DResource parts follow
343 **************************************************** */
344static HRESULT WINAPI IWineD3DTextureImpl_GetDevice(IWineD3DTexture *iface, IWineD3DDevice** ppDevice) {
345 return resource_get_device((IWineD3DResource *)iface, ppDevice);
346}
347
348static HRESULT WINAPI IWineD3DTextureImpl_SetPrivateData(IWineD3DTexture *iface, REFGUID refguid, CONST void* pData, DWORD SizeOfData, DWORD Flags) {
349 return resource_set_private_data((IWineD3DResource *)iface, refguid, pData, SizeOfData, Flags);
350}
351
352static HRESULT WINAPI IWineD3DTextureImpl_GetPrivateData(IWineD3DTexture *iface, REFGUID refguid, void* pData, DWORD* pSizeOfData) {
353 return resource_get_private_data((IWineD3DResource *)iface, refguid, pData, pSizeOfData);
354}
355
356static HRESULT WINAPI IWineD3DTextureImpl_FreePrivateData(IWineD3DTexture *iface, REFGUID refguid) {
357 return resource_free_private_data((IWineD3DResource *)iface, refguid);
358}
359
360static DWORD WINAPI IWineD3DTextureImpl_SetPriority(IWineD3DTexture *iface, DWORD PriorityNew) {
361 return resource_set_priority((IWineD3DResource *)iface, PriorityNew);
362}
363
364static DWORD WINAPI IWineD3DTextureImpl_GetPriority(IWineD3DTexture *iface) {
365 return resource_get_priority((IWineD3DResource *)iface);
366}
367
368static void WINAPI IWineD3DTextureImpl_PreLoad(IWineD3DTexture *iface) {
369 texture_internal_preload((IWineD3DBaseTexture *) iface, SRGB_ANY);
370}
371
372static void WINAPI IWineD3DTextureImpl_UnLoad(IWineD3DTexture *iface) {
373 unsigned int i;
374 IWineD3DTextureImpl *This = (IWineD3DTextureImpl *)iface;
375 TRACE("(%p)\n", This);
376
377 /* Unload all the surfaces and reset the texture name. If UnLoad was called on the
378 * surface before, this one will be a NOP and vice versa. Unloading an unloaded
379 * surface is fine
380 */
381 for (i = 0; i < This->baseTexture.levels; i++) {
382 IWineD3DSurface_UnLoad(This->surfaces[i]);
383 surface_set_texture_name(This->surfaces[i], 0, FALSE); /* Delete rgb name */
384 surface_set_texture_name(This->surfaces[i], 0, TRUE); /* delete srgb name */
385 }
386
387 basetexture_unload((IWineD3DBaseTexture *)iface);
388}
389
390static WINED3DRESOURCETYPE WINAPI IWineD3DTextureImpl_GetType(IWineD3DTexture *iface) {
391 return resource_get_type((IWineD3DResource *)iface);
392}
393
394static HRESULT WINAPI IWineD3DTextureImpl_GetParent(IWineD3DTexture *iface, IUnknown **pParent) {
395 return resource_get_parent((IWineD3DResource *)iface, pParent);
396}
397
398/* ******************************************************
399 IWineD3DTexture IWineD3DBaseTexture parts follow
400 ****************************************************** */
401static DWORD WINAPI IWineD3DTextureImpl_SetLOD(IWineD3DTexture *iface, DWORD LODNew) {
402 return basetexture_set_lod((IWineD3DBaseTexture *)iface, LODNew);
403}
404
405static DWORD WINAPI IWineD3DTextureImpl_GetLOD(IWineD3DTexture *iface) {
406 return basetexture_get_lod((IWineD3DBaseTexture *)iface);
407}
408
409static DWORD WINAPI IWineD3DTextureImpl_GetLevelCount(IWineD3DTexture *iface) {
410 return basetexture_get_level_count((IWineD3DBaseTexture *)iface);
411}
412
413static HRESULT WINAPI IWineD3DTextureImpl_SetAutoGenFilterType(IWineD3DTexture *iface, WINED3DTEXTUREFILTERTYPE FilterType) {
414 return basetexture_set_autogen_filter_type((IWineD3DBaseTexture *)iface, FilterType);
415}
416
417static WINED3DTEXTUREFILTERTYPE WINAPI IWineD3DTextureImpl_GetAutoGenFilterType(IWineD3DTexture *iface) {
418 return basetexture_get_autogen_filter_type((IWineD3DBaseTexture *)iface);
419}
420
421static void WINAPI IWineD3DTextureImpl_GenerateMipSubLevels(IWineD3DTexture *iface) {
422 basetexture_generate_mipmaps((IWineD3DBaseTexture *)iface);
423}
424
425/* Internal function, No d3d mapping */
426static BOOL WINAPI IWineD3DTextureImpl_SetDirty(IWineD3DTexture *iface, BOOL dirty) {
427 return basetexture_set_dirty((IWineD3DBaseTexture *)iface, dirty);
428}
429
430static BOOL WINAPI IWineD3DTextureImpl_GetDirty(IWineD3DTexture *iface) {
431 return basetexture_get_dirty((IWineD3DBaseTexture *)iface);
432}
433
434static HRESULT WINAPI IWineD3DTextureImpl_BindTexture(IWineD3DTexture *iface, BOOL srgb) {
435 IWineD3DTextureImpl *This = (IWineD3DTextureImpl *)iface;
436 BOOL set_gl_texture_desc;
437 HRESULT hr;
438
439 TRACE("(%p) : relay to BaseTexture\n", This);
440
441 hr = basetexture_bind((IWineD3DBaseTexture *)iface, srgb, &set_gl_texture_desc);
442 if (set_gl_texture_desc && SUCCEEDED(hr)) {
443 UINT i;
444 for (i = 0; i < This->baseTexture.levels; ++i) {
445 if(This->baseTexture.is_srgb) {
446 surface_set_texture_name(This->surfaces[i], This->baseTexture.srgbTextureName, TRUE);
447 } else {
448 surface_set_texture_name(This->surfaces[i], This->baseTexture.textureName, FALSE);
449 }
450 }
451 /* Conditinal non power of two textures use a different clamping default. If we're using the GL_WINE_normalized_texrect
452 * partial driver emulation, we're dealing with a GL_TEXTURE_2D texture which has the address mode set to repeat - something
453 * that prevents us from hitting the accelerated codepath. Thus manually set the GL state. The same applies to filtering.
454 * Even if the texture has only one mip level, the default LINEAR_MIPMAP_LINEAR filter causes a SW fallback on macos.
455 */
456 if(IWineD3DBaseTexture_IsCondNP2(iface)) {
457 ENTER_GL();
458 glTexParameteri(IWineD3DTexture_GetTextureDimensions(iface), GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
459 checkGLcall("glTexParameteri(dimension, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)");
460 glTexParameteri(IWineD3DTexture_GetTextureDimensions(iface), GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
461 checkGLcall("glTexParameteri(dimension, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)");
462 glTexParameteri(IWineD3DTexture_GetTextureDimensions(iface), GL_TEXTURE_MIN_FILTER, GL_NEAREST);
463 checkGLcall("glTexParameteri(dimension, GL_TEXTURE_MIN_FILTER, GL_NEAREST)");
464 glTexParameteri(IWineD3DTexture_GetTextureDimensions(iface), GL_TEXTURE_MAG_FILTER, GL_NEAREST);
465 checkGLcall("glTexParameteri(dimension, GL_TEXTURE_MAG_FILTER, GL_NEAREST)");
466 LEAVE_GL();
467 This->baseTexture.states[WINED3DTEXSTA_ADDRESSU] = WINED3DTADDRESS_CLAMP;
468 This->baseTexture.states[WINED3DTEXSTA_ADDRESSV] = WINED3DTADDRESS_CLAMP;
469 This->baseTexture.states[WINED3DTEXSTA_MAGFILTER] = WINED3DTEXF_POINT;
470 This->baseTexture.states[WINED3DTEXSTA_MINFILTER] = WINED3DTEXF_POINT;
471 This->baseTexture.states[WINED3DTEXSTA_MIPFILTER] = WINED3DTEXF_NONE;
472 }
473 }
474
475 return hr;
476}
477
478static UINT WINAPI IWineD3DTextureImpl_GetTextureDimensions(IWineD3DTexture *iface) {
479 IWineD3DTextureImpl *This = (IWineD3DTextureImpl *)iface;
480 TRACE("(%p)\n", This);
481
482 return This->target;
483}
484
485static BOOL WINAPI IWineD3DTextureImpl_IsCondNP2(IWineD3DTexture *iface) {
486 IWineD3DTextureImpl *This = (IWineD3DTextureImpl *)iface;
487 TRACE("(%p)\n", This);
488
489 return This->cond_np2;
490}
491
492/* *******************************************
493 IWineD3DTexture IWineD3DTexture parts follow
494 ******************************************* */
495static void WINAPI IWineD3DTextureImpl_Destroy(IWineD3DTexture *iface, D3DCB_DESTROYSURFACEFN D3DCB_DestroySurface) {
496 IWineD3DTextureImpl *This = (IWineD3DTextureImpl *)iface;
497
498 texture_cleanup(This, D3DCB_DestroySurface);
499 /* free the object */
500 HeapFree(GetProcessHeap(), 0, This);
501}
502
503static HRESULT WINAPI IWineD3DTextureImpl_GetLevelDesc(IWineD3DTexture *iface, UINT Level, WINED3DSURFACE_DESC* pDesc) {
504 IWineD3DTextureImpl *This = (IWineD3DTextureImpl *)iface;
505
506 if (Level < This->baseTexture.levels) {
507 TRACE("(%p) Level (%d)\n", This, Level);
508 return IWineD3DSurface_GetDesc(This->surfaces[Level], pDesc);
509 }
510 WARN("(%p) level(%d) overflow Levels(%d)\n", This, Level, This->baseTexture.levels);
511 return WINED3DERR_INVALIDCALL;
512}
513
514static HRESULT WINAPI IWineD3DTextureImpl_GetSurfaceLevel(IWineD3DTexture *iface, UINT Level, IWineD3DSurface** ppSurfaceLevel) {
515 IWineD3DTextureImpl *This = (IWineD3DTextureImpl *)iface;
516 HRESULT hr = WINED3DERR_INVALIDCALL;
517
518 if (Level < This->baseTexture.levels) {
519 *ppSurfaceLevel = This->surfaces[Level];
520 IWineD3DSurface_AddRef(This->surfaces[Level]);
521 hr = WINED3D_OK;
522 TRACE("(%p) : returning %p for level %d\n", This, *ppSurfaceLevel, Level);
523 }
524 if (WINED3D_OK != hr) {
525 WARN("(%p) level(%d) overflow Levels(%d)\n", This, Level, This->baseTexture.levels);
526 *ppSurfaceLevel = NULL; /* Just to be on the safe side.. */
527 }
528 return hr;
529}
530
531static HRESULT WINAPI IWineD3DTextureImpl_LockRect(IWineD3DTexture *iface, UINT Level, WINED3DLOCKED_RECT *pLockedRect,
532 CONST RECT *pRect, DWORD Flags) {
533 IWineD3DTextureImpl *This = (IWineD3DTextureImpl *)iface;
534 HRESULT hr = WINED3DERR_INVALIDCALL;
535
536 if (Level < This->baseTexture.levels) {
537 hr = IWineD3DSurface_LockRect(This->surfaces[Level], pLockedRect, pRect, Flags);
538 }
539 if (WINED3D_OK == hr) {
540 TRACE("(%p) Level (%d) success\n", This, Level);
541 } else {
542 WARN("(%p) level(%d) overflow Levels(%d)\n", This, Level, This->baseTexture.levels);
543 }
544
545 return hr;
546}
547
548static HRESULT WINAPI IWineD3DTextureImpl_UnlockRect(IWineD3DTexture *iface, UINT Level) {
549 IWineD3DTextureImpl *This = (IWineD3DTextureImpl *)iface;
550 HRESULT hr = WINED3DERR_INVALIDCALL;
551
552 if (Level < This->baseTexture.levels) {
553 hr = IWineD3DSurface_UnlockRect(This->surfaces[Level]);
554 }
555 if ( WINED3D_OK == hr) {
556 TRACE("(%p) Level (%d) success\n", This, Level);
557 } else {
558 WARN("(%p) level(%d) overflow Levels(%d)\n", This, Level, This->baseTexture.levels);
559 }
560 return hr;
561}
562
563static HRESULT WINAPI IWineD3DTextureImpl_AddDirtyRect(IWineD3DTexture *iface, CONST RECT* pDirtyRect) {
564 IWineD3DTextureImpl *This = (IWineD3DTextureImpl *)iface;
565 This->baseTexture.dirty = TRUE;
566 This->baseTexture.srgbDirty = TRUE;
567 TRACE("(%p) : dirtyfication of surface Level (0)\n", This);
568 surface_add_dirty_rect(This->surfaces[0], pDirtyRect);
569
570 return WINED3D_OK;
571}
572
573const IWineD3DTextureVtbl IWineD3DTexture_Vtbl =
574{
575 /* IUnknown */
576 IWineD3DTextureImpl_QueryInterface,
577 IWineD3DTextureImpl_AddRef,
578 IWineD3DTextureImpl_Release,
579 /* IWineD3DResource */
580 IWineD3DTextureImpl_GetParent,
581 IWineD3DTextureImpl_GetDevice,
582 IWineD3DTextureImpl_SetPrivateData,
583 IWineD3DTextureImpl_GetPrivateData,
584 IWineD3DTextureImpl_FreePrivateData,
585 IWineD3DTextureImpl_SetPriority,
586 IWineD3DTextureImpl_GetPriority,
587 IWineD3DTextureImpl_PreLoad,
588 IWineD3DTextureImpl_UnLoad,
589 IWineD3DTextureImpl_GetType,
590 /* IWineD3DBaseTexture */
591 IWineD3DTextureImpl_SetLOD,
592 IWineD3DTextureImpl_GetLOD,
593 IWineD3DTextureImpl_GetLevelCount,
594 IWineD3DTextureImpl_SetAutoGenFilterType,
595 IWineD3DTextureImpl_GetAutoGenFilterType,
596 IWineD3DTextureImpl_GenerateMipSubLevels,
597 IWineD3DTextureImpl_SetDirty,
598 IWineD3DTextureImpl_GetDirty,
599 IWineD3DTextureImpl_BindTexture,
600 IWineD3DTextureImpl_GetTextureDimensions,
601 IWineD3DTextureImpl_IsCondNP2,
602 /* IWineD3DTexture */
603 IWineD3DTextureImpl_Destroy,
604 IWineD3DTextureImpl_GetLevelDesc,
605 IWineD3DTextureImpl_GetSurfaceLevel,
606 IWineD3DTextureImpl_LockRect,
607 IWineD3DTextureImpl_UnlockRect,
608 IWineD3DTextureImpl_AddDirtyRect
609};
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette