예제 #1
0
파일: swapchain9.c 프로젝트: chemecse/mesa
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;
}
예제 #3
0
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, &params);
    if (FAILED(hr))
        return hr;
    if (!params.hDeviceWindow)
        params.hDeviceWindow = hFocusWindow;

    return NineSwapChain9_Resize(This, &params);
}
예제 #4
0
파일: swapchain9.c 프로젝트: chemecse/mesa
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;
}