#endif
-static void
+void
NineDevice9_SetDefaultState( struct NineDevice9 *This, boolean is_reset )
{
struct NineSurface9 *refSurf = NULL;
ID3DPresentGroup *pPresentationGroup,
struct d3dadapter9_context *pCTX,
boolean ex,
- D3DDISPLAYMODEEX *pFullscreenDisplayMode )
+ D3DDISPLAYMODEEX *pFullscreenDisplayMode,
+ int minorVersionNum )
{
unsigned i;
HRESULT hr = NineUnknown_ctor(&This->base, pParams);
This->params = *pCreationParameters;
This->ex = ex;
This->present = pPresentationGroup;
+ This->minor_version_num = minorVersionNum;
+
IDirect3D9_AddRef(This->d3d9);
ID3DPresentGroup_AddRef(This->present);
if (This->params.BehaviorFlags & D3DCREATE_MIXED_VERTEXPROCESSING)
DBG("Application asked mixed Software Vertex Processing. Ignoring.\n");
- This->pipe = This->screen->context_create(This->screen, NULL);
+ This->pipe = This->screen->context_create(This->screen, NULL, 0);
if (!This->pipe) { return E_OUTOFMEMORY; } /* guess */
This->cso = cso_create_context(This->pipe);
if (strstr(pScreen->get_name(pScreen), "AMD") ||
strstr(pScreen->get_name(pScreen), "ATI")) {
- This->prefer_user_constbuf = TRUE;
This->driver_bugs.buggy_barycentrics = TRUE;
}
+ /* Disable NV path for now, needs some fixes */
+ This->prefer_user_constbuf = TRUE;
+
tmpl.target = PIPE_BUFFER;
tmpl.format = PIPE_FORMAT_R8_UNORM;
tmpl.height0 = 1;
This->driver_caps.user_cbufs = GET_PCAP(USER_CONSTANT_BUFFERS);
if (!This->driver_caps.user_vbufs)
- This->vertex_uploader = u_upload_create(This->pipe, 65536, 4, PIPE_BIND_VERTEX_BUFFER);
+ This->vertex_uploader = u_upload_create(This->pipe, 65536,
+ PIPE_BIND_VERTEX_BUFFER, PIPE_USAGE_STREAM);
if (!This->driver_caps.user_ibufs)
- This->index_uploader = u_upload_create(This->pipe, 128 * 1024, 4, PIPE_BIND_INDEX_BUFFER);
+ This->index_uploader = u_upload_create(This->pipe, 128 * 1024,
+ PIPE_BIND_INDEX_BUFFER, PIPE_USAGE_STREAM);
if (!This->driver_caps.user_cbufs) {
- unsigned alignment = GET_PCAP(CONSTANT_BUFFER_OFFSET_ALIGNMENT);
-
+ This->constbuf_alignment = GET_PCAP(CONSTANT_BUFFER_OFFSET_ALIGNMENT);
This->constbuf_uploader = u_upload_create(This->pipe, This->vs_const_size,
- alignment, PIPE_BIND_CONSTANT_BUFFER);
+ PIPE_BIND_CONSTANT_BUFFER, PIPE_USAGE_STREAM);
}
This->driver_caps.window_space_position_support = GET_PCAP(TGSI_VS_WINDOW_SPACE_POSITION);
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);
}
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
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);
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);
This, 0, (IDirect3DSurface9 *)This->swapchains[0]->buffers[0]);
/* XXX: better use GetBackBuffer here ? */
+ This->device_needs_reset = (hr != D3D_OK);
return hr;
}
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],
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;
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 &&
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 ||
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;
Count = 0;
#endif
+ nine_update_state_framebuffer(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;
/* 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");
u_upload_data(This->vertex_uploader,
0,
(info.max_index + 1) * VertexStreamZeroStride, /* XXX */
+ 4,
vtxbuf.user_buffer,
&vtxbuf.buffer_offset,
&vtxbuf.buffer);
base,
(info.max_index -
info.min_index + 1) * VertexStreamZeroStride, /* XXX */
+ 4,
(const uint8_t *)vbuf.user_buffer + base,
&vbuf.buffer_offset,
&vbuf.buffer);
u_upload_data(This->index_uploader,
0,
info.count * ibuf.index_size,
+ 4,
ibuf.user_buffer,
&ibuf.offset,
&ibuf.buffer);
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,
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;
IDirect3DVertexShader9 *pShader )
{
struct nine_state *state = This->update;
+ BOOL was_programmable_vs = This->state.programmable_vs;
DBG("This=%p pShader=%p\n", This, pShader);
- /* ff -> non-ff: commit back non-ff constants */
- if (!state->vs && pShader)
- state->commit |= NINE_STATE_COMMIT_CONST_VS;
+ 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 (!was_programmable_vs && This->state.programmable_vs)
+ state->commit |= NINE_STATE_COMMIT_CONST_VS;
+
state->changed.group |= NINE_STATE_VS;
return D3D_OK;
return D3D_OK;
user_assert(pConstantData, D3DERR_INVALIDCALL);
+ if (!This->is_recording) {
+ if (!memcmp(&state->vs_const_f[StartRegister * 4], pConstantData,
+ Vector4fCount * 4 * sizeof(state->vs_const_f[0])))
+ return D3D_OK;
+ }
+
memcpy(&state->vs_const_f[StartRegister * 4],
pConstantData,
Vector4fCount * 4 * sizeof(state->vs_const_f[0]));
user_assert(pConstantData, D3DERR_INVALIDCALL);
if (This->driver_caps.vs_integer) {
+ if (!This->is_recording) {
+ if (!memcmp(&state->vs_const_i[StartRegister][0], pConstantData,
+ Vector4iCount * sizeof(state->vs_const_i[0])))
+ return D3D_OK;
+ }
memcpy(&state->vs_const_i[StartRegister][0],
pConstantData,
Vector4iCount * sizeof(state->vs_const_i[0]));
user_assert(StartRegister + BoolCount <= NINE_MAX_CONST_B, D3DERR_INVALIDCALL);
user_assert(pConstantData, D3DERR_INVALIDCALL);
+ if (!This->is_recording) {
+ bool noChange = true;
+ for (i = 0; i < BoolCount; i++) {
+ if (!!state->vs_const_b[StartRegister + i] != !!pConstantData[i])
+ noChange = false;
+ }
+ if (noChange)
+ return D3D_OK;
+ }
+
for (i = 0; i < BoolCount; i++)
state->vs_const_b[StartRegister + i] = pConstantData[i] ? bool_true : 0;
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;
}
(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)
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;
}
DBG("This=%p pShader=%p\n", This, pShader);
+ if (!This->is_recording && state->ps == (struct NinePixelShader9*)pShader)
+ return D3D_OK;
+
/* ff -> non-ff: commit back non-ff constants */
if (!state->ps && pShader)
state->commit |= NINE_STATE_COMMIT_CONST_PS;
return D3D_OK;
user_assert(pConstantData, D3DERR_INVALIDCALL);
+ if (!This->is_recording) {
+ if (!memcmp(&state->ps_const_f[StartRegister * 4], pConstantData,
+ Vector4fCount * 4 * sizeof(state->ps_const_f[0])))
+ return D3D_OK;
+ }
+
memcpy(&state->ps_const_f[StartRegister * 4],
pConstantData,
Vector4fCount * 4 * sizeof(state->ps_const_f[0]));
user_assert(pConstantData, D3DERR_INVALIDCALL);
if (This->driver_caps.ps_integer) {
+ if (!This->is_recording) {
+ if (!memcmp(&state->ps_const_i[StartRegister][0], pConstantData,
+ Vector4iCount * sizeof(state->ps_const_i[0])))
+ return D3D_OK;
+ }
memcpy(&state->ps_const_i[StartRegister][0],
pConstantData,
Vector4iCount * sizeof(state->ps_const_i[0]));
user_assert(StartRegister + BoolCount <= NINE_MAX_CONST_B, D3DERR_INVALIDCALL);
user_assert(pConstantData, D3DERR_INVALIDCALL);
+ if (!This->is_recording) {
+ bool noChange = true;
+ for (i = 0; i < BoolCount; i++) {
+ if (!!state->ps_const_b[StartRegister + i] != !!pConstantData[i])
+ noChange = false;
+ }
+ if (noChange)
+ return D3D_OK;
+ }
+
for (i = 0; i < BoolCount; i++)
state->ps_const_b[StartRegister + i] = pConstantData[i] ? bool_true : 0;
struct d3dadapter9_context *pCTX,
boolean ex,
D3DDISPLAYMODEEX *pFullscreenDisplayMode,
- struct NineDevice9 **ppOut )
+ struct NineDevice9 **ppOut,
+ int minorVersionNum )
{
BOOL lock;
lock = !!(pCreationParameters->BehaviorFlags & D3DCREATE_MULTITHREADED);
NINE_NEW(Device9, ppOut, lock, /* args */
pScreen, pCreationParameters, pCaps,
pPresentationParameters, pD3D9, pPresentationGroup, pCTX,
- ex, pFullscreenDisplayMode);
+ ex, pFullscreenDisplayMode, minorVersionNum );
}