예제 #1
0
static HRESULT d3d9_test_cooperative_level(void *data)
{
#ifndef _XBOX
   LPDIRECT3DDEVICE9 dev = (LPDIRECT3DDEVICE9)data;
   if (dev)
      return IDirect3DDevice9_TestCooperativeLevel(dev);
#endif
   return E_FAIL;
}
예제 #2
0
static HRESULT video_canvas_prepare_for_update(video_canvas_t *canvas)
{
    HRESULT coopresult;

    if (canvas->d3ddev == NULL || canvas->d3dsurface == NULL) {
        return -1;
    }

    coopresult = IDirect3DDevice9_TestCooperativeLevel(canvas->d3ddev);
    if (coopresult == D3DERR_DEVICENOTRESET) {
        coopresult = video_canvas_reset_dx9(canvas);
    }
    return coopresult;
}
예제 #3
0
파일: direct3d.c 프로젝트: asdlei00/vlc-2.1
static void Prepare(vout_display_t *vd, picture_t *picture, subpicture_t *subpicture)
{
    vout_display_sys_t *sys = vd->sys;
    LPDIRECT3DSURFACE9 surface = picture->p_sys->surface;
#if 0
    picture_Release(picture);
    VLC_UNUSED(subpicture);
#else
    /* FIXME it is a bit ugly, we need the surface to be unlocked for
     * rendering.
     *  The clean way would be to release the picture (and ensure that
     * the vout doesn't keep a reference). But because of the vout
     * wrapper, we can't */

    Direct3DUnlockSurface(picture);
    VLC_UNUSED(subpicture);
#endif

    /* check if device is still available */
    HRESULT hr = IDirect3DDevice9_TestCooperativeLevel(sys->d3ddev);
    if (FAILED(hr)) {
        if (hr == D3DERR_DEVICENOTRESET && !sys->reset_device) {
            vout_display_SendEventPicturesInvalid(vd);
            sys->reset_device = true;
            sys->lost_not_ready = false;
        }
        if (hr == D3DERR_DEVICELOST && !sys->lost_not_ready) {
            /* Device is lost but not yet ready for reset. */
            sys->lost_not_ready = true;
        }
        return;
    }

    d3d_region_t picture_region;
    if (!Direct3DImportPicture(vd, &picture_region, surface)) {
        int subpicture_region_count     = 0;
        d3d_region_t *subpicture_region = NULL;
        if (subpicture)
            Direct3DImportSubpicture(vd, &subpicture_region_count, &subpicture_region,
                                     subpicture);

        Direct3DRenderScene(vd, &picture_region,
                            subpicture_region_count, subpicture_region);

        Direct3DDeleteRegions(sys->d3dregion_count, sys->d3dregion);
        sys->d3dregion_count = subpicture_region_count;
        sys->d3dregion       = subpicture_region;
    }
}
static void
D3D_RenderPresent(SDL_Renderer * renderer)
{
    D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata;
    HRESULT result;

    if (!data->beginScene) {
        IDirect3DDevice9_EndScene(data->device);
        data->beginScene = SDL_TRUE;
    }

    result = IDirect3DDevice9_TestCooperativeLevel(data->device);
    if (result == D3DERR_DEVICELOST) {
        /* We'll reset later */
        return;
    }
    if (result == D3DERR_DEVICENOTRESET) {
        D3D_Reset(renderer);
    }
    result = IDirect3DDevice9_Present(data->device, NULL, NULL, NULL, NULL);
    if (FAILED(result)) {
        D3D_SetError("Present()", result);
    }
}
예제 #5
0
/**
 * It copies picture surface into a texture and renders into a scene.
 *
 * This function is intented for higher end 3D cards, with pixel shader support
 * and at least 64 MiB of video RAM.
 */
static void Direct3DRenderScene(vout_display_t *vd, LPDIRECT3DSURFACE9 surface)
{
    vout_display_sys_t *sys = vd->sys;
    LPDIRECT3DDEVICE9 d3ddev = sys->d3ddev;
    HRESULT hr;

    // check if device is still available
    hr = IDirect3DDevice9_TestCooperativeLevel(d3ddev);
    if (FAILED(hr)) {
        if (hr == D3DERR_DEVICENOTRESET && !sys->reset_device) {
            vout_display_SendEventPicturesInvalid(vd);
            sys->reset_device = true;
        }
        return;
    }
    /* */
    LPDIRECT3DTEXTURE9      d3dtex  = sys->d3dtex;
    LPDIRECT3DVERTEXBUFFER9 d3dvtc  = sys->d3dvtc;

    /* Clear the backbuffer and the zbuffer */
    hr = IDirect3DDevice9_Clear(d3ddev, 0, NULL, D3DCLEAR_TARGET,
                              D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
    if (FAILED(hr)) {
        msg_Dbg(vd, "%s:%d (hr=0x%0lX)", __FUNCTION__, __LINE__, hr);
        return;
    }
    /*  retrieve picture surface */
    LPDIRECT3DSURFACE9 d3dsrc = surface;
    if (!d3dsrc) {
        msg_Dbg(vd, "no surface to render ?");
        return;
    }

    /* retrieve texture top-level surface */
    LPDIRECT3DSURFACE9 d3ddest;
    hr = IDirect3DTexture9_GetSurfaceLevel(d3dtex, 0, &d3ddest);
    if (FAILED(hr)) {
        msg_Dbg(vd, "%s:%d (hr=0x%0lX)", __FUNCTION__, __LINE__, hr);
        return;
    }

    /* Copy picture surface into texture surface
     * color space conversion and scaling happen here */
    RECT src = vd->sys->rect_src_clipped;
    RECT dst = vd->sys->rect_dest_clipped;

    hr = IDirect3DDevice9_StretchRect(d3ddev, d3dsrc, &src, d3ddest, &dst, D3DTEXF_LINEAR);
    IDirect3DSurface9_Release(d3ddest);
    if (FAILED(hr)) {
        msg_Dbg(vd, "%s:%d (hr=0x%0lX)", __FUNCTION__, __LINE__, hr);
        return;
    }

    /* Update the vertex buffer */
    CUSTOMVERTEX *vertices;
    hr = IDirect3DVertexBuffer9_Lock(d3dvtc, 0, 0, (void **)&vertices, D3DLOCK_DISCARD);
    if (FAILED(hr)) {
        msg_Dbg(vd, "%s:%d (hr=0x%0lX)", __FUNCTION__, __LINE__, hr);
        return;
    }

    /* Setup vertices */
    const float f_width  = vd->sys->d3dpp.BackBufferWidth;
    const float f_height = vd->sys->d3dpp.BackBufferHeight;

    /* -0.5f is a "feature" of DirectX and it seems to apply to Direct3d also */
    /* http://www.sjbrown.co.uk/2003/05/01/fix-directx-rasterisation/ */
    vertices[0].x       = -0.5f;       // left
    vertices[0].y       = -0.5f;       // top
    vertices[0].z       = 0.0f;
    vertices[0].diffuse = D3DCOLOR_ARGB(255, 255, 255, 255);
    vertices[0].rhw     = 1.0f;
    vertices[0].tu      = 0.0f;
    vertices[0].tv      = 0.0f;

    vertices[1].x       = f_width - 0.5f;    // right
    vertices[1].y       = -0.5f;       // top
    vertices[1].z       = 0.0f;
    vertices[1].diffuse = D3DCOLOR_ARGB(255, 255, 255, 255);
    vertices[1].rhw     = 1.0f;
    vertices[1].tu      = 1.0f;
    vertices[1].tv      = 0.0f;

    vertices[2].x       = f_width - 0.5f;    // right
    vertices[2].y       = f_height - 0.5f;   // bottom
    vertices[2].z       = 0.0f;
    vertices[2].diffuse = D3DCOLOR_ARGB(255, 255, 255, 255);
    vertices[2].rhw     = 1.0f;
    vertices[2].tu      = 1.0f;
    vertices[2].tv      = 1.0f;

    vertices[3].x       = -0.5f;       // left
    vertices[3].y       = f_height - 0.5f;   // bottom
    vertices[3].z       = 0.0f;
    vertices[3].diffuse = D3DCOLOR_ARGB(255, 255, 255, 255);
    vertices[3].rhw     = 1.0f;
    vertices[3].tu      = 0.0f;
    vertices[3].tv      = 1.0f;

    hr= IDirect3DVertexBuffer9_Unlock(d3dvtc);
    if (FAILED(hr)) {
        msg_Dbg(vd, "%s:%d (hr=0x%0lX)", __FUNCTION__, __LINE__, hr);
        return;
    }

    // Begin the scene
    hr = IDirect3DDevice9_BeginScene(d3ddev);
    if (FAILED(hr)) {
        msg_Dbg(vd, "%s:%d (hr=0x%0lX)", __FUNCTION__, __LINE__, hr);
        return;
    }

    // Setup our texture. Using textures introduces the texture stage states,
    // which govern how textures get blended together (in the case of multiple
    // textures) and lighting information. In this case, we are modulating
    // (blending) our texture with the diffuse color of the vertices.
    hr = IDirect3DDevice9_SetTexture(d3ddev, 0, (LPDIRECT3DBASETEXTURE9)d3dtex);
    if (FAILED(hr)) {
        msg_Dbg(vd, "%s:%d (hr=0x%0lX)", __FUNCTION__, __LINE__, hr);
        IDirect3DDevice9_EndScene(d3ddev);
        return;
    }

    // Render the vertex buffer contents
    hr = IDirect3DDevice9_SetStreamSource(d3ddev, 0, d3dvtc, 0, sizeof(CUSTOMVERTEX));
    if (FAILED(hr)) {
        msg_Dbg(vd, "%s:%d (hr=0x%0lX)", __FUNCTION__, __LINE__, hr);
        IDirect3DDevice9_EndScene(d3ddev);
        return;
    }

    // we use FVF instead of vertex shader
    hr = IDirect3DDevice9_SetFVF(d3ddev, D3DFVF_CUSTOMVERTEX);
    if (FAILED(hr)) {
        msg_Dbg(vd, "%s:%d (hr=0x%0lX)", __FUNCTION__, __LINE__, hr);
        IDirect3DDevice9_EndScene(d3ddev);
        return;
    }

    // draw rectangle
    hr = IDirect3DDevice9_DrawPrimitive(d3ddev, D3DPT_TRIANGLEFAN, 0, 2);
    if (FAILED(hr)) {
        msg_Dbg(vd, "%s:%d (hr=0x%0lX)", __FUNCTION__, __LINE__, hr);
        IDirect3DDevice9_EndScene(d3ddev);
        return;
    }

    // End the scene
    hr = IDirect3DDevice9_EndScene(d3ddev);
    if (FAILED(hr)) {
        msg_Dbg(vd, "%s:%d (hr=0x%0lX)", __FUNCTION__, __LINE__, hr);
        return;
    }
}
예제 #6
0
HRESULT video_canvas_reset_dx9(video_canvas_t *canvas)
{
    LPDIRECT3DSWAPCHAIN9 d3dsc;
    HRESULT ddresult;

    if ((canvas->d3dsurface != NULL)
            && (S_OK != IDirect3DSurface9_Release(canvas->d3dsurface))
            || (canvas->d3ddev != NULL &&
                ((S_OK != IDirect3DDevice9_GetSwapChain(canvas->d3ddev, 0, &d3dsc))
                 || (S_OK != IDirect3DSwapChain9_Release(d3dsc)))
               ))
    {
        log_debug("video_dx9: Failed to release the DirectX9 device resources!");
    }

    canvas->d3dsurface = NULL;

    //if (canvas->d3dpp.Windowed == 0) {
    //    int device, width, height, bitdepth, refreshrate;

    //    GetCurrentModeParameters(&device, &width, &height, &bitdepth, &refreshrate);
    //    canvas->d3dpp.BackBufferWidth = width;
    //    canvas->d3dpp.BackBufferHeight = height;
    //} else {
    RECT wrect;

    GetClientRect(canvas->render_hwnd, &wrect);
    canvas->d3dpp.BackBufferWidth = wrect.right - wrect.left;
    canvas->d3dpp.BackBufferHeight = wrect.bottom - wrect.top;
    //}

    if (dx_primary_surface_rendering) {
        canvas->d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
    } else {
        canvas->d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
    }

    if (canvas->d3ddev == NULL) {
        if (S_OK != IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, canvas->render_hwnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &canvas->d3dpp, &canvas->d3ddev)) {
            log_debug("video_dx9: Failed to create the DirectX9 device!");
            return -1;
        }
    }
    else {
        if (S_OK != (ddresult = IDirect3DDevice9_Reset(
                                    canvas->d3ddev,
                                    &canvas->d3dpp))) {
            log_debug("video_dx9: Failed to reset the DirectX9 device!");
        }
    }

    if (S_OK != (ddresult = IDirect3DDevice9_CreateOffscreenPlainSurface(
                                canvas->d3ddev, canvas->draw_buffer->canvas_physical_width, canvas->draw_buffer->canvas_physical_height,
                                D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT,
                                &canvas->d3dsurface, NULL)))
    {
        log_debug("video_dx9: Failed to create new offscreen surface!");
        return ddresult;
    }

    return IDirect3DDevice9_TestCooperativeLevel(canvas->d3ddev);
}