/**
  \fn displayImage_argb
  \brief manually do the yv12-> RGB conversion + rescale and the upload to backbuffer
*/
bool dxvaRender::displayImage_argb(ADMImage *pic)
{
  IDirect3DSurface9 *bBuffer;
  // 1 upload to myYV12 surface
  if( ADM_FAILED(IDirect3DDevice9_GetBackBuffer(d3dDevice, 0, 0,
                                            D3DBACKBUFFER_TYPE_MONO,
                                            &bBuffer)))
  {
        ADM_warning("D3D Cannot create backBuffer\n");
        return false;
  }

  if(!ADMImage_To_argbSurface(pic,bBuffer,scaler))
  {
    ADM_warning("Image to argb surface failed\n");
    return false;
  }

  IDirect3DDevice9_BeginScene(d3dDevice);

  IDirect3DDevice9_EndScene(d3dDevice);
  if( ADM_FAILED(IDirect3DDevice9_Present(d3dDevice, &targetRect, 0, 0, 0)))
  {
    ADM_warning("D3D Present failed\n");
  }

  return true;
}
/**
  \fn brief input is already a surface, in yv12 format
*/
bool dxvaRender::displayImage_surface(ADMImage *pic,admDx2Surface *surface)
{
  // this does not work, both surfaces are coming from different device

  IDirect3DSurface9 *bBuffer;
  POINT point={0,0};
  // 1 upload to myYV12 surface
  if(ADM_FAILED(IDirect3DDevice9_UpdateSurface(d3dDevice,
          surface->surface,   // src
          &panScan,       // src rect
          myYV12Surface, // dst
          &point         // where to
        )))
        {
            ADM_warning("Copying surface failed, switching to non accelerated path \n");
            if(!pic->hwDownloadFromRef())
            {
              ADM_warning("Failed to download yv12 from dxva\n");
              return false;
            }
            // workaround : use default non bridged path
              if(useYV12)
              {
                  return displayImage_yv12(pic);
              }
              return displayImage_argb(pic);
            return false;
        }
 // upload....
  if( ADM_FAILED(IDirect3DDevice9_GetBackBuffer(d3dDevice, 0, 0,
                                            D3DBACKBUFFER_TYPE_MONO,
                                            &bBuffer)))
  {
        ADM_warning("D3D Cannot create backBuffer\n");
        return false;
  }


  // data are in YV12 surface, blit it to mySurface
  // zoom and color conversion happen there

  if (ADM_FAILED(IDirect3DDevice9_StretchRect(d3dDevice,
                  myYV12Surface,
                  NULL,
                  bBuffer,
                  NULL,
                  D3DTEXF_LINEAR)))
                  {
                         ADM_warning("StretchRec yv12 failed\n");
                  }
  IDirect3DDevice9_BeginScene(d3dDevice);
  IDirect3DDevice9_EndScene(d3dDevice);
  if( ADM_FAILED(IDirect3DDevice9_Present(d3dDevice, &targetRect, 0, 0, 0)))
  {
    ADM_warning("D3D Present failed\n");
  }

  return true;
}
Esempio n. 3
0
static int
D3D_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
                     Uint32 format, void * pixels, int pitch)
{
    D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata;
    D3DSURFACE_DESC desc;
    LPDIRECT3DSURFACE9 backBuffer;
    LPDIRECT3DSURFACE9 surface;
    RECT d3drect;
    D3DLOCKED_RECT locked;
    HRESULT result;

    result = IDirect3DDevice9_GetBackBuffer(data->device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backBuffer);
    if (FAILED(result)) {
        return D3D_SetError("GetBackBuffer()", result);
    }

    result = IDirect3DSurface9_GetDesc(backBuffer, &desc);
    if (FAILED(result)) {
        IDirect3DSurface9_Release(backBuffer);
        return D3D_SetError("GetDesc()", result);
    }

    result = IDirect3DDevice9_CreateOffscreenPlainSurface(data->device, desc.Width, desc.Height, desc.Format, D3DPOOL_SYSTEMMEM, &surface, NULL);
    if (FAILED(result)) {
        IDirect3DSurface9_Release(backBuffer);
        return D3D_SetError("CreateOffscreenPlainSurface()", result);
    }

    result = IDirect3DDevice9_GetRenderTargetData(data->device, backBuffer, surface);
    if (FAILED(result)) {
        IDirect3DSurface9_Release(surface);
        IDirect3DSurface9_Release(backBuffer);
        return D3D_SetError("GetRenderTargetData()", result);
    }

    d3drect.left = rect->x;
    d3drect.right = rect->x + rect->w;
    d3drect.top = rect->y;
    d3drect.bottom = rect->y + rect->h;

    result = IDirect3DSurface9_LockRect(surface, &locked, &d3drect, D3DLOCK_READONLY);
    if (FAILED(result)) {
        IDirect3DSurface9_Release(surface);
        IDirect3DSurface9_Release(backBuffer);
        return D3D_SetError("LockRect()", result);
    }

    SDL_ConvertPixels(rect->w, rect->h,
                      D3DFMTToPixelFormat(desc.Format), locked.pBits, locked.Pitch,
                      format, pixels, pitch);

    IDirect3DSurface9_UnlockRect(surface);

    IDirect3DSurface9_Release(surface);
    IDirect3DSurface9_Release(backBuffer);

    return 0;
}
/**
  \fn displayImage_yv12
  \brief copy image to myV12 surface then convert from yv12 to display format in mySurface

*/
bool dxvaRender::displayImage_yv12(ADMImage *pic)
{
    IDirect3DSurface9 *bBuffer;
    // 1 upload to myYV12 surface
    if(!ADMImage_To_yv12Surface(pic,myYV12Surface))
    {
      return false;
    }
   // upload....
    if( ADM_FAILED(IDirect3DDevice9_GetBackBuffer(d3dDevice, 0, 0,
                                              D3DBACKBUFFER_TYPE_MONO,
                                              &bBuffer)))
    {
          ADM_warning("D3D Cannot create backBuffer\n");
          return false;
    }


    // data are in YV12 surface, blit it to mySurface
    // zoom and color conversion happen there

    if (ADM_FAILED(IDirect3DDevice9_StretchRect(d3dDevice,
                    myYV12Surface,
                    NULL,
                    bBuffer,
                    NULL,
                    D3DTEXF_LINEAR)))
                    {
                           ADM_warning("StretchRec yv12 failed\n");
                    }
    IDirect3DDevice9_BeginScene(d3dDevice);
    IDirect3DDevice9_EndScene(d3dDevice);
    if( ADM_FAILED(IDirect3DDevice9_Present(d3dDevice, &targetRect, 0, 0, 0)))
    {
      ADM_warning("D3D Present failed\n");
    }

    return true;
}
Esempio n. 5
0
/** @brief Create D3D Offscreen and Backbuffer surfaces. Each
 *         surface is created only if it's not already present.
 *  @return 1 on success, 0 on failure
 */
static int create_d3d_surfaces(void)
{
    int osd_width = vo_dwidth, osd_height = vo_dheight;
    int tex_width = osd_width, tex_height = osd_height;
    mp_msg(MSGT_VO, MSGL_V, "<vo_direct3d>create_d3d_surfaces called.\n");

    if (!priv->d3d_surface &&
        FAILED(IDirect3DDevice9_CreateOffscreenPlainSurface(
               priv->d3d_device, priv->src_width, priv->src_height,
               priv->movie_src_fmt, D3DPOOL_DEFAULT, &priv->d3d_surface, NULL))) {
        mp_msg(MSGT_VO, MSGL_ERR,
               "<vo_direct3d>Allocating offscreen surface failed.\n");
        return 0;
    }

    if (!priv->d3d_backbuf &&
        FAILED(IDirect3DDevice9_GetBackBuffer(priv->d3d_device, 0, 0,
                                              D3DBACKBUFFER_TYPE_MONO,
                                              &priv->d3d_backbuf))) {
        mp_msg(MSGT_VO, MSGL_ERR, "<vo_direct3d>Allocating backbuffer failed.\n");
        return 0;
    }

    /* calculate the best size for the OSD depending on the factors from the device */
    if (priv->device_caps_power2_only) {
        tex_width  = 1;
        tex_height = 1;
        while (tex_width  < osd_width ) tex_width  <<= 1;
        while (tex_height < osd_height) tex_height <<= 1;
    }
    if (priv->device_caps_square_only)
        /* device only supports square textures */
        tex_width = tex_height = tex_width > tex_height ? tex_width : tex_height;
    // better round up to a multiple of 16
    tex_width  = (tex_width  + 15) & ~15;
    tex_height = (tex_height + 15) & ~15;

    // make sure we respect the size limits without breaking aspect or pow2-requirements
    while (tex_width > priv->max_texture_width || tex_height > priv->max_texture_height) {
        osd_width  >>= 1;
        osd_height >>= 1;
        tex_width  >>= 1;
        tex_height >>= 1;
    }

    priv->osd_width  = osd_width;
    priv->osd_height = osd_height;
    priv->osd_texture_width  = tex_width;
    priv->osd_texture_height = tex_height;

    mp_msg(MSGT_VO, MSGL_V, "<vo_direct3d>OSD texture size (%dx%d), requested (%dx%d).\n",
           vo_dwidth, vo_dheight, priv->osd_texture_width, priv->osd_texture_height);

    /* create OSD */
    if (!priv->d3d_texture_system &&
        FAILED(IDirect3DDevice9_CreateTexture(priv->d3d_device,
                                              priv->osd_texture_width,
                                              priv->osd_texture_height,
                                              1,
                                              D3DUSAGE_DYNAMIC,
                                              D3DFMT_A8L8,
                                              D3DPOOL_SYSTEMMEM,
                                              &priv->d3d_texture_system,
                                              NULL))) {
        mp_msg(MSGT_VO,MSGL_ERR,
               "<vo_direct3d>Allocating OSD texture in system RAM failed.\n");
        return 0;
    }

    if (!priv->device_texture_sys) {
        /* only create if we need a shadow version on the external device */
        if (!priv->d3d_texture_osd &&
            FAILED(IDirect3DDevice9_CreateTexture(priv->d3d_device,
                                                  priv->osd_texture_width,
                                                  priv->osd_texture_height,
                                                  1,
                                                  D3DUSAGE_DYNAMIC,
                                                  D3DFMT_A8L8,
                                                  D3DPOOL_DEFAULT,
                                                  &priv->d3d_texture_osd,
                                                  NULL))) {
            mp_msg(MSGT_VO,MSGL_ERR,
                   "<vo_direct3d>Allocating OSD texture in video RAM failed.\n");
            return 0;
        }
    }

    /* setup default renderstate */
    IDirect3DDevice9_SetRenderState(priv->d3d_device, D3DRS_SRCBLEND, D3DBLEND_ONE);
    IDirect3DDevice9_SetRenderState(priv->d3d_device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
    IDirect3DDevice9_SetRenderState(priv->d3d_device, D3DRS_ALPHAFUNC, D3DCMP_GREATER);
    IDirect3DDevice9_SetRenderState(priv->d3d_device, D3DRS_ALPHAREF, (DWORD)0x0);
    IDirect3DDevice9_SetRenderState(priv->d3d_device, D3DRS_LIGHTING, FALSE);
    IDirect3DDevice9_SetSamplerState(priv->d3d_device, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
    IDirect3DDevice9_SetSamplerState(priv->d3d_device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);

    return 1;
}
Esempio n. 6
0
int video_canvas_refresh_dx9(video_canvas_t *canvas, unsigned int xs, unsigned int ys, unsigned int xi, unsigned int yi, unsigned int w, unsigned int h)
{
    HRESULT stretchresult;
    LPDIRECT3DSURFACE9 d3dbackbuffer = NULL;
    D3DLOCKED_RECT lockedrect;

    if (canvas->videoconfig->doublesizex) {
        xi *= (canvas->videoconfig->doublesizex + 1);
        w *= (canvas->videoconfig->doublesizex + 1);
    }

    if (canvas->videoconfig->doublesizey) {
        yi *= (canvas->videoconfig->doublesizey + 1);
        h *= (canvas->videoconfig->doublesizey + 1);
    }

    if (S_OK != video_canvas_prepare_for_update(canvas)) {
        return -1;
    }

    if (S_OK != IDirect3DDevice9_Clear(canvas->d3ddev, 0, NULL, D3DCLEAR_TARGET, 0, 0, 0) ||
            S_OK != IDirect3DDevice9_BeginScene(canvas->d3ddev) ||
            S_OK != IDirect3DDevice9_GetBackBuffer(canvas->d3ddev, 0, 0, D3DBACKBUFFER_TYPE_MONO, &d3dbackbuffer) ||
            S_OK != IDirect3DSurface9_LockRect(canvas->d3dsurface, &lockedrect, NULL, 0)) {
        log_debug("video_dx9: Failed to prepare for rendering!");
        return -1;
    }

    video_canvas_render(canvas, lockedrect.pBits, w, h, xs, ys, xi, yi, lockedrect.Pitch, 32);
    //video_save_screen ("c:\\temp\\screens\\", w, h, 32, lockedrect.pBits);

    if (S_OK != IDirect3DSurface9_UnlockRect(canvas->d3dsurface)) {
        log_debug("video_dx9: Failed to unlock surface!");
        return -1;
    }

    do {
        stretchresult = IDirect3DDevice9_StretchRect(canvas->d3ddev, canvas->d3dsurface, NULL, d3dbackbuffer, canvas->dest_rect_ptr, d3dpreffilter);

        if (d3dpreffilter == D3DTEXF_NONE) {
            break;
        }

        if (stretchresult != S_OK) {
            /* Some adapters don't support filtering */
            d3dpreffilter = D3DTEXF_NONE;
            log_debug("video_dx9: Disabled StretchRect filtering!");
        }

    } while (stretchresult != S_OK);
    if (stretchresult != S_OK) {
        log_debug("video_dx9: StretchRect failed even without filtering!");
    }

    if (S_OK != IDirect3DSurface9_Release(d3dbackbuffer)
            || S_OK != IDirect3DDevice9_EndScene(canvas->d3ddev))
    {
        log_debug("video_dx9: EndScene failed!");
        return -1;
    }

    if (S_OK != IDirect3DDevice9_Present(canvas->d3ddev, NULL, NULL, NULL, NULL)) {
        log_debug("video_dx9: Refresh failed to present the scene!");
        return -1;
    }
    return 0;
}
Esempio n. 7
0
void initD3D9()
{
#ifdef __WIN32__
    static HMODULE d3d9_handle = 0;
    IDirect3D9 *(__stdcall * d3d9_create)(UINT SDKVersion) = NULL;
    D3DPRESENT_PARAMETERS present_parameters;
    D3DADAPTER_IDENTIFIER9 identifier;
    HRESULT hr;
    HWND hwnd;

    d3d9_handle = LoadLibraryA("d3d9.dll");
    if (!d3d9_handle) {
        fprintf(stderr, "Could not load d3d9.dll\n");
        return;
    }

    d3d9_create = (void *)GetProcAddress(d3d9_handle, "Direct3DCreate9");
    if (!d3d9_create) {
        fprintf(stderr, "Could not get address of Direct3DCreate9\n");
        return;
    }

    gD3D9Ptr = d3d9_create(D3D_SDK_VERSION);
    if (!gD3D9Ptr) {
        fprintf(stderr, "could not create D3D9\n");
        return;
    }

    hwnd = createWindowWin32();

    ZeroMemory(&present_parameters, sizeof(present_parameters));
    present_parameters.Windowed = FALSE;
    present_parameters.hDeviceWindow = hwnd;
    present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
    present_parameters.BackBufferWidth = DEFAULT_WINDOW_WIDTH;;
    present_parameters.BackBufferHeight = DEFAULT_WINDOW_HEIGHT;
    present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
    present_parameters.EnableAutoDepthStencil = TRUE;
    present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
    present_parameters.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;

    memset(&identifier, 0, sizeof(identifier));
    IDirect3D9_GetAdapterIdentifier(gD3D9Ptr, 0, 0, &identifier);
    printf("Driver string: \"%s\"\n", identifier.Driver);
    printf("Description string: \"%s\"\n", identifier.Description);
    printf("Device name string: \"%s\"\n", identifier.DeviceName);
    printf("Driver version %d.%d.%d.%d\n",
          HIWORD(identifier.DriverVersion.HighPart), LOWORD(identifier.DriverVersion.HighPart),
          HIWORD(identifier.DriverVersion.LowPart), LOWORD(identifier.DriverVersion.LowPart));

    hr = IDirect3D9_CreateDevice(gD3D9Ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &gDevicePtr);
    if(FAILED(hr)) {
        present_parameters.AutoDepthStencilFormat = D3DFMT_D16;
        hr = IDirect3D9_CreateDevice(gD3D9Ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &gDevicePtr);
        if(FAILED(hr)) {
            hr = IDirect3D9_CreateDevice(gD3D9Ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &gDevicePtr);
        }
    }

    if (FAILED(hr) || !gDevicePtr) {
        fprintf(stderr, "Creating the device failed\n");
        return;
    }

    /* Not yet being used */
    if (0)
        createDummyTexD3D9();

    createShadersD3D9();
    createVertexBuffersD3D9();

    IDirect3DDevice9_GetBackBuffer(gDevicePtr, 0, 0, D3DBACKBUFFER_TYPE_MONO, &gDeviceBackBufferPtr);

    ShowWindow(hwnd, TRUE);
    UpdateWindow(hwnd);

    while (!gIsQuitting) {
        MSG msg;
        while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        displayD3D9();
    }
#else
    fprintf(stderr, "ERROR: D3D9 not supported on this platform\n");
#endif
}