/** * It initializes an instance of Direct3D9 */ static int Direct3DCreate(vout_display_t *vd) { vout_display_sys_t *sys = vd->sys; sys->hd3d9_dll = LoadLibrary(TEXT("D3D9.DLL")); if (!sys->hd3d9_dll) { msg_Warn(vd, "cannot load d3d9.dll, aborting"); return VLC_EGENERIC; } LPDIRECT3D9 (WINAPI *OurDirect3DCreate9)(UINT SDKVersion); OurDirect3DCreate9 = (void *)GetProcAddress(sys->hd3d9_dll, "Direct3DCreate9"); if (!OurDirect3DCreate9) { msg_Err(vd, "Cannot locate reference to Direct3DCreate9 ABI in DLL"); return VLC_EGENERIC; } /* Create the D3D object. */ LPDIRECT3D9 d3dobj = OurDirect3DCreate9(D3D_SDK_VERSION); if (!d3dobj) { msg_Err(vd, "Could not create Direct3D9 instance."); return VLC_EGENERIC; } sys->d3dobj = d3dobj; /* ** Get device capabilities */ ZeroMemory(&sys->d3dcaps, sizeof(sys->d3dcaps)); HRESULT hr = IDirect3D9_GetDeviceCaps(d3dobj, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &sys->d3dcaps); if (FAILED(hr)) { msg_Err(vd, "Could not read adapter capabilities. (hr=0x%lX)", hr); return VLC_EGENERIC; } /* TODO: need to test device capabilities and select the right render function */ if (!(sys->d3dcaps.DevCaps2 & D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES) || !(sys->d3dcaps.TextureFilterCaps & (D3DPTFILTERCAPS_MAGFLINEAR)) || !(sys->d3dcaps.TextureFilterCaps & (D3DPTFILTERCAPS_MINFLINEAR))) { msg_Err(vd, "Device does not support stretching from textures."); return VLC_EGENERIC; } return VLC_SUCCESS; }
/** * It initializes an instance of Direct3D9 */ static int Direct3DCreate(vout_display_t *vd) { vout_display_sys_t *sys = vd->sys; sys->hd3d9_dll = LoadLibrary(TEXT("D3D9.DLL")); if (!sys->hd3d9_dll) { msg_Warn(vd, "cannot load d3d9.dll, aborting"); return VLC_EGENERIC; } LPDIRECT3D9 (WINAPI *OurDirect3DCreate9)(UINT SDKVersion); OurDirect3DCreate9 = (void *)GetProcAddress(sys->hd3d9_dll, TEXT("Direct3DCreate9")); if (!OurDirect3DCreate9) { msg_Err(vd, "Cannot locate reference to Direct3DCreate9 ABI in DLL"); return VLC_EGENERIC; } /* Create the D3D object. */ LPDIRECT3D9 d3dobj = OurDirect3DCreate9(D3D_SDK_VERSION); if (!d3dobj) { msg_Err(vd, "Could not create Direct3D9 instance."); return VLC_EGENERIC; } sys->d3dobj = d3dobj; /* ** Get device capabilities */ D3DCAPS9 d3dCaps; ZeroMemory(&d3dCaps, sizeof(d3dCaps)); HRESULT hr = IDirect3D9_GetDeviceCaps(d3dobj, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &d3dCaps); if (FAILED(hr)) { msg_Err(vd, "Could not read adapter capabilities. (hr=0x%lX)", hr); return VLC_EGENERIC; } /* TODO: need to test device capabilities and select the right render function */ return VLC_SUCCESS; }
HRESULT D3D9_CreateDeviceExternal(IDirect3DDevice9 *dev, d3d9_handle_t *hd3d, HWND hwnd, const video_format_t *source, d3d9_device_t *out) { D3DDEVICE_CREATION_PARAMETERS params; HRESULT hr = IDirect3DDevice9_GetCreationParameters(dev, ¶ms); if (FAILED(hr)) return hr; out->dev = dev; out->owner = false; out->hwnd = hwnd; out->adapterId = params.AdapterOrdinal; ZeroMemory(&out->caps, sizeof(out->caps)); hr = IDirect3D9_GetDeviceCaps(hd3d->obj, out->adapterId, params.DeviceType, &out->caps); if (FAILED(hr)) return hr; if (D3D9_FillPresentationParameters(hd3d, source, out)) { return E_FAIL; } IDirect3DDevice9_AddRef(out->dev); return S_OK; }
static HRESULT d3d_get_caps_dword(d3d *d3dptr, UINT adapter, D3DDEVTYPE devtype, d3d_caps_index which, DWORD *value) { IDirect3D9 *d3d9 = (IDirect3D9 *)d3dptr->d3dobj; D3DCAPS9 caps; HRESULT result = IDirect3D9_GetDeviceCaps(d3d9, adapter, devtype, &caps); switch (which) { case CAPS_PRESENTATION_INTERVALS: *value = caps.PresentationIntervals; break; case CAPS_CAPS2: *value = caps.Caps2; break; case CAPS_DEV_CAPS: *value = caps.DevCaps; break; case CAPS_SRCBLEND_CAPS: *value = caps.SrcBlendCaps; break; case CAPS_DSTBLEND_CAPS: *value = caps.DestBlendCaps; break; case CAPS_TEXTURE_CAPS: *value = caps.TextureCaps; break; case CAPS_TEXTURE_FILTER_CAPS: *value = caps.TextureFilterCaps; break; case CAPS_TEXTURE_ADDRESS_CAPS: *value = caps.TextureAddressCaps; break; case CAPS_TEXTURE_OP_CAPS: *value = caps.TextureOpCaps; break; case CAPS_MAX_TEXTURE_ASPECT: *value = caps.MaxTextureAspectRatio; break; case CAPS_MAX_TEXTURE_WIDTH: *value = caps.MaxTextureWidth; break; case CAPS_MAX_TEXTURE_HEIGHT: *value = caps.MaxTextureHeight; break; case CAPS_STRETCH_RECT_FILTER: *value = caps.StretchRectFilterCaps; break; } return result; }
static int preinit(const char *arg) { D3DDISPLAYMODE disp_mode; D3DCAPS9 disp_caps; DWORD texture_caps; DWORD dev_caps; /* Set to zero all global variables. */ priv = calloc(1, sizeof(struct global_priv)); if (!priv) { mp_msg(MSGT_VO, MSGL_ERR, "<vo_direct3d>Allocating private memory failed.\n"); goto err_out; } /* FIXME > Please use subopt-helper.h for this, see vo_gl.c:preinit for > an example of how to use it. */ priv->d3d9_dll = LoadLibraryA("d3d9.dll"); if (!priv->d3d9_dll) { mp_msg(MSGT_VO, MSGL_ERR, "<vo_direct3d>Unable to dynamically load d3d9.dll\n"); goto err_out; } priv->pDirect3DCreate9 = (void *)GetProcAddress(priv->d3d9_dll, "Direct3DCreate9"); if (!priv->pDirect3DCreate9) { mp_msg(MSGT_VO, MSGL_ERR, "<vo_direct3d>Unable to find entry point of Direct3DCreate9\n"); goto err_out; } priv->d3d_handle = priv->pDirect3DCreate9(D3D_SDK_VERSION); if (!priv->d3d_handle) { mp_msg(MSGT_VO, MSGL_ERR, "<vo_direct3d>Initializing Direct3D failed.\n"); goto err_out; } if (FAILED(IDirect3D9_GetAdapterDisplayMode(priv->d3d_handle, D3DADAPTER_DEFAULT, &disp_mode))) { mp_msg(MSGT_VO, MSGL_ERR, "<vo_direct3d>Reading display mode failed.\n"); goto err_out; } /* Store in priv->desktop_fmt the user desktop's colorspace. Usually XRGB. */ priv->desktop_fmt = disp_mode.Format; priv->cur_backbuf_width = disp_mode.Width; priv->cur_backbuf_height = disp_mode.Height; mp_msg(MSGT_VO, MSGL_V, "<vo_direct3d>Setting backbuffer dimensions to (%dx%d).\n", disp_mode.Width, disp_mode.Height); if (FAILED(IDirect3D9_GetDeviceCaps(priv->d3d_handle, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &disp_caps))) { mp_msg(MSGT_VO, MSGL_ERR, "<vo_direct3d>Reading display capabilities failed.\n"); goto err_out; } /* Store relevant information reguarding caps of device */ texture_caps = disp_caps.TextureCaps; dev_caps = disp_caps.DevCaps; priv->device_caps_power2_only = (texture_caps & D3DPTEXTURECAPS_POW2) && !(texture_caps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL); priv->device_caps_square_only = texture_caps & D3DPTEXTURECAPS_SQUAREONLY; priv->device_texture_sys = dev_caps & D3DDEVCAPS_TEXTURESYSTEMMEMORY; priv->max_texture_width = disp_caps.MaxTextureWidth; priv->max_texture_height = disp_caps.MaxTextureHeight; mp_msg(MSGT_VO, MSGL_V, "<vo_direct3d>device_caps_power2_only %d, device_caps_square_only %d\n" "<vo_direct3d>device_texture_sys %d\n" "<vo_direct3d>max_texture_width %d, max_texture_height %d\n", priv->device_caps_power2_only, priv->device_caps_square_only, priv->device_texture_sys, priv->max_texture_width, priv->max_texture_height); /* w32_common framework call. Configures window on the screen, gets * fullscreen dimensions and does other useful stuff. */ if (!vo_w32_init()) { mp_msg(MSGT_VO, MSGL_V, "<vo_direct3d>Configuring onscreen window failed.\n"); goto err_out; } return 0; err_out: uninit(); return -1; }
/** \fn changeZoom */ bool dxvaRender::init( GUI_WindowInfo * window, uint32_t w, uint32_t h,renderZoom zoom) { ADM_info("Initializing dxva2/D3D render\n"); info=*window; baseInit(w,h,zoom); windowId=(HWND)window->systemWindowId; if(!d3dHandle) { ADM_warning("No D3DHandle\n"); return false; } if (ADM_FAILED(IDirect3D9_GetAdapterDisplayMode(d3dHandle, D3DADAPTER_DEFAULT, &displayMode))) { ADM_warning("Dxv2/D3D Render: Cannot get display mode\n"); return 0; } D3DCAPS9 deviceCapabilities; ADM_info("D3D Checking device capabilities\n"); if (ADM_FAILED(IDirect3D9_GetDeviceCaps(d3dHandle, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &deviceCapabilities))) { ADM_warning("Cannot get device capabilities"); return false; } int texture = deviceCapabilities.TextureCaps; ADM_info("Power of 2 : %d\n", (texture & D3DPTEXTURECAPS_POW2) && !(texture & D3DPTEXTURECAPS_NONPOW2CONDITIONAL)); ADM_info("Square only: %d\n", (texture & D3DPTEXTURECAPS_SQUAREONLY)); // Check if we support YV12 D3DFORMAT fmt=displayMode.Format; D3DFORMAT yv12=(D3DFORMAT)MAKEFOURCC('Y','V','1','2'); if (ADM_FAILED(IDirect3D9_CheckDeviceFormatConversion( d3dHandle, // adapter D3DADAPTER_DEFAULT, // device type D3DDEVTYPE_HAL, // adapter format yv12, // render target format fmt))) // depth stencil format { useYV12=false; ADM_info("D3D YV12 not supported\n"); } else { useYV12=true; ADM_info("D3D YV12 is supported\n"); } if(!setup()) { ADM_warning("Dxva/D3D setup failed\n"); return false; } videoWidget=(ADM_Qvideo *)info.widget; videoWidget->useExternalRedraw(true); // deactivate Qt Double buffering videoWidget->setDrawer(this); ADM_info("Dxva (D3D) init successful, dxva render. w=%d, h=%d,zoom=%d, displayWidth=%d, displayHeight=%d\n",(int)w,(int)h,(int)zoom,(int)displayWidth,(int)displayHeight); return true; }
SDL_Renderer * D3D_CreateRenderer(SDL_Window * window, Uint32 flags) { SDL_Renderer *renderer; D3D_RenderData *data; SDL_SysWMinfo windowinfo; HRESULT result; D3DPRESENT_PARAMETERS pparams; IDirect3DSwapChain9 *chain; D3DCAPS9 caps; Uint32 window_flags; int w, h; SDL_DisplayMode fullscreen_mode; D3DMATRIX matrix; renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer)); if (!renderer) { SDL_OutOfMemory(); return NULL; } data = (D3D_RenderData *) SDL_calloc(1, sizeof(*data)); if (!data) { SDL_free(renderer); SDL_OutOfMemory(); return NULL; } data->d3dDLL = SDL_LoadObject("D3D9.DLL"); if (data->d3dDLL) { IDirect3D9 *(WINAPI * D3DCreate) (UINT SDKVersion); D3DCreate = (IDirect3D9 * (WINAPI *) (UINT)) SDL_LoadFunction(data->d3dDLL, "Direct3DCreate9"); if (D3DCreate) { data->d3d = D3DCreate(D3D_SDK_VERSION); } if (!data->d3d) { SDL_UnloadObject(data->d3dDLL); data->d3dDLL = NULL; } } if (!data->d3d) { SDL_free(renderer); SDL_free(data); SDL_SetError("Unable to create Direct3D interface"); return NULL; } renderer->WindowEvent = D3D_WindowEvent; renderer->CreateTexture = D3D_CreateTexture; renderer->UpdateTexture = D3D_UpdateTexture; renderer->LockTexture = D3D_LockTexture; renderer->UnlockTexture = D3D_UnlockTexture; renderer->SetRenderTarget = D3D_SetRenderTarget; renderer->UpdateViewport = D3D_UpdateViewport; renderer->RenderClear = D3D_RenderClear; renderer->RenderDrawPoints = D3D_RenderDrawPoints; renderer->RenderDrawLines = D3D_RenderDrawLines; renderer->RenderFillRects = D3D_RenderFillRects; renderer->RenderCopy = D3D_RenderCopy; renderer->RenderReadPixels = D3D_RenderReadPixels; renderer->RenderPresent = D3D_RenderPresent; renderer->DestroyTexture = D3D_DestroyTexture; renderer->DestroyRenderer = D3D_DestroyRenderer; renderer->info = D3D_RenderDriver.info; renderer->driverdata = data; renderer->info.flags = SDL_RENDERER_ACCELERATED; SDL_VERSION(&windowinfo.version); SDL_GetWindowWMInfo(window, &windowinfo); window_flags = SDL_GetWindowFlags(window); SDL_GetWindowSize(window, &w, &h); SDL_GetWindowDisplayMode(window, &fullscreen_mode); SDL_zero(pparams); pparams.hDeviceWindow = windowinfo.info.win.window; pparams.BackBufferWidth = w; pparams.BackBufferHeight = h; if (window_flags & SDL_WINDOW_FULLSCREEN) { pparams.BackBufferFormat = PixelFormatToD3DFMT(fullscreen_mode.format); } else { pparams.BackBufferFormat = D3DFMT_UNKNOWN; } pparams.BackBufferCount = 1; pparams.SwapEffect = D3DSWAPEFFECT_DISCARD; if (window_flags & SDL_WINDOW_FULLSCREEN) { pparams.Windowed = FALSE; pparams.FullScreen_RefreshRateInHz = fullscreen_mode.refresh_rate; } else { pparams.Windowed = TRUE; pparams.FullScreen_RefreshRateInHz = 0; } if (flags & SDL_RENDERER_PRESENTVSYNC) { pparams.PresentationInterval = D3DPRESENT_INTERVAL_ONE; } else { pparams.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; } /* FIXME: Which adapter? */ data->adapter = D3DADAPTER_DEFAULT; IDirect3D9_GetDeviceCaps(data->d3d, data->adapter, D3DDEVTYPE_HAL, &caps); result = IDirect3D9_CreateDevice(data->d3d, data->adapter, D3DDEVTYPE_HAL, pparams.hDeviceWindow, D3DCREATE_FPU_PRESERVE | ((caps. DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) ? D3DCREATE_HARDWARE_VERTEXPROCESSING : D3DCREATE_SOFTWARE_VERTEXPROCESSING), &pparams, &data->device); if (FAILED(result)) { D3D_DestroyRenderer(renderer); D3D_SetError("CreateDevice()", result); return NULL; } data->beginScene = SDL_TRUE; data->scaleMode = D3DTEXF_FORCE_DWORD; /* Get presentation parameters to fill info */ result = IDirect3DDevice9_GetSwapChain(data->device, 0, &chain); if (FAILED(result)) { D3D_DestroyRenderer(renderer); D3D_SetError("GetSwapChain()", result); return NULL; } result = IDirect3DSwapChain9_GetPresentParameters(chain, &pparams); if (FAILED(result)) { IDirect3DSwapChain9_Release(chain); D3D_DestroyRenderer(renderer); D3D_SetError("GetPresentParameters()", result); return NULL; } IDirect3DSwapChain9_Release(chain); if (pparams.PresentationInterval == D3DPRESENT_INTERVAL_ONE) { renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC; } data->pparams = pparams; IDirect3DDevice9_GetDeviceCaps(data->device, &caps); renderer->info.max_texture_width = caps.MaxTextureWidth; renderer->info.max_texture_height = caps.MaxTextureHeight; if (caps.NumSimultaneousRTs >= 2) { renderer->info.flags |= SDL_RENDERER_TARGETTEXTURE; } /* Set up parameters for rendering */ IDirect3DDevice9_SetVertexShader(data->device, NULL); IDirect3DDevice9_SetFVF(data->device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1); IDirect3DDevice9_SetRenderState(data->device, D3DRS_ZENABLE, D3DZB_FALSE); IDirect3DDevice9_SetRenderState(data->device, D3DRS_CULLMODE, D3DCULL_NONE); IDirect3DDevice9_SetRenderState(data->device, D3DRS_LIGHTING, FALSE); /* Enable color modulation by diffuse color */ IDirect3DDevice9_SetTextureStageState(data->device, 0, D3DTSS_COLOROP, D3DTOP_MODULATE); IDirect3DDevice9_SetTextureStageState(data->device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE); IDirect3DDevice9_SetTextureStageState(data->device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); /* Enable alpha modulation by diffuse alpha */ IDirect3DDevice9_SetTextureStageState(data->device, 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); IDirect3DDevice9_SetTextureStageState(data->device, 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); IDirect3DDevice9_SetTextureStageState(data->device, 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); /* Disable second texture stage, since we're done */ IDirect3DDevice9_SetTextureStageState(data->device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE); IDirect3DDevice9_SetTextureStageState(data->device, 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); /* Store the default render target */ IDirect3DDevice9_GetRenderTarget(data->device, 0, &data->defaultRenderTarget ); data->currentRenderTarget = NULL; /* Set an identity world and view matrix */ matrix.m[0][0] = 1.0f; matrix.m[0][1] = 0.0f; matrix.m[0][2] = 0.0f; matrix.m[0][3] = 0.0f; matrix.m[1][0] = 0.0f; matrix.m[1][1] = 1.0f; matrix.m[1][2] = 0.0f; matrix.m[1][3] = 0.0f; matrix.m[2][0] = 0.0f; matrix.m[2][1] = 0.0f; matrix.m[2][2] = 1.0f; matrix.m[2][3] = 0.0f; matrix.m[3][0] = 0.0f; matrix.m[3][1] = 0.0f; matrix.m[3][2] = 0.0f; matrix.m[3][3] = 1.0f; IDirect3DDevice9_SetTransform(data->device, D3DTS_WORLD, &matrix); IDirect3DDevice9_SetTransform(data->device, D3DTS_VIEW, &matrix); return renderer; }
SDL_Renderer * D3D_CreateRenderer(SDL_Window * window, Uint32 flags) { SDL_VideoDisplay *display = window->display; SDL_VideoData *videodata = (SDL_VideoData *) display->device->driverdata; SDL_WindowData *windowdata = (SDL_WindowData *) window->driverdata; SDL_Renderer *renderer; D3D_RenderData *data; HRESULT result; D3DPRESENT_PARAMETERS pparams; IDirect3DSwapChain9 *chain; D3DCAPS9 caps; renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer)); if (!renderer) { SDL_OutOfMemory(); return NULL; } data = (D3D_RenderData *) SDL_calloc(1, sizeof(*data)); if (!data) { D3D_DestroyRenderer(renderer); SDL_OutOfMemory(); return NULL; } data->d3d = videodata->d3d; videodata->render = RENDER_D3D; renderer->DisplayModeChanged = D3D_DisplayModeChanged; renderer->CreateTexture = D3D_CreateTexture; renderer->QueryTexturePixels = D3D_QueryTexturePixels; renderer->SetTexturePalette = D3D_SetTexturePalette; renderer->GetTexturePalette = D3D_GetTexturePalette; renderer->SetTextureColorMod = D3D_SetTextureColorMod; renderer->SetTextureAlphaMod = D3D_SetTextureAlphaMod; renderer->SetTextureBlendMode = D3D_SetTextureBlendMode; renderer->SetTextureScaleMode = D3D_SetTextureScaleMode; renderer->UpdateTexture = D3D_UpdateTexture; renderer->LockTexture = D3D_LockTexture; renderer->UnlockTexture = D3D_UnlockTexture; renderer->DirtyTexture = D3D_DirtyTexture; renderer->RenderDrawPoints = D3D_RenderDrawPoints; renderer->RenderDrawLines = D3D_RenderDrawLines; renderer->RenderDrawRects = D3D_RenderDrawRects; renderer->RenderFillRects = D3D_RenderFillRects; renderer->RenderCopy = D3D_RenderCopy; renderer->RenderReadPixels = D3D_RenderReadPixels; renderer->RenderWritePixels = D3D_RenderWritePixels; renderer->RenderPresent = D3D_RenderPresent; renderer->DestroyTexture = D3D_DestroyTexture; renderer->DestroyRenderer = D3D_DestroyRenderer; renderer->info = D3D_RenderDriver.info; renderer->window = window; renderer->driverdata = data; renderer->info.flags = SDL_RENDERER_ACCELERATED; SDL_zero(pparams); pparams.BackBufferWidth = window->w; pparams.BackBufferHeight = window->h; if (window->flags & SDL_WINDOW_FULLSCREEN) { pparams.BackBufferFormat = PixelFormatToD3DFMT(window->fullscreen_mode.format); } else { pparams.BackBufferFormat = D3DFMT_UNKNOWN; } if (flags & SDL_RENDERER_PRESENTFLIP2) { pparams.BackBufferCount = 2; pparams.SwapEffect = D3DSWAPEFFECT_FLIP; } else if (flags & SDL_RENDERER_PRESENTFLIP3) { pparams.BackBufferCount = 3; pparams.SwapEffect = D3DSWAPEFFECT_FLIP; } else if (flags & SDL_RENDERER_PRESENTCOPY) { pparams.BackBufferCount = 1; pparams.SwapEffect = D3DSWAPEFFECT_COPY; } else { pparams.BackBufferCount = 1; pparams.SwapEffect = D3DSWAPEFFECT_DISCARD; } if (window->flags & SDL_WINDOW_FULLSCREEN) { pparams.Windowed = FALSE; pparams.FullScreen_RefreshRateInHz = window->fullscreen_mode.refresh_rate; } else { pparams.Windowed = TRUE; pparams.FullScreen_RefreshRateInHz = 0; } if (flags & SDL_RENDERER_PRESENTVSYNC) { pparams.PresentationInterval = D3DPRESENT_INTERVAL_ONE; } else { pparams.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; } data->adapter = D3D_FindAdapter(videodata->d3d, display); IDirect3D9_GetDeviceCaps(videodata->d3d, data->adapter, D3DDEVTYPE_HAL, &caps); result = IDirect3D9_CreateDevice(videodata->d3d, data->adapter, D3DDEVTYPE_HAL, windowdata->hwnd, (caps. DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) ? D3DCREATE_HARDWARE_VERTEXPROCESSING : D3DCREATE_SOFTWARE_VERTEXPROCESSING, &pparams, &data->device); if (FAILED(result)) { D3D_DestroyRenderer(renderer); D3D_SetError("CreateDevice()", result); return NULL; } data->beginScene = SDL_TRUE; /* Get presentation parameters to fill info */ result = IDirect3DDevice9_GetSwapChain(data->device, 0, &chain); if (FAILED(result)) { D3D_DestroyRenderer(renderer); D3D_SetError("GetSwapChain()", result); return NULL; } result = IDirect3DSwapChain9_GetPresentParameters(chain, &pparams); if (FAILED(result)) { IDirect3DSwapChain9_Release(chain); D3D_DestroyRenderer(renderer); D3D_SetError("GetPresentParameters()", result); return NULL; } IDirect3DSwapChain9_Release(chain); switch (pparams.SwapEffect) { case D3DSWAPEFFECT_COPY: renderer->info.flags |= SDL_RENDERER_PRESENTCOPY; break; case D3DSWAPEFFECT_FLIP: switch (pparams.BackBufferCount) { case 2: renderer->info.flags |= SDL_RENDERER_PRESENTFLIP2; break; case 3: renderer->info.flags |= SDL_RENDERER_PRESENTFLIP3; break; } break; case D3DSWAPEFFECT_DISCARD: renderer->info.flags |= SDL_RENDERER_PRESENTDISCARD; break; } if (pparams.PresentationInterval == D3DPRESENT_INTERVAL_ONE) { renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC; } data->pparams = pparams; IDirect3DDevice9_GetDeviceCaps(data->device, &caps); renderer->info.max_texture_width = caps.MaxTextureWidth; renderer->info.max_texture_height = caps.MaxTextureHeight; /* Set up parameters for rendering */ IDirect3DDevice9_SetVertexShader(data->device, NULL); IDirect3DDevice9_SetFVF(data->device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1); IDirect3DDevice9_SetRenderState(data->device, D3DRS_ZENABLE, D3DZB_FALSE); IDirect3DDevice9_SetRenderState(data->device, D3DRS_CULLMODE, D3DCULL_NONE); IDirect3DDevice9_SetRenderState(data->device, D3DRS_LIGHTING, FALSE); /* Enable color modulation by diffuse color */ IDirect3DDevice9_SetTextureStageState(data->device, 0, D3DTSS_COLOROP, D3DTOP_MODULATE); IDirect3DDevice9_SetTextureStageState(data->device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE); IDirect3DDevice9_SetTextureStageState(data->device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); /* Enable alpha modulation by diffuse alpha */ IDirect3DDevice9_SetTextureStageState(data->device, 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); IDirect3DDevice9_SetTextureStageState(data->device, 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); IDirect3DDevice9_SetTextureStageState(data->device, 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); /* Disable second texture stage, since we're done */ IDirect3DDevice9_SetTextureStageState(data->device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE); IDirect3DDevice9_SetTextureStageState(data->device, 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); { #ifdef ASSEMBLE_SHADER const char *shader_text = "ps_1_1\n" "def c0, 0, 0, 0, 0.496\n" "def c1, 0, 0, 0, 1\n" "def c2, 0, 0, 0, -1\n" "tex t0\n" "mul r1, t0, v0\n" "add r0, r1, c0\n" "cnd r0, r0.a, c1, c2\n" "add r0, r0, r1\n"; LPD3DXBUFFER pCode; // buffer with the assembled shader code LPD3DXBUFFER pErrorMsgs; // buffer with error messages LPDWORD shader_data; DWORD shader_size; result = D3DXAssembleShader( shader_text, SDL_strlen(shader_text), NULL, NULL, 0, &pCode, &pErrorMsgs ); if (FAILED(result)) { D3D_SetError("D3DXAssembleShader()", result); } shader_data = (DWORD*)pCode->lpVtbl->GetBufferPointer(pCode); shader_size = pCode->lpVtbl->GetBufferSize(pCode); #else const DWORD shader_data[] = { 0xffff0101,0x00000051,0xa00f0000,0x00000000,0x00000000,0x00000000, 0x3efdf3b6,0x00000051,0xa00f0001,0x00000000,0x00000000,0x00000000, 0x3f800000,0x00000051,0xa00f0002,0x00000000,0x00000000,0x00000000, 0xbf800000,0x00000042,0xb00f0000,0x00000005,0x800f0001,0xb0e40000, 0x90e40000,0x00000002,0x800f0000,0x80e40001,0xa0e40000,0x00000050, 0x800f0000,0x80ff0000,0xa0e40001,0xa0e40002,0x00000002,0x800f0000, 0x80e40000,0x80e40001,0x0000ffff }; #endif result = IDirect3DDevice9_CreatePixelShader(data->device, shader_data, &data->ps_mask); if (FAILED(result)) { D3D_SetError("CreatePixelShader()", result); } } return renderer; }
SDL_Renderer * D3D_CreateRenderer(SDL_Window * window, Uint32 flags) { SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window); SDL_VideoData *videodata = (SDL_VideoData *) display->device->driverdata; SDL_WindowData *windowdata = (SDL_WindowData *) window->driverdata; SDL_Renderer *renderer; D3D_RenderData *data; HRESULT result; D3DPRESENT_PARAMETERS pparams; IDirect3DSwapChain9 *chain; D3DCAPS9 caps; renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer)); if (!renderer) { SDL_OutOfMemory(); return NULL; } data = (D3D_RenderData *) SDL_calloc(1, sizeof(*data)); if (!data) { D3D_DestroyRenderer(renderer); SDL_OutOfMemory(); return NULL; } data->d3d = videodata->d3d; renderer->DisplayModeChanged = D3D_DisplayModeChanged; renderer->CreateTexture = D3D_CreateTexture; renderer->QueryTexturePixels = D3D_QueryTexturePixels; renderer->SetTexturePalette = D3D_SetTexturePalette; renderer->GetTexturePalette = D3D_GetTexturePalette; renderer->SetTextureColorMod = D3D_SetTextureColorMod; renderer->SetTextureAlphaMod = D3D_SetTextureAlphaMod; renderer->SetTextureBlendMode = D3D_SetTextureBlendMode; renderer->SetTextureScaleMode = D3D_SetTextureScaleMode; renderer->UpdateTexture = D3D_UpdateTexture; renderer->LockTexture = D3D_LockTexture; renderer->UnlockTexture = D3D_UnlockTexture; renderer->DirtyTexture = D3D_DirtyTexture; renderer->RenderPoint = D3D_RenderPoint; renderer->RenderLine = D3D_RenderLine; renderer->RenderFill = D3D_RenderFill; renderer->RenderCopy = D3D_RenderCopy; renderer->RenderPresent = D3D_RenderPresent; renderer->DestroyTexture = D3D_DestroyTexture; renderer->DestroyRenderer = D3D_DestroyRenderer; renderer->info = D3D_RenderDriver.info; renderer->window = window->id; renderer->driverdata = data; renderer->info.flags = SDL_RENDERER_ACCELERATED; SDL_zero(pparams); pparams.BackBufferWidth = window->w; pparams.BackBufferHeight = window->h; if (window->flags & SDL_WINDOW_FULLSCREEN) { pparams.BackBufferFormat = PixelFormatToD3DFMT(display->fullscreen_mode.format); } else { pparams.BackBufferFormat = D3DFMT_UNKNOWN; } if (flags & SDL_RENDERER_PRESENTFLIP2) { pparams.BackBufferCount = 2; pparams.SwapEffect = D3DSWAPEFFECT_FLIP; } else if (flags & SDL_RENDERER_PRESENTFLIP3) { pparams.BackBufferCount = 3; pparams.SwapEffect = D3DSWAPEFFECT_FLIP; } else if (flags & SDL_RENDERER_PRESENTCOPY) { pparams.BackBufferCount = 1; pparams.SwapEffect = D3DSWAPEFFECT_COPY; } else { pparams.BackBufferCount = 1; pparams.SwapEffect = D3DSWAPEFFECT_DISCARD; } if (window->flags & SDL_WINDOW_FULLSCREEN) { pparams.Windowed = FALSE; pparams.FullScreen_RefreshRateInHz = display->fullscreen_mode.refresh_rate; } else { pparams.Windowed = TRUE; pparams.FullScreen_RefreshRateInHz = 0; } if (flags & SDL_RENDERER_PRESENTVSYNC) { pparams.PresentationInterval = D3DPRESENT_INTERVAL_ONE; } else { pparams.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; } IDirect3D9_GetDeviceCaps(videodata->d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &caps); result = IDirect3D9_CreateDevice(videodata->d3d, D3DADAPTER_DEFAULT, /* FIXME */ D3DDEVTYPE_HAL, windowdata->hwnd, (caps. DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) ? D3DCREATE_HARDWARE_VERTEXPROCESSING : D3DCREATE_SOFTWARE_VERTEXPROCESSING, &pparams, &data->device); if (FAILED(result)) { D3D_DestroyRenderer(renderer); D3D_SetError("CreateDevice()", result); return NULL; } data->beginScene = SDL_TRUE; /* Get presentation parameters to fill info */ result = IDirect3DDevice9_GetSwapChain(data->device, 0, &chain); if (FAILED(result)) { D3D_DestroyRenderer(renderer); D3D_SetError("GetSwapChain()", result); return NULL; } result = IDirect3DSwapChain9_GetPresentParameters(chain, &pparams); if (FAILED(result)) { IDirect3DSwapChain9_Release(chain); D3D_DestroyRenderer(renderer); D3D_SetError("GetPresentParameters()", result); return NULL; } IDirect3DSwapChain9_Release(chain); switch (pparams.SwapEffect) { case D3DSWAPEFFECT_COPY: renderer->info.flags |= SDL_RENDERER_PRESENTCOPY; break; case D3DSWAPEFFECT_FLIP: switch (pparams.BackBufferCount) { case 2: renderer->info.flags |= SDL_RENDERER_PRESENTFLIP2; break; case 3: renderer->info.flags |= SDL_RENDERER_PRESENTFLIP3; break; } break; case D3DSWAPEFFECT_DISCARD: renderer->info.flags |= SDL_RENDERER_PRESENTDISCARD; break; } if (pparams.PresentationInterval == D3DPRESENT_INTERVAL_ONE) { renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC; } data->pparams = pparams; IDirect3DDevice9_GetDeviceCaps(data->device, &caps); renderer->info.max_texture_width = caps.MaxTextureWidth; renderer->info.max_texture_height = caps.MaxTextureHeight; /* Set up parameters for rendering */ IDirect3DDevice9_SetVertexShader(data->device, NULL); IDirect3DDevice9_SetFVF(data->device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1); IDirect3DDevice9_SetRenderState(data->device, D3DRS_ZENABLE, D3DZB_FALSE); IDirect3DDevice9_SetRenderState(data->device, D3DRS_CULLMODE, D3DCULL_NONE); IDirect3DDevice9_SetRenderState(data->device, D3DRS_LIGHTING, FALSE); /* Enable color modulation by diffuse color */ IDirect3DDevice9_SetTextureStageState(data->device, 0, D3DTSS_COLOROP, D3DTOP_MODULATE); IDirect3DDevice9_SetTextureStageState(data->device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE); IDirect3DDevice9_SetTextureStageState(data->device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); /* Enable alpha modulation by diffuse alpha */ IDirect3DDevice9_SetTextureStageState(data->device, 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); IDirect3DDevice9_SetTextureStageState(data->device, 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); IDirect3DDevice9_SetTextureStageState(data->device, 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); /* Disable second texture stage, since we're done */ IDirect3DDevice9_SetTextureStageState(data->device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE); IDirect3DDevice9_SetTextureStageState(data->device, 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); return renderer; }
HRESULT D3D9_CreateDevice(vlc_object_t *o, d3d9_handle_t *hd3d, HWND hwnd, const video_format_t *source, d3d9_device_t *out) { HRESULT hr; UINT AdapterToUse = D3DADAPTER_DEFAULT; D3DDEVTYPE DeviceType = D3DDEVTYPE_HAL; #ifndef NDEBUG // Look for 'NVIDIA PerfHUD' adapter // If it is present, override default settings for (UINT Adapter=0; Adapter< IDirect3D9_GetAdapterCount(hd3d->obj); ++Adapter) { D3DADAPTER_IDENTIFIER9 Identifier; hr = IDirect3D9_GetAdapterIdentifier(hd3d->obj,Adapter,0,&Identifier); if (SUCCEEDED(hr) && strstr(Identifier.Description,"PerfHUD") != 0) { AdapterToUse = Adapter; DeviceType = D3DDEVTYPE_REF; break; } } #endif /* ** Get device capabilities */ ZeroMemory(&out->caps, sizeof(out->caps)); hr = IDirect3D9_GetDeviceCaps(hd3d->obj, AdapterToUse, DeviceType, &out->caps); if (FAILED(hr)) { msg_Err(o, "Could not read adapter capabilities. (hr=0x%0lx)", hr); return hr; } msg_Dbg(o, "D3D9 device caps 0x%0lX / 0x%0lX", out->caps.DevCaps, out->caps.DevCaps2); /* TODO: need to test device capabilities and select the right render function */ if (!(out->caps.DevCaps2 & D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES)) { msg_Err(o, "Device does not support stretching from textures."); return E_INVALIDARG; } if ( source->i_width > out->caps.MaxTextureWidth || source->i_height > out->caps.MaxTextureHeight ) { msg_Err(o, "Textures too large %ux%u max possible: %ux%u", source->i_width, source->i_height, (unsigned) out->caps.MaxTextureWidth, (unsigned) out->caps.MaxTextureHeight); return E_INVALIDARG; } out->adapterId = AdapterToUse; out->hwnd = hwnd; if (D3D9_FillPresentationParameters(hd3d, source, out)) { msg_Err(o, "Could not presentation parameters"); return E_INVALIDARG; } /* */ D3DADAPTER_IDENTIFIER9 d3dai; if (FAILED(IDirect3D9_GetAdapterIdentifier(hd3d->obj, AdapterToUse,0, &d3dai))) { msg_Warn(o, "IDirect3D9_GetAdapterIdentifier failed"); } else { msg_Dbg(o, "Direct3d9 Device: %s %lx %lx %lx", d3dai.Description, d3dai.VendorId, d3dai.DeviceId, d3dai.Revision ); } DWORD thread_modes[] = { D3DCREATE_MULTITHREADED, 0 }; DWORD vertex_modes[] = { D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE, D3DCREATE_HARDWARE_VERTEXPROCESSING, D3DCREATE_MIXED_VERTEXPROCESSING, D3DCREATE_SOFTWARE_VERTEXPROCESSING }; for (size_t t = 0; t < ARRAY_SIZE(thread_modes); t++) { for (size_t v = 0; v < ARRAY_SIZE(vertex_modes); v++) { DWORD creationFlags = thread_modes[t] | vertex_modes[v]; if (hd3d->use_ex) hr = IDirect3D9Ex_CreateDeviceEx(hd3d->objex, AdapterToUse, DeviceType, hwnd, creationFlags, &out->pp, NULL, &out->devex); else hr = IDirect3D9_CreateDevice(hd3d->obj, AdapterToUse, DeviceType, hwnd, creationFlags, &out->pp, &out->dev); if (SUCCEEDED(hr)) { out->owner = true; return hr; } } } msg_Err(o, "failed to create the D3D9%s device %d/%d. (hr=0x%lX)", hd3d->use_ex?"Ex":"", AdapterToUse, DeviceType, hr); return hr; }
IDirect3DDevice9 *d3dwin_open( char *title, unsigned int width_, unsigned int height_, D3DFORMAT format, BOOL fullscreen_ ){ DIRECT3DCREATE9 Direct3DCreate9; RECT rect; WNDCLASS wc; UINT32 style; D3DDISPLAYMODE displaymode; D3DPRESENT_PARAMETERS presentparameters; D3DCAPS9 caps; width = width_; height = height_; fullscreen = fullscreen_; inst = GetModuleHandle(NULL); library = (HMODULE) LoadLibrary("d3d9.dll"); if(!library) return NULL; Direct3DCreate9 = (DIRECT3DCREATE9) GetProcAddress(library,"Direct3DCreate9"); if(!Direct3DCreate9) return NULL; direct3d=Direct3DCreate9(D3D_SDK_VERSION); if(!direct3d) return NULL; if(!fullscreen) style = WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU; else{ style = WS_POPUP; ShowCursor(FALSE); } rect.left = 0; rect.top = 0; rect.right = width; rect.bottom = height; if(!fullscreen) AdjustWindowRect( &rect, style, FALSE ); wc.style = CS_VREDRAW|CS_HREDRAW; wc.lpfnWndProc = window_proc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = 0; wc.hIcon = LoadIcon(inst,MAKEINTRESOURCE(IDI_ICON)); wc.hCursor = LoadCursor(inst,IDC_ARROW); wc.hbrBackground = 0; wc.lpszMenuName = 0; wc.lpszClassName = "d3d9"; RegisterClass(&wc); win = CreateWindowEx(0, "d3d9", title, (style)|WS_VISIBLE, 0, 0, rect.right-rect.left, rect.bottom-rect.top, 0, 0, inst, 0); if(!win) return NULL; memset(&presentparameters, 0, sizeof(D3DPRESENT_PARAMETERS)); if(!fullscreen){ if(FAILED(IDirect3D9_GetAdapterDisplayMode( direct3d, D3DADAPTER_DEFAULT, &displaymode ))){ d3dwin_close(); return NULL; } } if(!fullscreen) presentparameters.Windowed = TRUE; presentparameters.SwapEffect = D3DSWAPEFFECT_DISCARD; presentparameters.BackBufferWidth = width; presentparameters.BackBufferHeight = height; if( fullscreen ) presentparameters.BackBufferFormat = format; else presentparameters.BackBufferFormat = displaymode.Format; presentparameters.AutoDepthStencilFormat = D3DFMT_D24S8; presentparameters.EnableAutoDepthStencil = TRUE; IDirect3D9_GetDeviceCaps(direct3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &caps); if(FAILED(IDirect3D9_CreateDevice( direct3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, win, (caps.DevCaps&D3DDEVCAPS_HWTRANSFORMANDLIGHT) ? D3DCREATE_HARDWARE_VERTEXPROCESSING : D3DCREATE_SOFTWARE_VERTEXPROCESSING, &presentparameters, &device))){ d3dwin_close(); return NULL; } IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,0), 1.0f, 0); IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL); return device; }