X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;ds=sidebyside;f=src%2Fgallium%2Fstate_trackers%2Fnine%2Fsurface9.c;h=db74de2823acd0fe640b70a9903b849b2a9e0128;hb=9e467d111b2c9046c9b35b9e76891a8cfbb752c1;hp=996cde807d0a318a3ff994e3f3320c20ad80a10d;hpb=35047681ffc1b48f09fe3cedc15c9889eecef907;p=mesa.git diff --git a/src/gallium/state_trackers/nine/surface9.c b/src/gallium/state_trackers/nine/surface9.c index 996cde807d0..db74de2823a 100644 --- a/src/gallium/state_trackers/nine/surface9.c +++ b/src/gallium/state_trackers/nine/surface9.c @@ -20,6 +20,7 @@ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE * USE OR OTHER DEALINGS IN THE SOFTWARE. */ +#include "iunknown.h" #include "surface9.h" #include "device9.h" @@ -31,6 +32,7 @@ #include "nine_helpers.h" #include "nine_pipe.h" #include "nine_dump.h" +#include "nine_state.h" #include "pipe/p_context.h" #include "pipe/p_screen.h" @@ -42,7 +44,8 @@ #define DBG_CHANNEL DBG_SURFACE -#define is_ATI1_ATI2(format) (format == PIPE_FORMAT_RGTC1_UNORM || format == PIPE_FORMAT_RGTC2_UNORM) +static void +NineSurface9_CreatePipeSurfaces( struct NineSurface9 *This ); HRESULT NineSurface9_ctor( struct NineSurface9 *This, @@ -56,31 +59,43 @@ NineSurface9_ctor( struct NineSurface9 *This, D3DSURFACE_DESC *pDesc ) { HRESULT hr; - union pipe_color_union rgba = {0}; - struct pipe_surface *surf; - struct pipe_context *pipe = pParams->device->pipe; + bool allocate = !pContainer && pDesc->Format != D3DFMT_NULL; + D3DMULTISAMPLE_TYPE multisample_type; DBG("This=%p pDevice=%p pResource=%p Level=%u Layer=%u pDesc=%p\n", This, pParams->device, pResource, Level, Layer, pDesc); /* Mark this as a special surface held by another internal resource. */ pParams->container = pContainer; + /* Make sure there's a Desc */ + assert(pDesc); - user_assert(!(pDesc->Usage & D3DUSAGE_DYNAMIC) || - (pDesc->Pool != D3DPOOL_MANAGED), D3DERR_INVALIDCALL); - - assert(pResource || (user_buffer && pDesc->Pool != D3DPOOL_DEFAULT) || - (!pContainer && pDesc->Pool != D3DPOOL_DEFAULT) || + assert(allocate || pResource || user_buffer || pDesc->Format == D3DFMT_NULL); - + assert(!allocate || (!pResource && !user_buffer)); assert(!pResource || !user_buffer); assert(!user_buffer || pDesc->Pool != D3DPOOL_DEFAULT); - /* The only way we can have !pContainer is being created - * from create_zs_or_rt_surface with params 0 0 0 */ - assert(pContainer || (Level == 0 && Layer == 0 && TextureType == 0)); + assert(!pResource || pDesc->Pool == D3DPOOL_DEFAULT); + /* Allocation only from create_zs_or_rt_surface with params 0 0 0 */ + assert(!allocate || (Level == 0 && Layer == 0 && TextureType == 0)); This->data = (uint8_t *)user_buffer; + multisample_type = pDesc->MultiSampleType; + + /* Map MultiSampleQuality to MultiSampleType */ + hr = d3dmultisample_type_check(pParams->device->screen, + pDesc->Format, + &multisample_type, + pDesc->MultiSampleQuality, + NULL); + if (FAILED(hr)) { + return hr; + } + + /* TODO: this is (except width and height) duplicate from + * container info (in the pContainer case). Some refactoring is + * needed to avoid duplication */ This->base.info.screen = pParams->device->screen; This->base.info.target = PIPE_TEXTURE_2D; This->base.info.width0 = pDesc->Width; @@ -88,26 +103,69 @@ NineSurface9_ctor( struct NineSurface9 *This, This->base.info.depth0 = 1; This->base.info.last_level = 0; This->base.info.array_size = 1; - This->base.info.nr_samples = pDesc->MultiSampleType; + This->base.info.nr_samples = multisample_type; + This->base.info.nr_storage_samples = multisample_type; This->base.info.usage = PIPE_USAGE_DEFAULT; - This->base.info.bind = PIPE_BIND_SAMPLER_VIEW; + This->base.info.bind = PIPE_BIND_SAMPLER_VIEW; /* StretchRect */ + + if (pDesc->Usage & D3DUSAGE_RENDERTARGET) { + This->base.info.bind |= PIPE_BIND_RENDER_TARGET; + } else if (pDesc->Usage & D3DUSAGE_DEPTHSTENCIL) { + if (!depth_stencil_format(pDesc->Format)) + return D3DERR_INVALIDCALL; + This->base.info.bind = d3d9_get_pipe_depth_format_bindings(pDesc->Format); + if (TextureType) + This->base.info.bind |= PIPE_BIND_SAMPLER_VIEW; + } + This->base.info.flags = 0; This->base.info.format = d3d9_to_pipe_format_checked(This->base.info.screen, pDesc->Format, This->base.info.target, This->base.info.nr_samples, This->base.info.bind, - FALSE); + FALSE, + pDesc->Pool == D3DPOOL_SCRATCH); - if (pDesc->Usage & D3DUSAGE_RENDERTARGET) - This->base.info.bind |= PIPE_BIND_RENDER_TARGET; - if (pDesc->Usage & D3DUSAGE_DEPTHSTENCIL) - This->base.info.bind |= PIPE_BIND_DEPTH_STENCIL; + if (This->base.info.format == PIPE_FORMAT_NONE && pDesc->Format != D3DFMT_NULL) + return D3DERR_INVALIDCALL; + + if (allocate && compressed_format(pDesc->Format)) { + const unsigned w = util_format_get_blockwidth(This->base.info.format); + const unsigned h = util_format_get_blockheight(This->base.info.format); + + /* Note: In the !allocate case, the test could fail (lower levels of a texture) */ + user_assert(!(pDesc->Width % w) && !(pDesc->Height % h), D3DERR_INVALIDCALL); + } + + /* Get true format */ + This->format_internal = d3d9_to_pipe_format_checked(This->base.info.screen, + pDesc->Format, + This->base.info.target, + This->base.info.nr_samples, + This->base.info.bind, + FALSE, + TRUE); + if (This->base.info.format != This->format_internal || + /* DYNAMIC Textures requires same stride as ram buffers. + * Do not use workaround by default as it eats more virtual space */ + (pParams->device->workarounds.dynamic_texture_workaround && + pDesc->Pool == D3DPOOL_DEFAULT && pDesc->Usage & D3DUSAGE_DYNAMIC)) { + This->data_internal = align_calloc( + nine_format_get_level_alloc_size(This->format_internal, + pDesc->Width, + pDesc->Height, + 0), 32); + if (!This->data_internal) + return E_OUTOFMEMORY; + This->stride_internal = nine_format_get_stride(This->format_internal, + pDesc->Width); + } - /* Ram buffer with no parent. Has to allocate the resource itself */ - if (!pResource && !pContainer) { + if ((allocate && pDesc->Pool != D3DPOOL_DEFAULT) || pDesc->Format == D3DFMT_NULL) { + /* Ram buffer with no parent. Has to allocate the resource itself */ assert(!user_buffer); - This->data = align_malloc( + This->data = align_calloc( nine_format_get_level_alloc_size(This->base.info.format, pDesc->Width, pDesc->Height, @@ -116,20 +174,13 @@ NineSurface9_ctor( struct NineSurface9 *This, return E_OUTOFMEMORY; } - if (pDesc->Pool == D3DPOOL_SYSTEMMEM) { - This->base.info.usage = PIPE_USAGE_STAGING; - assert(!pResource); - } else { - if (pResource && (pDesc->Usage & D3DUSAGE_DYNAMIC)) - pResource->flags |= NINE_RESOURCE_FLAG_LOCKABLE; - } + hr = NineResource9_ctor(&This->base, pParams, pResource, + allocate && (pDesc->Pool == D3DPOOL_DEFAULT), + D3DRTYPE_SURFACE, pDesc->Pool, pDesc->Usage); - hr = NineResource9_ctor(&This->base, pParams, pResource, FALSE, D3DRTYPE_SURFACE, - pDesc->Pool, pDesc->Usage); if (FAILED(hr)) return hr; - This->pipe = This->base.base.device->pipe; This->transfer = NULL; This->texture = TextureType; @@ -140,14 +191,15 @@ NineSurface9_ctor( struct NineSurface9 *This, This->stride = nine_format_get_stride(This->base.info.format, pDesc->Width); - if (pResource && NineSurface9_IsOffscreenPlain(This)) - pResource->flags |= NINE_RESOURCE_FLAG_LOCKABLE; + if (This->base.resource && (pDesc->Usage & D3DUSAGE_DYNAMIC)) + This->base.resource->flags |= NINE_RESOURCE_FLAG_LOCKABLE; + + if (This->base.resource && (pDesc->Usage & (D3DUSAGE_RENDERTARGET | D3DUSAGE_DEPTHSTENCIL))) + NineSurface9_CreatePipeSurfaces(This); /* TODO: investigate what else exactly needs to be cleared */ - if (This->base.resource && (pDesc->Usage & D3DUSAGE_RENDERTARGET)) { - surf = NineSurface9_GetSurface(This, 0); - pipe->clear_render_target(pipe, surf, &rgba, 0, 0, pDesc->Width, pDesc->Height); - } + if (This->base.resource && (pDesc->Usage & D3DUSAGE_RENDERTARGET)) + nine_context_clear_render_target(pParams->device, This, 0, 0, 0, pDesc->Width, pDesc->Height); NineSurface9_Dump(This); @@ -157,23 +209,36 @@ NineSurface9_ctor( struct NineSurface9 *This, void NineSurface9_dtor( struct NineSurface9 *This ) { - if (This->transfer) - NineSurface9_UnlockRect(This); + DBG("This=%p\n", This); + + if (This->transfer) { + struct pipe_context *pipe = nine_context_get_pipe_multithread(This->base.base.device); + pipe->transfer_unmap(pipe, This->transfer); + This->transfer = NULL; + } + + /* Note: Following condition cannot happen currently, since we + * refcount the surface in the functions increasing + * pending_uploads_counter. */ + if (p_atomic_read(&This->pending_uploads_counter)) + nine_csmt_process(This->base.base.device); pipe_surface_reference(&This->surface[0], NULL); pipe_surface_reference(&This->surface[1], NULL); /* Release system memory when we have to manage it (no parent) */ if (!This->base.base.container && This->data) - FREE(This->data); + align_free(This->data); + if (This->data_internal) + align_free(This->data_internal); NineResource9_dtor(&This->base); } -struct pipe_surface * -NineSurface9_CreatePipeSurface( struct NineSurface9 *This, const int sRGB ) +static void +NineSurface9_CreatePipeSurfaces( struct NineSurface9 *This ) { - struct pipe_context *pipe = This->pipe; - struct pipe_screen *screen = pipe->screen; + struct pipe_context *pipe; + struct pipe_screen *screen = NineDevice9_GetScreen(This->base.base.device); struct pipe_resource *resource = This->base.resource; struct pipe_surface templ; enum pipe_format srgb_format; @@ -182,22 +247,36 @@ NineSurface9_CreatePipeSurface( struct NineSurface9 *This, const int sRGB ) assert(resource); srgb_format = util_format_srgb(resource->format); - if (sRGB && srgb_format != PIPE_FORMAT_NONE && - screen->is_format_supported(screen, srgb_format, - resource->target, 0, resource->bind)) - templ.format = srgb_format; - else - templ.format = resource->format; + if (srgb_format == PIPE_FORMAT_NONE || + !screen->is_format_supported(screen, srgb_format, + resource->target, 0, 0, resource->bind)) + srgb_format = resource->format; + + memset(&templ, 0, sizeof(templ)); + templ.format = resource->format; templ.u.tex.level = This->level; templ.u.tex.first_layer = This->layer; templ.u.tex.last_layer = This->layer; - This->surface[sRGB] = pipe->create_surface(pipe, resource, &templ); - assert(This->surface[sRGB]); - return This->surface[sRGB]; + pipe = nine_context_get_pipe_acquire(This->base.base.device); + + This->surface[0] = pipe->create_surface(pipe, resource, &templ); + + memset(&templ, 0, sizeof(templ)); + templ.format = srgb_format; + templ.u.tex.level = This->level; + templ.u.tex.first_layer = This->layer; + templ.u.tex.last_layer = This->layer; + + This->surface[1] = pipe->create_surface(pipe, resource, &templ); + + nine_context_get_pipe_release(This->base.base.device); + + assert(This->surface[0]); /* TODO: Handle failure */ + assert(This->surface[1]); } -#ifdef DEBUG +#if defined(DEBUG) || !defined(NDEBUG) void NineSurface9_Dump( struct NineSurface9 *This ) { @@ -225,16 +304,31 @@ NineSurface9_Dump( struct NineSurface9 *This ) NineUnknown_Release(NineUnknown(tex)); } } -#endif /* DEBUG */ +#endif /* DEBUG || !NDEBUG */ -HRESULT WINAPI +HRESULT NINE_WINAPI NineSurface9_GetContainer( struct NineSurface9 *This, REFIID riid, void **ppContainer ) { HRESULT hr; - if (!NineUnknown(This)->container) - return E_NOINTERFACE; + char guid_str[64]; + + DBG("This=%p riid=%p id=%s ppContainer=%p\n", + This, riid, riid ? GUID_sprintf(guid_str, riid) : "", ppContainer); + + (void)guid_str; + + if (!ppContainer) return E_POINTER; + + /* Return device for OffscreenPlainSurface, DepthStencilSurface and RenderTarget */ + if (!NineUnknown(This)->container) { + *ppContainer = NineUnknown(This)->device; + NineUnknown_AddRef(NineUnknown(*ppContainer)); + + return D3D_OK; + } + hr = NineUnknown_QueryInterface(NineUnknown(This)->container, riid, ppContainer); if (FAILED(hr)) DBG("QueryInterface FAILED!\n"); @@ -260,7 +354,7 @@ NineSurface9_MarkContainerDirty( struct NineSurface9 *This ) } } -HRESULT WINAPI +HRESULT NINE_WINAPI NineSurface9_GetDesc( struct NineSurface9 *This, D3DSURFACE_DESC *pDesc ) { @@ -304,24 +398,25 @@ NineSurface9_AddDirtyRect( struct NineSurface9 *This, } } -static inline uint8_t * -NineSurface9_GetSystemMemPointer(struct NineSurface9 *This, int x, int y) +static inline unsigned +NineSurface9_GetSystemMemOffset(enum pipe_format format, unsigned stride, + int x, int y) { - unsigned x_offset = util_format_get_stride(This->base.info.format, x); + unsigned x_offset = util_format_get_stride(format, x); - y = util_format_get_nblocksy(This->base.info.format, y); + y = util_format_get_nblocksy(format, y); - assert(This->data); - return This->data + (y * This->stride + x_offset); + return y * stride + x_offset; } -HRESULT WINAPI +HRESULT NINE_WINAPI NineSurface9_LockRect( struct NineSurface9 *This, D3DLOCKED_RECT *pLockedRect, const RECT *pRect, DWORD Flags ) { struct pipe_resource *resource = This->base.resource; + struct pipe_context *pipe; struct pipe_box box; unsigned usage; @@ -357,7 +452,7 @@ NineSurface9_LockRect( struct NineSurface9 *This, D3DERR_INVALIDCALL); if (pRect && This->desc.Pool == D3DPOOL_DEFAULT && - compressed_format (This->desc.Format)) { + util_format_is_compressed(This->base.info.format)) { const unsigned w = util_format_get_blockwidth(This->base.info.format); const unsigned h = util_format_get_blockheight(This->base.info.format); user_assert((pRect->left == 0 && pRect->right == This->desc.Width && @@ -383,31 +478,55 @@ NineSurface9_LockRect( struct NineSurface9 *This, } else { u_box_origin_2d(This->desc.Width, This->desc.Height, &box); } + box.z = This->layer; user_warn(This->desc.Format == D3DFMT_NULL); - if (This->data) { + if (p_atomic_read(&This->pending_uploads_counter)) + nine_csmt_process(This->base.base.device); + + if (This->data_internal || This->data) { + enum pipe_format format = This->base.info.format; + unsigned stride = This->stride; + uint8_t *data = This->data; + if (This->data_internal) { + format = This->format_internal; + stride = This->stride_internal; + data = This->data_internal; + } DBG("returning system memory\n"); /* ATI1 and ATI2 need special handling, because of d3d9 bug. * We must advertise to the application as if it is uncompressed * and bpp 8, and the app has a workaround to work with the fact * that it is actually compressed. */ - if (is_ATI1_ATI2(This->base.info.format)) { + if (is_ATI1_ATI2(format)) { pLockedRect->Pitch = This->desc.Width; - pLockedRect->pBits = This->data + box.y * This->desc.Width + box.x; + pLockedRect->pBits = data + box.y * This->desc.Width + box.x; } else { - pLockedRect->Pitch = This->stride; - pLockedRect->pBits = NineSurface9_GetSystemMemPointer(This, - box.x, - box.y); + pLockedRect->Pitch = stride; + pLockedRect->pBits = data + + NineSurface9_GetSystemMemOffset(format, + stride, + box.x, + box.y); } } else { + bool no_refs = !p_atomic_read(&This->base.base.bind) && + !(This->base.base.container && p_atomic_read(&This->base.base.container->bind)); DBG("mapping pipe_resource %p (level=%u usage=%x)\n", resource, This->level, usage); - pLockedRect->pBits = This->pipe->transfer_map(This->pipe, resource, - This->level, usage, &box, - &This->transfer); + /* if the object is not bound internally, there can't be any pending + * operation with the surface in the queue */ + if (no_refs) + pipe = nine_context_get_pipe_acquire(This->base.base.device); + else + pipe = NineDevice9_GetPipe(This->base.base.device); + pLockedRect->pBits = pipe->transfer_map(pipe, resource, + This->level, usage, &box, + &This->transfer); + if (no_refs) + nine_context_get_pipe_release(This->base.base.device); if (!This->transfer) { DBG("transfer_map failed\n"); if (Flags & D3DLOCK_DONOTWAIT) @@ -426,27 +545,61 @@ NineSurface9_LockRect( struct NineSurface9 *This, return D3D_OK; } -HRESULT WINAPI +HRESULT NINE_WINAPI NineSurface9_UnlockRect( struct NineSurface9 *This ) { + struct pipe_box dst_box, src_box; + struct pipe_context *pipe; DBG("This=%p lock_count=%u\n", This, This->lock_count); user_assert(This->lock_count, D3DERR_INVALIDCALL); if (This->transfer) { - This->pipe->transfer_unmap(This->pipe, This->transfer); + pipe = nine_context_get_pipe_acquire(This->base.base.device); + pipe->transfer_unmap(pipe, This->transfer); + nine_context_get_pipe_release(This->base.base.device); This->transfer = NULL; } --This->lock_count; + + if (This->data_internal) { + if (This->data) { + (void) util_format_translate(This->base.info.format, + This->data, This->stride, + 0, 0, + This->format_internal, + This->data_internal, + This->stride_internal, + 0, 0, + This->desc.Width, This->desc.Height); + } else { + u_box_2d_zslice(0, 0, This->layer, + This->desc.Width, This->desc.Height, &dst_box); + u_box_2d_zslice(0, 0, 0, + This->desc.Width, This->desc.Height, &src_box); + + nine_context_box_upload(This->base.base.device, + &This->pending_uploads_counter, + (struct NineUnknown *)This, + This->base.resource, + This->level, + &dst_box, + This->format_internal, + This->data_internal, + This->stride_internal, + 0, /* depth = 1 */ + &src_box); + } + } return D3D_OK; } -HRESULT WINAPI +HRESULT NINE_WINAPI NineSurface9_GetDC( struct NineSurface9 *This, HDC *phdc ) { STUB(D3DERR_INVALIDCALL); } -HRESULT WINAPI +HRESULT NINE_WINAPI NineSurface9_ReleaseDC( struct NineSurface9 *This, HDC hdc ) { @@ -458,9 +611,9 @@ IDirect3DSurface9Vtbl NineSurface9_vtable = { (void *)NineUnknown_AddRef, (void *)NineUnknown_Release, (void *)NineUnknown_GetDevice, /* actually part of Resource9 iface */ - (void *)NineResource9_SetPrivateData, - (void *)NineResource9_GetPrivateData, - (void *)NineResource9_FreePrivateData, + (void *)NineUnknown_SetPrivateData, + (void *)NineUnknown_GetPrivateData, + (void *)NineUnknown_FreePrivateData, (void *)NineResource9_SetPriority, (void *)NineResource9_GetPriority, (void *)NineResource9_PreLoad, @@ -481,10 +634,8 @@ NineSurface9_CopyMemToDefault( struct NineSurface9 *This, const POINT *pDestPoint, const RECT *pSourceRect ) { - struct pipe_context *pipe = This->pipe; struct pipe_resource *r_dst = This->base.resource; - struct pipe_box dst_box; - const uint8_t *p_src; + struct pipe_box dst_box, src_box; int src_x, src_y, dst_x, dst_y, copy_width, copy_height; assert(This->base.pool == D3DPOOL_DEFAULT && @@ -512,12 +663,42 @@ NineSurface9_CopyMemToDefault( struct NineSurface9 *This, u_box_2d_zslice(dst_x, dst_y, This->layer, copy_width, copy_height, &dst_box); + u_box_2d_zslice(src_x, src_y, 0, + copy_width, copy_height, &src_box); + + nine_context_box_upload(This->base.base.device, + &From->pending_uploads_counter, + (struct NineUnknown *)From, + r_dst, + This->level, + &dst_box, + From->base.info.format, + From->data, From->stride, + 0, /* depth = 1 */ + &src_box); + if (From->texture == D3DRTYPE_TEXTURE) { + struct NineTexture9 *tex = + NineTexture9(From->base.base.container); + /* D3DPOOL_SYSTEMMEM with buffer content passed + * from the user: execute the upload right now. + * It is possible it is enough to delay upload + * until the surface refcount is 0, but the + * bind refcount may not be 0, and thus the dtor + * is not executed (and doesn't trigger the + * pending_uploads_counter check). */ + if (!tex->managed_buffer) + nine_csmt_process(This->base.base.device); + } - p_src = NineSurface9_GetSystemMemPointer(From, src_x, src_y); - - pipe->transfer_inline_write(pipe, r_dst, This->level, - 0, /* WRITE|DISCARD are implicit */ - &dst_box, p_src, From->stride, 0); + if (This->data_internal) + (void) util_format_translate(This->format_internal, + This->data_internal, + This->stride_internal, + dst_x, dst_y, + From->base.info.format, + From->data, From->stride, + src_x, src_y, + copy_width, copy_height); NineSurface9_MarkContainerDirty(This); } @@ -526,7 +707,7 @@ void NineSurface9_CopyDefaultToMem( struct NineSurface9 *This, struct NineSurface9 *From ) { - struct pipe_context *pipe = This->pipe; + struct pipe_context *pipe; struct pipe_resource *r_src = From->base.resource; struct pipe_transfer *transfer; struct pipe_box src_box; @@ -542,10 +723,14 @@ NineSurface9_CopyDefaultToMem( struct NineSurface9 *This, u_box_origin_2d(This->desc.Width, This->desc.Height, &src_box); src_box.z = From->layer; + if (p_atomic_read(&This->pending_uploads_counter)) + nine_csmt_process(This->base.base.device); + + pipe = NineDevice9_GetPipe(This->base.base.device); p_src = pipe->transfer_map(pipe, r_src, From->level, PIPE_TRANSFER_READ, &src_box, &transfer); - p_dst = NineSurface9_GetSystemMemPointer(This, 0, 0); + p_dst = This->data; assert (p_src && p_dst); @@ -566,9 +751,7 @@ HRESULT NineSurface9_UploadSelf( struct NineSurface9 *This, const struct pipe_box *damaged ) { - struct pipe_context *pipe = This->pipe; struct pipe_resource *res = This->base.resource; - uint8_t *ptr; struct pipe_box box; DBG("This=%p damaged=%p\n", This, damaged); @@ -588,14 +771,47 @@ NineSurface9_UploadSelf( struct NineSurface9 *This, box.depth = 1; } - ptr = NineSurface9_GetSystemMemPointer(This, box.x, box.y); - - pipe->transfer_inline_write(pipe, res, This->level, 0, - &box, ptr, This->stride, 0); + nine_context_box_upload(This->base.base.device, + &This->pending_uploads_counter, + (struct NineUnknown *)This, + res, + This->level, + &box, + res->format, + This->data, This->stride, + 0, /* depth = 1 */ + &box); return D3D_OK; } +/* Currently nine_context uses the NineSurface9 + * fields when it is render target. Any modification requires + * pending commands with the surface to be executed. If the bind + * count is 0, there is no pending commands. */ +#define PROCESS_IF_BOUND(surf) \ + if (surf->base.base.bind) \ + nine_csmt_process(surf->base.base.device); + +void +NineSurface9_SetResource( struct NineSurface9 *This, + struct pipe_resource *resource, unsigned level ) +{ + /* No need to call PROCESS_IF_BOUND, because SetResource is used only + * for MANAGED textures, and they are not render targets. */ + assert(This->base.pool == D3DPOOL_MANAGED); + This->level = level; + pipe_resource_reference(&This->base.resource, resource); +} + +void +NineSurface9_SetMultiSampleType( struct NineSurface9 *This, + D3DMULTISAMPLE_TYPE mst ) +{ + PROCESS_IF_BOUND(This); + This->desc.MultiSampleType = mst; +} + void NineSurface9_SetResourceResize( struct NineSurface9 *This, struct pipe_resource *resource ) @@ -605,17 +821,21 @@ NineSurface9_SetResourceResize( struct NineSurface9 *This, assert(This->desc.Pool == D3DPOOL_DEFAULT); assert(!This->texture); + PROCESS_IF_BOUND(This); pipe_resource_reference(&This->base.resource, resource); This->desc.Width = This->base.info.width0 = resource->width0; This->desc.Height = This->base.info.height0 = resource->height0; - This->desc.MultiSampleType = This->base.info.nr_samples = resource->nr_samples; + This->base.info.nr_samples = resource->nr_samples; + This->base.info.nr_storage_samples = resource->nr_storage_samples; This->stride = nine_format_get_stride(This->base.info.format, This->desc.Width); pipe_surface_reference(&This->surface[0], NULL); pipe_surface_reference(&This->surface[1], NULL); + if (resource) + NineSurface9_CreatePipeSurfaces(This); }