diff options
author | Jason Ekstrand <[email protected]> | 2016-02-05 15:21:11 -0800 |
---|---|---|
committer | Jason Ekstrand <[email protected]> | 2016-02-05 15:21:11 -0800 |
commit | 9401516113152ea2a571dc1103a2fa7ce68d4ee8 (patch) | |
tree | 2472a42bd85a3d3b9697be9235c029099c3d575d /src/gallium/state_trackers | |
parent | 741744f691d6ef63e9f9a4c03136f969f2ffb0bf (diff) | |
parent | 5b51b2e00013af70072106e9d34905326fc357fc (diff) |
Merge remote-tracking branch 'mesa-public/master' into vulkan
Diffstat (limited to 'src/gallium/state_trackers')
37 files changed, 1000 insertions, 426 deletions
diff --git a/src/gallium/state_trackers/nine/Makefile.sources b/src/gallium/state_trackers/nine/Makefile.sources index 99b623a5b59..8d178d4b18f 100644 --- a/src/gallium/state_trackers/nine/Makefile.sources +++ b/src/gallium/state_trackers/nine/Makefile.sources @@ -5,6 +5,8 @@ C_SOURCES := \ authenticatedchannel9.h \ basetexture9.c \ basetexture9.h \ + buffer9.c \ + buffer9.h \ cryptosession9.c \ cryptosession9.h \ cubetexture9.c \ diff --git a/src/gallium/state_trackers/nine/adapter9.c b/src/gallium/state_trackers/nine/adapter9.c index 69e0fa25961..8428b1bd7eb 100644 --- a/src/gallium/state_trackers/nine/adapter9.c +++ b/src/gallium/state_trackers/nine/adapter9.c @@ -563,7 +563,7 @@ NineAdapter9_GetDeviceCaps( struct NineAdapter9 *This, D3DPIPECAP(INDEP_BLEND_ENABLE, D3DPMISCCAPS_INDEPENDENTWRITEMASKS) | /*D3DPMISCCAPS_PERSTAGECONSTANT |*/ /* TODO */ /*D3DPMISCCAPS_POSTBLENDSRGBCONVERT |*/ /* TODO */ - D3DPMISCCAPS_FOGANDSPECULARALPHA | + D3DPMISCCAPS_FOGANDSPECULARALPHA | /* Note: documentation of the flag is wrong */ D3DPIPECAP(BLEND_EQUATION_SEPARATE, D3DPMISCCAPS_SEPARATEALPHABLEND) | D3DPIPECAP(MIXED_COLORBUFFER_FORMATS, D3DPMISCCAPS_MRTINDEPENDENTBITDEPTHS) | D3DPMISCCAPS_MRTPOSTPIXELSHADERBLENDING | @@ -618,7 +618,8 @@ NineAdapter9_GetDeviceCaps( struct NineAdapter9 *This, pCaps->DestBlendCaps = pCaps->SrcBlendCaps; - pCaps->AlphaCmpCaps = D3DPCMPCAPS_LESS | + pCaps->AlphaCmpCaps = D3DPCMPCAPS_NEVER | + D3DPCMPCAPS_LESS | D3DPCMPCAPS_EQUAL | D3DPCMPCAPS_LESSEQUAL | D3DPCMPCAPS_GREATER | @@ -980,7 +981,8 @@ NineAdapter9_CreateDevice( struct NineAdapter9 *This, hr = NineDevice9_new(screen, ¶ms, &caps, pPresentationParameters, pD3D9, pPresentationGroup, This->ctx, FALSE, NULL, - (struct NineDevice9 **)ppReturnedDeviceInterface); + (struct NineDevice9 **)ppReturnedDeviceInterface, + minor); if (FAILED(hr)) { DBG("Failed to create device.\n"); return hr; @@ -1041,7 +1043,8 @@ NineAdapter9_CreateDeviceEx( struct NineAdapter9 *This, hr = NineDevice9Ex_new(screen, ¶ms, &caps, pPresentationParameters, pFullscreenDisplayMode, pD3D9Ex, pPresentationGroup, This->ctx, - (struct NineDevice9Ex **)ppReturnedDeviceInterface); + (struct NineDevice9Ex **)ppReturnedDeviceInterface, + minor); if (FAILED(hr)) { DBG("Failed to create device.\n"); return hr; diff --git a/src/gallium/state_trackers/nine/basetexture9.c b/src/gallium/state_trackers/nine/basetexture9.c index d13138b7d5c..7a0959a8f3e 100644 --- a/src/gallium/state_trackers/nine/basetexture9.c +++ b/src/gallium/state_trackers/nine/basetexture9.c @@ -319,7 +319,7 @@ NineBaseTexture9_UploadSelf( struct NineBaseTexture9 *This ) if (tex->dirty_box.width) { for (l = min_level_dirty; l <= last_level; ++l) { - u_box_minify_2d(&box, &tex->dirty_box, l); + u_box_minify_3d(&box, &tex->dirty_box, l); NineVolume9_UploadSelf(tex->volumes[l], &box); } memset(&tex->dirty_box, 0, sizeof(tex->dirty_box)); diff --git a/src/gallium/state_trackers/nine/buffer9.c b/src/gallium/state_trackers/nine/buffer9.c new file mode 100644 index 00000000000..b4b91ec2a02 --- /dev/null +++ b/src/gallium/state_trackers/nine/buffer9.c @@ -0,0 +1,189 @@ +/* + * Copyright 2011 Joakim Sindholt <[email protected]> + * Copyright 2015 Patrick Rudolph <[email protected]> + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "buffer9.h" +#include "device9.h" +#include "nine_helpers.h" +#include "nine_pipe.h" + +#include "pipe/p_screen.h" +#include "pipe/p_context.h" +#include "pipe/p_state.h" +#include "pipe/p_defines.h" +#include "pipe/p_format.h" +#include "util/u_box.h" + +#define DBG_CHANNEL (DBG_INDEXBUFFER|DBG_VERTEXBUFFER) + +HRESULT +NineBuffer9_ctor( struct NineBuffer9 *This, + struct NineUnknownParams *pParams, + D3DRESOURCETYPE Type, + DWORD Usage, + UINT Size, + D3DPOOL Pool ) +{ + struct pipe_resource *info = &This->base.info; + HRESULT hr; + + DBG("This=%p Size=0x%x Usage=%x Pool=%u\n", This, Size, Usage, Pool); + + user_assert(Pool != D3DPOOL_SCRATCH, D3DERR_INVALIDCALL); + + This->maps = MALLOC(sizeof(struct pipe_transfer *)); + if (!This->maps) + return E_OUTOFMEMORY; + This->nmaps = 0; + This->maxmaps = 1; + This->size = Size; + + This->pipe = pParams->device->pipe; + + info->screen = pParams->device->screen; + info->target = PIPE_BUFFER; + info->format = PIPE_FORMAT_R8_UNORM; + info->width0 = Size; + info->flags = 0; + + info->bind = PIPE_BIND_VERTEX_BUFFER | PIPE_BIND_TRANSFER_WRITE; + if (!(Usage & D3DUSAGE_WRITEONLY)) + info->bind |= PIPE_BIND_TRANSFER_READ; + + info->usage = PIPE_USAGE_DEFAULT; + if (Usage & D3DUSAGE_DYNAMIC) + info->usage = PIPE_USAGE_STREAM; + else if (Pool == D3DPOOL_SYSTEMMEM) + info->usage = PIPE_USAGE_STAGING; + + /* if (pDesc->Usage & D3DUSAGE_DONOTCLIP) { } */ + /* if (pDesc->Usage & D3DUSAGE_NONSECURE) { } */ + /* if (pDesc->Usage & D3DUSAGE_NPATCHES) { } */ + /* if (pDesc->Usage & D3DUSAGE_POINTS) { } */ + /* if (pDesc->Usage & D3DUSAGE_RTPATCHES) { } */ + if (Usage & D3DUSAGE_SOFTWAREPROCESSING) + DBG("Application asked for Software Vertex Processing, " + "but this is unimplemented\n"); + /* if (pDesc->Usage & D3DUSAGE_TEXTAPI) { } */ + + info->height0 = 1; + info->depth0 = 1; + info->array_size = 1; + info->last_level = 0; + info->nr_samples = 0; + + hr = NineResource9_ctor(&This->base, pParams, NULL, TRUE, + Type, Pool, Usage); + return hr; +} + +void +NineBuffer9_dtor( struct NineBuffer9 *This ) +{ + if (This->maps) { + while (This->nmaps) { + NineBuffer9_Unlock(This); + } + FREE(This->maps); + } + + NineResource9_dtor(&This->base); +} + +struct pipe_resource * +NineBuffer9_GetResource( struct NineBuffer9 *This ) +{ + return NineResource9_GetResource(&This->base); +} + +HRESULT WINAPI +NineBuffer9_Lock( struct NineBuffer9 *This, + UINT OffsetToLock, + UINT SizeToLock, + void **ppbData, + DWORD Flags ) +{ + struct pipe_box box; + void *data; + unsigned usage = d3dlock_buffer_to_pipe_transfer_usage(Flags); + + DBG("This=%p(pipe=%p) OffsetToLock=0x%x, SizeToLock=0x%x, Flags=0x%x\n", + This, This->base.resource, + OffsetToLock, SizeToLock, Flags); + + user_assert(ppbData, E_POINTER); + user_assert(!(Flags & ~(D3DLOCK_DISCARD | + D3DLOCK_DONOTWAIT | + D3DLOCK_NO_DIRTY_UPDATE | + D3DLOCK_NOSYSLOCK | + D3DLOCK_READONLY | + D3DLOCK_NOOVERWRITE)), D3DERR_INVALIDCALL); + + if (This->nmaps == This->maxmaps) { + struct pipe_transfer **newmaps = + REALLOC(This->maps, sizeof(struct pipe_transfer *)*This->maxmaps, + sizeof(struct pipe_transfer *)*(This->maxmaps << 1)); + if (newmaps == NULL) + return E_OUTOFMEMORY; + + This->maxmaps <<= 1; + This->maps = newmaps; + } + + if (SizeToLock == 0) { + SizeToLock = This->size - OffsetToLock; + user_warn(OffsetToLock != 0); + } + + u_box_1d(OffsetToLock, SizeToLock, &box); + + data = This->pipe->transfer_map(This->pipe, This->base.resource, 0, + usage, &box, &This->maps[This->nmaps]); + + if (!data) { + DBG("pipe::transfer_map failed\n" + " usage = %x\n" + " box.x = %u\n" + " box.width = %u\n", + usage, box.x, box.width); + /* not sure what to return, msdn suggests this */ + if (Flags & D3DLOCK_DONOTWAIT) + return D3DERR_WASSTILLDRAWING; + return D3DERR_INVALIDCALL; + } + + DBG("returning pointer %p\n", data); + This->nmaps++; + *ppbData = data; + + return D3D_OK; +} + +HRESULT WINAPI +NineBuffer9_Unlock( struct NineBuffer9 *This ) +{ + DBG("This=%p\n", This); + + user_assert(This->nmaps > 0, D3DERR_INVALIDCALL); + This->pipe->transfer_unmap(This->pipe, This->maps[--(This->nmaps)]); + return D3D_OK; +} diff --git a/src/gallium/state_trackers/nine/buffer9.h b/src/gallium/state_trackers/nine/buffer9.h new file mode 100644 index 00000000000..1afd9a996ea --- /dev/null +++ b/src/gallium/state_trackers/nine/buffer9.h @@ -0,0 +1,73 @@ +/* + * Copyright 2011 Joakim Sindholt <[email protected]> + * Copyright 2015 Patrick Rudolph <[email protected]> + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef _NINE_BUFFER9_H_ +#define _NINE_BUFFER9_H_ + +#include "resource9.h" + +struct pipe_screen; +struct pipe_context; +struct pipe_transfer; + +struct NineBuffer9 +{ + struct NineResource9 base; + + /* G3D */ + struct pipe_context *pipe; + struct pipe_transfer **maps; + int nmaps, maxmaps; + UINT size; +}; +static inline struct NineBuffer9 * +NineBuffer9( void *data ) +{ + return (struct NineBuffer9 *)data; +} + +HRESULT +NineBuffer9_ctor( struct NineBuffer9 *This, + struct NineUnknownParams *pParams, + D3DRESOURCETYPE Type, + DWORD Usage, + UINT Size, + D3DPOOL Pool ); + +void +NineBuffer9_dtor( struct NineBuffer9 *This ); + +struct pipe_resource * +NineBuffer9_GetResource( struct NineBuffer9 *This ); + +HRESULT WINAPI +NineBuffer9_Lock( struct NineBuffer9 *This, + UINT OffsetToLock, + UINT SizeToLock, + void **ppbData, + DWORD Flags ); + +HRESULT WINAPI +NineBuffer9_Unlock( struct NineBuffer9 *This ); + +#endif /* _NINE_BUFFER9_H_ */ diff --git a/src/gallium/state_trackers/nine/cubetexture9.c b/src/gallium/state_trackers/nine/cubetexture9.c index abba2637946..460cc853942 100644 --- a/src/gallium/state_trackers/nine/cubetexture9.c +++ b/src/gallium/state_trackers/nine/cubetexture9.c @@ -181,7 +181,7 @@ NineCubeTexture9_dtor( struct NineCubeTexture9 *This ) } if (This->managed_buffer) - FREE(This->managed_buffer); + align_free(This->managed_buffer); NineBaseTexture9_dtor(&This->base); } diff --git a/src/gallium/state_trackers/nine/device9.c b/src/gallium/state_trackers/nine/device9.c index 0be83658928..475ef96788e 100644 --- a/src/gallium/state_trackers/nine/device9.c +++ b/src/gallium/state_trackers/nine/device9.c @@ -38,6 +38,7 @@ #include "nine_pipe.h" #include "nine_ff.h" #include "nine_dump.h" +#include "nine_limits.h" #include "pipe/p_screen.h" #include "pipe/p_context.h" @@ -81,7 +82,7 @@ static void nine_setup_fpu(void) #endif -static void +void NineDevice9_SetDefaultState( struct NineDevice9 *This, boolean is_reset ) { struct NineSurface9 *refSurf = NULL; @@ -112,8 +113,10 @@ NineDevice9_SetDefaultState( struct NineDevice9 *This, boolean is_reset ) This->state.scissor.maxy = refSurf->desc.Height; } - if (This->nswapchains && This->swapchains[0]->params.EnableAutoDepthStencil) + if (This->nswapchains && This->swapchains[0]->params.EnableAutoDepthStencil) { This->state.rs[D3DRS_ZENABLE] = TRUE; + This->state.rs_advertised[D3DRS_ZENABLE] = TRUE; + } if (This->state.rs[D3DRS_ZENABLE]) NineDevice9_SetDepthStencilSurface( This, (IDirect3DSurface9 *)This->swapchains[0]->zsbuf); @@ -131,7 +134,8 @@ NineDevice9_ctor( struct NineDevice9 *This, ID3DPresentGroup *pPresentationGroup, struct d3dadapter9_context *pCTX, boolean ex, - D3DDISPLAYMODEEX *pFullscreenDisplayMode ) + D3DDISPLAYMODEEX *pFullscreenDisplayMode, + int minorVersionNum ) { unsigned i; HRESULT hr = NineUnknown_ctor(&This->base, pParams); @@ -152,6 +156,8 @@ NineDevice9_ctor( struct NineDevice9 *This, This->params = *pCreationParameters; This->ex = ex; This->present = pPresentationGroup; + This->minor_version_num = minorVersionNum; + IDirect3D9_AddRef(This->d3d9); ID3DPresentGroup_AddRef(This->present); @@ -172,6 +178,19 @@ NineDevice9_ctor( struct NineDevice9 *This, /* Create first, it messes up our state. */ This->hud = hud_create(This->pipe, This->cso); /* NULL result is fine */ + /* Available memory counter. Updated only for allocations with this device + * instance. This is the Win 7 behavior. + * Win XP shares this counter across multiple devices. */ + This->available_texture_mem = This->screen->get_param(This->screen, PIPE_CAP_VIDEO_MEMORY); + if (This->available_texture_mem < 4096) + This->available_texture_mem <<= 20; + else + This->available_texture_mem = UINT_MAX; + /* We cap texture memory usage to 80% of what is reported free initially + * This helps get closer Win behaviour. For example VertexBuffer allocation + * still succeeds when texture allocation fails. */ + This->available_texture_limit = This->available_texture_mem * 20LL / 100LL; + /* create implicit swapchains */ This->nswapchains = ID3DPresentGroup_GetMultiheadCount(This->present); This->swapchains = CALLOC(This->nswapchains, @@ -460,7 +479,8 @@ NineDevice9_dtor( struct NineDevice9 *This ) if (This->swapchains) { for (i = 0; i < This->nswapchains; ++i) - NineUnknown_Unbind(NineUnknown(This->swapchains[i])); + if (This->swapchains[i]) + NineUnknown_Unbind(NineUnknown(This->swapchains[i])); FREE(This->swapchains); } @@ -523,17 +543,20 @@ NineDevice9_ResumeRecording( struct NineDevice9 *This ) HRESULT WINAPI NineDevice9_TestCooperativeLevel( struct NineDevice9 *This ) { - return D3D_OK; /* TODO */ + if (NineSwapChain9_GetOccluded(This->swapchains[0])) { + This->device_needs_reset = TRUE; + return D3DERR_DEVICELOST; + } else if (This->device_needs_reset) { + return D3DERR_DEVICENOTRESET; + } + + return D3D_OK; } UINT WINAPI NineDevice9_GetAvailableTextureMem( struct NineDevice9 *This ) { - const unsigned mem = This->screen->get_param(This->screen, PIPE_CAP_VIDEO_MEMORY); - if (mem < 4096) - return mem << 20; - else - return UINT_MAX; + return This->available_texture_mem; } HRESULT WINAPI @@ -606,6 +629,7 @@ NineDevice9_SetCursorProperties( struct NineDevice9 *This, "pCursorBitmap=%p\n", This, XHotSpot, YHotSpot, pCursorBitmap); user_assert(pCursorBitmap, D3DERR_INVALIDCALL); + user_assert(surf->desc.Format == D3DFMT_A8R8G8B8, D3DERR_INVALIDCALL); if (This->swapchains[0]->params.Windowed) { This->cursor.w = MIN2(surf->desc.Width, 32); @@ -709,6 +733,11 @@ NineDevice9_CreateAdditionalSwapChain( struct NineDevice9 *This, This, pPresentationParameters, pSwapChain); user_assert(pPresentationParameters, D3DERR_INVALIDCALL); + user_assert(tmplt->params.Windowed && pPresentationParameters->Windowed, D3DERR_INVALIDCALL); + + /* TODO: this deserves more tests */ + if (!pPresentationParameters->hDeviceWindow) + pPresentationParameters->hDeviceWindow = This->params.hFocusWindow; hr = ID3DPresentGroup_CreateAdditionalPresent(This->present, pPresentationParameters, &present); @@ -757,11 +786,16 @@ NineDevice9_Reset( struct NineDevice9 *This, DBG("This=%p pPresentationParameters=%p\n", This, pPresentationParameters); + if (NineSwapChain9_GetOccluded(This->swapchains[0])) { + This->device_needs_reset = TRUE; + return D3DERR_DEVICELOST; + } + for (i = 0; i < This->nswapchains; ++i) { D3DPRESENT_PARAMETERS *params = &pPresentationParameters[i]; hr = NineSwapChain9_Resize(This->swapchains[i], params, NULL); if (hr != D3D_OK) - return hr; + break; } nine_pipe_context_clear(This); @@ -772,6 +806,7 @@ NineDevice9_Reset( struct NineDevice9 *This, This, 0, (IDirect3DSurface9 *)This->swapchains[0]->buffers[0]); /* XXX: better use GetBackBuffer here ? */ + This->device_needs_reset = (hr != D3D_OK); return hr; } @@ -806,6 +841,8 @@ NineDevice9_GetBackBuffer( struct NineDevice9 *This, IDirect3DSurface9 **ppBackBuffer ) { user_assert(ppBackBuffer != NULL, D3DERR_INVALIDCALL); + /* return NULL on error */ + *ppBackBuffer = NULL; user_assert(iSwapChain < This->nswapchains, D3DERR_INVALIDCALL); return NineSwapChain9_GetBackBuffer(This->swapchains[iSwapChain], @@ -1455,7 +1492,7 @@ NineDevice9_StretchRect( struct NineDevice9 *This, struct NineSurface9 *src = NineSurface9(pSourceSurface); struct pipe_resource *dst_res = NineSurface9_GetResource(dst); struct pipe_resource *src_res = NineSurface9_GetResource(src); - const boolean zs = util_format_is_depth_or_stencil(dst_res->format); + boolean zs; struct pipe_blit_info blit; boolean scaled, clamped, ms, flip_x = FALSE, flip_y = FALSE; @@ -1470,6 +1507,9 @@ NineDevice9_StretchRect( struct NineDevice9 *This, DBG("pDestRect=(%u,%u)-(%u,%u)\n", pDestRect->left, pDestRect->top, pDestRect->right, pDestRect->bottom); + user_assert(dst->base.pool == D3DPOOL_DEFAULT && + src->base.pool == D3DPOOL_DEFAULT, D3DERR_INVALIDCALL); + zs = util_format_is_depth_or_stencil(dst_res->format); user_assert(!zs || !This->in_scene, D3DERR_INVALIDCALL); user_assert(!zs || !pSourceRect || (pSourceRect->left == 0 && @@ -1493,8 +1533,6 @@ NineDevice9_StretchRect( struct NineDevice9 *This, src_res->nr_samples, PIPE_BIND_SAMPLER_VIEW), D3DERR_INVALIDCALL); - user_assert(dst->base.pool == D3DPOOL_DEFAULT && - src->base.pool == D3DPOOL_DEFAULT, D3DERR_INVALIDCALL); /* We might want to permit these, but wine thinks we shouldn't. */ user_assert(!pDestRect || @@ -1668,6 +1706,8 @@ NineDevice9_ColorFill( struct NineDevice9 *This, user_assert((surf->base.usage & D3DUSAGE_RENDERTARGET) || NineSurface9_IsOffscreenPlain(surf), D3DERR_INVALIDCALL); + user_assert(surf->desc.Format != D3DFMT_NULL, D3D_OK); + if (pRect) { x = pRect->left; y = pRect->top; @@ -1884,15 +1924,18 @@ NineDevice9_Clear( struct NineDevice9 *This, Count = 0; #endif + nine_update_state_framebuffer_clear(This); + if (Flags & D3DCLEAR_TARGET) bufs |= PIPE_CLEAR_COLOR; - if (Flags & D3DCLEAR_ZBUFFER) bufs |= PIPE_CLEAR_DEPTH; - if (Flags & D3DCLEAR_STENCIL) bufs |= PIPE_CLEAR_STENCIL; + /* Ignore Z buffer if not bound */ + if (This->state.fb.zsbuf != NULL) { + if (Flags & D3DCLEAR_ZBUFFER) bufs |= PIPE_CLEAR_DEPTH; + if (Flags & D3DCLEAR_STENCIL) bufs |= PIPE_CLEAR_STENCIL; + } if (!bufs) return D3D_OK; d3dcolor_to_pipe_color_union(&rgba, Color); - nine_update_state_framebuffer(This); - rect.x1 = This->state.viewport.X; rect.y1 = This->state.viewport.Y; rect.x2 = This->state.viewport.Width + rect.x1; @@ -1935,7 +1978,6 @@ NineDevice9_Clear( struct NineDevice9 *This, /* Case we clear depth buffer (and eventually rt too). * depth buffer size is always >= rt size. Compare to clear region */ ((bufs & (PIPE_CLEAR_DEPTH | PIPE_CLEAR_STENCIL)) && - This->state.fb.zsbuf != NULL && rect.x2 >= zsbuf_surf->desc.Width && rect.y2 >= zsbuf_surf->desc.Height))) { DBG("Clear fast path\n"); @@ -2342,8 +2384,15 @@ NineDevice9_SetRenderState( struct NineDevice9 *This, DBG("This=%p State=%u(%s) Value=%08x\n", This, State, nine_d3drs_to_string(State), Value); + user_assert(State < D3DRS_COUNT, D3DERR_INVALIDCALL); + + if (state->rs_advertised[State] == Value && likely(!This->is_recording)) + return D3D_OK; + + state->rs_advertised[State] = Value; + /* Amd hacks (equivalent to GL extensions) */ - if (State == D3DRS_POINTSIZE) { + if (unlikely(State == D3DRS_POINTSIZE)) { if (Value == RESZ_CODE) return NineDevice9_ResolveZ(This); @@ -2356,20 +2405,17 @@ NineDevice9_SetRenderState( struct NineDevice9 *This, } /* NV hack */ - if (State == D3DRS_ADAPTIVETESS_Y && - (Value == D3DFMT_ATOC || (Value == D3DFMT_UNKNOWN && state->rs[NINED3DRS_ALPHACOVERAGE]))) { + if (unlikely(State == D3DRS_ADAPTIVETESS_Y)) { + if (Value == D3DFMT_ATOC || (Value == D3DFMT_UNKNOWN && state->rs[NINED3DRS_ALPHACOVERAGE])) { state->rs[NINED3DRS_ALPHACOVERAGE] = (Value == D3DFMT_ATOC); state->changed.group |= NINE_STATE_BLEND; return D3D_OK; + } } - user_assert(State < Elements(state->rs), D3DERR_INVALIDCALL); - - if (likely(state->rs[State] != Value) || unlikely(This->is_recording)) { - state->rs[State] = Value; - state->changed.rs[State / 32] |= 1 << (State % 32); - state->changed.group |= nine_render_state_group[State]; - } + state->rs[State] = nine_fix_render_state_value(State, Value); + state->changed.rs[State / 32] |= 1 << (State % 32); + state->changed.group |= nine_render_state_group[State]; return D3D_OK; } @@ -2379,9 +2425,9 @@ NineDevice9_GetRenderState( struct NineDevice9 *This, D3DRENDERSTATETYPE State, DWORD *pValue ) { - user_assert(State < Elements(This->state.rs), D3DERR_INVALIDCALL); + user_assert(State < D3DRS_COUNT, D3DERR_INVALIDCALL); - *pValue = This->state.rs[State]; + *pValue = This->state.rs_advertised[State]; return D3D_OK; } @@ -3122,7 +3168,7 @@ NineDevice9_ProcessVertices( struct NineDevice9 *This, buffer_offset = 0; } else { /* SO matches vertex declaration */ - resource = dst->base.resource; + resource = NineVertexBuffer9_GetResource(dst); buffer_offset = DestIndex * vs->so->stride[0]; } target = This->pipe->create_stream_output_target(This->pipe, resource, @@ -3184,13 +3230,21 @@ NineDevice9_SetVertexDeclaration( struct NineDevice9 *This, IDirect3DVertexDeclaration9 *pDecl ) { struct nine_state *state = This->update; + BOOL was_programmable_vs = This->state.programmable_vs; DBG("This=%p pDecl=%p\n", This, pDecl); if (likely(!This->is_recording) && state->vdecl == NineVertexDeclaration9(pDecl)) return D3D_OK; + nine_bind(&state->vdecl, pDecl); + This->state.programmable_vs = This->state.vs && !(This->state.vdecl && This->state.vdecl->position_t); + if (likely(!This->is_recording) && was_programmable_vs != This->state.programmable_vs) { + state->commit |= NINE_STATE_COMMIT_CONST_VS; + state->changed.group |= NINE_STATE_VS; + } + state->changed.group |= NINE_STATE_VDECL; return D3D_OK; @@ -3262,18 +3316,21 @@ NineDevice9_SetVertexShader( struct NineDevice9 *This, IDirect3DVertexShader9 *pShader ) { struct nine_state *state = This->update; + BOOL was_programmable_vs = This->state.programmable_vs; DBG("This=%p pShader=%p\n", This, pShader); if (!This->is_recording && state->vs == (struct NineVertexShader9*)pShader) return D3D_OK; + nine_bind(&state->vs, pShader); + + This->state.programmable_vs = This->state.vs && !(This->state.vdecl && This->state.vdecl->position_t); + /* ff -> non-ff: commit back non-ff constants */ - if (!state->vs && pShader) + if (!was_programmable_vs && This->state.programmable_vs) state->commit |= NINE_STATE_COMMIT_CONST_VS; - nine_bind(&state->vs, pShader); - state->changed.group |= NINE_STATE_VS; return D3D_OK; @@ -3499,7 +3556,8 @@ NineDevice9_SetStreamSource( struct NineDevice9 *This, state->vtxbuf[i].stride = Stride; state->vtxbuf[i].buffer_offset = OffsetInBytes; } - state->vtxbuf[i].buffer = pStreamData ? pVBuf9->base.resource : NULL; + pipe_resource_reference(&state->vtxbuf[i].buffer, + pStreamData ? NineVertexBuffer9_GetResource(pVBuf9) : NULL); return D3D_OK; } @@ -3542,6 +3600,9 @@ NineDevice9_SetStreamSourceFreq( struct NineDevice9 *This, (Setting & D3DSTREAMSOURCE_INDEXEDDATA)), D3DERR_INVALIDCALL); user_assert(Setting, D3DERR_INVALIDCALL); + if (likely(!This->is_recording) && state->stream_freq[StreamNumber] == Setting) + return D3D_OK; + state->stream_freq[StreamNumber] = Setting; if (Setting & D3DSTREAMSOURCE_INSTANCEDATA) @@ -3549,7 +3610,9 @@ NineDevice9_SetStreamSourceFreq( struct NineDevice9 *This, else state->stream_instancedata_mask &= ~(1 << StreamNumber); - state->changed.stream_freq |= 1 << StreamNumber; + state->changed.stream_freq |= 1 << StreamNumber; /* Used for stateblocks */ + if (StreamNumber != 0) + state->changed.group |= NINE_STATE_STREAMFREQ; return D3D_OK; } @@ -4013,7 +4076,8 @@ NineDevice9_new( struct pipe_screen *pScreen, struct d3dadapter9_context *pCTX, boolean ex, D3DDISPLAYMODEEX *pFullscreenDisplayMode, - struct NineDevice9 **ppOut ) + struct NineDevice9 **ppOut, + int minorVersionNum ) { BOOL lock; lock = !!(pCreationParameters->BehaviorFlags & D3DCREATE_MULTITHREADED); @@ -4021,5 +4085,5 @@ NineDevice9_new( struct pipe_screen *pScreen, NINE_NEW(Device9, ppOut, lock, /* args */ pScreen, pCreationParameters, pCaps, pPresentationParameters, pD3D9, pPresentationGroup, pCTX, - ex, pFullscreenDisplayMode); + ex, pFullscreenDisplayMode, minorVersionNum ); } diff --git a/src/gallium/state_trackers/nine/device9.h b/src/gallium/state_trackers/nine/device9.h index cbc1e61f5db..34edf0cfa48 100644 --- a/src/gallium/state_trackers/nine/device9.h +++ b/src/gallium/state_trackers/nine/device9.h @@ -137,6 +137,10 @@ struct NineDevice9 /* dummy vbo (containing 0 0 0 0) to bind if vertex shader input * is not bound to anything by the vertex declaration */ struct pipe_resource *dummy_vbo; + BOOL device_needs_reset; + int minor_version_num; + long long available_texture_mem; + long long available_texture_limit; }; static inline struct NineDevice9 * NineDevice9( void *data ) @@ -154,7 +158,8 @@ NineDevice9_new( struct pipe_screen *pScreen, struct d3dadapter9_context *pCTX, boolean ex, D3DDISPLAYMODEEX *pFullscreenDisplayMode, - struct NineDevice9 **ppOut ); + struct NineDevice9 **ppOut, + int minorVersionNum ); HRESULT NineDevice9_ctor( struct NineDevice9 *This, @@ -167,12 +172,15 @@ NineDevice9_ctor( struct NineDevice9 *This, ID3DPresentGroup *pPresentationGroup, struct d3dadapter9_context *pCTX, boolean ex, - D3DDISPLAYMODEEX *pFullscreenDisplayMode ); + D3DDISPLAYMODEEX *pFullscreenDisplayMode, + int minorVersionNum ); void NineDevice9_dtor( struct NineDevice9 *This ); /*** Nine private ***/ +void +NineDevice9_SetDefaultState( struct NineDevice9 *This, boolean is_reset ); struct pipe_screen * NineDevice9_GetScreen( struct NineDevice9 *This ); diff --git a/src/gallium/state_trackers/nine/device9ex.c b/src/gallium/state_trackers/nine/device9ex.c index fe8aa9b2704..11244b1bedf 100644 --- a/src/gallium/state_trackers/nine/device9ex.c +++ b/src/gallium/state_trackers/nine/device9ex.c @@ -20,7 +20,9 @@ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE * USE OR OTHER DEALINGS IN THE SOFTWARE. */ +#include "device9.h" #include "device9ex.h" +#include "nine_pipe.h" #include "swapchain9ex.h" #include "nine_helpers.h" @@ -37,7 +39,8 @@ NineDevice9Ex_ctor( struct NineDevice9Ex *This, D3DDISPLAYMODEEX *pFullscreenDisplayMode, IDirect3D9Ex *pD3D9Ex, ID3DPresentGroup *pPresentationGroup, - struct d3dadapter9_context *pCTX ) + struct d3dadapter9_context *pCTX, + int minorVersionNum ) { DBG("This=%p pParams=%p pScreen=%p pCreationParameters=%p pCaps=%p " "pPresentationParameters=%p pFullscreenDisplayMode=%p " @@ -50,7 +53,7 @@ NineDevice9Ex_ctor( struct NineDevice9Ex *This, pScreen, pCreationParameters, pCaps, pPresentationParameters, (IDirect3D9 *)pD3D9Ex, pPresentationGroup, pCTX, - TRUE, pFullscreenDisplayMode); + TRUE, pFullscreenDisplayMode, minorVersionNum); } static void @@ -158,6 +161,14 @@ NineDevice9Ex_CheckDeviceState( struct NineDevice9Ex *This, DBG("This=%p hDestinationWindow=%p\n", This, hDestinationWindow); + user_assert(!This->base.swapchains[0]->params.Windowed, D3D_OK); + + if (This->base.params.hFocusWindow == hDestinationWindow) { + if (NineSwapChain9_GetOccluded(This->base.swapchains[0])) + return S_PRESENT_OCCLUDED; + } else if(!NineSwapChain9_GetOccluded(This->base.swapchains[0])) { + return S_PRESENT_OCCLUDED; + } /* TODO: handle the other return values */ return D3D_OK; } @@ -221,12 +232,37 @@ NineDevice9Ex_ResetEx( struct NineDevice9Ex *This, if (pFullscreenDisplayMode) mode = &(pFullscreenDisplayMode[i]); hr = NineSwapChain9_Resize(This->base.swapchains[i], params, mode); if (FAILED(hr)) - return (hr == D3DERR_OUTOFVIDEOMEMORY) ? hr : D3DERR_DEVICELOST; + break; } NineDevice9_SetRenderTarget( (struct NineDevice9 *)This, 0, (IDirect3DSurface9 *)This->base.swapchains[0]->buffers[0]); + return hr; +} + +HRESULT WINAPI +NineDevice9Ex_Reset( struct NineDevice9Ex *This, + D3DPRESENT_PARAMETERS *pPresentationParameters ) +{ + HRESULT hr = D3D_OK; + unsigned i; + + DBG("This=%p pPresentationParameters=%p\n", This, pPresentationParameters); + + for (i = 0; i < This->base.nswapchains; ++i) { + D3DPRESENT_PARAMETERS *params = &pPresentationParameters[i]; + hr = NineSwapChain9_Resize(This->base.swapchains[i], params, NULL); + if (FAILED(hr)) + break; + } + + nine_pipe_context_clear((struct NineDevice9 *)This); + nine_state_clear(&This->base.state, TRUE); + + NineDevice9_SetDefaultState((struct NineDevice9 *)This, TRUE); + NineDevice9_SetRenderTarget( + (struct NineDevice9 *)This, 0, (IDirect3DSurface9 *)This->base.swapchains[0]->buffers[0]); return hr; } @@ -248,11 +284,18 @@ NineDevice9Ex_GetDisplayModeEx( struct NineDevice9Ex *This, return NineSwapChain9Ex_GetDisplayModeEx(swapchain, pMode, pRotation); } +HRESULT WINAPI +NineDevice9Ex_TestCooperativeLevel( struct NineDevice9Ex *This ) +{ + return D3D_OK; +} + + IDirect3DDevice9ExVtbl NineDevice9Ex_vtable = { (void *)NineUnknown_QueryInterface, (void *)NineUnknown_AddRef, (void *)NineUnknown_Release, - (void *)NineDevice9_TestCooperativeLevel, + (void *)NineDevice9Ex_TestCooperativeLevel, (void *)NineDevice9_GetAvailableTextureMem, (void *)NineDevice9_EvictManagedResources, (void *)NineDevice9_GetDirect3D, @@ -265,7 +308,7 @@ IDirect3DDevice9ExVtbl NineDevice9Ex_vtable = { (void *)NineDevice9_CreateAdditionalSwapChain, (void *)NineDevice9_GetSwapChain, (void *)NineDevice9_GetNumberOfSwapChains, - (void *)NineDevice9_Reset, + (void *)NineDevice9Ex_Reset, (void *)NineDevice9_Present, (void *)NineDevice9_GetBackBuffer, (void *)NineDevice9_GetRasterStatus, @@ -401,13 +444,14 @@ NineDevice9Ex_new( struct pipe_screen *pScreen, IDirect3D9Ex *pD3D9Ex, ID3DPresentGroup *pPresentationGroup, struct d3dadapter9_context *pCTX, - struct NineDevice9Ex **ppOut ) + struct NineDevice9Ex **ppOut, + int minorVersionNum ) { BOOL lock; lock = !!(pCreationParameters->BehaviorFlags & D3DCREATE_MULTITHREADED); NINE_NEW(Device9Ex, ppOut, lock, pScreen, pCreationParameters, pCaps, pPresentationParameters, - pFullscreenDisplayMode, pD3D9Ex, pPresentationGroup, pCTX); + pFullscreenDisplayMode, pD3D9Ex, pPresentationGroup, pCTX, minorVersionNum ); } diff --git a/src/gallium/state_trackers/nine/device9ex.h b/src/gallium/state_trackers/nine/device9ex.h index 8375622d8a1..1c7e57e0974 100644 --- a/src/gallium/state_trackers/nine/device9ex.h +++ b/src/gallium/state_trackers/nine/device9ex.h @@ -44,7 +44,8 @@ NineDevice9Ex_new( struct pipe_screen *pScreen, IDirect3D9Ex *pD3D9Ex, ID3DPresentGroup *pPresentationGroup, struct d3dadapter9_context *pCTX, - struct NineDevice9Ex **ppOut ); + struct NineDevice9Ex **ppOut, + int minorVersionNum ); HRESULT WINAPI NineDevice9Ex_SetConvolutionMonoKernel( struct NineDevice9Ex *This, @@ -73,6 +74,13 @@ NineDevice9Ex_PresentEx( struct NineDevice9Ex *This, DWORD dwFlags ); HRESULT WINAPI +NineDevice9Ex_Present( struct NineDevice9Ex *This, + const RECT *pSourceRect, + const RECT *pDestRect, + HWND hDestWindowOverride, + const RGNDATA *pDirtyRegion ); + +HRESULT WINAPI NineDevice9Ex_GetGPUThreadPriority( struct NineDevice9Ex *This, INT *pPriority ); @@ -141,9 +149,16 @@ NineDevice9Ex_ResetEx( struct NineDevice9Ex *This, D3DDISPLAYMODEEX *pFullscreenDisplayMode ); HRESULT WINAPI +NineDevice9Ex_Reset( struct NineDevice9Ex *This, + D3DPRESENT_PARAMETERS *pPresentationParameters ); + +HRESULT WINAPI NineDevice9Ex_GetDisplayModeEx( struct NineDevice9Ex *This, UINT iSwapChain, D3DDISPLAYMODEEX *pMode, D3DDISPLAYROTATION *pRotation ); +HRESULT WINAPI +NineDevice9Ex_TestCooperativeLevel( struct NineDevice9Ex *This ); + #endif /* _NINE_DEVICE9EX_H_ */ diff --git a/src/gallium/state_trackers/nine/guid.c b/src/gallium/state_trackers/nine/guid.c index 5034feb4d71..5e63d2f6629 100644 --- a/src/gallium/state_trackers/nine/guid.c +++ b/src/gallium/state_trackers/nine/guid.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 <stdio.h> #include "guid.h" const GUID IID_IUnknown = { 0x00000000, 0x0000, 0x0000, { 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 } }; @@ -64,3 +65,20 @@ GUID_equal( const GUID *a, } return TRUE; } + +char* GUID_sprintf(char *guid_str, REFGUID id) { + sprintf( guid_str, + "{%08X,%04X,%04X,%02X%02X%02X%02X%02X%02X%02X%02X}", + id->Data1, + id->Data2, + id->Data3, + id->Data4[0], + id->Data4[1], + id->Data4[2], + id->Data4[3], + id->Data4[4], + id->Data4[5], + id->Data4[6], + id->Data4[7]); + return guid_str; +} diff --git a/src/gallium/state_trackers/nine/guid.h b/src/gallium/state_trackers/nine/guid.h index 1f9ff009ad8..af8f081bfb5 100644 --- a/src/gallium/state_trackers/nine/guid.h +++ b/src/gallium/state_trackers/nine/guid.h @@ -33,4 +33,8 @@ boolean GUID_equal( const GUID *a, const GUID *b ); +char* +GUID_sprintf( char *guid_str, + REFGUID id ); + #endif /* _NINE_GUID_H_ */ diff --git a/src/gallium/state_trackers/nine/indexbuffer9.c b/src/gallium/state_trackers/nine/indexbuffer9.c index 860313b7f7e..401fe75e95f 100644 --- a/src/gallium/state_trackers/nine/indexbuffer9.c +++ b/src/gallium/state_trackers/nine/indexbuffer9.c @@ -40,52 +40,17 @@ NineIndexBuffer9_ctor( struct NineIndexBuffer9 *This, struct NineUnknownParams *pParams, D3DINDEXBUFFER_DESC *pDesc ) { - struct pipe_resource *info = &This->base.info; HRESULT hr; DBG("This=%p pParams=%p pDesc=%p Usage=%s\n", This, pParams, pDesc, nine_D3DUSAGE_to_str(pDesc->Usage)); - This->pipe = pParams->device->pipe; - - info->screen = pParams->device->screen; - info->target = PIPE_BUFFER; - info->format = PIPE_FORMAT_R8_UNORM; - info->width0 = pDesc->Size; - info->flags = 0; - - info->bind = PIPE_BIND_INDEX_BUFFER | PIPE_BIND_TRANSFER_WRITE; - if (!(pDesc->Usage & D3DUSAGE_WRITEONLY)) - info->bind |= PIPE_BIND_TRANSFER_READ; - - info->usage = PIPE_USAGE_DEFAULT; - if (pDesc->Usage & D3DUSAGE_DYNAMIC) - info->usage = PIPE_USAGE_STREAM; - if (pDesc->Pool == D3DPOOL_SYSTEMMEM) - info->usage = PIPE_USAGE_STAGING; - - /* if (pDesc->Usage & D3DUSAGE_DONOTCLIP) { } */ - /* if (pDesc->Usage & D3DUSAGE_NONSECURE) { } */ - /* if (pDesc->Usage & D3DUSAGE_NPATCHES) { } */ - /* if (pDesc->Usage & D3DUSAGE_POINTS) { } */ - /* if (pDesc->Usage & D3DUSAGE_RTPATCHES) { } */ - if (pDesc->Usage & D3DUSAGE_SOFTWAREPROCESSING) - DBG("Application asked for Software Vertex Processing, " - "but this is unimplemented\n"); - - info->height0 = 1; - info->depth0 = 1; - info->array_size = 1; - info->last_level = 0; - info->nr_samples = 0; - - hr = NineResource9_ctor(&This->base, pParams, NULL, TRUE, D3DRTYPE_INDEXBUFFER, - pDesc->Pool, pDesc->Usage); + hr = NineBuffer9_ctor(&This->base, pParams, D3DRTYPE_INDEXBUFFER, + pDesc->Usage, pDesc->Size, pDesc->Pool); if (FAILED(hr)) return hr; - This->buffer.buffer = This->base.resource; + This->buffer.buffer = NineIndexBuffer9_GetResource(This); This->buffer.offset = 0; - This->map_count = 0; switch (pDesc->Format) { case D3DFMT_INDEX16: This->buffer.index_size = 2; break; @@ -105,9 +70,7 @@ NineIndexBuffer9_ctor( struct NineIndexBuffer9 *This, void NineIndexBuffer9_dtor( struct NineIndexBuffer9 *This ) { - if (This->transfer) { NineIndexBuffer9_Unlock(This); } - - NineResource9_dtor(&This->base); + NineBuffer9_dtor(&This->base); } const struct pipe_index_buffer * @@ -116,6 +79,12 @@ NineIndexBuffer9_GetBuffer( struct NineIndexBuffer9 *This ) return &This->buffer; } +struct pipe_resource * +NineIndexBuffer9_GetResource( struct NineIndexBuffer9 *This ) +{ + return NineBuffer9_GetResource(&This->base); +} + HRESULT WINAPI NineIndexBuffer9_Lock( struct NineIndexBuffer9 *This, UINT OffsetToLock, @@ -123,59 +92,13 @@ NineIndexBuffer9_Lock( struct NineIndexBuffer9 *This, void **ppbData, DWORD Flags ) { - struct pipe_box box; - void *data; - UINT count; - const unsigned usage = d3dlock_buffer_to_pipe_transfer_usage(Flags); - - DBG("This=%p OffsetToLock=%u SizeToLock=%u ppbData=%p Flags=%i " - "transfer=%p map_count=%u\n", This, OffsetToLock, - SizeToLock, ppbData, Flags, This->transfer, This->map_count); - - count = ++This->map_count; - - if (SizeToLock == 0) { - SizeToLock = This->desc.Size - OffsetToLock; - user_warn(OffsetToLock != 0); - } - - u_box_1d(OffsetToLock, SizeToLock, &box); - - if (unlikely(count != 1)) { - DBG("Lock has been called on already locked buffer." - "Unmapping before mapping again."); - This->pipe->transfer_unmap(This->pipe, This->transfer); - } - data = This->pipe->transfer_map(This->pipe, This->base.resource, 0, - usage, &box, &This->transfer); - if (!This->transfer) { - DBG("pipe::transfer_map failed\n" - " usage = %u\n" - " box.x = %u\n" - " box.width = %u\n", - usage, box.x, box.width); - } - *ppbData = data; - DBG("Returning memory at %p at address %p\n", *ppbData, ppbData); - - return D3D_OK; + return NineBuffer9_Lock(&This->base, OffsetToLock, SizeToLock, ppbData, Flags); } HRESULT WINAPI NineIndexBuffer9_Unlock( struct NineIndexBuffer9 *This ) { - DBG("This=%p\n", This); - if (!This->map_count) { - DBG("Unmap called without a previous map call.\n"); - return D3D_OK; - } - if (--This->map_count) { - DBG("Ignoring unmap.\n"); - return D3D_OK; - } - This->pipe->transfer_unmap(This->pipe, This->transfer); - This->transfer = NULL; - return D3D_OK; + return NineBuffer9_Unlock(&This->base); } HRESULT WINAPI diff --git a/src/gallium/state_trackers/nine/indexbuffer9.h b/src/gallium/state_trackers/nine/indexbuffer9.h index f10578f47ba..f3274b71224 100644 --- a/src/gallium/state_trackers/nine/indexbuffer9.h +++ b/src/gallium/state_trackers/nine/indexbuffer9.h @@ -24,7 +24,7 @@ #define _NINE_INDEXBUFFER9_H_ #include "resource9.h" - +#include "buffer9.h" #include "pipe/p_state.h" struct pipe_screen; @@ -35,13 +35,10 @@ struct NineDevice9; struct NineIndexBuffer9 { - struct NineResource9 base; + struct NineBuffer9 base; /* g3d stuff */ - struct pipe_context *pipe; struct pipe_index_buffer buffer; - struct pipe_transfer *transfer; - UINT map_count; D3DINDEXBUFFER_DESC desc; }; @@ -69,6 +66,8 @@ NineIndexBuffer9_dtor( struct NineIndexBuffer9 *This ); const struct pipe_index_buffer * NineIndexBuffer9_GetBuffer( struct NineIndexBuffer9 *This ); +struct pipe_resource * +NineIndexBuffer9_GetResource( struct NineIndexBuffer9 *This ); /*** Direct3D public ***/ HRESULT WINAPI diff --git a/src/gallium/state_trackers/nine/nine_ff.c b/src/gallium/state_trackers/nine/nine_ff.c index 0feaeab7330..a5466a7bdd4 100644 --- a/src/gallium/state_trackers/nine/nine_ff.c +++ b/src/gallium/state_trackers/nine/nine_ff.c @@ -58,7 +58,8 @@ struct nine_ff_vs_key uint32_t color0in_one : 1; uint32_t color1in_one : 1; uint32_t fog : 1; - uint32_t pad1 : 7; + uint32_t specular_enable : 1; + uint32_t pad1 : 6; uint32_t tc_dim_input: 16; /* 8 * 2 bits */ uint32_t pad2 : 16; uint32_t tc_dim_output: 24; /* 8 * 3 bits */ @@ -466,6 +467,10 @@ nine_ff_build_vs(struct NineDevice9 *device, struct vs_build_ctx *vs) ureg_MAD(ureg, tmp, vs->aInd, ureg_imm1f(ureg, 4.0f), ureg_imm1f(ureg, 224.0f)); ureg_ARL(ureg, AR, ureg_src(tmp)); } + + ureg_MOV(ureg, r[2], ureg_imm4f(ureg, 0.0f, 0.0f, 0.0f, 0.0f)); + ureg_MOV(ureg, r[3], ureg_imm4f(ureg, 1.0f, 1.0f, 1.0f, 1.0f)); + for (i = 0; i < key->vertexblend; ++i) { for (c = 0; c < 4; ++c) { cWM[c] = ureg_src_register(TGSI_FILE_CONSTANT, (224 + i * 4) * !key->vertexblend_indexed + c); @@ -473,22 +478,27 @@ nine_ff_build_vs(struct NineDevice9 *device, struct vs_build_ctx *vs) cWM[c] = ureg_src_indirect(cWM[c], ureg_scalar(ureg_src(AR), i)); } /* multiply by WORLD(index) */ - ureg_MUL(ureg, r[0], _XXXX(vs->aVtx), cWM[0]); - ureg_MAD(ureg, r[0], _YYYY(vs->aVtx), cWM[1], ureg_src(r[0])); - ureg_MAD(ureg, r[0], _ZZZZ(vs->aVtx), cWM[2], ureg_src(r[0])); - ureg_MAD(ureg, r[0], _WWWW(vs->aVtx), cWM[3], ureg_src(r[0])); - - /* accumulate weighted position value */ - if (i) - ureg_MAD(ureg, r[2], ureg_src(r[0]), ureg_scalar(vs->aWgt, i), ureg_src(r[2])); - else - ureg_MUL(ureg, r[2], ureg_src(r[0]), ureg_scalar(vs->aWgt, 0)); + ureg_MUL(ureg, tmp, _XXXX(vs->aVtx), cWM[0]); + ureg_MAD(ureg, tmp, _YYYY(vs->aVtx), cWM[1], ureg_src(tmp)); + ureg_MAD(ureg, tmp, _ZZZZ(vs->aVtx), cWM[2], ureg_src(tmp)); + ureg_MAD(ureg, tmp, _WWWW(vs->aVtx), cWM[3], ureg_src(tmp)); + + if (i < (key->vertexblend - 1)) { + /* accumulate weighted position value */ + ureg_MAD(ureg, r[2], ureg_src(tmp), ureg_scalar(vs->aWgt, i), ureg_src(r[2])); + /* subtract weighted position value for last value */ + ureg_SUB(ureg, r[3], ureg_src(r[3]), ureg_scalar(vs->aWgt, i)); + } } + + /* the last weighted position is always 1 - sum_of_previous_weights */ + ureg_MAD(ureg, r[2], ureg_src(tmp), ureg_scalar(ureg_src(r[3]), key->vertexblend - 1), ureg_src(r[2])); + /* multiply by VIEW_PROJ */ - ureg_MUL(ureg, r[0], _X(r[2]), _CONST(8)); - ureg_MAD(ureg, r[0], _Y(r[2]), _CONST(9), ureg_src(r[0])); - ureg_MAD(ureg, r[0], _Z(r[2]), _CONST(10), ureg_src(r[0])); - ureg_MAD(ureg, oPos, _W(r[2]), _CONST(11), ureg_src(r[0])); + ureg_MUL(ureg, tmp, _X(r[2]), _CONST(8)); + ureg_MAD(ureg, tmp, _Y(r[2]), _CONST(9), ureg_src(tmp)); + ureg_MAD(ureg, tmp, _Z(r[2]), _CONST(10), ureg_src(tmp)); + ureg_MAD(ureg, oPos, _W(r[2]), _CONST(11), ureg_src(tmp)); if (need_rVtx) vs->aVtx = ureg_src(r[2]); @@ -515,10 +525,10 @@ nine_ff_build_vs(struct NineDevice9 *device, struct vs_build_ctx *vs) ureg_MOV(ureg, oPos, ureg_src(tmp)); } else { /* position = vertex * WORLD_VIEW_PROJ */ - ureg_MUL(ureg, r[0], _XXXX(vs->aVtx), _CONST(0)); - ureg_MAD(ureg, r[0], _YYYY(vs->aVtx), _CONST(1), ureg_src(r[0])); - ureg_MAD(ureg, r[0], _ZZZZ(vs->aVtx), _CONST(2), ureg_src(r[0])); - ureg_MAD(ureg, oPos, _WWWW(vs->aVtx), _CONST(3), ureg_src(r[0])); + ureg_MUL(ureg, tmp, _XXXX(vs->aVtx), _CONST(0)); + ureg_MAD(ureg, tmp, _YYYY(vs->aVtx), _CONST(1), ureg_src(tmp)); + ureg_MAD(ureg, tmp, _ZZZZ(vs->aVtx), _CONST(2), ureg_src(tmp)); + ureg_MAD(ureg, oPos, _WWWW(vs->aVtx), _CONST(3), ureg_src(tmp)); } if (need_rVtx) { @@ -746,12 +756,10 @@ nine_ff_build_vs(struct NineDevice9 *device, struct vs_build_ctx *vs) { /* hitDir = light.position - eyeVtx * d = length(hitDir) - * hitDir /= d */ ureg_SUB(ureg, rHit, cLPos, ureg_src(rVtx)); ureg_DP3(ureg, tmp_x, ureg_src(rHit), ureg_src(rHit)); ureg_RSQ(ureg, tmp_y, _X(tmp)); - ureg_MUL(ureg, rHit, ureg_src(rHit), _Y(tmp)); /* normalize */ ureg_MUL(ureg, tmp_x, _X(tmp), _Y(tmp)); /* length */ /* att = 1.0 / (light.att0 + (light.att1 + light.att2 * d) * d) */ @@ -765,6 +773,9 @@ nine_ff_build_vs(struct NineDevice9 *device, struct vs_build_ctx *vs) ureg_fixup_label(ureg, label[l-1], ureg_get_instruction_number(ureg)); ureg_ENDIF(ureg); + /* normalize hitDir */ + ureg_normalize3(ureg, rHit, ureg_src(rHit), tmp); + /* if (SPOT light) */ ureg_SEQ(ureg, tmp_x, cLKind, ureg_imm1f(ureg, D3DLIGHT_SPOT)); ureg_IF(ureg, _X(tmp), &label[l++]); @@ -799,9 +810,9 @@ nine_ff_build_vs(struct NineDevice9 *device, struct vs_build_ctx *vs) /* midVec = normalize(hitDir + eyeDir) */ if (key->localviewer) { ureg_normalize3(ureg, rMid, ureg_src(rVtx), tmp); - ureg_ADD(ureg, rMid, ureg_src(rHit), ureg_negate(ureg_src(rMid))); + ureg_SUB(ureg, rMid, ureg_src(rHit), ureg_src(rMid)); } else { - ureg_ADD(ureg, rMid, ureg_src(rHit), ureg_imm3f(ureg, 0.0f, 0.0f, 1.0f)); + ureg_SUB(ureg, rMid, ureg_src(rHit), ureg_imm3f(ureg, 0.0f, 0.0f, 1.0f)); } ureg_normalize3(ureg, rMid, ureg_src(rMid), tmp); ureg_DP3(ureg, ureg_saturate(tmp_y), ureg_src(rNrm), ureg_src(rMid)); @@ -849,7 +860,14 @@ nine_ff_build_vs(struct NineDevice9 *device, struct vs_build_ctx *vs) ureg_MAD(ureg, ureg_writemask(tmp, TGSI_WRITEMASK_XYZ), vs->mtlA, ureg_src(tmp), vs->mtlE); ureg_ADD(ureg, ureg_writemask(tmp, TGSI_WRITEMASK_W ), vs->mtlA, vs->mtlE); } - ureg_MAD(ureg, oCol[0], ureg_src(rD), vs->mtlD, ureg_src(tmp)); + + if (key->specular_enable) { + /* add oCol[1] to oCol[0] */ + ureg_MAD(ureg, tmp, ureg_src(rD), vs->mtlD, ureg_src(tmp)); + ureg_MAD(ureg, oCol[0], ureg_src(rS), vs->mtlS, ureg_src(tmp)); + } else { + ureg_MAD(ureg, oCol[0], ureg_src(rD), vs->mtlD, ureg_src(tmp)); + } ureg_MUL(ureg, oCol[1], ureg_src(rS), vs->mtlS); } else /* COLOR */ @@ -1012,10 +1030,10 @@ ps_get_ts_arg(struct ps_build_ctx *ps, unsigned ta) reg = (ps->stage.index == ps->stage.index_pre_mod) ? ureg_src(ps->rMod) : ps->rCurSrc; break; case D3DTA_DIFFUSE: - reg = ureg_DECL_fs_input(ps->ureg, TGSI_SEMANTIC_COLOR, 0, TGSI_INTERPOLATE_PERSPECTIVE); + reg = ureg_DECL_fs_input(ps->ureg, TGSI_SEMANTIC_COLOR, 0, TGSI_INTERPOLATE_COLOR); break; case D3DTA_SPECULAR: - reg = ureg_DECL_fs_input(ps->ureg, TGSI_SEMANTIC_COLOR, 1, TGSI_INTERPOLATE_PERSPECTIVE); + reg = ureg_DECL_fs_input(ps->ureg, TGSI_SEMANTIC_COLOR, 1, TGSI_INTERPOLATE_COLOR); break; case D3DTA_TEMP: reg = ps->rTmpSrc; @@ -1222,7 +1240,7 @@ nine_ff_build_ps(struct NineDevice9 *device, struct nine_ff_ps_key *key) ps.ureg = ureg; ps.stage.index_pre_mod = -1; - ps.vC[0] = ureg_DECL_fs_input(ureg, TGSI_SEMANTIC_COLOR, 0, TGSI_INTERPOLATE_PERSPECTIVE); + ps.vC[0] = ureg_DECL_fs_input(ureg, TGSI_SEMANTIC_COLOR, 0, TGSI_INTERPOLATE_COLOR); /* Declare all TEMPs we might need, serious drivers have a register allocator. */ for (i = 0; i < Elements(ps.r); ++i) @@ -1241,7 +1259,7 @@ nine_ff_build_ps(struct NineDevice9 *device, struct nine_ff_ps_key *key) if (key->ts[s].colorarg0 == D3DTA_SPECULAR || key->ts[s].colorarg1 == D3DTA_SPECULAR || key->ts[s].colorarg2 == D3DTA_SPECULAR) - ps.vC[1] = ureg_DECL_fs_input(ureg, TGSI_SEMANTIC_COLOR, 1, TGSI_INTERPOLATE_PERSPECTIVE); + ps.vC[1] = ureg_DECL_fs_input(ureg, TGSI_SEMANTIC_COLOR, 1, TGSI_INTERPOLATE_COLOR); if (key->ts[s].colorarg0 == D3DTA_TEXTURE || key->ts[s].colorarg1 == D3DTA_TEXTURE || @@ -1258,7 +1276,7 @@ nine_ff_build_ps(struct NineDevice9 *device, struct nine_ff_ps_key *key) if (key->ts[s].alphaarg0 == D3DTA_SPECULAR || key->ts[s].alphaarg1 == D3DTA_SPECULAR || key->ts[s].alphaarg2 == D3DTA_SPECULAR) - ps.vC[1] = ureg_DECL_fs_input(ureg, TGSI_SEMANTIC_COLOR, 1, TGSI_INTERPOLATE_PERSPECTIVE); + ps.vC[1] = ureg_DECL_fs_input(ureg, TGSI_SEMANTIC_COLOR, 1, TGSI_INTERPOLATE_COLOR); if (key->ts[s].alphaarg0 == D3DTA_TEXTURE || key->ts[s].alphaarg1 == D3DTA_TEXTURE || @@ -1269,7 +1287,7 @@ nine_ff_build_ps(struct NineDevice9 *device, struct nine_ff_ps_key *key) } } if (key->specular) - ps.vC[1] = ureg_DECL_fs_input(ureg, TGSI_SEMANTIC_COLOR, 1, TGSI_INTERPOLATE_PERSPECTIVE); + ps.vC[1] = ureg_DECL_fs_input(ureg, TGSI_SEMANTIC_COLOR, 1, TGSI_INTERPOLATE_COLOR); oCol = ureg_DECL_output(ureg, TGSI_SEMANTIC_COLOR, 0); @@ -1500,6 +1518,9 @@ nine_ff_get_vs(struct NineDevice9 *device) if (key.fog_mode) key.fog_range = !key.position_t && state->rs[D3DRS_RANGEFOGENABLE]; + key.localviewer = !!state->rs[D3DRS_LOCALVIEWER]; + key.specular_enable = !!state->rs[D3DRS_SPECULARENABLE]; + if (state->rs[D3DRS_VERTEXBLEND] != D3DVBF_DISABLE) { key.vertexblend_indexed = !!state->rs[D3DRS_INDEXEDVERTEXBLENDENABLE]; @@ -1847,7 +1868,7 @@ nine_ff_update(struct NineDevice9 *device) DBG("vs=%p ps=%p\n", device->state.vs, device->state.ps); /* NOTE: the only reference belongs to the hash table */ - if (!device->state.vs) { + if (!state->programmable_vs) { device->ff.vs = nine_ff_get_vs(device); device->state.changed.group |= NINE_STATE_VS; } @@ -1856,7 +1877,7 @@ nine_ff_update(struct NineDevice9 *device) device->state.changed.group |= NINE_STATE_PS; } - if (!device->state.vs) { + if (!state->programmable_vs) { nine_ff_load_vs_transforms(device); nine_ff_load_tex_matrices(device); nine_ff_load_lights(device); diff --git a/src/gallium/state_trackers/nine/nine_limits.h b/src/gallium/state_trackers/nine/nine_limits.h new file mode 100644 index 00000000000..ef1ed2566ba --- /dev/null +++ b/src/gallium/state_trackers/nine/nine_limits.h @@ -0,0 +1,211 @@ +/* + * Copyright 2015 Axel Davy <[email protected]> + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef _NINE_LIMITS_H_ +#define _NINE_LIMITS_H_ + +#include "assert.h" +#include "d3d9types.h" + +// state can be any value +#define NINE_STATE_NO_LIMIT 0 +// value is clamped if below min or max +#define NINE_STATE_CLAMP 1 +// boolean: 0 -> false; any other value -> true +#define NINE_STATE_BOOL 2 +// a mask is applied on the value +#define NINE_STATE_MASK 3 +// if outside a range, state value is changed to a default value +#define NINE_STATE_RANGE_DEF_VAL 4 + +struct nine_state_behaviour { + unsigned state_value_behaviour; + union { + struct { + unsigned min; + unsigned max; + } clamp; + unsigned mask; + struct { + unsigned min; + unsigned max; + unsigned default_val; + } range_def_val; + } u; +}; + +#define __NO_LIMIT_RS(o) \ + [D3DRS_##o] = {NINE_STATE_NO_LIMIT} + +#define __CLAMP_RS(o, m, M) \ + [D3DRS_##o] = {NINE_STATE_CLAMP, {.clamp = {m, M}}} + +#define __BOOLEAN_RS(o) \ + [D3DRS_##o] = {NINE_STATE_BOOL} + +#define __MASK_RS(o, m) \ + [D3DRS_##o] = {NINE_STATE_MASK, {.mask = m}} + +#define __RANGE_DEF_VAL_RS(o, m, M, d) \ + [D3DRS_##o] = {NINE_STATE_RANGE_DEF_VAL, {.range_def_val = {m, M, d}}} + +#define __TO_DETERMINE_RS(o, m, M) \ + [D3DRS_##o] = {NINE_STATE_NO_LIMIT} + +static const struct nine_state_behaviour +render_state_limits_table[D3DRS_BLENDOPALPHA + 1] = { + __TO_DETERMINE_RS(ZENABLE, 0, 3), + __TO_DETERMINE_RS(FILLMODE, 1, 3), + __CLAMP_RS(SHADEMODE, 1, 3), + __BOOLEAN_RS(ZWRITEENABLE), + __BOOLEAN_RS(ALPHATESTENABLE), + __BOOLEAN_RS(LASTPIXEL), + __RANGE_DEF_VAL_RS(SRCBLEND, 1, 17, D3DBLEND_ZERO), + __RANGE_DEF_VAL_RS(DESTBLEND, 1, 17, D3DBLEND_ZERO), + __CLAMP_RS(CULLMODE, 1, 3), + __CLAMP_RS(ZFUNC, 1, 8), + __MASK_RS(ALPHAREF, 0x000000FF), + __CLAMP_RS(ALPHAFUNC, 1, 8), + __BOOLEAN_RS(DITHERENABLE), + __BOOLEAN_RS(ALPHABLENDENABLE), + __BOOLEAN_RS(FOGENABLE), + __BOOLEAN_RS(SPECULARENABLE), + __NO_LIMIT_RS(FOGCOLOR), + __MASK_RS(FOGTABLEMODE, 0x00000007), + __NO_LIMIT_RS(FOGSTART), /* a bit more complex than that, lets ignore */ + __NO_LIMIT_RS(FOGEND), + __NO_LIMIT_RS(FOGDENSITY), /* actually should be between 0.0 and 1.0 */ + __BOOLEAN_RS(RANGEFOGENABLE), + __BOOLEAN_RS(STENCILENABLE), + __CLAMP_RS(STENCILFAIL, 1, 8), + __CLAMP_RS(STENCILZFAIL, 1, 8), + __CLAMP_RS(STENCILPASS, 1, 8), + __CLAMP_RS(STENCILFUNC, 1, 8), + __NO_LIMIT_RS(STENCILREF), + __NO_LIMIT_RS(STENCILMASK), + __NO_LIMIT_RS(STENCILWRITEMASK), + __NO_LIMIT_RS(TEXTUREFACTOR), + __TO_DETERMINE_RS(WRAP0, 0, 15), + __TO_DETERMINE_RS(WRAP1, 0, 15), + __TO_DETERMINE_RS(WRAP2, 0, 15), + __TO_DETERMINE_RS(WRAP3, 0, 15), + __TO_DETERMINE_RS(WRAP4, 0, 15), + __TO_DETERMINE_RS(WRAP5, 0, 15), + __TO_DETERMINE_RS(WRAP6, 0, 15), + __TO_DETERMINE_RS(WRAP7, 0, 15), + __BOOLEAN_RS(CLIPPING), + __BOOLEAN_RS(LIGHTING), + __NO_LIMIT_RS(AMBIENT), + __MASK_RS(FOGVERTEXMODE, 0x00000007), + __BOOLEAN_RS(COLORVERTEX), + __BOOLEAN_RS(LOCALVIEWER), + __BOOLEAN_RS(NORMALIZENORMALS), + __TO_DETERMINE_RS(DIFFUSEMATERIALSOURCE, 0, 2), + __TO_DETERMINE_RS(SPECULARMATERIALSOURCE, 0, 2), + __TO_DETERMINE_RS(AMBIENTMATERIALSOURCE, 0, 2), + __TO_DETERMINE_RS(EMISSIVEMATERIALSOURCE, 0, 2), + __TO_DETERMINE_RS(VERTEXBLEND, 0, 256), /* values between 4 and 254 -both included- are forbidden too */ + __NO_LIMIT_RS(CLIPPLANEENABLE), /* expected check seems complex */ + __TO_DETERMINE_RS(POINTSIZE, 0, 0xFFFFFFFF), + __TO_DETERMINE_RS(POINTSIZE_MIN, 0, 0x7FFFFFFF), /* float >= 0.0 */ + __BOOLEAN_RS(POINTSPRITEENABLE), + __BOOLEAN_RS(POINTSCALEENABLE), + __TO_DETERMINE_RS(POINTSCALE_A, 0, 0x7FFFFFFF), /* float >= 0.0 */ + __TO_DETERMINE_RS(POINTSCALE_B, 0, 0x7FFFFFFF), /* float >= 0.0 */ + __TO_DETERMINE_RS(POINTSCALE_C, 0, 0x7FFFFFFF), /* float >= 0.0 */ + __BOOLEAN_RS(MULTISAMPLEANTIALIAS), + __NO_LIMIT_RS(MULTISAMPLEMASK), + __TO_DETERMINE_RS(PATCHEDGESTYLE, 0, 1), + __TO_DETERMINE_RS(DEBUGMONITORTOKEN, 0, 1), + __TO_DETERMINE_RS(POINTSIZE_MAX, 0, 0x7FFFFFFF), /* check more complex than that */ + __BOOLEAN_RS(INDEXEDVERTEXBLENDENABLE), + __TO_DETERMINE_RS(COLORWRITEENABLE, 0, 15), + __NO_LIMIT_RS(TWEENFACTOR), + __CLAMP_RS(BLENDOP, 1, 5), + __TO_DETERMINE_RS(POSITIONDEGREE, 1, 5), /* can actually be only 1 or 5 */ + __TO_DETERMINE_RS(NORMALDEGREE, 1, 2), + __BOOLEAN_RS(SCISSORTESTENABLE), + __NO_LIMIT_RS(SLOPESCALEDEPTHBIAS), + __BOOLEAN_RS(ANTIALIASEDLINEENABLE), + __NO_LIMIT_RS(MINTESSELLATIONLEVEL), + __NO_LIMIT_RS(MAXTESSELLATIONLEVEL), + __NO_LIMIT_RS(ADAPTIVETESS_X), + __NO_LIMIT_RS(ADAPTIVETESS_Y), + __NO_LIMIT_RS(ADAPTIVETESS_Z), + __NO_LIMIT_RS(ADAPTIVETESS_W), + __BOOLEAN_RS(ENABLEADAPTIVETESSELLATION), + __BOOLEAN_RS(TWOSIDEDSTENCILMODE), + __CLAMP_RS(CCW_STENCILFAIL, 1, 8), + __CLAMP_RS(CCW_STENCILZFAIL, 1, 8), + __CLAMP_RS(CCW_STENCILPASS, 1, 8), + __CLAMP_RS(CCW_STENCILFUNC, 1, 8), + __TO_DETERMINE_RS(COLORWRITEENABLE1, 0, 15), + __TO_DETERMINE_RS(COLORWRITEENABLE2, 0, 15), + __TO_DETERMINE_RS(COLORWRITEENABLE3, 0, 15), + __NO_LIMIT_RS(BLENDFACTOR), + __BOOLEAN_RS(SRGBWRITEENABLE), + __NO_LIMIT_RS(DEPTHBIAS), + __TO_DETERMINE_RS(WRAP8, 0, 15), + __TO_DETERMINE_RS(WRAP9, 0, 15), + __TO_DETERMINE_RS(WRAP10, 0, 15), + __TO_DETERMINE_RS(WRAP11, 0, 15), + __TO_DETERMINE_RS(WRAP12, 0, 15), + __TO_DETERMINE_RS(WRAP13, 0, 15), + __TO_DETERMINE_RS(WRAP14, 0, 15), + __TO_DETERMINE_RS(WRAP15, 0, 15), + __BOOLEAN_RS(SEPARATEALPHABLENDENABLE), + __RANGE_DEF_VAL_RS(SRCBLENDALPHA, 1, 17, D3DBLEND_ZERO), + __RANGE_DEF_VAL_RS(DESTBLENDALPHA, 1, 17, D3DBLEND_ZERO), + __CLAMP_RS(BLENDOPALPHA, 1, 5) +}; + +static DWORD inline +nine_fix_render_state_value(D3DRENDERSTATETYPE State, + DWORD Value) +{ + struct nine_state_behaviour behaviour = render_state_limits_table[State]; + + switch (behaviour.state_value_behaviour) { + case NINE_STATE_NO_LIMIT: + break; + case NINE_STATE_CLAMP: + if (Value < behaviour.u.clamp.min) + Value = behaviour.u.clamp.min; + else if (Value > behaviour.u.clamp.max) + Value = behaviour.u.clamp.max; + break; + case NINE_STATE_BOOL: + Value = Value ? 1 : 0; + break; + case NINE_STATE_MASK: + Value = Value & behaviour.u.mask; + break; + case NINE_STATE_RANGE_DEF_VAL: + if (Value < behaviour.u.range_def_val.min || Value > behaviour.u.range_def_val.max) + Value = behaviour.u.range_def_val.default_val; + break; + } + + return Value; +} + +#endif /* _NINE_HELPERS_H_ */ diff --git a/src/gallium/state_trackers/nine/nine_pdata.h b/src/gallium/state_trackers/nine/nine_pdata.h index 7bdd702cfbb..0e9a2aa7160 100644 --- a/src/gallium/state_trackers/nine/nine_pdata.h +++ b/src/gallium/state_trackers/nine/nine_pdata.h @@ -5,6 +5,7 @@ struct pheader { boolean unknown; + GUID guid; DWORD size; char data[1]; }; diff --git a/src/gallium/state_trackers/nine/nine_pipe.c b/src/gallium/state_trackers/nine/nine_pipe.c index 2be30f7e097..27a10d64473 100644 --- a/src/gallium/state_trackers/nine/nine_pipe.c +++ b/src/gallium/state_trackers/nine/nine_pipe.c @@ -181,6 +181,7 @@ nine_convert_blend_state(struct pipe_blend_state *blend_state, const DWORD *rs) } nine_convert_blend_state_fixup(&blend, rs); /* for BOTH[INV]SRCALPHA */ } + blend.rt[0].colormask = rs[D3DRS_COLORWRITEENABLE]; if (rs[D3DRS_COLORWRITEENABLE1] != rs[D3DRS_COLORWRITEENABLE] || @@ -222,8 +223,8 @@ nine_convert_sampler_state(struct cso_context *ctx, int idx, const DWORD *ss) samp.wrap_s = d3dtextureaddress_to_pipe_tex_wrap(ss[D3DSAMP_ADDRESSU]); samp.wrap_t = d3dtextureaddress_to_pipe_tex_wrap(ss[D3DSAMP_ADDRESSV]); samp.wrap_r = d3dtextureaddress_to_pipe_tex_wrap(ss[D3DSAMP_ADDRESSW]); - samp.min_img_filter = ss[D3DSAMP_MINFILTER] == D3DTEXF_POINT ? PIPE_TEX_FILTER_NEAREST : PIPE_TEX_FILTER_LINEAR; - samp.mag_img_filter = ss[D3DSAMP_MAGFILTER] == D3DTEXF_POINT ? PIPE_TEX_FILTER_NEAREST : PIPE_TEX_FILTER_LINEAR; + samp.min_img_filter = (ss[D3DSAMP_MINFILTER] == D3DTEXF_POINT && !ss[NINED3DSAMP_SHADOW]) ? PIPE_TEX_FILTER_NEAREST : PIPE_TEX_FILTER_LINEAR; + samp.mag_img_filter = (ss[D3DSAMP_MAGFILTER] == D3DTEXF_POINT && !ss[NINED3DSAMP_SHADOW]) ? PIPE_TEX_FILTER_NEAREST : PIPE_TEX_FILTER_LINEAR; if (ss[D3DSAMP_MINFILTER] == D3DTEXF_ANISOTROPIC || ss[D3DSAMP_MAGFILTER] == D3DTEXF_ANISOTROPIC) samp.max_anisotropy = ss[D3DSAMP_MAXANISOTROPY]; @@ -265,7 +266,7 @@ nine_pipe_context_clear(struct NineDevice9 *This) const enum pipe_format nine_d3d9_to_pipe_format_map[120] = { [D3DFMT_UNKNOWN] = PIPE_FORMAT_NONE, - [D3DFMT_R8G8B8] = PIPE_FORMAT_NONE, + [D3DFMT_R8G8B8] = PIPE_FORMAT_R8G8B8_UNORM, [D3DFMT_A8R8G8B8] = PIPE_FORMAT_B8G8R8A8_UNORM, [D3DFMT_X8R8G8B8] = PIPE_FORMAT_B8G8R8X8_UNORM, [D3DFMT_R5G6B5] = PIPE_FORMAT_B5G6R5_UNORM, @@ -323,8 +324,8 @@ const enum pipe_format nine_d3d9_to_pipe_format_map[120] = const D3DFORMAT nine_pipe_to_d3d9_format_map[PIPE_FORMAT_COUNT] = { [PIPE_FORMAT_NONE] = D3DFMT_UNKNOWN, - -/* [PIPE_FORMAT_B8G8R8_UNORM] = D3DFMT_R8G8B8, */ + /* TODO: rename PIPE_FORMAT_R8G8B8_UNORM to PIPE_FORMAT_B8G8R8_UNORM */ + [PIPE_FORMAT_R8G8B8_UNORM] = D3DFMT_R8G8B8, [PIPE_FORMAT_B8G8R8A8_UNORM] = D3DFMT_A8R8G8B8, [PIPE_FORMAT_B8G8R8X8_UNORM] = D3DFMT_X8R8G8B8, [PIPE_FORMAT_B5G6R5_UNORM] = D3DFMT_R5G6B5, diff --git a/src/gallium/state_trackers/nine/nine_shader.c b/src/gallium/state_trackers/nine/nine_shader.c index ed431738abc..a7a7da27903 100644 --- a/src/gallium/state_trackers/nine/nine_shader.c +++ b/src/gallium/state_trackers/nine/nine_shader.c @@ -852,7 +852,12 @@ tx_src_param(struct shader_translator *tx, const struct sm1_src_param *param) /* the address register (vs only) must be * assigned before use */ assert(!ureg_dst_is_undef(tx->regs.a0)); - ureg_ARR(ureg, tx->regs.address, ureg_src(tx->regs.a0)); + /* Round to lowest for vs1.1 (contrary to the doc), else + * round to nearest */ + if (tx->version.major < 2 && tx->version.minor < 2) + ureg_ARL(ureg, tx->regs.address, ureg_src(tx->regs.a0)); + else + ureg_ARR(ureg, tx->regs.address, ureg_src(tx->regs.a0)); src = ureg_src(tx->regs.address); } else { if (tx->version.major < 2 && tx->version.minor < 4) { @@ -870,9 +875,12 @@ tx_src_param(struct shader_translator *tx, const struct sm1_src_param *param) } else { if (tx->version.major < 3) { assert(!param->rel); - src = ureg_DECL_fs_input(tx->ureg, TGSI_SEMANTIC_COLOR, - param->idx, - TGSI_INTERPOLATE_PERSPECTIVE); + src = ureg_DECL_fs_input_cyl_centroid( + ureg, TGSI_SEMANTIC_COLOR, param->idx, + TGSI_INTERPOLATE_COLOR, 0, + tx->info->force_color_in_centroid ? + TGSI_INTERPOLATE_LOC_CENTROID : 0, + 0, 1); } else { assert(!param->rel); /* TODO */ assert(param->idx < Elements(tx->regs.v)); @@ -1163,12 +1171,9 @@ _tx_dst_param(struct shader_translator *tx, const struct sm1_dst_param *param) assert(!param->rel); tx->info->rt_mask |= 1 << param->idx; if (ureg_dst_is_undef(tx->regs.oCol[param->idx])) { - /* ps < 3: oCol[0] will have fog blending afterward - * vs < 3: oD1.w (D3DPMISCCAPS_FOGANDSPECULARALPHA) set to 0 even if set */ + /* ps < 3: oCol[0] will have fog blending afterward */ if (!IS_VS && tx->version.major < 3 && param->idx == 0) { tx->regs.oCol[0] = ureg_DECL_temporary(tx->ureg); - } else if (IS_VS && tx->version.major < 3 && param->idx == 1) { - tx->regs.oCol[1] = ureg_DECL_temporary(tx->ureg); } else { tx->regs.oCol[param->idx] = ureg_DECL_output(tx->ureg, TGSI_SEMANTIC_COLOR, param->idx); @@ -1543,25 +1548,6 @@ DECL_SPECIAL(CALLNZ) return D3D_OK; } -DECL_SPECIAL(MOV_vs1x) -{ - if (tx->insn.dst[0].file == D3DSPR_ADDR) { - /* Implementation note: We don't write directly - * to the addr register, but to an intermediate - * float register. - * Contrary to the doc, when writing to ADDR here, - * the rounding is not to nearest, but to lowest - * (wine test). - * Since we use ARR next, substract 0.5. */ - ureg_SUB(tx->ureg, - tx_dst_param(tx, &tx->insn.dst[0]), - tx_src_param(tx, &tx->insn.src[0]), - ureg_imm1f(tx->ureg, 0.5f)); - return D3D_OK; - } - return NineTranslateInstruction_Generic(tx); -} - DECL_SPECIAL(LOOP) { struct ureg_program *ureg = tx->ureg; @@ -1978,6 +1964,7 @@ nine_tgsi_to_interp_mode(struct tgsi_declaration_semantic *sem) return TGSI_INTERPOLATE_LINEAR; case TGSI_SEMANTIC_BCOLOR: case TGSI_SEMANTIC_COLOR: + return TGSI_INTERPOLATE_COLOR; case TGSI_SEMANTIC_FOG: case TGSI_SEMANTIC_GENERIC: case TGSI_SEMANTIC_TEXCOORD: @@ -2058,13 +2045,17 @@ DECL_SPECIAL(DCL) } } else { if (is_input && tx->version.major >= 3) { + unsigned interp_location = 0; /* SM3 only, SM2 input semantic determined by file */ assert(sem.reg.idx < Elements(tx->regs.v)); + if (sem.reg.mod & NINED3DSPDM_CENTROID || + (tgsi.Name == TGSI_SEMANTIC_COLOR && tx->info->force_color_in_centroid)) + interp_location = TGSI_INTERPOLATE_LOC_CENTROID; tx->regs.v[sem.reg.idx] = ureg_DECL_fs_input_cyl_centroid( ureg, tgsi.Name, tgsi.Index, nine_tgsi_to_interp_mode(&tgsi), 0, /* cylwrap */ - sem.reg.mod & NINED3DSPDM_CENTROID, 0, 1); + interp_location, 0, 1); } else if (!is_input && 0) { /* declare in COLOROUT/DEPTHOUT case */ /* FragColor or FragDepth */ @@ -2736,8 +2727,7 @@ DECL_SPECIAL(COMMENT) struct sm1_op_info inst_table[] = { _OPI(NOP, NOP, V(0,0), V(3,0), V(0,0), V(3,0), 0, 0, NULL), /* 0 */ - _OPI(MOV, MOV, V(0,0), V(1,1), V(0,0), V(0,0), 1, 1, SPECIAL(MOV_vs1x)), - _OPI(MOV, MOV, V(2,0), V(3,0), V(0,0), V(3,0), 1, 1, NULL), + _OPI(MOV, MOV, V(0,0), V(3,0), V(0,0), V(3,0), 1, 1, NULL), _OPI(ADD, ADD, V(0,0), V(3,0), V(0,0), V(3,0), 1, 2, NULL), /* 2 */ _OPI(SUB, SUB, V(0,0), V(3,0), V(0,0), V(3,0), 1, 2, NULL), /* 3 */ _OPI(MAD, MAD, V(0,0), V(3,0), V(0,0), V(3,0), 1, 3, NULL), /* 4 */ @@ -3426,13 +3416,6 @@ nine_translate_shader(struct NineDevice9 *device, struct nine_shader_info *info) ureg_MOV(tx->ureg, ureg_writemask(tx->regs.oFog, TGSI_WRITEMASK_X), ureg_imm1f(tx->ureg, 0.0f)); } - /* vs < 3: oD1.w (D3DPMISCCAPS_FOGANDSPECULARALPHA) set to 0 even if set */ - if (IS_VS && tx->version.major < 3 && !ureg_dst_is_undef(tx->regs.oCol[1])) { - struct ureg_dst dst = ureg_DECL_output(tx->ureg, TGSI_SEMANTIC_COLOR, 1); - ureg_MOV(tx->ureg, ureg_writemask(dst, TGSI_WRITEMASK_XYZ), ureg_src(tx->regs.oCol[1])); - ureg_MOV(tx->ureg, ureg_writemask(dst, TGSI_WRITEMASK_W), ureg_imm1f(tx->ureg, 0.0f)); - } - if (info->position_t) ureg_property(tx->ureg, TGSI_PROPERTY_VS_WINDOW_SPACE_POSITION, TRUE); diff --git a/src/gallium/state_trackers/nine/nine_shader.h b/src/gallium/state_trackers/nine/nine_shader.h index 41577ac572b..1fe0c4bd182 100644 --- a/src/gallium/state_trackers/nine/nine_shader.h +++ b/src/gallium/state_trackers/nine/nine_shader.h @@ -61,6 +61,7 @@ struct nine_shader_info uint8_t fog_enable; uint8_t fog_mode; + uint8_t force_color_in_centroid; uint16_t projected; /* ps 1.1 to 1.3 */ unsigned const_i_base; /* in vec4 (16 byte) units */ diff --git a/src/gallium/state_trackers/nine/nine_state.c b/src/gallium/state_trackers/nine/nine_state.c index aee31622088..6f94e378984 100644 --- a/src/gallium/state_trackers/nine/nine_state.c +++ b/src/gallium/state_trackers/nine/nine_state.c @@ -367,14 +367,14 @@ prepare_vs(struct NineDevice9 *device, uint8_t shader_changed) uint32_t changed_group = 0; int has_key_changed = 0; - if (likely(vs)) + if (likely(state->programmable_vs)) has_key_changed = NineVertexShader9_UpdateKey(vs, state); if (!shader_changed && !has_key_changed) return 0; /* likely because we dislike FF */ - if (likely(vs)) { + if (likely(state->programmable_vs)) { state->cso.vs = NineVertexShader9_GetVariant(vs); } else { vs = device->ff.vs; @@ -427,8 +427,8 @@ prepare_ps(struct NineDevice9 *device, uint8_t shader_changed) /* State preparation + State commit */ -static uint32_t -update_framebuffer(struct NineDevice9 *device) +static void +update_framebuffer(struct NineDevice9 *device, bool is_clear) { struct pipe_context *pipe = device->pipe; struct nine_state *state = &device->state; @@ -438,7 +438,8 @@ update_framebuffer(struct NineDevice9 *device) unsigned w = rt0->desc.Width; unsigned h = rt0->desc.Height; D3DMULTISAMPLE_TYPE nr_samples = rt0->desc.MultiSampleType; - unsigned mask = state->ps ? state->ps->rt_mask : 1; + unsigned ps_mask = state->ps ? state->ps->rt_mask : 1; + unsigned mask = is_clear ? 0xf : ps_mask; const int sRGB = state->rs[D3DRS_SRGBWRITEENABLE] ? 1 : 0; DBG("\n"); @@ -498,13 +499,13 @@ update_framebuffer(struct NineDevice9 *device) pipe->set_framebuffer_state(pipe, fb); /* XXX: cso ? */ - return state->changed.group; + if (is_clear && state->rt_mask == ps_mask) + state->changed.group &= ~NINE_STATE_FB; } static void update_viewport(struct NineDevice9 *device) { - struct pipe_context *pipe = device->pipe; const D3DVIEWPORT9 *vport = &device->state.viewport; struct pipe_viewport_state pvport; @@ -543,7 +544,7 @@ update_viewport(struct NineDevice9 *device) pvport.translate[1] -= 1.0f / 128.0f; } - pipe->set_viewport_states(pipe, 0, 1, &pvport); + cso_set_viewport(device->cso, &pvport); } /* Loop through VS inputs and pick the vertex elements with the declared @@ -567,7 +568,7 @@ update_vertex_elements(struct NineDevice9 *device) state->stream_usage_mask = 0; memset(vdecl_index_map, -1, 16); memset(used_streams, 0, device->caps.MaxStreams); - vs = device->state.vs ? device->state.vs : device->ff.vs; + vs = state->programmable_vs ? device->state.vs : device->ff.vs; if (vdecl) { for (n = 0; n < vs->num_inputs; ++n) { @@ -761,7 +762,7 @@ update_textures_and_samplers(struct NineDevice9 *device) cso_single_sampler_done(device->cso, PIPE_SHADER_FRAGMENT); commit_samplers = FALSE; - sampler_mask = state->vs ? state->vs->sampler_mask : 0; + sampler_mask = state->programmable_vs ? state->vs->sampler_mask : 0; state->bound_samplers_mask_vs = 0; for (num_textures = 0, i = 0; i < NINE_MAX_SAMPLERS_VS; ++i) { const unsigned s = NINE_SAMPLER_VS(i); @@ -854,7 +855,7 @@ commit_vs_constants(struct NineDevice9 *device) { struct pipe_context *pipe = device->pipe; - if (unlikely(!device->state.vs)) + if (unlikely(!device->state.programmable_vs)) pipe->set_constant_buffer(pipe, PIPE_SHADER_VERTEX, 0, &device->state.pipe.cb_vs_ff); else pipe->set_constant_buffer(pipe, PIPE_SHADER_VERTEX, 0, &device->state.pipe.cb_vs); @@ -913,7 +914,8 @@ commit_ps(struct NineDevice9 *device) NINE_STATE_DSA | \ NINE_STATE_VIEWPORT | \ NINE_STATE_VDECL | \ - NINE_STATE_IDXBUF) + NINE_STATE_IDXBUF | \ + NINE_STATE_STREAMFREQ) #define NINE_STATE_RARE \ (NINE_STATE_SCISSOR | \ @@ -934,16 +936,14 @@ validate_textures(struct NineDevice9 *device) } void -nine_update_state_framebuffer(struct NineDevice9 *device) +nine_update_state_framebuffer_clear(struct NineDevice9 *device) { struct nine_state *state = &device->state; validate_textures(device); if (state->changed.group & NINE_STATE_FB) - update_framebuffer(device); - - state->changed.group &= ~NINE_STATE_FB; + update_framebuffer(device, TRUE); } boolean @@ -964,7 +964,7 @@ nine_update_state(struct NineDevice9 *device) validate_textures(device); /* may clobber state */ /* ff_update may change VS/PS dirty bits */ - if (unlikely(!state->vs || !state->ps)) + if (unlikely(!state->programmable_vs || !state->ps)) nine_ff_update(device); group = state->changed.group; @@ -977,15 +977,14 @@ nine_update_state(struct NineDevice9 *device) if (group & (NINE_STATE_COMMON | NINE_STATE_VS)) { if (group & NINE_STATE_FB) - group |= update_framebuffer(device); /* may set NINE_STATE_RASTERIZER */ + update_framebuffer(device, FALSE); if (group & NINE_STATE_BLEND) prepare_blend(device); if (group & NINE_STATE_DSA) prepare_dsa(device); if (group & NINE_STATE_VIEWPORT) update_viewport(device); - if ((group & (NINE_STATE_VDECL | NINE_STATE_VS)) || - state->changed.stream_freq & ~1) + if (group & (NINE_STATE_VDECL | NINE_STATE_VS | NINE_STATE_STREAMFREQ)) update_vertex_elements(device); if (group & NINE_STATE_IDXBUF) commit_index_buffer(device); @@ -997,12 +996,12 @@ nine_update_state(struct NineDevice9 *device) if (group & (NINE_STATE_TEXTURE | NINE_STATE_SAMPLER)) update_textures_and_samplers(device); if (device->prefer_user_constbuf) { - if ((group & (NINE_STATE_VS_CONST | NINE_STATE_VS)) && state->vs) + if ((group & (NINE_STATE_VS_CONST | NINE_STATE_VS)) && state->programmable_vs) prepare_vs_constants_userbuf(device); if ((group & (NINE_STATE_PS_CONST | NINE_STATE_PS)) && state->ps) prepare_ps_constants_userbuf(device); } else { - if ((group & NINE_STATE_VS_CONST) && state->vs) + if ((group & NINE_STATE_VS_CONST) && state->programmable_vs) upload_constants(device, PIPE_SHADER_VERTEX); if ((group & NINE_STATE_PS_CONST) && state->ps) upload_constants(device, PIPE_SHADER_FRAGMENT); @@ -1262,6 +1261,8 @@ nine_state_set_defaults(struct NineDevice9 *device, const D3DCAPS9 *caps, */ state->rs[D3DRS_POINTSIZE_MAX] = fui(caps->MaxPointSize); + memcpy(state->rs_advertised, state->rs, sizeof(state->rs)); + /* Set changed flags to initialize driver. */ state->changed.group = NINE_STATE_ALL; @@ -1314,8 +1315,10 @@ nine_state_clear(struct nine_state *state, const boolean device) nine_bind(&state->vs, NULL); nine_bind(&state->ps, NULL); nine_bind(&state->vdecl, NULL); - for (i = 0; i < PIPE_MAX_ATTRIBS; ++i) + for (i = 0; i < PIPE_MAX_ATTRIBS; ++i) { nine_bind(&state->stream[i], NULL); + pipe_resource_reference(&state->vtxbuf[i].buffer, NULL); + } nine_bind(&state->idxbuf, NULL); for (i = 0; i < NINE_MAX_SAMPLERS; ++i) { if (device && diff --git a/src/gallium/state_trackers/nine/nine_state.h b/src/gallium/state_trackers/nine/nine_state.h index b34da70ef48..a4ec4e3b63a 100644 --- a/src/gallium/state_trackers/nine/nine_state.h +++ b/src/gallium/state_trackers/nine/nine_state.h @@ -61,23 +61,24 @@ #define NINE_STATE_SAMPLER (1 << 11) #define NINE_STATE_VDECL (1 << 12) #define NINE_STATE_IDXBUF (1 << 13) -#define NINE_STATE_PRIM (1 << 14) -#define NINE_STATE_MATERIAL (1 << 15) -#define NINE_STATE_BLEND_COLOR (1 << 16) -#define NINE_STATE_STENCIL_REF (1 << 17) -#define NINE_STATE_SAMPLE_MASK (1 << 18) -#define NINE_STATE_FF (0x1f << 19) -#define NINE_STATE_FF_VS (0x17 << 19) -#define NINE_STATE_FF_PS (0x18 << 19) -#define NINE_STATE_FF_LIGHTING (1 << 19) -#define NINE_STATE_FF_MATERIAL (1 << 20) -#define NINE_STATE_FF_VSTRANSF (1 << 21) -#define NINE_STATE_FF_PSSTAGES (1 << 22) -#define NINE_STATE_FF_OTHER (1 << 23) -#define NINE_STATE_FOG_SHADER (1 << 24) -#define NINE_STATE_PS1X_SHADER (1 << 25) -#define NINE_STATE_ALL 0x3ffffff -#define NINE_STATE_UNHANDLED (1 << 26) +#define NINE_STATE_STREAMFREQ (1 << 14) +#define NINE_STATE_PRIM (1 << 15) +#define NINE_STATE_MATERIAL (1 << 16) +#define NINE_STATE_BLEND_COLOR (1 << 17) +#define NINE_STATE_STENCIL_REF (1 << 18) +#define NINE_STATE_SAMPLE_MASK (1 << 19) +#define NINE_STATE_FF (0x1f << 20) +#define NINE_STATE_FF_VS (0x17 << 20) +#define NINE_STATE_FF_PS (0x18 << 20) +#define NINE_STATE_FF_LIGHTING (1 << 20) +#define NINE_STATE_FF_MATERIAL (1 << 21) +#define NINE_STATE_FF_VSTRANSF (1 << 22) +#define NINE_STATE_FF_PSSTAGES (1 << 23) +#define NINE_STATE_FF_OTHER (1 << 24) +#define NINE_STATE_FOG_SHADER (1 << 25) +#define NINE_STATE_PS1X_SHADER (1 << 26) +#define NINE_STATE_ALL 0x7ffffff +#define NINE_STATE_UNHANDLED (1 << 27) #define NINE_STATE_COMMIT_DSA (1 << 0) #define NINE_STATE_COMMIT_RASTERIZER (1 << 1) @@ -152,6 +153,7 @@ struct nine_state int vs_const_i[NINE_MAX_CONST_I][4]; BOOL vs_const_b[NINE_MAX_CONST_B]; float *vs_lconstf_temp; + BOOL programmable_vs; struct NinePixelShader9 *ps; float *ps_const_f; @@ -179,6 +181,7 @@ struct nine_state uint8_t rt_mask; DWORD rs[NINED3DRS_COUNT]; + DWORD rs_advertised[NINED3DRS_COUNT]; /* the ones apps get with GetRenderState */ struct NineBaseTexture9 *texture[NINE_MAX_SAMPLERS]; /* PS, DMAP, VS */ @@ -236,7 +239,7 @@ extern const uint32_t nine_render_states_vertex[(NINED3DRS_COUNT + 31) / 32]; struct NineDevice9; -void nine_update_state_framebuffer(struct NineDevice9 *); +void nine_update_state_framebuffer_clear(struct NineDevice9 *); boolean nine_update_state(struct NineDevice9 *); void nine_state_restore_non_cso(struct NineDevice9 *device); diff --git a/src/gallium/state_trackers/nine/pixelshader9.c b/src/gallium/state_trackers/nine/pixelshader9.c index 42bc349c2cc..00be67f8955 100644 --- a/src/gallium/state_trackers/nine/pixelshader9.c +++ b/src/gallium/state_trackers/nine/pixelshader9.c @@ -160,6 +160,7 @@ NinePixelShader9_GetVariant( struct NinePixelShader9 *This ) info.sampler_ps1xtypes = key; info.fog_enable = device->state.rs[D3DRS_FOGENABLE]; info.fog_mode = device->state.rs[D3DRS_FOGTABLEMODE]; + info.force_color_in_centroid = key >> 34 & 1; info.projected = (key >> 48) & 0xffff; hr = nine_translate_shader(This->base.device, &info); diff --git a/src/gallium/state_trackers/nine/pixelshader9.h b/src/gallium/state_trackers/nine/pixelshader9.h index e09009f6621..6b431813a81 100644 --- a/src/gallium/state_trackers/nine/pixelshader9.h +++ b/src/gallium/state_trackers/nine/pixelshader9.h @@ -28,6 +28,7 @@ #include "nine_state.h" #include "basetexture9.h" #include "nine_ff.h" +#include "surface9.h" struct nine_lconstf; @@ -92,6 +93,10 @@ NinePixelShader9_UpdateKey( struct NinePixelShader9 *ps, key |= ((uint64_t)state->rs[D3DRS_FOGTABLEMODE]) << 33; } + /* centroid interpolation automatically used for color ps inputs */ + if (state->rt[0]->desc.MultiSampleType > 1) + key |= ((uint64_t)1) << 34; + if (unlikely(ps->byte_code.version < 0x14)) { projected = nine_ff_get_projected_key(state); key |= ((uint64_t) projected) << 48; diff --git a/src/gallium/state_trackers/nine/resource9.c b/src/gallium/state_trackers/nine/resource9.c index 6d915338b24..b929c50a83c 100644 --- a/src/gallium/state_trackers/nine/resource9.c +++ b/src/gallium/state_trackers/nine/resource9.c @@ -29,12 +29,12 @@ #include "util/u_hash_table.h" #include "util/u_inlines.h" +#include "util/u_resource.h" #include "nine_pdata.h" #define DBG_CHANNEL DBG_RESOURCE - HRESULT NineResource9_ctor( struct NineResource9 *This, struct NineUnknownParams *pParams, @@ -62,6 +62,33 @@ NineResource9_ctor( struct NineResource9 *This, if (Allocate) { assert(!initResource); + + /* On Windows it is possible allocation fails when + * IDirect3DDevice9::GetAvailableTextureMem() still reports + * enough free space. + * + * Some games allocate surfaces + * in a loop until they receive D3DERR_OUTOFVIDEOMEMORY to measure + * the available texture memory size. + * + * We are not using the drivers VRAM statistics because: + * * This would add overhead to each resource allocation. + * * Freeing memory is lazy and takes some time, but applications + * expects the memory counter to change immediately after allocating + * or freeing memory. + * + * Vertexbuffers and indexbuffers are not accounted ! + */ + if (This->info.target != PIPE_BUFFER) { + This->size = util_resource_size(&This->info); + + This->base.device->available_texture_mem -= This->size; + if (This->base.device->available_texture_mem <= + This->base.device->available_texture_limit) { + return D3DERR_OUTOFVIDEOMEMORY; + } + } + DBG("(%p) Creating pipe_resource.\n", This); This->resource = screen->resource_create(screen, &This->info); if (!This->resource) @@ -92,6 +119,10 @@ NineResource9_dtor( struct NineResource9 *This ) * still hold a reference. */ pipe_resource_reference(&This->resource, NULL); + /* NOTE: size is 0, unless something has actually been allocated */ + if (This->base.device) + This->base.device->available_texture_mem += This->size; + NineUnknown_dtor(&This->base); } @@ -117,9 +148,10 @@ NineResource9_SetPrivateData( struct NineResource9 *This, enum pipe_error err; struct pheader *header; const void *user_data = pData; + char guid_str[64]; - DBG("This=%p refguid=%p pData=%p SizeOfData=%u Flags=%x\n", - This, refguid, pData, SizeOfData, Flags); + DBG("This=%p GUID=%s pData=%p SizeOfData=%u Flags=%x\n", + This, GUID_sprintf(guid_str, refguid), pData, SizeOfData, Flags); if (Flags & D3DSPD_IUNKNOWN) user_assert(SizeOfData == sizeof(IUnknown *), D3DERR_INVALIDCALL); @@ -141,8 +173,9 @@ NineResource9_SetPrivateData( struct NineResource9 *This, header->size = SizeOfData; memcpy(header->data, user_data, header->size); + memcpy(&header->guid, refguid, sizeof(header->guid)); - err = util_hash_table_set(This->pdata, refguid, header); + err = util_hash_table_set(This->pdata, &header->guid, header); if (err == PIPE_OK) { if (header->unknown) { IUnknown_AddRef(*(IUnknown **)header->data); } return D3D_OK; @@ -162,9 +195,10 @@ NineResource9_GetPrivateData( struct NineResource9 *This, { struct pheader *header; DWORD sizeofdata; + char guid_str[64]; - DBG("This=%p refguid=%p pData=%p pSizeOfData=%p\n", - This, refguid, pData, pSizeOfData); + DBG("This=%p GUID=%s pData=%p pSizeOfData=%p\n", + This, GUID_sprintf(guid_str, refguid), pData, pSizeOfData); header = util_hash_table_get(This->pdata, refguid); if (!header) { return D3DERR_NOTFOUND; } @@ -191,8 +225,9 @@ NineResource9_FreePrivateData( struct NineResource9 *This, REFGUID refguid ) { struct pheader *header; + char guid_str[64]; - DBG("This=%p refguid=%p\n", This, refguid); + DBG("This=%p GUID=%s\n", This, GUID_sprintf(guid_str, refguid)); header = util_hash_table_get(This->pdata, refguid); if (!header) diff --git a/src/gallium/state_trackers/nine/resource9.h b/src/gallium/state_trackers/nine/resource9.h index 906f90806ce..8122257b7a7 100644 --- a/src/gallium/state_trackers/nine/resource9.h +++ b/src/gallium/state_trackers/nine/resource9.h @@ -45,6 +45,8 @@ struct NineResource9 /* for [GS]etPrivateData/FreePrivateData */ struct util_hash_table *pdata; + + long long size; }; static inline struct NineResource9 * NineResource9( void *data ) diff --git a/src/gallium/state_trackers/nine/stateblock9.c b/src/gallium/state_trackers/nine/stateblock9.c index 6d6e1be0b7f..0d1a04b657a 100644 --- a/src/gallium/state_trackers/nine/stateblock9.c +++ b/src/gallium/state_trackers/nine/stateblock9.c @@ -24,6 +24,7 @@ #include "device9.h" #include "basetexture9.h" #include "nine_helpers.h" +#include "vertexdeclaration9.h" #define DBG_CHANNEL DBG_STATEBLOCK @@ -179,6 +180,7 @@ nine_state_copy_common(struct nine_state *dst, const int r = ffs(m) - 1; m &= ~(1 << r); dst->rs[i * 32 + r] = src->rs[i * 32 + r]; + dst->rs_advertised[i * 32 + r] = src->rs_advertised[i * 32 + r]; } } @@ -223,7 +225,7 @@ nine_state_copy_common(struct nine_state *dst, nine_bind(&dst->stream[i], src->stream[i]); if (src->stream[i]) { dst->vtxbuf[i].buffer_offset = src->vtxbuf[i].buffer_offset; - dst->vtxbuf[i].buffer = src->vtxbuf[i].buffer; + pipe_resource_reference(&dst->vtxbuf[i].buffer, src->vtxbuf[i].buffer); dst->vtxbuf[i].stride = src->vtxbuf[i].stride; } } @@ -269,6 +271,10 @@ nine_state_copy_common(struct nine_state *dst, dst->ff.light = REALLOC(dst->ff.light, dst->ff.num_lights * sizeof(D3DLIGHT9), mask->ff.num_lights * sizeof(D3DLIGHT9)); + for (i = dst->ff.num_lights; i < mask->ff.num_lights; ++i) { + memset(&dst->ff.light[i], 0, sizeof(D3DLIGHT9)); + dst->ff.light[i].Type = (D3DLIGHTTYPE)NINED3DLIGHT_INVALID; + } dst->ff.num_lights = mask->ff.num_lights; } for (i = 0; i < mask->ff.num_lights; ++i) @@ -353,6 +359,7 @@ nine_state_copy_common_all(struct nine_state *dst, /* Render states. */ memcpy(dst->rs, src->rs, sizeof(dst->rs)); + memcpy(dst->rs_advertised, src->rs_advertised, sizeof(dst->rs_advertised)); if (apply) memcpy(dst->changed.rs, src->changed.rs, sizeof(dst->changed.rs)); @@ -377,7 +384,7 @@ nine_state_copy_common_all(struct nine_state *dst, nine_bind(&dst->stream[i], src->stream[i]); if (src->stream[i]) { dst->vtxbuf[i].buffer_offset = src->vtxbuf[i].buffer_offset; - dst->vtxbuf[i].buffer = src->vtxbuf[i].buffer; + pipe_resource_reference(&dst->vtxbuf[i].buffer, src->vtxbuf[i].buffer); dst->vtxbuf[i].stride = src->vtxbuf[i].stride; } dst->stream_freq[i] = src->stream_freq[i]; @@ -486,7 +493,10 @@ NineStateBlock9_Apply( struct NineStateBlock9 *This ) nine_state_copy_common(dst, src, src, TRUE, pool); if ((src->changed.group & NINE_STATE_VDECL) && src->vdecl) - nine_bind(&dst->vdecl, src->vdecl); + NineDevice9_SetVertexDeclaration(This->base.device, (IDirect3DVertexDeclaration9 *)src->vdecl); + + /* Recomputing it is needed if we changed vs but not vdecl */ + dst->programmable_vs = dst->vs && !(dst->vdecl && dst->vdecl->position_t); /* Textures */ if (src->changed.texture) { diff --git a/src/gallium/state_trackers/nine/surface9.c b/src/gallium/state_trackers/nine/surface9.c index 14c1ce927ad..f88b75c3dd7 100644 --- a/src/gallium/state_trackers/nine/surface9.c +++ b/src/gallium/state_trackers/nine/surface9.c @@ -56,6 +56,9 @@ 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; DBG("This=%p pDevice=%p pResource=%p Level=%u Layer=%u pDesc=%p\n", This, pParams->device, pResource, Level, Layer, pDesc); @@ -140,6 +143,12 @@ NineSurface9_ctor( struct NineSurface9 *This, if (pResource && NineSurface9_IsOffscreenPlain(This)) pResource->flags |= NINE_RESOURCE_FLAG_LOCKABLE; + /* 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); + } + NineSurface9_Dump(This); return D3D_OK; @@ -156,7 +165,7 @@ NineSurface9_dtor( struct NineSurface9 *This ) /* 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); NineResource9_dtor(&This->base); } @@ -348,7 +357,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 && @@ -384,8 +393,8 @@ NineSurface9_LockRect( struct NineSurface9 *This, * 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)) { - pLockedRect->Pitch = This->desc.Height; - pLockedRect->pBits = This->data + box.y * This->desc.Height + box.x; + pLockedRect->Pitch = This->desc.Width; + pLockedRect->pBits = This->data + box.y * This->desc.Width + box.x; } else { pLockedRect->Pitch = This->stride; pLockedRect->pBits = NineSurface9_GetSystemMemPointer(This, diff --git a/src/gallium/state_trackers/nine/swapchain9.c b/src/gallium/state_trackers/nine/swapchain9.c index 3b1a7a4493c..82d4173fbb2 100644 --- a/src/gallium/state_trackers/nine/swapchain9.c +++ b/src/gallium/state_trackers/nine/swapchain9.c @@ -118,6 +118,14 @@ NineSwapChain9_Resize( struct NineSwapChain9 *This, DBG("This=%p pParams=%p\n", This, pParams); user_assert(pParams != NULL, E_POINTER); + user_assert(pParams->SwapEffect, D3DERR_INVALIDCALL); + user_assert((pParams->SwapEffect != D3DSWAPEFFECT_COPY) || + (pParams->BackBufferCount <= 1), D3DERR_INVALIDCALL); + user_assert(pDevice->ex || pParams->BackBufferCount <= 3, D3DERR_INVALIDCALL); + user_assert(pDevice->ex || + (pParams->SwapEffect == D3DSWAPEFFECT_FLIP) || + (pParams->SwapEffect == D3DSWAPEFFECT_COPY) || + (pParams->SwapEffect == D3DSWAPEFFECT_DISCARD), D3DERR_INVALIDCALL); DBG("pParams(%p):\n" "BackBufferWidth: %u\n" @@ -145,11 +153,6 @@ NineSwapChain9_Resize( struct NineSwapChain9 *This, pParams->FullScreen_RefreshRateInHz, pParams->PresentationInterval); - if (pParams->SwapEffect == D3DSWAPEFFECT_COPY && - pParams->BackBufferCount > 1) { - pParams->BackBufferCount = 1; - } - if (pParams->BackBufferCount > 3) { pParams->BackBufferCount = 3; } @@ -713,6 +716,10 @@ present( struct NineSwapChain9 *This, This->pipe->blit(This->pipe, &blit); } + /* The resource we present has to resolve fast clears + * if needed (and other things) */ + This->pipe->flush_resource(This->pipe, resource); + if (This->params.SwapEffect != D3DSWAPEFFECT_DISCARD) handle_draw_cursor_and_hud(This, resource); @@ -738,12 +745,6 @@ bypass_rendering: return D3DERR_WASSTILLDRAWING; } - if (This->present_buffers) - resource = This->present_buffers[0]; - else - resource = This->buffers[0]->base.resource; - This->pipe->flush_resource(This->pipe, resource); - if (!This->enable_threadpool) { This->tasks[0]=NULL; fence = swap_fences_pop_front(This); @@ -786,6 +787,19 @@ NineSwapChain9_Present( struct NineSwapChain9 *This, if (hr == D3DERR_WASSTILLDRAWING) return hr; + if (This->base.device->ex) { + if (NineSwapChain9_GetOccluded(This)) { + return S_PRESENT_OCCLUDED; + } + } else { + if (NineSwapChain9_GetOccluded(This)) { + This->base.device->device_needs_reset = TRUE; + } + if (This->base.device->device_needs_reset) { + return D3DERR_DEVICELOST; + } + } + switch (This->params.SwapEffect) { case D3DSWAPEFFECT_FLIP: UNTESTED(4); @@ -840,7 +854,6 @@ NineSwapChain9_Present( struct NineSwapChain9 *This, ID3DPresent_WaitBufferReleased(This->present, This->present_handles[0]); This->base.device->state.changed.group |= NINE_STATE_FB; - nine_update_state_framebuffer(This->base.device); return hr; } @@ -907,8 +920,9 @@ NineSwapChain9_GetBackBuffer( struct NineSwapChain9 *This, DBG("GetBackBuffer: This=%p iBackBuffer=%d Type=%d ppBackBuffer=%p\n", This, iBackBuffer, Type, ppBackBuffer); (void)user_error(Type == D3DBACKBUFFER_TYPE_MONO); + /* don't touch ppBackBuffer on error */ + user_assert(ppBackBuffer != NULL, D3DERR_INVALIDCALL); user_assert(iBackBuffer < This->params.BackBufferCount, D3DERR_INVALIDCALL); - user_assert(ppBackBuffer != NULL, E_POINTER); NineUnknown_AddRef(NineUnknown(This->buffers[iBackBuffer])); *ppBackBuffer = (IDirect3DSurface9 *)This->buffers[iBackBuffer]; @@ -990,3 +1004,13 @@ NineSwapChain9_new( struct NineDevice9 *pDevice, implicit, pPresent, pPresentationParameters, pCTX, hFocusWindow, NULL); } + +BOOL +NineSwapChain9_GetOccluded( struct NineSwapChain9 *This ) +{ + if (This->base.device->minor_version_num > 0) { + return ID3DPresent_GetWindowOccluded(This->present); + } + + return FALSE; +} diff --git a/src/gallium/state_trackers/nine/swapchain9.h b/src/gallium/state_trackers/nine/swapchain9.h index 5e48dde5004..4bd74f7b6ec 100644 --- a/src/gallium/state_trackers/nine/swapchain9.h +++ b/src/gallium/state_trackers/nine/swapchain9.h @@ -139,4 +139,7 @@ HRESULT WINAPI NineSwapChain9_GetPresentParameters( struct NineSwapChain9 *This, D3DPRESENT_PARAMETERS *pPresentationParameters ); +BOOL +NineSwapChain9_GetOccluded( struct NineSwapChain9 *This ); + #endif /* _NINE_SWAPCHAIN9_H_ */ diff --git a/src/gallium/state_trackers/nine/texture9.c b/src/gallium/state_trackers/nine/texture9.c index bc325c1335e..ada08cea90a 100644 --- a/src/gallium/state_trackers/nine/texture9.c +++ b/src/gallium/state_trackers/nine/texture9.c @@ -235,7 +235,7 @@ NineTexture9_dtor( struct NineTexture9 *This ) } if (This->managed_buffer) - FREE(This->managed_buffer); + align_free(This->managed_buffer); NineBaseTexture9_dtor(&This->base); } diff --git a/src/gallium/state_trackers/nine/vertexbuffer9.c b/src/gallium/state_trackers/nine/vertexbuffer9.c index 8e2eaaf8ff9..10311b428fe 100644 --- a/src/gallium/state_trackers/nine/vertexbuffer9.c +++ b/src/gallium/state_trackers/nine/vertexbuffer9.c @@ -39,56 +39,13 @@ NineVertexBuffer9_ctor( struct NineVertexBuffer9 *This, struct NineUnknownParams *pParams, D3DVERTEXBUFFER_DESC *pDesc ) { - struct pipe_resource *info = &This->base.info; HRESULT hr; DBG("This=%p Size=0x%x Usage=%x Pool=%u\n", This, pDesc->Size, pDesc->Usage, pDesc->Pool); - user_assert(pDesc->Pool != D3DPOOL_SCRATCH, D3DERR_INVALIDCALL); - - This->maps = MALLOC(sizeof(struct pipe_transfer *)); - if (!This->maps) - return E_OUTOFMEMORY; - This->nmaps = 0; - This->maxmaps = 1; - - This->pipe = pParams->device->pipe; - - info->screen = pParams->device->screen; - info->target = PIPE_BUFFER; - info->format = PIPE_FORMAT_R8_UNORM; - info->width0 = pDesc->Size; - info->flags = 0; - - info->bind = PIPE_BIND_VERTEX_BUFFER | PIPE_BIND_TRANSFER_WRITE; - if (!(pDesc->Usage & D3DUSAGE_WRITEONLY)) - info->bind |= PIPE_BIND_TRANSFER_READ; - - info->usage = PIPE_USAGE_DEFAULT; - if (pDesc->Usage & D3DUSAGE_DYNAMIC) - info->usage = PIPE_USAGE_STREAM; - if (pDesc->Pool == D3DPOOL_SYSTEMMEM) - info->usage = PIPE_USAGE_STAGING; - - /* if (pDesc->Usage & D3DUSAGE_DONOTCLIP) { } */ - /* if (pDesc->Usage & D3DUSAGE_NONSECURE) { } */ - /* if (pDesc->Usage & D3DUSAGE_NPATCHES) { } */ - /* if (pDesc->Usage & D3DUSAGE_POINTS) { } */ - /* if (pDesc->Usage & D3DUSAGE_RTPATCHES) { } */ - if (pDesc->Usage & D3DUSAGE_SOFTWAREPROCESSING) - DBG("Application asked for Software Vertex Processing, " - "but this is unimplemented\n"); - /* if (pDesc->Usage & D3DUSAGE_TEXTAPI) { } */ - - info->height0 = 1; - info->depth0 = 1; - info->array_size = 1; - info->last_level = 0; - info->nr_samples = 0; - - hr = NineResource9_ctor(&This->base, pParams, NULL, TRUE, - D3DRTYPE_VERTEXBUFFER, pDesc->Pool, pDesc->Usage); + hr = NineBuffer9_ctor(&This->base, pParams, D3DRTYPE_VERTEXBUFFER, + pDesc->Usage, pDesc->Size, pDesc->Pool); if (FAILED(hr)) return hr; @@ -102,85 +59,29 @@ NineVertexBuffer9_ctor( struct NineVertexBuffer9 *This, void NineVertexBuffer9_dtor( struct NineVertexBuffer9 *This ) { - if (This->maps) { - while (This->nmaps) { - NineVertexBuffer9_Unlock(This); - } - FREE(This->maps); - } - - NineResource9_dtor(&This->base); + NineBuffer9_dtor(&This->base); +} + +struct pipe_resource * +NineVertexBuffer9_GetResource( struct NineVertexBuffer9 *This ) +{ + return NineBuffer9_GetResource(&This->base); } HRESULT WINAPI NineVertexBuffer9_Lock( struct NineVertexBuffer9 *This, - UINT OffsetToLock, - UINT SizeToLock, - void **ppbData, - DWORD Flags ) + UINT OffsetToLock, + UINT SizeToLock, + void **ppbData, + DWORD Flags ) { - struct pipe_box box; - void *data; - const unsigned usage = d3dlock_buffer_to_pipe_transfer_usage(Flags); - - DBG("This=%p(pipe=%p) OffsetToLock=0x%x, SizeToLock=0x%x, Flags=0x%x\n", - This, This->base.resource, - OffsetToLock, SizeToLock, Flags); - - user_assert(ppbData, E_POINTER); - user_assert(!(Flags & ~(D3DLOCK_DISCARD | - D3DLOCK_DONOTWAIT | - D3DLOCK_NO_DIRTY_UPDATE | - D3DLOCK_NOSYSLOCK | - D3DLOCK_READONLY | - D3DLOCK_NOOVERWRITE)), D3DERR_INVALIDCALL); - - if (This->nmaps == This->maxmaps) { - struct pipe_transfer **newmaps = - REALLOC(This->maps, sizeof(struct pipe_transfer *)*This->maxmaps, - sizeof(struct pipe_transfer *)*(This->maxmaps << 1)); - if (newmaps == NULL) - return E_OUTOFMEMORY; - - This->maxmaps <<= 1; - This->maps = newmaps; - } - - if (SizeToLock == 0) { - SizeToLock = This->desc.Size - OffsetToLock; - user_warn(OffsetToLock != 0); - } - - u_box_1d(OffsetToLock, SizeToLock, &box); - - data = This->pipe->transfer_map(This->pipe, This->base.resource, 0, - usage, &box, &This->maps[This->nmaps]); - if (!data) { - DBG("pipe::transfer_map failed\n" - " usage = %x\n" - " box.x = %u\n" - " box.width = %u\n", - usage, box.x, box.width); - /* not sure what to return, msdn suggests this */ - if (Flags & D3DLOCK_DONOTWAIT) - return D3DERR_WASSTILLDRAWING; - return D3DERR_INVALIDCALL; - } - - This->nmaps++; - *ppbData = data; - - return D3D_OK; + return NineBuffer9_Lock(&This->base, OffsetToLock, SizeToLock, ppbData, Flags); } HRESULT WINAPI NineVertexBuffer9_Unlock( struct NineVertexBuffer9 *This ) { - DBG("This=%p\n", This); - - user_assert(This->nmaps > 0, D3DERR_INVALIDCALL); - This->pipe->transfer_unmap(This->pipe, This->maps[--(This->nmaps)]); - return D3D_OK; + return NineBuffer9_Unlock(&This->base); } HRESULT WINAPI diff --git a/src/gallium/state_trackers/nine/vertexbuffer9.h b/src/gallium/state_trackers/nine/vertexbuffer9.h index 6174de4df08..859402b925b 100644 --- a/src/gallium/state_trackers/nine/vertexbuffer9.h +++ b/src/gallium/state_trackers/nine/vertexbuffer9.h @@ -22,8 +22,8 @@ #ifndef _NINE_VERTEXBUFFER9_H_ #define _NINE_VERTEXBUFFER9_H_ - #include "resource9.h" +#include "buffer9.h" struct pipe_screen; struct pipe_context; @@ -31,13 +31,10 @@ struct pipe_transfer; struct NineVertexBuffer9 { - struct NineResource9 base; + struct NineBuffer9 base; /* G3D */ struct pipe_context *pipe; - struct pipe_transfer **maps; - int nmaps, maxmaps; - D3DVERTEXBUFFER_DESC desc; }; static inline struct NineVertexBuffer9 * @@ -58,6 +55,12 @@ NineVertexBuffer9_ctor( struct NineVertexBuffer9 *This, void NineVertexBuffer9_dtor( struct NineVertexBuffer9 *This ); +/*** Nine private ***/ + +struct pipe_resource * +NineVertexBuffer9_GetResource( struct NineVertexBuffer9 *This ); + +/*** Direct3D public ***/ HRESULT WINAPI NineVertexBuffer9_Lock( struct NineVertexBuffer9 *This, diff --git a/src/gallium/state_trackers/nine/vertexdeclaration9.c b/src/gallium/state_trackers/nine/vertexdeclaration9.c index 2047b91abc4..36c594b5be3 100644 --- a/src/gallium/state_trackers/nine/vertexdeclaration9.c +++ b/src/gallium/state_trackers/nine/vertexdeclaration9.c @@ -174,24 +174,24 @@ NineVertexDeclaration9_ctor( struct NineVertexDeclaration9 *This, const D3DVERTEXELEMENT9 *pElements ) { const D3DCAPS9 *caps; - unsigned i; - + unsigned i, nelems; DBG("This=%p pParams=%p pElements=%p\n", This, pParams, pElements); - HRESULT hr = NineUnknown_ctor(&This->base, pParams); - if (FAILED(hr)) { return hr; } - /* wine */ - for (This->nelems = 0; - pElements[This->nelems].Stream != 0xFF; - ++This->nelems) { - user_assert(pElements[This->nelems].Type != D3DDECLTYPE_UNUSED, E_FAIL); - user_assert(!(pElements[This->nelems].Offset & 3), E_FAIL); + for (nelems = 0; + pElements[nelems].Stream != 0xFF; + ++nelems) { + user_assert(pElements[nelems].Type != D3DDECLTYPE_UNUSED, E_FAIL); + user_assert(!(pElements[nelems].Offset & 3), E_FAIL); } - caps = NineDevice9_GetCaps(This->base.device); - user_assert(This->nelems <= caps->MaxStreams, D3DERR_INVALIDCALL); + caps = NineDevice9_GetCaps(pParams->device); + user_assert(nelems <= caps->MaxStreams, D3DERR_INVALIDCALL); + HRESULT hr = NineUnknown_ctor(&This->base, pParams); + if (FAILED(hr)) { return hr; } + + This->nelems = nelems; This->decls = CALLOC(This->nelems+1, sizeof(D3DVERTEXELEMENT9)); This->elems = CALLOC(This->nelems, sizeof(struct pipe_vertex_element)); This->usage_map = CALLOC(This->nelems, sizeof(uint16_t)); @@ -203,6 +203,9 @@ NineVertexDeclaration9_ctor( struct NineVertexDeclaration9 *This, This->decls[i].UsageIndex); This->usage_map[i] = usage; + if (This->decls[i].Usage == D3DDECLUSAGE_POSITIONT) + This->position_t = TRUE; + This->elems[i].src_offset = This->decls[i].Offset; This->elems[i].instance_divisor = 0; This->elems[i].vertex_buffer_index = This->decls[i].Stream; diff --git a/src/gallium/state_trackers/nine/vertexdeclaration9.h b/src/gallium/state_trackers/nine/vertexdeclaration9.h index 655bcfbf165..e39f259440f 100644 --- a/src/gallium/state_trackers/nine/vertexdeclaration9.h +++ b/src/gallium/state_trackers/nine/vertexdeclaration9.h @@ -46,6 +46,8 @@ struct NineVertexDeclaration9 D3DVERTEXELEMENT9 *decls; DWORD fvf; + + BOOL position_t; }; static inline struct NineVertexDeclaration9 * NineVertexDeclaration9( void *data ) diff --git a/src/gallium/state_trackers/nine/volume9.c b/src/gallium/state_trackers/nine/volume9.c index 0b9005685a9..f6988923caa 100644 --- a/src/gallium/state_trackers/nine/volume9.c +++ b/src/gallium/state_trackers/nine/volume9.c @@ -136,7 +136,7 @@ NineVolume9_dtor( struct NineVolume9 *This ) NineVolume9_UnlockBox(This); if (This->data) - FREE(This->data); + align_free(This->data); pipe_resource_reference(&This->resource, NULL); @@ -264,6 +264,13 @@ NineVolume9_LockBox( struct NineVolume9 *This, usage |= PIPE_TRANSFER_DONTBLOCK; if (pBox) { + user_assert(pBox->Right > pBox->Left, D3DERR_INVALIDCALL); + user_assert(pBox->Bottom > pBox->Top, D3DERR_INVALIDCALL); + user_assert(pBox->Back > pBox->Front, D3DERR_INVALIDCALL); + user_assert(pBox->Right <= This->desc.Width, D3DERR_INVALIDCALL); + user_assert(pBox->Bottom <= This->desc.Height, D3DERR_INVALIDCALL); + user_assert(pBox->Back <= This->desc.Depth, D3DERR_INVALIDCALL); + d3dbox_to_pipe_box(&box, pBox); if (u_box_clip_2d(&box, &box, This->desc.Width, This->desc.Height) < 0) { DBG("Locked volume intersection empty.\n"); diff --git a/src/gallium/state_trackers/omx/vid_dec_h264.c b/src/gallium/state_trackers/omx/vid_dec_h264.c index f66ed896e62..b4536828909 100644 --- a/src/gallium/state_trackers/omx/vid_dec_h264.c +++ b/src/gallium/state_trackers/omx/vid_dec_h264.c @@ -35,6 +35,7 @@ #include "util/u_memory.h" #include "util/u_video.h" #include "vl/vl_rbsp.h" +#include "vl/vl_zscan.h" #include "entrypoint.h" #include "vid_dec.h" @@ -205,6 +206,7 @@ static void scaling_list(struct vl_rbsp *rbsp, uint8_t *scalingList, unsigned si const uint8_t *defaultList, const uint8_t *fallbackList) { unsigned lastScale = 8, nextScale = 8; + const int *list; unsigned i; /* (pic|seq)_scaling_list_present_flag[i] */ @@ -214,6 +216,7 @@ static void scaling_list(struct vl_rbsp *rbsp, uint8_t *scalingList, unsigned si return; } + list = (sizeOfScalingList == 16) ? vl_zscan_normal_16 : vl_zscan_normal; for (i = 0; i < sizeOfScalingList; ++i ) { if (nextScale != 0) { @@ -224,8 +227,8 @@ static void scaling_list(struct vl_rbsp *rbsp, uint8_t *scalingList, unsigned si return; } } - scalingList[i] = nextScale == 0 ? lastScale : nextScale; - lastScale = scalingList[i]; + scalingList[list[i]] = nextScale == 0 ? lastScale : nextScale; + lastScale = scalingList[list[i]]; } } |