static void handle_draw_cursor_and_hud( struct NineSwapChain9 *This, struct pipe_resource *resource) { struct NineDevice9 *device = This->base.device; struct pipe_blit_info blit; struct pipe_context *pipe; 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.src.box.x = 0; blit.src.box.y = 0; blit.src.box.z = 0; blit.src.box.depth = 1; blit.src.box.width = device->cursor.w; blit.src.box.height = device->cursor.h; blit.dst.resource = resource; blit.dst.level = 0; blit.dst.format = resource->format; blit.dst.box.z = 0; blit.dst.box.depth = 1; blit.mask = PIPE_MASK_RGBA; blit.filter = PIPE_TEX_FILTER_NEAREST; blit.scissor_enable = FALSE; /* 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.dst.box.height = blit.src.box.height; DBG("Blitting cursor(%ux%u) to (%i,%i).\n", blit.src.box.width, blit.src.box.height, blit.dst.box.x, blit.dst.box.y); blit.alpha_blend = TRUE; pipe = NineDevice9_GetPipe(This->base.device); pipe->blit(pipe, &blit); } if (device->hud && resource) { /* Implicit use of context pipe */ (void)NineDevice9_GetPipe(This->base.device); hud_run(device->hud, NULL, resource); /* XXX: no offset */ /* HUD doesn't clobber stipple */ nine_state_restore_non_cso(device); } }
struct pipe_context * WINAPI GaNinePipeContextFromDevice(IDirect3DDevice9 *pDevice) { /// @todo Verify that this is a NineDevice? struct pipe_context *pPipeContext = NineDevice9_GetPipe((struct NineDevice9 *)pDevice); return pPipeContext; }
HRESULT NineSwapChain9_ctor( struct NineSwapChain9 *This, struct NineUnknownParams *pParams, BOOL implicit, ID3DPresent *pPresent, struct d3dadapter9_context *pCTX, HWND hFocusWindow ) { D3DPRESENT_PARAMETERS params; HRESULT hr; DBG("This=%p pDevice=%p pPresent=%p pCTX=%p hFocusWindow=%p\n", This, pParams->device, pPresent, pCTX, hFocusWindow); hr = NineUnknown_ctor(&This->base, pParams); if (FAILED(hr)) return hr; This->screen = NineDevice9_GetScreen(This->base.device); This->pipe = NineDevice9_GetPipe(This->base.device); This->cso = NineDevice9_GetCSO(This->base.device); This->implicit = implicit; This->actx = pCTX; This->present = pPresent; ID3DPresent_AddRef(pPresent); hr = ID3DPresent_GetPresentParameters(This->present, ¶ms); if (FAILED(hr)) return hr; if (!params.hDeviceWindow) params.hDeviceWindow = hFocusWindow; return NineSwapChain9_Resize(This, ¶ms); }
static inline HRESULT present( struct NineSwapChain9 *This, const RECT *pSourceRect, const RECT *pDestRect, HWND hDestWindowOverride, const RGNDATA *pDirtyRegion, DWORD dwFlags ) { struct pipe_context *pipe; struct pipe_resource *resource; struct pipe_fence_handle *fence; HRESULT hr; struct pipe_blit_info blit; DBG("present: This=%p pSourceRect=%p pDestRect=%p " "pDirtyRegion=%p hDestWindowOverride=%p" "dwFlags=%d resource=%p\n", This, pSourceRect, pDestRect, pDirtyRegion, hDestWindowOverride, (int)dwFlags, This->buffers[0]->base.resource); if (pSourceRect) DBG("pSourceRect = (%u..%u)x(%u..%u)\n", pSourceRect->left, pSourceRect->right, pSourceRect->top, pSourceRect->bottom); if (pDestRect) DBG("pDestRect = (%u..%u)x(%u..%u)\n", pDestRect->left, pDestRect->right, pDestRect->top, pDestRect->bottom); /* TODO: in the case the source and destination rect have different size: * We need to allocate a new buffer, and do a blit to it to resize. * We can't use the present_buffer for that since when we created it, * we couldn't guess which size would have been needed. * If pDestRect or pSourceRect is null, we have to check the sizes * from the source size, and the destination window size. * In this case, either resize rngdata, or pass NULL instead */ /* Note: This->buffers[0]->level should always be 0 */ if (This->rendering_done) goto bypass_rendering; resource = This->buffers[0]->base.resource; if (This->params.SwapEffect == D3DSWAPEFFECT_DISCARD) handle_draw_cursor_and_hud(This, resource); pipe = NineDevice9_GetPipe(This->base.device); if (This->present_buffers[0]) { memset(&blit, 0, sizeof(blit)); blit.src.resource = resource; blit.src.level = 0; blit.src.format = resource->format; blit.src.box.z = 0; blit.src.box.depth = 1; blit.src.box.x = 0; blit.src.box.y = 0; blit.src.box.width = resource->width0; blit.src.box.height = resource->height0; resource = This->present_buffers[0]; blit.dst.resource = resource; blit.dst.level = 0; blit.dst.format = resource->format; blit.dst.box.z = 0; blit.dst.box.depth = 1; blit.dst.box.x = 0; blit.dst.box.y = 0; blit.dst.box.width = resource->width0; blit.dst.box.height = resource->height0; blit.mask = PIPE_MASK_RGBA; blit.filter = PIPE_TEX_FILTER_NEAREST; blit.scissor_enable = FALSE; blit.alpha_blend = FALSE; pipe->blit(pipe, &blit); } /* The resource we present has to resolve fast clears * if needed (and other things) */ pipe->flush_resource(pipe, resource); if (This->params.SwapEffect != D3DSWAPEFFECT_DISCARD) handle_draw_cursor_and_hud(This, resource); fence = NULL; pipe->flush(pipe, &fence, PIPE_FLUSH_END_OF_FRAME); if (fence) { swap_fences_push_back(This, fence); This->screen->fence_reference(This->screen, &fence, NULL); } This->rendering_done = TRUE; bypass_rendering: if (dwFlags & D3DPRESENT_DONOTWAIT) { UNTESTED(2); BOOL still_draw = FALSE; fence = swap_fences_see_front(This); if (fence) { still_draw = !This->screen->fence_finish(This->screen, NULL, fence, 0); This->screen->fence_reference(This->screen, &fence, NULL); } if (still_draw) return D3DERR_WASSTILLDRAWING; } if (!This->enable_threadpool) { This->tasks[0]=NULL; fence = swap_fences_pop_front(This); if (fence) { (void) This->screen->fence_finish(This->screen, NULL, fence, PIPE_TIMEOUT_INFINITE); This->screen->fence_reference(This->screen, &fence, NULL); } hr = ID3DPresent_PresentBuffer(This->present, This->present_handles[0], hDestWindowOverride, pSourceRect, pDestRect, pDirtyRegion, dwFlags); if (FAILED(hr)) { UNTESTED(3);return hr; } } else { pend_present(This, hDestWindowOverride); } This->rendering_done = FALSE; return D3D_OK; }