Changeset 82415 in vbox for trunk/src/VBox/Additions
- Timestamp:
- Dec 5, 2019 12:56:36 PM (5 years ago)
- Location:
- trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/gallium
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/gallium/GaDxva.cpp
r82330 r82415 16 16 */ 17 17 18 #include "VBoxGallium.h"19 //#include "../../../common/wddm/VBoxMPIf.h"20 18 #include "../VBoxDispD3DCmn.h" 21 #include "../VBoxDispD3D.h"22 23 19 24 20 #define D3D_RELEASE(ptr) do { \ … … 32 28 struct Vertex 33 29 { 34 float x, y; /* The vertex position . */35 float u, v; /* Texture coordinates. */30 float x, y; /* The vertex position in pixels. */ 31 float u, v; /* Normalized texture coordinates. */ 36 32 }; 33 34 /* Saved context. */ 35 typedef struct VBOXDXVAD3D9SAVEDSTATE 36 { 37 D3DVIEWPORT9 Viewport; 38 DWORD rsCull; 39 DWORD rsZEnable; 40 IDirect3DSurface9 *pRT; 41 IDirect3DVertexShader9 *pVS; 42 IDirect3DPixelShader9 *pPS; 43 IDirect3DBaseTexture9 *pTexture; 44 float aVSConstantData[4]; 45 float aPSConstantData[4]; 46 DWORD ssMagFilter; 47 DWORD ssMinFilter; 48 DWORD ssMipFilter; 49 } VBOXDXVAD3D9SAVEDSTATE; 37 50 38 51 /* … … 51 64 /* The current render target, i.e. the Blt destination. */ 52 65 PVBOXWDDMDISP_RESOURCE pRenderTarget; 53 UINT SubResourceIndex; 54 IDirect3DTexture9 *pRTTexture; 66 UINT RTSubResourceIndex; 67 IDirect3DTexture9 *pRTTexture; 68 IDirect3DSurface9 *pRTSurface; 55 69 56 70 /* Private objects for video processing. */ 57 IDirect3DTexture9 *p Texture; /* Intermediate texture. */71 IDirect3DTexture9 *pStagingTexture; /* Intermediate texture. */ 58 72 IDirect3DVertexBuffer9 *pVB; /* Vertex buffer which describes the quad we render. */ 59 73 IDirect3DVertexDeclaration9 *pVertexDecl; /* Vertex declaration for the quad vertices. */ 60 74 IDirect3DVertexShader9 *pVS; /* Vertex shader. */ 61 75 IDirect3DPixelShader9 *pPS; /* Pixel shader. */ 76 77 /* Saved D3D device state, which the blitter changes. */ 78 VBOXDXVAD3D9SAVEDSTATE SavedState; 62 79 } VBOXWDDMVIDEOPROCESSDEVICE; 63 80 64 static const GUIDgaDeviceGuids[] =81 static GUID const gaDeviceGuids[] = 65 82 { 66 83 DXVADDI_VideoProcProgressiveDevice, … … 68 85 }; 69 86 70 static const D3DDDIFORMATgaInputFormats[] =87 static D3DDDIFORMAT const gaInputFormats[] = 71 88 { 72 89 D3DDDIFMT_YUY2 73 90 }; 74 91 75 static const D3DDDIFORMATgaOutputFormats[] =92 static D3DDDIFORMAT const gaOutputFormats[] = 76 93 { 77 94 D3DDDIFMT_A8R8G8B8, … … 99 116 } 100 117 101 102 static HRESULT vboxDxvaInit(VBOXWDDMVIDEOPROCESSDEVICE *pVideoProcessDevice /*, 103 DWORD const *paVS, DWORD const *paPS*/) 118 static HRESULT vboxDxvaCopyToVertexBuffer(IDirect3DVertexBuffer9 *pVB, const void *pvSrc, int cbSrc) 119 { 120 void *pvDst = 0; 121 HRESULT hr = pVB->Lock(0, 0, &pvDst, 0); 122 if (SUCCEEDED(hr)) 123 { 124 memcpy(pvDst, pvSrc, cbSrc); 125 hr = pVB->Unlock(); 126 } 127 return hr; 128 } 129 130 static HRESULT vboxDxvaDeviceStateSave(IDirect3DDevice9 *pDevice9, VBOXDXVAD3D9SAVEDSTATE *pState) 104 131 { 105 132 HRESULT hr; 106 133 134 hr = pDevice9->GetViewport(&pState->Viewport); 135 AssertReturn(hr == D3D_OK, hr); 136 137 hr = pDevice9->GetRenderState(D3DRS_CULLMODE, &pState->rsCull); 138 AssertReturn(hr == D3D_OK, hr); 139 140 hr = pDevice9->GetRenderState(D3DRS_ZENABLE, &pState->rsZEnable); 141 AssertReturn(hr == D3D_OK, hr); 142 143 hr = pDevice9->GetRenderTarget(0, &pState->pRT); 144 AssertReturn(hr == D3D_OK, hr); 145 146 hr = pDevice9->GetVertexShader(&pState->pVS); 147 AssertReturn(hr == D3D_OK, hr); 148 149 hr = pDevice9->GetPixelShader(&pState->pPS); 150 AssertReturn(hr == D3D_OK, hr); 151 152 hr = pDevice9->GetTexture(0, &pState->pTexture); 153 AssertReturn(hr == D3D_OK, hr); 154 155 hr = pDevice9->GetVertexShaderConstantF(0, pState->aVSConstantData, 1); 156 AssertReturn(hr == D3D_OK, hr); 157 158 hr = pDevice9->GetPixelShaderConstantF(0, pState->aPSConstantData, 1); 159 AssertReturn(hr == D3D_OK, hr); 160 161 hr = pDevice9->GetSamplerState(0, D3DSAMP_MAGFILTER, &pState->ssMagFilter); 162 AssertReturn(hr == D3D_OK, hr); 163 164 hr = pDevice9->GetSamplerState(0, D3DSAMP_MINFILTER, &pState->ssMinFilter); 165 AssertReturn(hr == D3D_OK, hr); 166 167 hr = pDevice9->GetSamplerState(0, D3DSAMP_MIPFILTER, &pState->ssMipFilter); 168 AssertReturn(hr == D3D_OK, hr); 169 170 return hr; 171 } 172 173 static void vboxDxvaDeviceStateRestore(IDirect3DDevice9 *pDevice9, VBOXDXVAD3D9SAVEDSTATE const *pState) 174 { 175 HRESULT hr; 176 177 hr = pDevice9->SetViewport(&pState->Viewport); 178 Assert(hr == D3D_OK); 179 180 hr = pDevice9->SetRenderState(D3DRS_CULLMODE, pState->rsCull); 181 Assert(hr == D3D_OK); 182 183 hr = pDevice9->SetRenderState(D3DRS_ZENABLE, pState->rsZEnable); 184 Assert(hr == D3D_OK); 185 186 hr = pDevice9->SetRenderTarget(0, pState->pRT); 187 Assert(hr == D3D_OK); 188 189 hr = pDevice9->SetVertexShader(pState->pVS); 190 Assert(hr == D3D_OK); 191 192 hr = pDevice9->SetPixelShader(pState->pPS); 193 Assert(hr == D3D_OK); 194 195 hr = pDevice9->SetTexture(0, pState->pTexture); 196 Assert(hr == D3D_OK); 197 198 hr = pDevice9->SetVertexShaderConstantF(0, pState->aVSConstantData, 1); 199 Assert(hr == D3D_OK); 200 201 hr = pDevice9->SetPixelShaderConstantF(0, pState->aPSConstantData, 1); 202 Assert(hr == D3D_OK); 203 204 hr = pDevice9->SetSamplerState(0, D3DSAMP_MAGFILTER, pState->ssMagFilter); 205 Assert(hr == D3D_OK); 206 207 hr = pDevice9->SetSamplerState(0, D3DSAMP_MINFILTER, pState->ssMinFilter); 208 Assert(hr == D3D_OK); 209 210 hr = pDevice9->SetSamplerState(0, D3DSAMP_MIPFILTER, pState->ssMipFilter); 211 Assert(hr == D3D_OK); 212 } 213 214 static HRESULT vboxDxvaUploadSample(VBOXWDDMVIDEOPROCESSDEVICE *pVideoProcessDevice, 215 IDirect3DTexture9 *pSrcTexture, 216 UINT SrcSubResourceIndex) 217 { 218 HRESULT hr; 219 220 /* 221 * Upload the source data to the staging texture. 222 */ 223 D3DLOCKED_RECT StagingLockedRect; 224 hr = pVideoProcessDevice->pStagingTexture->LockRect(0, /* texture level */ 225 &StagingLockedRect, 226 NULL, /* entire texture */ 227 D3DLOCK_DISCARD); 228 Assert(hr == D3D_OK); 229 if (hr == D3D_OK) 230 { 231 D3DLOCKED_RECT SampleLockedRect; 232 hr = pSrcTexture->LockRect(SrcSubResourceIndex, /* texture level */ 233 &SampleLockedRect, 234 NULL, /* entire texture */ 235 D3DLOCK_READONLY); 236 Assert(hr == D3D_OK); 237 if (hr == D3D_OK) 238 { 239 uint8_t *pDst = (uint8_t *)StagingLockedRect.pBits; 240 const uint8_t *pSrc = (uint8_t *)SampleLockedRect.pBits; 241 for (uint32_t j = 0; j < pVideoProcessDevice->VideoDesc.SampleHeight; ++j) 242 { 243 memcpy(pDst, pSrc, RT_MIN(SampleLockedRect.Pitch, StagingLockedRect.Pitch)); 244 245 pDst += StagingLockedRect.Pitch; 246 pSrc += SampleLockedRect.Pitch; 247 } 248 249 pSrcTexture->UnlockRect(SrcSubResourceIndex /* texture level */); 250 } 251 pVideoProcessDevice->pStagingTexture->UnlockRect(0 /* texture level */); 252 } 253 254 return hr; 255 } 256 257 /* 258 * The shader code has been obtained from the hex listing file (hexdump.txt) produced by fxc HLSL compiler: 259 * fxc.exe /Op /Tfx_2_0 /Fxhexdump.txt shader.fx 260 * 261 uniform extern float4 gTextureInfo; // .xy = (TargetWidth, TargetHeight), .zw = (SourceWidth, SourceHeight) in pixels 262 uniform extern texture gTexSource; 263 sampler sSource = sampler_state 264 { 265 Texture = <gTexSource>; 266 }; 267 268 struct VS_INPUT 269 { 270 float2 Position : POSITION; // In pixels 271 float2 TexCoord : TEXCOORD0; // Normalized 272 }; 273 274 struct VS_OUTPUT 275 { 276 float4 Position : POSITION; // Normalized 277 float2 TexCoord : TEXCOORD0; // Normalized 278 }; 279 280 VS_OUTPUT VS(VS_INPUT In) 281 { 282 VS_OUTPUT Output; 283 284 // Target position is in pixels, i.e left,top is 0,0; right,bottom is width - 1,height - 1. 285 // Convert to the normalized coords in the -1;1 range (x right, y up). 286 float4 Position; 287 Position.x = 2.0f * In.Position.x / (gTextureInfo.x - 1.0f) - 1.0f; 288 Position.y = -2.0f * In.Position.y / (gTextureInfo.y - 1.0f) + 1.0f; 289 Position.z = 0.0f; // Not used. 290 Position.w = 1.0f; // It is a point. 291 292 Output.Position = Position; 293 Output.TexCoord = In.TexCoord; 294 295 return Output; 296 } 297 298 struct PS_OUTPUT 299 { 300 float4 Color : COLOR0; 301 }; 302 303 static const float3x3 yuvCoeffs = 304 { 305 1.164383f, 1.164383f, 1.164383f, 306 0.0f, -0.391762f, 2.017232f, 307 1.596027f, -0.812968f, 0.0f 308 }; 309 310 PS_OUTPUT PS(VS_OUTPUT In) 311 { 312 PS_OUTPUT Output; 313 314 // 4 bytes of an YUV macropixel contain 2 pixels in X for the target. 315 // I.e. each YUV texture pixel is sampled twice: for both even and odd target pixels. 316 317 // In.TexCoord are in [0;1] range for the source texture. 318 float2 texCoord = In.TexCoord; 319 320 // Source texture data is half width, i.e. it contains data in pixels [0; width / 2 - 1]. 321 texCoord.x = texCoord.x / 2.0f; 322 323 // Which source pixel needs to be read: xPixel = TexCoord.x * SourceWidth. 324 float xSourcePixel = texCoord.x * gTextureInfo.z; 325 326 // Remainder is about 0.25 for even pixels and about 0.75 for odd pixels. 327 float remainder = xSourcePixel - trunc(xSourcePixel); 328 329 // Fetch YUV 330 float4 texColor = tex2D(sSource, texCoord); 331 332 // Get YUV components. 333 float y0 = texColor.b; 334 float u = texColor.g; 335 float y1 = texColor.r; 336 float v = texColor.a; 337 338 // Get y0 for even x coordinates and y1 for odd ones. 339 float y = remainder < 0.5f ? y0 : y1; 340 341 // Make a vector for easier calculation. 342 float3 yuv = float3(y, u, v); 343 344 // Convert YUV to RGB for BT.601: 345 // https://docs.microsoft.com/en-us/windows/win32/medfound/recommended-8-bit-yuv-formats-for-video-rendering#converting-8-bit-yuv-to-rgb888 346 // 347 // For 8bit [0;255] when Y = [16;235], U,V = [16;239]: 348 // 349 // C = Y - 16 350 // D = U - 128 351 // E = V - 128 352 // 353 // R = 1.164383 * C + 1.596027 * E 354 // G = 1.164383 * C - 0.391762 * D - 0.812968 * E 355 // B = 1.164383 * C + 2.017232 * D 356 // 357 // For shader values [0;1.0] when Y = [16/255;235/255], U,V = [16/255;239/255]: 358 // 359 // C = Y - 0.0627 360 // D = U - 0.5020 361 // E = V - 0.5020 362 // 363 // R = 1.164383 * C + 1.596027 * E 364 // G = 1.164383 * C - 0.391762 * D - 0.812968 * E 365 // B = 1.164383 * C + 2.017232 * D 366 // 367 yuv -= float3(0.0627f, 0.502f, 0.502f); 368 float3 bgr = mul(yuv, yuvCoeffs); 369 370 // Clamp to [0;1] 371 bgr = saturate(bgr); 372 373 // Return RGBA 374 Output.Color = float4(bgr, 1.0f); 375 376 return Output; 377 } 378 379 technique RenderScene 380 { 381 pass P0 382 { 383 VertexShader = compile vs_2_0 VS(); 384 PixelShader = compile ps_2_0 PS(); 385 } 386 } 387 */ 388 389 static DWORD const aVSCode[] = 390 { 391 0xfffe0200, // vs_2_0 392 0x05000051, 0xa00f0001, 0xbf800000, 0xc0000000, 0x3f800000, 0x00000000, // def c1, -1, -2, 1, 0 393 0x0200001f, 0x80000000, 0x900f0000, // dcl_position v0 394 0x0200001f, 0x80000005, 0x900f0001, // dcl_texcoord v1 395 0x03000002, 0x80010000, 0x90000000, 0x90000000, // add r0.x, v0.x, v0.x 396 0x02000001, 0x80010001, 0xa0000001, // mov r1.x, c1.x 397 0x03000002, 0x80060000, 0x80000001, 0xa0d00000, // add r0.yz, r1.x, c0.xxyw 398 0x02000006, 0x80020000, 0x80550000, // rcp r0.y, r0.y 399 0x02000006, 0x80040000, 0x80aa0000, // rcp r0.z, r0.z 400 0x04000004, 0xc0010000, 0x80000000, 0x80550000, 0xa0000001, // mad oPos.x, r0.x, r0.y, c1.x 401 0x03000005, 0x80010000, 0x90550000, 0xa0550001, // mul r0.x, v0.y, c1.y 402 0x04000004, 0xc0020000, 0x80000000, 0x80aa0000, 0xa0aa0001, // mad oPos.y, r0.x, r0.z, c1.z 403 0x02000001, 0xc00c0000, 0xa0b40001, // mov oPos.zw, c1.xywz 404 0x02000001, 0xe0030000, 0x90e40001, // mov oT0.xy, v1 405 0x0000ffff 406 }; 407 408 static DWORD const aPSCodeYUY2toRGB[] = 409 { 410 0xffff0200, // ps_2_0 411 0x05000051, 0xa00f0001, 0xbd8068dc, 0xbf008312, 0xbf008312, 0x00000000, // def c1, -0.0627000034, -0.501999974, -0.501999974, 0 412 0x05000051, 0xa00f0002, 0x3f000000, 0x00000000, 0x3f800000, 0x3f000000, // def c2, 0.5, 0, 1, 0.5 413 0x05000051, 0xa00f0003, 0x3f950a81, 0x00000000, 0x3fcc4a9d, 0x00000000, // def c3, 1.16438305, 0, 1.59602702, 0 414 0x05000051, 0xa00f0004, 0x3f950a81, 0xbec89507, 0xbf501eac, 0x00000000, // def c4, 1.16438305, -0.391761988, -0.812968016, 0 415 0x05000051, 0xa00f0005, 0x3f950a81, 0x40011a54, 0x00000000, 0x00000000, // def c5, 1.16438305, 2.01723194, 0, 0 416 0x0200001f, 0x80000000, 0xb0030000, // dcl t0.xy 417 0x0200001f, 0x90000000, 0xa00f0800, // dcl_2d s0 418 0x03000005, 0x80080000, 0xb0000000, 0xa0000002, // mul r0.w, t0.x, c2.x 419 0x03000005, 0x80010000, 0x80ff0000, 0xa0aa0000, // mul r0.x, r0.w, c0.z 420 0x02000013, 0x80020000, 0x80000000, // frc r0.y, r0.x 421 0x04000058, 0x80040000, 0x81550000, 0xa0550002, 0xa0aa0002, // cmp r0.z, -r0.y, c2.y, c2.z 422 0x03000002, 0x80020000, 0x80000000, 0x81550000, // add r0.y, r0.x, -r0.y 423 0x04000058, 0x80010000, 0x80000000, 0xa0550002, 0x80aa0000, // cmp r0.x, r0.x, c2.y, r0.z 424 0x03000002, 0x80010000, 0x80000000, 0x80550000, // add r0.x, r0.x, r0.y 425 0x04000004, 0x80010000, 0x80ff0000, 0xa0aa0000, 0x81000000, // mad r0.x, r0.w, c0.z, -r0.x 426 0x03000002, 0x80010000, 0x80000000, 0xa1ff0002, // add r0.x, r0.x, -c2.w 427 0x03000005, 0x80030001, 0xb0e40000, 0xa01b0002, // mul r1.xy, t0, c2.wzyx 428 0x03000042, 0x800f0001, 0x80e40001, 0xa0e40800, // texld r1, r1, s0 429 0x04000058, 0x80010001, 0x80000000, 0x80000001, 0x80aa0001, // cmp r1.x, r0.x, r1.x, r1.z 430 0x02000001, 0x80040001, 0x80ff0001, // mov r1.z, r1.w 431 0x03000002, 0x80070000, 0x80e40001, 0xa0e40001, // add r0.xyz, r1, c1 432 0x03000008, 0x80110001, 0x80e40000, 0xa0e40003, // dp3_sat r1.x, r0, c3 433 0x03000008, 0x80120001, 0x80e40000, 0xa0e40004, // dp3_sat r1.y, r0, c4 434 0x0400005a, 0x80140001, 0x80e40000, 0xa0e40005, 0xa0aa0005, // dp2add_sat r1.z, r0, c5, c5.z 435 0x02000001, 0x80080001, 0xa0aa0002, // mov r1.w, c2.z 436 0x02000001, 0x800f0800, 0x80e40001, // mov oC0, r1 437 0x0000ffff 438 }; 439 440 441 static HRESULT vboxDxvaInit(VBOXWDDMVIDEOPROCESSDEVICE *pVideoProcessDevice) 442 { 443 HRESULT hr; 444 107 445 IDirect3DDevice9 *pDevice9 = pVideoProcessDevice->pDevice->pDevice9If; 108 AssertPtrReturn(pDevice9, E_INVALIDARG); 109 110 #if 0 446 447 DWORD const *paVS = &aVSCode[0]; 448 DWORD const *paPS = &aPSCodeYUY2toRGB[0]; 449 111 450 static D3DVERTEXELEMENT9 const aVertexElements[] = 112 451 { … … 116 455 }; 117 456 118 HRESULThr = pDevice9->CreateVertexDeclaration(aVertexElements, &pVideoProcessDevice->pVertexDecl);457 hr = pDevice9->CreateVertexDeclaration(aVertexElements, &pVideoProcessDevice->pVertexDecl); 119 458 AssertReturn(hr == D3D_OK, hr); 120 459 … … 132 471 hr = pDevice9->CreatePixelShader(paPS, &pVideoProcessDevice->pPS); 133 472 AssertReturn(hr == D3D_OK, hr); 134 #endif135 473 136 474 hr = pDevice9->CreateTexture(pVideoProcessDevice->VideoDesc.SampleWidth, 137 138 139 140 D3DFMT_YUY2, /** @todo Maybe a stretch is enough because host already does the conversion? */141 142 &pVideoProcessDevice->pTexture,143 475 pVideoProcessDevice->VideoDesc.SampleHeight, 476 0, /* Levels */ 477 0, /* D3DUSAGE_ */ 478 D3DFMT_A8R8G8B8, //D3DFMT_YUY2, 479 D3DPOOL_DEFAULT, 480 &pVideoProcessDevice->pStagingTexture, 481 NULL); 144 482 AssertReturn(hr == D3D_OK, hr); 145 483 … … 147 485 } 148 486 149 static HRESULT vboxDxvaBltRect(VBOXWDDMVIDEOPROCESSDEVICE *pVideoProcessDevice, 150 IDirect3DTexture9 *pSrcTexture, 151 UINT SrcSubResourceIndex, 152 RECT const *pSrcRect, 153 RECT const *pDstRect) 487 static HRESULT vboxDxvaSetState(VBOXWDDMVIDEOPROCESSDEVICE *pVideoProcessDevice) 154 488 { 155 489 HRESULT hr; 156 490 157 491 IDirect3DDevice9 *pDevice9 = pVideoProcessDevice->pDevice->pDevice9If; 158 AssertPtrReturn(pDevice9, E_INVALIDARG); 159 160 hr = pDevice9->UpdateTexture(pSrcTexture, pVideoProcessDevice->pTexture); 161 AssertReturn(hr == D3D_OK, hr); 162 163 IDirect3DSurface9 *pSrcSurface; 164 hr = pVideoProcessDevice->pTexture->GetSurfaceLevel(SrcSubResourceIndex, &pSrcSurface); 165 AssertReturn(hr == D3D_OK, hr); 166 167 IDirect3DSurface9 *pDstSurface; 168 hr = pVideoProcessDevice->pRTTexture->GetSurfaceLevel(pVideoProcessDevice->SubResourceIndex, &pDstSurface); 169 AssertReturnStmt(hr == D3D_OK, D3D_RELEASE(pSrcSurface), hr); 170 171 hr = pDevice9->StretchRect(pSrcSurface, pSrcRect, pDstSurface, pDstRect, D3DTEXF_NONE); 172 173 D3D_RELEASE(pSrcSurface); 174 D3D_RELEASE(pDstSurface); 175 492 493 hr = pDevice9->SetStreamSource(0, pVideoProcessDevice->pVB, 0, sizeof(Vertex)); 494 AssertReturn(hr == D3D_OK, hr); 495 496 hr = pDevice9->SetVertexDeclaration(pVideoProcessDevice->pVertexDecl); 497 AssertReturn(hr == D3D_OK, hr); 498 499 hr = pDevice9->SetVertexShader(pVideoProcessDevice->pVS); 500 AssertReturn(hr == D3D_OK, hr); 501 502 hr = pDevice9->SetPixelShader(pVideoProcessDevice->pPS); 503 AssertReturn(hr == D3D_OK, hr); 504 505 hr = pDevice9->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); 506 AssertReturn(hr == D3D_OK, hr); 507 508 hr = pDevice9->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE); 509 AssertReturn(hr == D3D_OK, hr); 510 511 hr = pDevice9->SetTexture(0, pVideoProcessDevice->pStagingTexture); 512 AssertReturn(hr == D3D_OK, hr); 513 514 float const cTargetWidth = pVideoProcessDevice->pRenderTarget->aAllocations[0].SurfDesc.width; 515 float const cTargetHeight = pVideoProcessDevice->pRenderTarget->aAllocations[0].SurfDesc.height; 516 517 float const cSampleWidth = pVideoProcessDevice->VideoDesc.SampleWidth; 518 float const cSampleHeight = pVideoProcessDevice->VideoDesc.SampleHeight; 519 520 float aTextureInfo[4]; 521 aTextureInfo[0] = cTargetWidth; 522 aTextureInfo[1] = cTargetHeight; 523 aTextureInfo[2] = cSampleWidth; 524 aTextureInfo[3] = cSampleHeight; 525 526 hr = pDevice9->SetVertexShaderConstantF(0, aTextureInfo, 1); 527 AssertReturn(hr == D3D_OK, hr); 528 hr = pDevice9->SetPixelShaderConstantF(0, aTextureInfo, 1); 529 AssertReturn(hr == D3D_OK, hr); 530 531 hr = pDevice9->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT); 532 AssertReturn(hr == D3D_OK, hr); 533 hr = pDevice9->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT); 534 AssertReturn(hr == D3D_OK, hr); 535 hr = pDevice9->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_NONE); 536 AssertReturn(hr == D3D_OK, hr); 537 538 hr = pDevice9->SetRenderTarget(0, pVideoProcessDevice->pRTSurface); 176 539 AssertReturn(hr == D3D_OK, hr); 177 540 178 541 return S_OK; 542 } 543 544 static HRESULT vboxDxvaUpdateVertexBuffer(VBOXWDDMVIDEOPROCESSDEVICE *pVideoProcessDevice, 545 RECT const *pSrcRect, 546 RECT const *pDstRect) 547 { 548 HRESULT hr; 549 550 /* Do not display anything if the source rectangle is not what is expected. 551 * But assert anyway in order to be able to investigate. 552 */ 553 AssertReturn(pSrcRect->right > pSrcRect->left, S_OK); 554 AssertReturn(pSrcRect->bottom > pSrcRect->top, S_OK); 555 556 float const cSrcWidth = pVideoProcessDevice->VideoDesc.SampleWidth; 557 float const cSrcHeight = pVideoProcessDevice->VideoDesc.SampleHeight; 558 559 float const uSrcLeft = pSrcRect->left/cSrcWidth; 560 float const uSrcRight = pSrcRect->right/cSrcWidth; 561 float const vSrcTop = pSrcRect->top/cSrcHeight; 562 float const vSrcBottom = pSrcRect->bottom/cSrcHeight; 563 564 /* Subtract 0.5 to line up the pixel centers with texels 565 * https://docs.microsoft.com/en-us/windows/win32/direct3d9/directly-mapping-texels-to-pixels 566 */ 567 float const xDstLeft = pDstRect->left - 0.5f; 568 float const xDstRight = pDstRect->right - 0.5f; 569 float const yDstTop = pDstRect->top - 0.5f; 570 float const yDstBottom = pDstRect->bottom - 0.5f; 571 572 Vertex const aVertices[] = 573 { 574 { xDstLeft, yDstTop, uSrcLeft, vSrcTop}, 575 { xDstRight, yDstTop, uSrcRight, vSrcTop}, 576 { xDstRight, yDstBottom, uSrcRight, vSrcBottom}, 577 578 { xDstLeft, yDstTop, uSrcLeft, vSrcTop}, 579 { xDstRight, yDstBottom, uSrcRight, vSrcBottom}, 580 { xDstLeft, yDstBottom, uSrcLeft, vSrcBottom}, 581 }; 582 583 hr = vboxDxvaCopyToVertexBuffer(pVideoProcessDevice->pVB, aVertices, sizeof(aVertices)); 584 AssertReturn(hr == D3D_OK, hr); 585 586 return S_OK; 587 } 588 589 static HRESULT vboxDxvaProcessBlt(VBOXWDDMVIDEOPROCESSDEVICE *pVideoProcessDevice, 590 D3DDDIARG_VIDEOPROCESSBLT const *pData, 591 IDirect3DTexture9 *paSrcTextures[]) 592 { 593 HRESULT hr; 594 595 IDirect3DDevice9 *pDevice9 = pVideoProcessDevice->pDevice->pDevice9If; 596 597 hr = vboxDxvaDeviceStateSave(pDevice9, &pVideoProcessDevice->SavedState); 598 if (hr == D3D_OK) 599 { 600 /* Set the required state for the blits, inclusding the render target. */ 601 hr = vboxDxvaSetState(pVideoProcessDevice); 602 if (hr == D3D_OK) 603 { 604 /* Clear the target rectangle. */ 605 /** @todo Use pData->BackgroundColor */ 606 D3DCOLOR BgColor = 0; 607 D3DRECT TargetRect; 608 TargetRect.x1 = pData->TargetRect.left; 609 TargetRect.y1 = pData->TargetRect.top; 610 TargetRect.x2 = pData->TargetRect.right; 611 TargetRect.y2 = pData->TargetRect.bottom; 612 hr = pDevice9->Clear(1, &TargetRect, D3DCLEAR_TARGET, BgColor, 0.0f, 0); 613 Assert(hr == D3D_OK); /* Ignore errors. */ 614 615 DXVADDI_VIDEOSAMPLE const *pSrcSample = &pData->pSrcSurfaces[0]; 616 IDirect3DTexture9 *pSrcTexture = paSrcTextures[0]; 617 618 /* Upload the source data to the staging texture. */ 619 hr = vboxDxvaUploadSample(pVideoProcessDevice, pSrcTexture, pSrcSample->SrcSubResourceIndex); 620 if (hr == D3D_OK) 621 { 622 /* Setup the blit dimensions. */ 623 hr = vboxDxvaUpdateVertexBuffer(pVideoProcessDevice, &pSrcSample->SrcRect, &pSrcSample->DstRect); 624 Assert(hr == D3D_OK); 625 if (hr == D3D_OK) 626 { 627 628 hr = pDevice9->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2); 629 Assert(hr == D3D_OK); 630 } 631 } 632 } 633 634 vboxDxvaDeviceStateRestore(pDevice9, &pVideoProcessDevice->SavedState); 635 } 636 637 return hr; 179 638 } 180 639 … … 209 668 if (pVPI) 210 669 { 211 LOGREL(("%dx%d", pVPI->VideoDesc.SampleWidth, pVPI->VideoDesc.SampleHeight));212 213 670 if (vboxDxvaFindDeviceGuid(pVPI->pVideoProcGuid) >= 0) 214 671 { … … 230 687 if (pVPI) 231 688 { 232 LOGREL(("%dx%d", pVPI->VideoDesc.SampleWidth, pVPI->VideoDesc.SampleHeight));233 234 689 if (vboxDxvaFindDeviceGuid(pVPI->pVideoProcGuid) >= 0) 235 690 { … … 256 711 if (pVPI) 257 712 { 258 LOGREL(("%dx%d", pVPI->VideoDesc.SampleWidth, pVPI->VideoDesc.SampleHeight));259 260 713 if (vboxDxvaFindDeviceGuid(pVPI->pVideoProcGuid) >= 0) 261 714 { … … 310 763 HRESULT VBoxDxvaDestroyVideoProcessDevice(PVBOXWDDMDISP_DEVICE pDevice, HANDLE hVideoProcessor) 311 764 { 312 RT_NOREF(pDevice);313 314 VBOXWDDMVIDEOPROCESSDEVICE *pVideoProcessDevice = (VBOXWDDMVIDEOPROCESSDEVICE *)hVideoProcessor;315 if (pVideoProcessDevice)316 {317 D3D_RELEASE(pVideoProcessDevice->pVertexDecl);318 D3D_RELEASE(pVideoProcessDevice->pVB);319 D3D_RELEASE(pVideoProcessDevice->pVS);320 D3D_RELEASE(pVideoProcessDevice->pPS);321 322 RTMemFree(pVideoProcessDevice);323 }324 return S_OK;325 }326 327 HRESULT VBoxDxvaVideoProcessBeginFrame(PVBOXWDDMDISP_DEVICE pDevice, HANDLE hVideoProcessor)328 {329 765 VBOXWDDMVIDEOPROCESSDEVICE *pVideoProcessDevice = (VBOXWDDMVIDEOPROCESSDEVICE *)hVideoProcessor; 330 766 AssertReturn(pDevice == pVideoProcessDevice->pDevice, E_INVALIDARG); 331 767 768 D3D_RELEASE(pVideoProcessDevice->pRTSurface); 769 770 D3D_RELEASE(pVideoProcessDevice->pStagingTexture); 771 D3D_RELEASE(pVideoProcessDevice->pVertexDecl); 772 D3D_RELEASE(pVideoProcessDevice->pVB); 773 D3D_RELEASE(pVideoProcessDevice->pVS); 774 D3D_RELEASE(pVideoProcessDevice->pPS); 775 776 RTMemFree(pVideoProcessDevice); 777 778 return S_OK; 779 } 780 781 HRESULT VBoxDxvaVideoProcessBeginFrame(PVBOXWDDMDISP_DEVICE pDevice, HANDLE hVideoProcessor) 782 { 783 VBOXWDDMVIDEOPROCESSDEVICE *pVideoProcessDevice = (VBOXWDDMVIDEOPROCESSDEVICE *)hVideoProcessor; 784 AssertReturn(pDevice == pVideoProcessDevice->pDevice, E_INVALIDARG); 785 AssertPtrReturn(pDevice->pDevice9If, E_INVALIDARG); 786 332 787 HRESULT hr = S_OK; 333 if (!pVideoProcessDevice->p Texture)788 if (!pVideoProcessDevice->pStagingTexture) 334 789 { 335 790 hr = vboxDxvaInit(pVideoProcessDevice); … … 352 807 AssertReturn(pDevice == pVideoProcessDevice->pDevice, E_INVALIDARG); 353 808 809 D3D_RELEASE(pVideoProcessDevice->pRTSurface); 810 pVideoProcessDevice->pRenderTarget = NULL; 811 pVideoProcessDevice->RTSubResourceIndex = 0; 812 pVideoProcessDevice->pRTTexture = NULL; 813 354 814 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hRenderTarget; 355 815 AssertReturn(pRc->cAllocations > pData->SubResourceIndex, E_INVALIDARG); 356 357 pVideoProcessDevice->pRenderTarget = pRc;358 pVideoProcessDevice->SubResourceIndex = pData->SubResourceIndex;359 816 360 817 VBOXWDDMDISP_ALLOCATION *pAllocation = &pRc->aAllocations[pData->SubResourceIndex]; … … 362 819 AssertReturn(pAllocation->enmD3DIfType == VBOXDISP_D3DIFTYPE_TEXTURE, E_INVALIDARG); 363 820 364 pVideoProcessDevice->pRTTexture = (IDirect3DTexture9 *)pAllocation->pD3DIf; 365 821 #ifdef LOG_ENABLED 366 822 LOGREL_EXACT(("VideoProcess RT %dx%d sid=%u\n", 367 823 pRc->aAllocations[0].SurfDesc.width, pRc->aAllocations[0].SurfDesc.height, pAllocation->hostID)); 824 #endif 825 826 IDirect3DTexture9 *pRTTexture = (IDirect3DTexture9 *)pAllocation->pD3DIf; 827 HRESULT hr = pRTTexture->GetSurfaceLevel(pData->SubResourceIndex, &pVideoProcessDevice->pRTSurface); 828 AssertReturn(hr == D3D_OK, E_INVALIDARG); 829 830 pVideoProcessDevice->pRenderTarget = pRc; 831 pVideoProcessDevice->RTSubResourceIndex = pData->SubResourceIndex; 832 pVideoProcessDevice->pRTTexture = pRTTexture; 368 833 369 834 return S_OK; … … 372 837 HRESULT VBoxDxvaVideoProcessBlt(PVBOXWDDMDISP_DEVICE pDevice, const D3DDDIARG_VIDEOPROCESSBLT *pData) 373 838 { 374 HRESULT hr;375 376 839 VBOXWDDMVIDEOPROCESSDEVICE *pVideoProcessDevice = (VBOXWDDMVIDEOPROCESSDEVICE *)pData->hVideoProcess; 377 840 AssertReturn(pDevice == pVideoProcessDevice->pDevice, E_INVALIDARG); 841 AssertPtrReturn(pDevice->pDevice9If, E_INVALIDARG); 842 AssertPtrReturn(pVideoProcessDevice->pRTSurface, E_INVALIDARG); 843 844 AssertReturn(pData->NumSrcSurfaces > 0, E_INVALIDARG); 378 845 379 846 PVBOXWDDMDISP_RESOURCE pSrcRc = (PVBOXWDDMDISP_RESOURCE)pData->pSrcSurfaces[0].SrcResource; 380 381 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->pSrcSurfaces[0].SrcResource; 382 AssertReturn(pRc->cAllocations > pData->pSrcSurfaces[0].SrcSubResourceIndex, E_INVALIDARG); 383 384 VBOXWDDMDISP_ALLOCATION *pAllocation = &pRc->aAllocations[pData->pSrcSurfaces[0].SrcSubResourceIndex]; 847 AssertReturn(pSrcRc->cAllocations > pData->pSrcSurfaces[0].SrcSubResourceIndex, E_INVALIDARG); 848 849 VBOXWDDMDISP_ALLOCATION *pAllocation = &pSrcRc->aAllocations[pData->pSrcSurfaces[0].SrcSubResourceIndex]; 385 850 AssertPtrReturn(pAllocation->pD3DIf, E_INVALIDARG); 386 851 AssertReturn(pAllocation->enmD3DIfType == VBOXDISP_D3DIFTYPE_TEXTURE, E_INVALIDARG); … … 388 853 IDirect3DTexture9 *pSrcTexture = (IDirect3DTexture9 *)pAllocation->pD3DIf; 389 854 390 LOGREL_EXACT(("VideoProcess Blt sid = %u %d,%d %dx%d (%dx%d) -> %d,%d %dx%d (%d,%d %dx%d, %dx%d)\n", 391 pAllocation->hostID, 855 #ifdef LOG_ENABLED 856 LOGREL_EXACT(("VideoProcess Blt sid = %u fmt 0x%08x %d,%d %dx%d (%dx%d) -> %d,%d %dx%d (%d,%d %dx%d, %dx%d)\n", 857 pAllocation->hostID, pSrcRc->aAllocations[0].SurfDesc.format, 392 858 pData->pSrcSurfaces[0].SrcRect.left, pData->pSrcSurfaces[0].SrcRect.top, 393 859 pData->pSrcSurfaces[0].SrcRect.right - pData->pSrcSurfaces[0].SrcRect.left, … … 406 872 pVideoProcessDevice->pRenderTarget->aAllocations[0].SurfDesc.width, 407 873 pVideoProcessDevice->pRenderTarget->aAllocations[0].SurfDesc.height)); 408 409 hr = vboxDxvaBltRect(pVideoProcessDevice, pSrcTexture, pData->pSrcSurfaces[0].SrcSubResourceIndex, 410 &pData->pSrcSurfaces[0].SrcRect, 411 &pData->pSrcSurfaces[0].DstRect); 412 413 return S_OK; 414 } 874 #endif 875 876 HRESULT hr = vboxDxvaProcessBlt(pVideoProcessDevice, pData, &pSrcTexture); 877 return hr; 878 } -
trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/gallium/GaDxva.h
r82330 r82415 32 32 HRESULT VBoxDxvaGetOutputFormats(D3DDDIFORMAT *paFormats, UINT cbFormats, DXVADDI_VIDEOPROCESSORINPUT const *pVPI, bool fSubstream); 33 33 34 HRESULT VBoxDxvaGetCaps(DXVADDI_VIDEOPROCESSORCAPS *pVideoProcessorCaps, 35 DXVADDI_VIDEOPROCESSORINPUT const *pVPI); 34 HRESULT VBoxDxvaGetCaps(DXVADDI_VIDEOPROCESSORCAPS *pVideoProcessorCaps, DXVADDI_VIDEOPROCESSORINPUT const *pVPI); 36 35 37 36 HRESULT VBoxDxvaCreateVideoProcessDevice(PVBOXWDDMDISP_DEVICE pDevice, D3DDDIARG_CREATEVIDEOPROCESSDEVICE *pData); … … 39 38 HRESULT VBoxDxvaVideoProcessBeginFrame(PVBOXWDDMDISP_DEVICE pDevice, HANDLE hVideoProcessor); 40 39 HRESULT VBoxDxvaVideoProcessEndFrame(PVBOXWDDMDISP_DEVICE pDevice, D3DDDIARG_VIDEOPROCESSENDFRAME *pData); 41 HRESULT VBoxDxvaSetVideoProcessRenderTarget(PVBOXWDDMDISP_DEVICE pDevice, 42 const D3DDDIARG_SETVIDEOPROCESSRENDERTARGET *pData); 40 HRESULT VBoxDxvaSetVideoProcessRenderTarget(PVBOXWDDMDISP_DEVICE pDevice, const D3DDDIARG_SETVIDEOPROCESSRENDERTARGET *pData); 43 41 HRESULT VBoxDxvaVideoProcessBlt(PVBOXWDDMDISP_DEVICE pDevice, const D3DDDIARG_VIDEOPROCESSBLT *pData); 44 42
Note:
See TracChangeset
for help on using the changeset viewer.