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. */
25 #include "basetexture9.h" /* for marking dirty */
27 #include "nine_helpers.h"
28 #include "nine_pipe.h"
29 #include "nine_dump.h"
31 #include "pipe/p_context.h"
32 #include "pipe/p_screen.h"
33 #include "pipe/p_state.h"
35 #include "util/u_math.h"
36 #include "util/u_inlines.h"
37 #include "util/u_surface.h"
39 #define DBG_CHANNEL DBG_SURFACE
41 #define is_ATI1_ATI2(format) (format == PIPE_FORMAT_RGTC1_UNORM || format == PIPE_FORMAT_RGTC2_UNORM)
44 NineSurface9_ctor( struct NineSurface9
*This
,
45 struct NineUnknownParams
*pParams
,
46 struct NineUnknown
*pContainer
,
47 struct pipe_resource
*pResource
,
52 D3DSURFACE_DESC
*pDesc
)
56 DBG("This=%p pDevice=%p pResource=%p Level=%u Layer=%u pDesc=%p\n",
57 This
, pParams
->device
, pResource
, Level
, Layer
, pDesc
);
59 /* Mark this as a special surface held by another internal resource. */
60 pParams
->container
= pContainer
;
62 user_assert(!(pDesc
->Usage
& D3DUSAGE_DYNAMIC
) ||
63 (pDesc
->Pool
!= D3DPOOL_MANAGED
), D3DERR_INVALIDCALL
);
66 pDesc
->Pool
!= D3DPOOL_DEFAULT
|| pDesc
->Format
== D3DFMT_NULL
);
68 assert(!pResource
|| !user_buffer
);
70 This
->base
.info
.screen
= pParams
->device
->screen
;
71 This
->base
.info
.target
= PIPE_TEXTURE_2D
;
72 This
->base
.info
.width0
= pDesc
->Width
;
73 This
->base
.info
.height0
= pDesc
->Height
;
74 This
->base
.info
.depth0
= 1;
75 This
->base
.info
.last_level
= 0;
76 This
->base
.info
.array_size
= 1;
77 This
->base
.info
.nr_samples
= pDesc
->MultiSampleType
;
78 This
->base
.info
.usage
= PIPE_USAGE_DEFAULT
;
79 This
->base
.info
.bind
= PIPE_BIND_SAMPLER_VIEW
;
80 This
->base
.info
.flags
= 0;
81 This
->base
.info
.format
= d3d9_to_pipe_format_checked(This
->base
.info
.screen
,
83 This
->base
.info
.target
,
84 This
->base
.info
.nr_samples
,
88 if (pDesc
->Usage
& D3DUSAGE_RENDERTARGET
)
89 This
->base
.info
.bind
|= PIPE_BIND_RENDER_TARGET
;
90 if (pDesc
->Usage
& D3DUSAGE_DEPTHSTENCIL
)
91 This
->base
.info
.bind
|= PIPE_BIND_DEPTH_STENCIL
;
93 if (pDesc
->Pool
== D3DPOOL_SYSTEMMEM
) {
94 This
->base
.info
.usage
= PIPE_USAGE_STAGING
;
95 This
->data
= (uint8_t *)user_buffer
; /* this is *pSharedHandle */
98 if (pResource
&& (pDesc
->Usage
& D3DUSAGE_DYNAMIC
))
99 pResource
->flags
|= NINE_RESOURCE_FLAG_LOCKABLE
;
102 hr
= NineResource9_ctor(&This
->base
, pParams
, pResource
, FALSE
, D3DRTYPE_SURFACE
,
103 pDesc
->Pool
, pDesc
->Usage
);
107 This
->pipe
= This
->base
.base
.device
->pipe
;
108 This
->transfer
= NULL
;
110 This
->texture
= TextureType
;
112 This
->level_actual
= Level
;
116 This
->stride
= util_format_get_stride(This
->base
.info
.format
, pDesc
->Width
);
117 This
->stride
= align(This
->stride
, 4);
119 if (!pResource
&& !This
->data
) {
120 const unsigned size
= This
->stride
*
121 util_format_get_nblocksy(This
->base
.info
.format
, This
->desc
.Height
);
123 DBG("(%p(This=%p),level=%u) Allocating 0x%x bytes of system memory.\n",
124 This
->base
.base
.container
, This
, This
->level
, size
);
126 This
->data
= (uint8_t *)MALLOC(size
);
128 return E_OUTOFMEMORY
;
129 This
->manage_data
= TRUE
;
131 if (pResource
&& NineSurface9_IsOffscreenPlain(This
))
132 pResource
->flags
|= NINE_RESOURCE_FLAG_LOCKABLE
; /* why setting this flag there ? too late ? should be before NineResource9_ctor call perhaps ? */
135 NineSurface9_Dump(This
);
141 NineSurface9_dtor( struct NineSurface9
*This
)
144 NineSurface9_UnlockRect(This
);
145 NineSurface9_ClearDirtyRects(This
);
147 pipe_surface_reference(&This
->surface
[0], NULL
);
148 pipe_surface_reference(&This
->surface
[1], NULL
);
150 /* release allocated system memory for non-D3DPOOL_DEFAULT resources */
151 if (This
->manage_data
&& This
->data
)
153 NineResource9_dtor(&This
->base
);
156 struct pipe_surface
*
157 NineSurface9_CreatePipeSurface( struct NineSurface9
*This
, const int sRGB
)
159 struct pipe_context
*pipe
= This
->pipe
;
160 struct pipe_screen
*screen
= pipe
->screen
;
161 struct pipe_resource
*resource
= This
->base
.resource
;
162 struct pipe_surface templ
;
163 enum pipe_format srgb_format
;
165 assert(This
->desc
.Pool
== D3DPOOL_DEFAULT
||
166 This
->desc
.Pool
== D3DPOOL_MANAGED
);
169 srgb_format
= util_format_srgb(resource
->format
);
170 if (sRGB
&& srgb_format
!= PIPE_FORMAT_NONE
&&
171 screen
->is_format_supported(screen
, srgb_format
,
172 resource
->target
, 0, resource
->bind
))
173 templ
.format
= srgb_format
;
175 templ
.format
= resource
->format
;
176 templ
.u
.tex
.level
= This
->level
;
177 templ
.u
.tex
.first_layer
= This
->layer
;
178 templ
.u
.tex
.last_layer
= This
->layer
;
180 This
->surface
[sRGB
] = pipe
->create_surface(pipe
, resource
, &templ
);
181 assert(This
->surface
[sRGB
]);
182 return This
->surface
[sRGB
];
187 NineSurface9_Dump( struct NineSurface9
*This
)
189 struct NineBaseTexture9
*tex
;
190 GUID id
= IID_IDirect3DBaseTexture9
;
193 DBG("\nNineSurface9(%p->%p/%p): Pool=%s Type=%s Usage=%s\n"
194 "Dims=%ux%u Format=%s Stride=%u Lockable=%i\n"
195 "Level=%u(%u), Layer=%u\n", This
, This
->base
.resource
, This
->data
,
196 nine_D3DPOOL_to_str(This
->desc
.Pool
),
197 nine_D3DRTYPE_to_str(This
->desc
.Type
),
198 nine_D3DUSAGE_to_str(This
->desc
.Usage
),
199 This
->desc
.Width
, This
->desc
.Height
,
200 d3dformat_to_string(This
->desc
.Format
), This
->stride
,
201 This
->base
.resource
&&
202 (This
->base
.resource
->flags
& NINE_RESOURCE_FLAG_LOCKABLE
),
203 This
->level
, This
->level_actual
, This
->layer
);
205 if (!This
->base
.base
.container
)
207 NineUnknown_QueryInterface(This
->base
.base
.container
, ref
, (void **)&tex
);
209 NineBaseTexture9_Dump(tex
);
210 NineUnknown_Release(NineUnknown(tex
));
216 NineSurface9_GetContainer( struct NineSurface9
*This
,
221 if (!NineUnknown(This
)->container
)
222 return E_NOINTERFACE
;
223 hr
= NineUnknown_QueryInterface(NineUnknown(This
)->container
, riid
, ppContainer
);
225 DBG("QueryInterface FAILED!\n");
230 NineSurface9_MarkContainerDirty( struct NineSurface9
*This
)
233 struct NineBaseTexture9
*tex
=
234 NineBaseTexture9(This
->base
.base
.container
);
236 assert(This
->texture
== D3DRTYPE_TEXTURE
||
237 This
->texture
== D3DRTYPE_CUBETEXTURE
);
238 if (This
->base
.pool
== D3DPOOL_MANAGED
)
241 if (This
->base
.usage
& D3DUSAGE_AUTOGENMIPMAP
)
242 tex
->dirty_mip
= TRUE
;
244 BASETEX_REGISTER_UPDATE(tex
);
249 NineSurface9_GetDesc( struct NineSurface9
*This
,
250 D3DSURFACE_DESC
*pDesc
)
252 user_assert(pDesc
!= NULL
, E_POINTER
);
257 /* Wine just keeps a single directy rect and expands it to cover all
258 * the dirty rects ever added.
259 * We'll keep 2, and expand the one that fits better, just for fun.
262 NineSurface9_AddDirtyRect( struct NineSurface9
*This
,
263 const struct pipe_box
*box
)
266 struct u_rect rect
, cover_a
, cover_b
;
268 DBG("This=%p box=%p\n", This
, box
);
271 This
->dirty_rects
[0].x0
= 0;
272 This
->dirty_rects
[0].y0
= 0;
273 This
->dirty_rects
[0].x1
= This
->desc
.Width
;
274 This
->dirty_rects
[0].y1
= This
->desc
.Height
;
276 memset(&This
->dirty_rects
[1], 0, sizeof(This
->dirty_rects
[1]));
281 rect
.x1
= box
->x
+ box
->width
;
282 rect
.y1
= box
->y
+ box
->height
;
284 if (This
->dirty_rects
[0].x1
== 0) {
285 This
->dirty_rects
[0] = rect
;
289 u_rect_union(&cover_a
, &This
->dirty_rects
[0], &rect
);
290 area
[0] = u_rect_area(&cover_a
);
292 if (This
->dirty_rects
[1].x1
== 0) {
293 area
[1] = u_rect_area(&This
->dirty_rects
[0]);
294 if (area
[0] > (area
[1] * 1.25f
))
295 This
->dirty_rects
[1] = rect
;
297 This
->dirty_rects
[0] = cover_a
;
299 u_rect_union(&cover_b
, &This
->dirty_rects
[1], &rect
);
300 area
[1] = u_rect_area(&cover_b
);
302 if (area
[0] > area
[1])
303 This
->dirty_rects
[1] = cover_b
;
305 This
->dirty_rects
[0] = cover_a
;
309 static INLINE
uint8_t *
310 NineSurface9_GetSystemMemPointer(struct NineSurface9
*This
, int x
, int y
)
312 unsigned x_offset
= util_format_get_stride(This
->base
.info
.format
, x
);
314 y
= util_format_get_nblocksy(This
->base
.info
.format
, y
);
317 return This
->data
+ (y
* This
->stride
+ x_offset
);
321 NineSurface9_LockRect( struct NineSurface9
*This
,
322 D3DLOCKED_RECT
*pLockedRect
,
326 struct pipe_resource
*resource
= This
->base
.resource
;
330 DBG("This=%p pLockedRect=%p pRect=%p[%u..%u,%u..%u] Flags=%s\n", This
,
332 pRect
? pRect
->left
: 0, pRect
? pRect
->right
: 0,
333 pRect
? pRect
->top
: 0, pRect
? pRect
->bottom
: 0,
334 nine_D3DLOCK_to_str(Flags
));
335 NineSurface9_Dump(This
);
338 user_assert(This
->base
.pool
!= D3DPOOL_DEFAULT
||
339 (resource
&& (resource
->flags
& NINE_RESOURCE_FLAG_LOCKABLE
)),
342 user_assert(!(Flags
& ~(D3DLOCK_DISCARD
|
344 D3DLOCK_NO_DIRTY_UPDATE
|
345 D3DLOCK_NOOVERWRITE
|
346 D3DLOCK_NOSYSLOCK
| /* ignored */
347 D3DLOCK_READONLY
)), D3DERR_INVALIDCALL
);
348 user_assert(!((Flags
& D3DLOCK_DISCARD
) && (Flags
& D3DLOCK_READONLY
)),
351 /* check if it's already locked */
352 user_assert(This
->lock_count
== 0, D3DERR_INVALIDCALL
);
353 user_assert(pLockedRect
, E_POINTER
);
355 user_assert(This
->desc
.MultiSampleType
== D3DMULTISAMPLE_NONE
,
358 if (pRect
&& This
->base
.pool
== D3DPOOL_DEFAULT
&&
359 util_format_is_compressed(This
->base
.info
.format
)) {
360 const unsigned w
= util_format_get_blockwidth(This
->base
.info
.format
);
361 const unsigned h
= util_format_get_blockheight(This
->base
.info
.format
);
362 user_assert(!(pRect
->left
% w
) && !(pRect
->right
% w
) &&
363 !(pRect
->top
% h
) && !(pRect
->bottom
% h
),
367 if (Flags
& D3DLOCK_DISCARD
) {
368 usage
= PIPE_TRANSFER_WRITE
| PIPE_TRANSFER_DISCARD_RANGE
;
370 usage
= (Flags
& D3DLOCK_READONLY
) ?
371 PIPE_TRANSFER_READ
: PIPE_TRANSFER_READ_WRITE
;
373 if (Flags
& D3DLOCK_DONOTWAIT
)
374 usage
|= PIPE_TRANSFER_DONTBLOCK
;
377 rect_to_pipe_box(&box
, pRect
);
378 if (u_box_clip_2d(&box
, &box
, This
->desc
.Width
,
379 This
->desc
.Height
) < 0) {
380 DBG("pRect clipped by Width=%u Height=%u\n",
381 This
->desc
.Width
, This
->desc
.Height
);
382 return D3DERR_INVALIDCALL
;
385 u_box_origin_2d(This
->desc
.Width
, This
->desc
.Height
, &box
);
388 user_warn(This
->desc
.Format
== D3DFMT_NULL
);
391 DBG("returning system memory\n");
392 /* ATI1 and ATI2 need special handling, because of d3d9 bug.
393 * We must advertise to the application as if it is uncompressed
394 * and bpp 8, and the app has a workaround to work with the fact
395 * that it is actually compressed. */
396 if (is_ATI1_ATI2(This
->base
.info
.format
)) {
397 pLockedRect
->Pitch
= This
->desc
.Height
;
398 pLockedRect
->pBits
= This
->data
+ box
.y
* This
->desc
.Height
+ box
.x
;
400 pLockedRect
->Pitch
= This
->stride
;
401 pLockedRect
->pBits
= NineSurface9_GetSystemMemPointer(This
,
406 DBG("mapping pipe_resource %p (level=%u usage=%x)\n",
407 resource
, This
->level
, usage
);
409 pLockedRect
->pBits
= This
->pipe
->transfer_map(This
->pipe
, resource
,
410 This
->level
, usage
, &box
,
412 if (!This
->transfer
) {
413 DBG("transfer_map failed\n");
414 if (Flags
& D3DLOCK_DONOTWAIT
)
415 return D3DERR_WASSTILLDRAWING
;
416 return D3DERR_INVALIDCALL
;
418 pLockedRect
->Pitch
= This
->transfer
->stride
;
421 if (!(Flags
& (D3DLOCK_NO_DIRTY_UPDATE
| D3DLOCK_READONLY
))) {
422 NineSurface9_MarkContainerDirty(This
);
423 if (This
->base
.pool
== D3DPOOL_MANAGED
)
424 NineSurface9_AddDirtyRect(This
, &box
);
432 NineSurface9_UnlockRect( struct NineSurface9
*This
)
434 DBG("This=%p lock_count=%u\n", This
, This
->lock_count
);
435 user_assert(This
->lock_count
, D3DERR_INVALIDCALL
);
436 if (This
->transfer
) {
437 This
->pipe
->transfer_unmap(This
->pipe
, This
->transfer
);
438 This
->transfer
= NULL
;
445 NineSurface9_GetDC( struct NineSurface9
*This
,
448 STUB(D3DERR_INVALIDCALL
);
452 NineSurface9_ReleaseDC( struct NineSurface9
*This
,
455 STUB(D3DERR_INVALIDCALL
);
458 IDirect3DSurface9Vtbl NineSurface9_vtable
= {
459 (void *)NineUnknown_QueryInterface
,
460 (void *)NineUnknown_AddRef
,
461 (void *)NineUnknown_Release
,
462 (void *)NineUnknown_GetDevice
, /* actually part of Resource9 iface */
463 (void *)NineResource9_SetPrivateData
,
464 (void *)NineResource9_GetPrivateData
,
465 (void *)NineResource9_FreePrivateData
,
466 (void *)NineResource9_SetPriority
,
467 (void *)NineResource9_GetPriority
,
468 (void *)NineResource9_PreLoad
,
469 (void *)NineResource9_GetType
,
470 (void *)NineSurface9_GetContainer
,
471 (void *)NineSurface9_GetDesc
,
472 (void *)NineSurface9_LockRect
,
473 (void *)NineSurface9_UnlockRect
,
474 (void *)NineSurface9_GetDC
,
475 (void *)NineSurface9_ReleaseDC
479 static INLINE boolean
480 NineSurface9_IsDirty(struct NineSurface9
*This
)
482 return This
->dirty_rects
[0].x1
!= 0;
486 NineSurface9_CopySurface( struct NineSurface9
*This
,
487 struct NineSurface9
*From
,
488 const POINT
*pDestPoint
,
489 const RECT
*pSourceRect
)
491 struct pipe_context
*pipe
= This
->pipe
;
492 struct pipe_resource
*r_dst
= This
->base
.resource
;
493 struct pipe_resource
*r_src
= From
->base
.resource
;
494 struct pipe_transfer
*transfer
;
495 struct pipe_box src_box
;
496 struct pipe_box dst_box
;
498 const uint8_t *p_src
;
500 DBG("This=%p From=%p pDestPoint=%p pSourceRect=%p\n",
501 This
, From
, pDestPoint
, pSourceRect
);
503 user_assert(This
->desc
.Format
== From
->desc
.Format
, D3DERR_INVALIDCALL
);
505 dst_box
.x
= pDestPoint
? pDestPoint
->x
: 0;
506 dst_box
.y
= pDestPoint
? pDestPoint
->y
: 0;
508 user_assert(dst_box
.x
>= 0 &&
509 dst_box
.y
>= 0, D3DERR_INVALIDCALL
);
511 dst_box
.z
= This
->layer
;
512 src_box
.z
= From
->layer
;
518 /* make sure it doesn't range outside the source surface */
519 user_assert(pSourceRect
->left
>= 0 &&
520 pSourceRect
->right
<= From
->desc
.Width
&&
521 pSourceRect
->top
>= 0 &&
522 pSourceRect
->bottom
<= From
->desc
.Height
,
524 if (rect_to_pipe_box_xy_only_clamp(&src_box
, pSourceRect
))
529 src_box
.width
= From
->desc
.Width
;
530 src_box
.height
= From
->desc
.Height
;
534 dst_box
.width
= This
->desc
.Width
- dst_box
.x
;
535 dst_box
.height
= This
->desc
.Height
- dst_box
.y
;
537 user_assert(src_box
.width
<= dst_box
.width
&&
538 src_box
.height
<= dst_box
.height
, D3DERR_INVALIDCALL
);
540 dst_box
.width
= src_box
.width
;
541 dst_box
.height
= src_box
.height
;
543 /* Don't copy to device memory of managed resources.
544 * We don't want to download it back again later.
546 if (This
->base
.pool
== D3DPOOL_MANAGED
)
549 /* Don't copy from stale device memory of managed resources.
550 * Also, don't copy between system and device if we don't have to.
552 if (From
->base
.pool
== D3DPOOL_MANAGED
) {
553 if (!r_dst
|| NineSurface9_IsDirty(From
))
557 /* check source block align for compressed textures */
558 if (util_format_is_compressed(From
->base
.info
.format
) &&
559 ((src_box
.width
!= From
->desc
.Width
) ||
560 (src_box
.height
!= From
->desc
.Height
))) {
561 const unsigned w
= util_format_get_blockwidth(From
->base
.info
.format
);
562 const unsigned h
= util_format_get_blockheight(From
->base
.info
.format
);
563 user_assert(!(src_box
.width
% w
) &&
564 !(src_box
.height
% h
),
568 /* check destination block align for compressed textures */
569 if (util_format_is_compressed(This
->base
.info
.format
) &&
570 ((dst_box
.width
!= This
->desc
.Width
) ||
571 (dst_box
.height
!= This
->desc
.Height
) ||
574 const unsigned w
= util_format_get_blockwidth(This
->base
.info
.format
);
575 const unsigned h
= util_format_get_blockheight(This
->base
.info
.format
);
576 user_assert(!(dst_box
.x
% w
) && !(dst_box
.width
% w
) &&
577 !(dst_box
.y
% h
) && !(dst_box
.height
% h
),
581 if (r_dst
&& r_src
) {
582 pipe
->resource_copy_region(pipe
,
584 dst_box
.x
, dst_box
.y
, dst_box
.z
,
589 p_src
= NineSurface9_GetSystemMemPointer(From
, src_box
.x
, src_box
.y
);
591 pipe
->transfer_inline_write(pipe
, r_dst
, This
->level
,
592 0, /* WRITE|DISCARD are implicit */
593 &dst_box
, p_src
, From
->stride
, 0);
596 p_dst
= NineSurface9_GetSystemMemPointer(This
, 0, 0);
598 p_src
= pipe
->transfer_map(pipe
, r_src
, From
->level
,
600 &src_box
, &transfer
);
602 return D3DERR_DRIVERINTERNALERROR
;
604 util_copy_rect(p_dst
, This
->base
.info
.format
,
605 This
->stride
, dst_box
.x
, dst_box
.y
,
606 dst_box
.width
, dst_box
.height
,
608 transfer
->stride
, src_box
.x
, src_box
.y
);
610 pipe
->transfer_unmap(pipe
, transfer
);
612 p_dst
= NineSurface9_GetSystemMemPointer(This
, 0, 0);
613 p_src
= NineSurface9_GetSystemMemPointer(From
, 0, 0);
615 util_copy_rect(p_dst
, This
->base
.info
.format
,
616 This
->stride
, dst_box
.x
, dst_box
.y
,
617 dst_box
.width
, dst_box
.height
,
619 From
->stride
, src_box
.x
, src_box
.y
);
622 if (This
->base
.pool
== D3DPOOL_DEFAULT
||
623 This
->base
.pool
== D3DPOOL_MANAGED
)
624 NineSurface9_MarkContainerDirty(This
);
625 if (!r_dst
&& This
->base
.resource
)
626 NineSurface9_AddDirtyRect(This
, &dst_box
);
631 /* Gladly, rendering to a MANAGED surface is not permitted, so we will
632 * never have to do the reverse, i.e. download the surface.
635 NineSurface9_UploadSelf( struct NineSurface9
*This
)
637 struct pipe_context
*pipe
= This
->pipe
;
638 struct pipe_resource
*res
= This
->base
.resource
;
642 DBG("This=%p\n", This
);
644 assert(This
->base
.pool
== D3DPOOL_MANAGED
);
646 if (!NineSurface9_IsDirty(This
))
649 for (i
= 0; i
< Elements(This
->dirty_rects
); ++i
) {
651 nine_u_rect_to_pipe_box(&box
, &This
->dirty_rects
[i
], This
->layer
);
655 ptr
= NineSurface9_GetSystemMemPointer(This
, box
.x
, box
.y
);
657 pipe
->transfer_inline_write(pipe
, res
, This
->level
,
659 &box
, ptr
, This
->stride
, 0);
661 NineSurface9_ClearDirtyRects(This
);
667 NineSurface9_SetResourceResize( struct NineSurface9
*This
,
668 struct pipe_resource
*resource
)
670 assert(This
->level
== 0 && This
->level_actual
== 0);
671 assert(!This
->lock_count
);
672 assert(This
->desc
.Pool
== D3DPOOL_DEFAULT
);
673 assert(!This
->texture
);
675 pipe_resource_reference(&This
->base
.resource
, resource
);
677 This
->desc
.Width
= This
->base
.info
.width0
= resource
->width0
;
678 This
->desc
.Height
= This
->base
.info
.height0
= resource
->height0
;
680 This
->stride
= util_format_get_stride(This
->base
.info
.format
,
682 This
->stride
= align(This
->stride
, 4);
684 pipe_surface_reference(&This
->surface
[0], NULL
);
685 pipe_surface_reference(&This
->surface
[1], NULL
);
689 static const GUID
*NineSurface9_IIDs
[] = {
690 &IID_IDirect3DSurface9
,
691 &IID_IDirect3DResource9
,
697 NineSurface9_new( struct NineDevice9
*pDevice
,
698 struct NineUnknown
*pContainer
,
699 struct pipe_resource
*pResource
,
704 D3DSURFACE_DESC
*pDesc
,
705 struct NineSurface9
**ppOut
)
707 NINE_DEVICE_CHILD_NEW(Surface9
, ppOut
, pDevice
, /* args */
708 pContainer
, pResource
, user_buffer
,
709 TextureType
, Level
, Layer
, pDesc
);