summaryrefslogtreecommitdiffstats
path: root/src/gallium/state_trackers
diff options
context:
space:
mode:
authorJason Ekstrand <[email protected]>2016-02-05 15:21:11 -0800
committerJason Ekstrand <[email protected]>2016-02-05 15:21:11 -0800
commit9401516113152ea2a571dc1103a2fa7ce68d4ee8 (patch)
tree2472a42bd85a3d3b9697be9235c029099c3d575d /src/gallium/state_trackers
parent741744f691d6ef63e9f9a4c03136f969f2ffb0bf (diff)
parent5b51b2e00013af70072106e9d34905326fc357fc (diff)
Merge remote-tracking branch 'mesa-public/master' into vulkan
Diffstat (limited to 'src/gallium/state_trackers')
-rw-r--r--src/gallium/state_trackers/nine/Makefile.sources2
-rw-r--r--src/gallium/state_trackers/nine/adapter9.c11
-rw-r--r--src/gallium/state_trackers/nine/basetexture9.c2
-rw-r--r--src/gallium/state_trackers/nine/buffer9.c189
-rw-r--r--src/gallium/state_trackers/nine/buffer9.h73
-rw-r--r--src/gallium/state_trackers/nine/cubetexture9.c2
-rw-r--r--src/gallium/state_trackers/nine/device9.c142
-rw-r--r--src/gallium/state_trackers/nine/device9.h12
-rw-r--r--src/gallium/state_trackers/nine/device9ex.c58
-rw-r--r--src/gallium/state_trackers/nine/device9ex.h17
-rw-r--r--src/gallium/state_trackers/nine/guid.c18
-rw-r--r--src/gallium/state_trackers/nine/guid.h4
-rw-r--r--src/gallium/state_trackers/nine/indexbuffer9.c101
-rw-r--r--src/gallium/state_trackers/nine/indexbuffer9.h9
-rw-r--r--src/gallium/state_trackers/nine/nine_ff.c85
-rw-r--r--src/gallium/state_trackers/nine/nine_limits.h211
-rw-r--r--src/gallium/state_trackers/nine/nine_pdata.h1
-rw-r--r--src/gallium/state_trackers/nine/nine_pipe.c11
-rw-r--r--src/gallium/state_trackers/nine/nine_shader.c57
-rw-r--r--src/gallium/state_trackers/nine/nine_shader.h1
-rw-r--r--src/gallium/state_trackers/nine/nine_state.c49
-rw-r--r--src/gallium/state_trackers/nine/nine_state.h39
-rw-r--r--src/gallium/state_trackers/nine/pixelshader9.c1
-rw-r--r--src/gallium/state_trackers/nine/pixelshader9.h5
-rw-r--r--src/gallium/state_trackers/nine/resource9.c49
-rw-r--r--src/gallium/state_trackers/nine/resource9.h2
-rw-r--r--src/gallium/state_trackers/nine/stateblock9.c16
-rw-r--r--src/gallium/state_trackers/nine/surface9.c17
-rw-r--r--src/gallium/state_trackers/nine/swapchain9.c50
-rw-r--r--src/gallium/state_trackers/nine/swapchain9.h3
-rw-r--r--src/gallium/state_trackers/nine/texture9.c2
-rw-r--r--src/gallium/state_trackers/nine/vertexbuffer9.c129
-rw-r--r--src/gallium/state_trackers/nine/vertexbuffer9.h13
-rw-r--r--src/gallium/state_trackers/nine/vertexdeclaration9.c27
-rw-r--r--src/gallium/state_trackers/nine/vertexdeclaration9.h2
-rw-r--r--src/gallium/state_trackers/nine/volume9.c9
-rw-r--r--src/gallium/state_trackers/omx/vid_dec_h264.c7
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, &params, &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, &params, &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]];
}
}