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"
pParams->FullScreen_RefreshRateInHz,
pParams->PresentationInterval);
- if (pParams->SwapEffect == D3DSWAPEFFECT_COPY &&
- pParams->BackBufferCount > 1) {
- pParams->BackBufferCount = 1;
- }
-
if (pParams->BackBufferCount > 3) {
pParams->BackBufferCount = 3;
}
This->mode = NULL;
}
- /* Note: It is the role of the backend to fill if neccessary
+ /* Note: It is the role of the backend to fill if necessary
* BackBufferWidth and BackBufferHeight */
- ID3DPresent_SetPresentParameters(This->present, pParams, This->mode);
+ hr = ID3DPresent_SetPresentParameters(This->present, pParams, This->mode);
+ if (hr != D3D_OK)
+ return hr;
/* When we have flip behaviour, d3d9 expects we get back the screen buffer when we flip.
* Here we don't get back the initial content of the screen. To emulate the behaviour
if (!bufs)
return E_OUTOFMEMORY;
This->buffers = bufs;
- if (has_present_buffers) {
- This->present_buffers = REALLOC(This->present_buffers,
- This->present_buffers == NULL ? 0 : oldBufferCount * sizeof(struct pipe_resource *),
- newBufferCount * sizeof(struct pipe_resource *));
- memset(This->present_buffers, 0, newBufferCount * sizeof(struct pipe_resource *));
- }
This->present_handles = REALLOC(This->present_handles,
oldBufferCount * sizeof(D3DWindowBuffer *),
newBufferCount * sizeof(D3DWindowBuffer *));
}
}
+ if (has_present_buffers &&
+ (newBufferCount != oldBufferCount || !This->present_buffers)) {
+ This->present_buffers = REALLOC(This->present_buffers,
+ This->present_buffers == NULL ? 0 :
+ oldBufferCount * sizeof(struct pipe_resource *),
+ newBufferCount * sizeof(struct pipe_resource *));
+ memset(This->present_buffers, 0, newBufferCount * sizeof(struct pipe_resource *));
+ }
+
for (i = 0; i < newBufferCount; ++i) {
tmplt.bind = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_TRANSFER_READ |
PIPE_BIND_TRANSFER_WRITE | PIPE_BIND_RENDER_TARGET;
pipe_resource_reference(&(This->present_buffers[i]), resource);
}
This->present_handles[i] = D3DWindowBuffer_create(This, resource, depth);
- if (!has_present_buffers)
- pipe_resource_reference(&resource, NULL);
+ pipe_resource_reference(&resource, NULL);
}
if (pParams->EnableAutoDepthStencil) {
- tmplt.bind = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_TRANSFER_READ |
- PIPE_BIND_TRANSFER_WRITE | PIPE_BIND_DEPTH_STENCIL;
+ tmplt.bind = d3d9_get_pipe_depth_format_bindings(pParams->AutoDepthStencilFormat);
+ /* Checking the d3d9 depth format for texture support indicates the app if it can use
+ * the format for shadow mapping or texturing. If the check returns true, then the app
+ * is allowed to use this functionnality, so try first to create the buffer
+ * with PIPE_BIND_SAMPLER_VIEW. If the format can't be created with it, try without.
+ * If it fails with PIPE_BIND_SAMPLER_VIEW, then the app check for texture support
+ * would fail too, so we are fine. */
+ tmplt.bind |= PIPE_BIND_SAMPLER_VIEW;
tmplt.nr_samples = pParams->MultiSampleType;
tmplt.format = d3d9_to_pipe_format_checked(This->screen,
pParams->AutoDepthStencilFormat,
tmplt.nr_samples,
tmplt.bind,
FALSE);
+ if (tmplt.format == PIPE_FORMAT_NONE) {
+ tmplt.bind &= ~PIPE_BIND_SAMPLER_VIEW;
+ tmplt.format = d3d9_to_pipe_format_checked(This->screen,
+ pParams->AutoDepthStencilFormat,
+ PIPE_TEXTURE_2D,
+ tmplt.nr_samples,
+ tmplt.bind,
+ FALSE);
+ }
+
if (tmplt.format == PIPE_FORMAT_NONE)
return D3DERR_INVALIDCALL;
struct pipe_blit_info blit;
if (device->cursor.software && device->cursor.visible && device->cursor.w) {
+ memset(&blit, 0, sizeof(blit));
blit.src.resource = device->cursor.image;
blit.src.level = 0;
blit.src.format = device->cursor.image->format;
blit.filter = PIPE_TEX_FILTER_NEAREST;
blit.scissor_enable = FALSE;
- ID3DPresent_GetCursorPos(This->present, &device->cursor.pos);
-
- /* NOTE: blit messes up when box.x + box.width < 0, fix driver */
+ /* NOTE: blit messes up when box.x + box.width < 0, fix driver
+ * NOTE2: device->cursor.pos contains coordinates relative to the screen.
+ * This happens to be also the position of the cursor when we are fullscreen.
+ * We don't use sw cursor for Windowed mode */
blit.dst.box.x = MAX2(device->cursor.pos.x, 0) - device->cursor.hotspot.x;
blit.dst.box.y = MAX2(device->cursor.pos.y, 0) - device->cursor.hotspot.y;
blit.dst.box.width = blit.src.box.width;
blit.src.box.width, blit.src.box.height,
blit.dst.box.x, blit.dst.box.y);
+ blit.alpha_blend = TRUE;
This->pipe->blit(This->pipe, &blit);
}
if (device->hud && resource) {
hud_draw(device->hud, resource); /* XXX: no offset */
/* HUD doesn't clobber stipple */
- NineDevice9_RestoreNonCSOState(device, ~0x2);
+ nine_state_restore_non_cso(device);
}
}
return;
}
-static INLINE HRESULT
+static inline HRESULT
present( struct NineSwapChain9 *This,
const RECT *pSourceRect,
const RECT *pDestRect,
handle_draw_cursor_and_hud(This, resource);
if (This->present_buffers) {
+ memset(&blit, 0, sizeof(blit));
blit.src.resource = resource;
blit.src.level = 0;
blit.src.format = resource->format;
blit.mask = PIPE_MASK_RGBA;
blit.filter = PIPE_TEX_FILTER_NEAREST;
blit.scissor_enable = FALSE;
+ blit.alpha_blend = FALSE;
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);
BOOL still_draw = FALSE;
fence = swap_fences_see_front(This);
if (fence) {
- still_draw = !This->screen->fence_signalled(This->screen, fence);
+ still_draw = !This->screen->fence_finish(This->screen, fence, 0);
This->screen->fence_reference(This->screen, &fence, NULL);
}
if (still_draw)
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);
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);
case D3DSWAPEFFECT_DISCARD:
- /* rotate the queue */;
+ /* rotate the queue */
pipe_resource_reference(&res, This->buffers[0]->base.resource);
for (i = 1; i <= This->params.BackBufferCount; i++) {
NineSurface9_SetResourceResize(This->buffers[i - 1],
ID3DPresent_WaitBufferReleased(This->present, This->present_handles[0]);
This->base.device->state.changed.group |= NINE_STATE_FB;
- nine_update_state(This->base.device, NINE_STATE_FB);
+ nine_update_state_framebuffer(This->base.device);
return hr;
}
DBG("GetFrontBufferData: This=%p pDestSurface=%p\n",
This, pDestSurface);
+ user_assert(dest_surface->base.pool == D3DPOOL_SYSTEMMEM, D3DERR_INVALIDCALL);
+
width = dest_surface->desc.Width;
height = dest_surface->desc.Height;
desc.MultiSampleQuality = 0;
desc.Width = width;
desc.Height = height;
- /* NineSurface9_CopySurface needs same format. */
+ /* NineSurface9_CopyDefaultToMem needs same format. */
desc.Format = dest_surface->desc.Format;
desc.Usage = D3DUSAGE_RENDERTARGET;
hr = NineSurface9_new(pDevice, NineUnknown(This), temp_resource, NULL, 0,
ID3DPresent_FrontBufferCopy(This->present, temp_handle);
- NineSurface9_CopySurface(dest_surface, temp_surface, NULL, NULL);
+ NineSurface9_CopyDefaultToMem(dest_surface, temp_surface);
ID3DPresent_DestroyD3DWindowBuffer(This->present, temp_handle);
NineUnknown_Destroy(NineUnknown(temp_surface));
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];
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;
+}