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. */
26 /* for marking dirty */
27 #include "basetexture9.h"
29 #include "cubetexture9.h"
31 #include "nine_helpers.h"
32 #include "nine_pipe.h"
33 #include "nine_dump.h"
35 #include "pipe/p_context.h"
36 #include "pipe/p_screen.h"
37 #include "pipe/p_state.h"
39 #include "util/u_math.h"
40 #include "util/u_inlines.h"
41 #include "util/u_surface.h"
43 #define DBG_CHANNEL DBG_SURFACE
45 #define is_ATI1_ATI2(format) (format == PIPE_FORMAT_RGTC1_UNORM || format == PIPE_FORMAT_RGTC2_UNORM)
48 NineSurface9_ctor( struct NineSurface9
*This
,
49 struct NineUnknownParams
*pParams
,
50 struct NineUnknown
*pContainer
,
51 struct pipe_resource
*pResource
,
56 D3DSURFACE_DESC
*pDesc
)
59 union pipe_color_union rgba
= {0};
60 struct pipe_surface
*surf
;
61 struct pipe_context
*pipe
= pParams
->device
->pipe
;
63 DBG("This=%p pDevice=%p pResource=%p Level=%u Layer=%u pDesc=%p\n",
64 This
, pParams
->device
, pResource
, Level
, Layer
, pDesc
);
66 /* Mark this as a special surface held by another internal resource. */
67 pParams
->container
= pContainer
;
69 user_assert(!(pDesc
->Usage
& D3DUSAGE_DYNAMIC
) ||
70 (pDesc
->Pool
!= D3DPOOL_MANAGED
), D3DERR_INVALIDCALL
);
72 assert(pResource
|| (user_buffer
&& pDesc
->Pool
!= D3DPOOL_DEFAULT
) ||
73 (!pContainer
&& pDesc
->Pool
!= D3DPOOL_DEFAULT
) ||
74 pDesc
->Format
== D3DFMT_NULL
);
76 assert(!pResource
|| !user_buffer
);
77 assert(!user_buffer
|| pDesc
->Pool
!= D3DPOOL_DEFAULT
);
78 /* The only way we can have !pContainer is being created
79 * from create_zs_or_rt_surface with params 0 0 0 */
80 assert(pContainer
|| (Level
== 0 && Layer
== 0 && TextureType
== 0));
82 This
->data
= (uint8_t *)user_buffer
;
84 This
->base
.info
.screen
= pParams
->device
->screen
;
85 This
->base
.info
.target
= PIPE_TEXTURE_2D
;
86 This
->base
.info
.width0
= pDesc
->Width
;
87 This
->base
.info
.height0
= pDesc
->Height
;
88 This
->base
.info
.depth0
= 1;
89 This
->base
.info
.last_level
= 0;
90 This
->base
.info
.array_size
= 1;
91 This
->base
.info
.nr_samples
= pDesc
->MultiSampleType
;
92 This
->base
.info
.usage
= PIPE_USAGE_DEFAULT
;
93 This
->base
.info
.bind
= PIPE_BIND_SAMPLER_VIEW
;
94 This
->base
.info
.flags
= 0;
95 This
->base
.info
.format
= d3d9_to_pipe_format_checked(This
->base
.info
.screen
,
97 This
->base
.info
.target
,
98 This
->base
.info
.nr_samples
,
101 pDesc
->Pool
== D3DPOOL_SCRATCH
);
103 if (pDesc
->Usage
& D3DUSAGE_RENDERTARGET
)
104 This
->base
.info
.bind
|= PIPE_BIND_RENDER_TARGET
;
105 if (pDesc
->Usage
& D3DUSAGE_DEPTHSTENCIL
)
106 This
->base
.info
.bind
|= PIPE_BIND_DEPTH_STENCIL
;
108 /* Get true format */
109 This
->format_conversion
= d3d9_to_pipe_format_checked(This
->base
.info
.screen
,
111 This
->base
.info
.target
,
112 This
->base
.info
.nr_samples
,
113 This
->base
.info
.bind
,
116 if (This
->base
.info
.format
!= This
->format_conversion
) {
117 This
->data_conversion
= align_malloc(
118 nine_format_get_level_alloc_size(This
->format_conversion
,
122 if (!This
->data_conversion
)
123 return E_OUTOFMEMORY
;
124 This
->stride_conversion
= nine_format_get_stride(This
->format_conversion
,
128 /* Ram buffer with no parent. Has to allocate the resource itself */
129 if (!pResource
&& !pContainer
) {
130 assert(!user_buffer
);
131 This
->data
= align_malloc(
132 nine_format_get_level_alloc_size(This
->base
.info
.format
,
137 return E_OUTOFMEMORY
;
140 assert(pDesc
->Pool
!= D3DPOOL_SYSTEMMEM
|| !pResource
);
142 if (pResource
&& (pDesc
->Usage
& D3DUSAGE_DYNAMIC
))
143 pResource
->flags
|= NINE_RESOURCE_FLAG_LOCKABLE
;
145 hr
= NineResource9_ctor(&This
->base
, pParams
, pResource
, FALSE
, D3DRTYPE_SURFACE
,
146 pDesc
->Pool
, pDesc
->Usage
);
150 This
->pipe
= This
->base
.base
.device
->pipe
;
151 This
->transfer
= NULL
;
153 This
->texture
= TextureType
;
155 This
->level_actual
= Level
;
159 This
->stride
= nine_format_get_stride(This
->base
.info
.format
, pDesc
->Width
);
161 if (pResource
&& NineSurface9_IsOffscreenPlain(This
))
162 pResource
->flags
|= NINE_RESOURCE_FLAG_LOCKABLE
;
164 /* TODO: investigate what else exactly needs to be cleared */
165 if (This
->base
.resource
&& (pDesc
->Usage
& D3DUSAGE_RENDERTARGET
)) {
166 surf
= NineSurface9_GetSurface(This
, 0);
167 pipe
->clear_render_target(pipe
, surf
, &rgba
, 0, 0, pDesc
->Width
, pDesc
->Height
);
170 NineSurface9_Dump(This
);
176 NineSurface9_dtor( struct NineSurface9
*This
)
178 DBG("This=%p\n", This
);
181 NineSurface9_UnlockRect(This
);
183 pipe_surface_reference(&This
->surface
[0], NULL
);
184 pipe_surface_reference(&This
->surface
[1], NULL
);
186 /* Release system memory when we have to manage it (no parent) */
187 if (!This
->base
.base
.container
&& This
->data
)
188 align_free(This
->data
);
189 if (This
->data_conversion
)
190 align_free(This
->data_conversion
);
191 NineResource9_dtor(&This
->base
);
194 struct pipe_surface
*
195 NineSurface9_CreatePipeSurface( struct NineSurface9
*This
, const int sRGB
)
197 struct pipe_context
*pipe
= This
->pipe
;
198 struct pipe_screen
*screen
= pipe
->screen
;
199 struct pipe_resource
*resource
= This
->base
.resource
;
200 struct pipe_surface templ
;
201 enum pipe_format srgb_format
;
203 assert(This
->desc
.Pool
== D3DPOOL_DEFAULT
);
206 srgb_format
= util_format_srgb(resource
->format
);
207 if (sRGB
&& srgb_format
!= PIPE_FORMAT_NONE
&&
208 screen
->is_format_supported(screen
, srgb_format
,
209 resource
->target
, 0, resource
->bind
))
210 templ
.format
= srgb_format
;
212 templ
.format
= resource
->format
;
213 templ
.u
.tex
.level
= This
->level
;
214 templ
.u
.tex
.first_layer
= This
->layer
;
215 templ
.u
.tex
.last_layer
= This
->layer
;
217 This
->surface
[sRGB
] = pipe
->create_surface(pipe
, resource
, &templ
);
218 assert(This
->surface
[sRGB
]);
219 return This
->surface
[sRGB
];
224 NineSurface9_Dump( struct NineSurface9
*This
)
226 struct NineBaseTexture9
*tex
;
227 GUID id
= IID_IDirect3DBaseTexture9
;
230 DBG("\nNineSurface9(%p->%p/%p): Pool=%s Type=%s Usage=%s\n"
231 "Dims=%ux%u Format=%s Stride=%u Lockable=%i\n"
232 "Level=%u(%u), Layer=%u\n", This
, This
->base
.resource
, This
->data
,
233 nine_D3DPOOL_to_str(This
->desc
.Pool
),
234 nine_D3DRTYPE_to_str(This
->desc
.Type
),
235 nine_D3DUSAGE_to_str(This
->desc
.Usage
),
236 This
->desc
.Width
, This
->desc
.Height
,
237 d3dformat_to_string(This
->desc
.Format
), This
->stride
,
238 This
->base
.resource
&&
239 (This
->base
.resource
->flags
& NINE_RESOURCE_FLAG_LOCKABLE
),
240 This
->level
, This
->level_actual
, This
->layer
);
242 if (!This
->base
.base
.container
)
244 NineUnknown_QueryInterface(This
->base
.base
.container
, ref
, (void **)&tex
);
246 NineBaseTexture9_Dump(tex
);
247 NineUnknown_Release(NineUnknown(tex
));
253 NineSurface9_GetContainer( struct NineSurface9
*This
,
258 if (!NineUnknown(This
)->container
)
259 return E_NOINTERFACE
;
260 hr
= NineUnknown_QueryInterface(NineUnknown(This
)->container
, riid
, ppContainer
);
262 DBG("QueryInterface FAILED!\n");
267 NineSurface9_MarkContainerDirty( struct NineSurface9
*This
)
270 struct NineBaseTexture9
*tex
=
271 NineBaseTexture9(This
->base
.base
.container
);
273 assert(This
->texture
== D3DRTYPE_TEXTURE
||
274 This
->texture
== D3DRTYPE_CUBETEXTURE
);
275 if (This
->base
.pool
== D3DPOOL_MANAGED
)
276 tex
->managed
.dirty
= TRUE
;
278 if (This
->base
.usage
& D3DUSAGE_AUTOGENMIPMAP
)
279 tex
->dirty_mip
= TRUE
;
281 BASETEX_REGISTER_UPDATE(tex
);
286 NineSurface9_GetDesc( struct NineSurface9
*This
,
287 D3DSURFACE_DESC
*pDesc
)
289 user_assert(pDesc
!= NULL
, E_POINTER
);
294 /* Add the dirty rects to the source texture */
296 NineSurface9_AddDirtyRect( struct NineSurface9
*This
,
297 const struct pipe_box
*box
)
301 DBG("This=%p box=%p\n", This
, box
);
303 assert (This
->base
.pool
!= D3DPOOL_MANAGED
||
304 This
->texture
== D3DRTYPE_CUBETEXTURE
||
305 This
->texture
== D3DRTYPE_TEXTURE
);
307 if (This
->base
.pool
== D3DPOOL_DEFAULT
)
310 /* Add a dirty rect to level 0 of the parent texture */
311 dirty_rect
.left
= box
->x
<< This
->level_actual
;
312 dirty_rect
.right
= dirty_rect
.left
+ (box
->width
<< This
->level_actual
);
313 dirty_rect
.top
= box
->y
<< This
->level_actual
;
314 dirty_rect
.bottom
= dirty_rect
.top
+ (box
->height
<< This
->level_actual
);
316 if (This
->texture
== D3DRTYPE_TEXTURE
) {
317 struct NineTexture9
*tex
=
318 NineTexture9(This
->base
.base
.container
);
320 NineTexture9_AddDirtyRect(tex
, &dirty_rect
);
321 } else if (This
->texture
== D3DRTYPE_CUBETEXTURE
) {
322 struct NineCubeTexture9
*ctex
=
323 NineCubeTexture9(This
->base
.base
.container
);
325 NineCubeTexture9_AddDirtyRect(ctex
, This
->layer
, &dirty_rect
);
329 static inline uint8_t *
330 NineSurface9_GetSystemMemPointer(struct NineSurface9
*This
, int x
, int y
)
332 unsigned x_offset
= util_format_get_stride(This
->base
.info
.format
, x
);
334 y
= util_format_get_nblocksy(This
->base
.info
.format
, y
);
337 return This
->data
+ (y
* This
->stride
+ x_offset
);
341 NineSurface9_LockRect( struct NineSurface9
*This
,
342 D3DLOCKED_RECT
*pLockedRect
,
346 struct pipe_resource
*resource
= This
->base
.resource
;
350 DBG("This=%p pLockedRect=%p pRect=%p[%u..%u,%u..%u] Flags=%s\n", This
,
352 pRect
? pRect
->left
: 0, pRect
? pRect
->right
: 0,
353 pRect
? pRect
->top
: 0, pRect
? pRect
->bottom
: 0,
354 nine_D3DLOCK_to_str(Flags
));
355 NineSurface9_Dump(This
);
357 /* check if it's already locked */
358 user_assert(This
->lock_count
== 0, D3DERR_INVALIDCALL
);
360 /* set pBits to NULL after lock_count check */
361 user_assert(pLockedRect
, E_POINTER
);
362 pLockedRect
->pBits
= NULL
;
365 user_assert(This
->base
.pool
!= D3DPOOL_DEFAULT
||
366 (resource
&& (resource
->flags
& NINE_RESOURCE_FLAG_LOCKABLE
)),
369 user_assert(!(Flags
& ~(D3DLOCK_DISCARD
|
371 D3DLOCK_NO_DIRTY_UPDATE
|
372 D3DLOCK_NOOVERWRITE
|
373 D3DLOCK_NOSYSLOCK
| /* ignored */
374 D3DLOCK_READONLY
)), D3DERR_INVALIDCALL
);
375 user_assert(!((Flags
& D3DLOCK_DISCARD
) && (Flags
& D3DLOCK_READONLY
)),
378 user_assert(This
->desc
.MultiSampleType
== D3DMULTISAMPLE_NONE
,
381 if (pRect
&& This
->desc
.Pool
== D3DPOOL_DEFAULT
&&
382 util_format_is_compressed(This
->base
.info
.format
)) {
383 const unsigned w
= util_format_get_blockwidth(This
->base
.info
.format
);
384 const unsigned h
= util_format_get_blockheight(This
->base
.info
.format
);
385 user_assert((pRect
->left
== 0 && pRect
->right
== This
->desc
.Width
&&
386 pRect
->top
== 0 && pRect
->bottom
== This
->desc
.Height
) ||
387 (!(pRect
->left
% w
) && !(pRect
->right
% w
) &&
388 !(pRect
->top
% h
) && !(pRect
->bottom
% h
)),
392 if (Flags
& D3DLOCK_DISCARD
) {
393 usage
= PIPE_TRANSFER_WRITE
| PIPE_TRANSFER_DISCARD_RANGE
;
395 usage
= (Flags
& D3DLOCK_READONLY
) ?
396 PIPE_TRANSFER_READ
: PIPE_TRANSFER_READ_WRITE
;
398 if (Flags
& D3DLOCK_DONOTWAIT
)
399 usage
|= PIPE_TRANSFER_DONTBLOCK
;
402 /* Windows XP accepts invalid locking rectangles, Windows 7 rejects
403 * them. Use Windows XP behaviour for now. */
404 rect_to_pipe_box(&box
, pRect
);
406 u_box_origin_2d(This
->desc
.Width
, This
->desc
.Height
, &box
);
409 user_warn(This
->desc
.Format
== D3DFMT_NULL
);
411 if (This
->data_conversion
) {
412 /* For now we only have uncompressed formats here */
413 pLockedRect
->Pitch
= This
->stride_conversion
;
414 pLockedRect
->pBits
= This
->data_conversion
+ box
.y
* This
->stride_conversion
+
415 util_format_get_stride(This
->format_conversion
, box
.x
);
416 } else if (This
->data
) {
417 DBG("returning system memory\n");
418 /* ATI1 and ATI2 need special handling, because of d3d9 bug.
419 * We must advertise to the application as if it is uncompressed
420 * and bpp 8, and the app has a workaround to work with the fact
421 * that it is actually compressed. */
422 if (is_ATI1_ATI2(This
->base
.info
.format
)) {
423 pLockedRect
->Pitch
= This
->desc
.Width
;
424 pLockedRect
->pBits
= This
->data
+ box
.y
* This
->desc
.Width
+ box
.x
;
426 pLockedRect
->Pitch
= This
->stride
;
427 pLockedRect
->pBits
= NineSurface9_GetSystemMemPointer(This
,
432 DBG("mapping pipe_resource %p (level=%u usage=%x)\n",
433 resource
, This
->level
, usage
);
435 pLockedRect
->pBits
= This
->pipe
->transfer_map(This
->pipe
, resource
,
436 This
->level
, usage
, &box
,
438 if (!This
->transfer
) {
439 DBG("transfer_map failed\n");
440 if (Flags
& D3DLOCK_DONOTWAIT
)
441 return D3DERR_WASSTILLDRAWING
;
442 return D3DERR_INVALIDCALL
;
444 pLockedRect
->Pitch
= This
->transfer
->stride
;
447 if (!(Flags
& (D3DLOCK_NO_DIRTY_UPDATE
| D3DLOCK_READONLY
))) {
448 NineSurface9_MarkContainerDirty(This
);
449 NineSurface9_AddDirtyRect(This
, &box
);
457 NineSurface9_UnlockRect( struct NineSurface9
*This
)
459 DBG("This=%p lock_count=%u\n", This
, This
->lock_count
);
460 user_assert(This
->lock_count
, D3DERR_INVALIDCALL
);
461 if (This
->transfer
) {
462 This
->pipe
->transfer_unmap(This
->pipe
, This
->transfer
);
463 This
->transfer
= NULL
;
467 if (This
->data_conversion
) {
468 struct pipe_transfer
*transfer
;
469 uint8_t *dst
= This
->data
;
472 u_box_origin_2d(This
->desc
.Width
, This
->desc
.Height
, &box
);
475 dst
= This
->pipe
->transfer_map(This
->pipe
,
478 PIPE_TRANSFER_WRITE
|
479 PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE
,
485 (void) util_format_translate(This
->base
.info
.format
,
486 dst
, This
->data
? This
->stride
: transfer
->stride
,
488 This
->format_conversion
,
489 This
->data_conversion
,
490 This
->stride_conversion
,
492 This
->desc
.Width
, This
->desc
.Height
);
495 pipe_transfer_unmap(This
->pipe
, transfer
);
501 NineSurface9_GetDC( struct NineSurface9
*This
,
504 STUB(D3DERR_INVALIDCALL
);
508 NineSurface9_ReleaseDC( struct NineSurface9
*This
,
511 STUB(D3DERR_INVALIDCALL
);
514 IDirect3DSurface9Vtbl NineSurface9_vtable
= {
515 (void *)NineUnknown_QueryInterface
,
516 (void *)NineUnknown_AddRef
,
517 (void *)NineUnknown_Release
,
518 (void *)NineUnknown_GetDevice
, /* actually part of Resource9 iface */
519 (void *)NineResource9_SetPrivateData
,
520 (void *)NineResource9_GetPrivateData
,
521 (void *)NineResource9_FreePrivateData
,
522 (void *)NineResource9_SetPriority
,
523 (void *)NineResource9_GetPriority
,
524 (void *)NineResource9_PreLoad
,
525 (void *)NineResource9_GetType
,
526 (void *)NineSurface9_GetContainer
,
527 (void *)NineSurface9_GetDesc
,
528 (void *)NineSurface9_LockRect
,
529 (void *)NineSurface9_UnlockRect
,
530 (void *)NineSurface9_GetDC
,
531 (void *)NineSurface9_ReleaseDC
534 /* When this function is called, we have already checked
535 * The copy regions fit the surfaces */
537 NineSurface9_CopyMemToDefault( struct NineSurface9
*This
,
538 struct NineSurface9
*From
,
539 const POINT
*pDestPoint
,
540 const RECT
*pSourceRect
)
542 struct pipe_context
*pipe
= This
->pipe
;
543 struct pipe_transfer
*transfer
= NULL
;
544 struct pipe_resource
*r_dst
= This
->base
.resource
;
545 struct pipe_box dst_box
;
547 int src_x
, src_y
, dst_x
, dst_y
, copy_width
, copy_height
;
549 assert(This
->base
.pool
== D3DPOOL_DEFAULT
&&
550 From
->base
.pool
== D3DPOOL_SYSTEMMEM
);
553 dst_x
= pDestPoint
->x
;
554 dst_y
= pDestPoint
->y
;
561 src_x
= pSourceRect
->left
;
562 src_y
= pSourceRect
->top
;
563 copy_width
= pSourceRect
->right
- pSourceRect
->left
;
564 copy_height
= pSourceRect
->bottom
- pSourceRect
->top
;
568 copy_width
= From
->desc
.Width
;
569 copy_height
= From
->desc
.Height
;
572 u_box_2d_zslice(dst_x
, dst_y
, This
->layer
,
573 copy_width
, copy_height
, &dst_box
);
575 map
= pipe
->transfer_map(pipe
,
578 PIPE_TRANSFER_WRITE
| PIPE_TRANSFER_DISCARD_RANGE
,
579 &dst_box
, &transfer
);
583 /* Note: if formats are the sames, it will revert
584 * to normal memcpy */
585 (void) util_format_translate(r_dst
->format
,
586 map
, transfer
->stride
,
588 From
->base
.info
.format
,
589 From
->data
, From
->stride
,
591 copy_width
, copy_height
);
593 pipe_transfer_unmap(pipe
, transfer
);
595 if (This
->data_conversion
)
596 (void) util_format_translate(This
->format_conversion
,
597 This
->data_conversion
,
598 This
->stride_conversion
,
600 From
->base
.info
.format
,
601 From
->data
, From
->stride
,
603 copy_width
, copy_height
);
605 NineSurface9_MarkContainerDirty(This
);
609 NineSurface9_CopyDefaultToMem( struct NineSurface9
*This
,
610 struct NineSurface9
*From
)
612 struct pipe_context
*pipe
= This
->pipe
;
613 struct pipe_resource
*r_src
= From
->base
.resource
;
614 struct pipe_transfer
*transfer
;
615 struct pipe_box src_box
;
617 const uint8_t *p_src
;
619 assert(This
->base
.pool
== D3DPOOL_SYSTEMMEM
&&
620 From
->base
.pool
== D3DPOOL_DEFAULT
);
622 assert(This
->desc
.Width
== From
->desc
.Width
);
623 assert(This
->desc
.Height
== From
->desc
.Height
);
625 u_box_origin_2d(This
->desc
.Width
, This
->desc
.Height
, &src_box
);
626 src_box
.z
= From
->layer
;
628 p_src
= pipe
->transfer_map(pipe
, r_src
, From
->level
,
630 &src_box
, &transfer
);
631 p_dst
= NineSurface9_GetSystemMemPointer(This
, 0, 0);
633 assert (p_src
&& p_dst
);
635 util_copy_rect(p_dst
, This
->base
.info
.format
,
637 This
->desc
.Width
, This
->desc
.Height
,
639 transfer
->stride
, 0, 0);
641 pipe
->transfer_unmap(pipe
, transfer
);
645 /* Gladly, rendering to a MANAGED surface is not permitted, so we will
646 * never have to do the reverse, i.e. download the surface.
649 NineSurface9_UploadSelf( struct NineSurface9
*This
,
650 const struct pipe_box
*damaged
)
652 struct pipe_context
*pipe
= This
->pipe
;
653 struct pipe_resource
*res
= This
->base
.resource
;
657 DBG("This=%p damaged=%p\n", This
, damaged
);
659 assert(This
->base
.pool
== D3DPOOL_MANAGED
);
669 box
.width
= This
->desc
.Width
;
670 box
.height
= This
->desc
.Height
;
674 ptr
= NineSurface9_GetSystemMemPointer(This
, box
.x
, box
.y
);
676 pipe
->texture_subdata(pipe
, res
, This
->level
, 0,
677 &box
, ptr
, This
->stride
, 0);
683 NineSurface9_SetResourceResize( struct NineSurface9
*This
,
684 struct pipe_resource
*resource
)
686 assert(This
->level
== 0 && This
->level_actual
== 0);
687 assert(!This
->lock_count
);
688 assert(This
->desc
.Pool
== D3DPOOL_DEFAULT
);
689 assert(!This
->texture
);
691 pipe_resource_reference(&This
->base
.resource
, resource
);
693 This
->desc
.Width
= This
->base
.info
.width0
= resource
->width0
;
694 This
->desc
.Height
= This
->base
.info
.height0
= resource
->height0
;
695 This
->desc
.MultiSampleType
= This
->base
.info
.nr_samples
= resource
->nr_samples
;
697 This
->stride
= nine_format_get_stride(This
->base
.info
.format
,
700 pipe_surface_reference(&This
->surface
[0], NULL
);
701 pipe_surface_reference(&This
->surface
[1], NULL
);
705 static const GUID
*NineSurface9_IIDs
[] = {
706 &IID_IDirect3DSurface9
,
707 &IID_IDirect3DResource9
,
713 NineSurface9_new( struct NineDevice9
*pDevice
,
714 struct NineUnknown
*pContainer
,
715 struct pipe_resource
*pResource
,
720 D3DSURFACE_DESC
*pDesc
,
721 struct NineSurface9
**ppOut
)
723 NINE_DEVICE_CHILD_NEW(Surface9
, ppOut
, pDevice
, /* args */
724 pContainer
, pResource
, user_buffer
,
725 TextureType
, Level
, Layer
, pDesc
);