Changeset 49332 in vbox for trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm
- Timestamp:
- Oct 30, 2013 1:13:02 PM (11 years ago)
- Location:
- trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPVbva.cpp
r44529 r49332 20 20 #include "common/VBoxMPCommon.h" 21 21 22 static int vboxVBVAInformHost (PVBOXMP_DEVEXT pDevExt, VBOXVBVAINFO * pVbva, BOOL bEnable)23 {24 int rc = VERR_NO_MEMORY;25 void *p = VBoxHGSMIBufferAlloc (&VBoxCommonFromDeviceExt(pDevExt)->guestCtx,26 sizeof (VBVAENABLE_EX),27 HGSMI_CH_VBVA,28 VBVA_ENABLE);29 Assert(p);30 if (!p)31 {32 LOGREL(("HGSMIHeapAlloc failed"));33 rc = VERR_NO_MEMORY;34 }35 else36 {37 VBVAENABLE_EX *pEnableEx = (VBVAENABLE_EX *)p;38 pEnableEx->u32ScreenId = pVbva->srcId;39 40 VBVAENABLE *pEnable = &pEnableEx->Base;41 pEnable->u32Flags = bEnable? VBVA_F_ENABLE: VBVA_F_DISABLE;42 pEnable->u32Flags |= VBVA_F_EXTENDED | VBVA_F_ABSOFFSET;43 pEnable->u32Offset = (uint32_t)pVbva->offVBVA;44 pEnable->i32Result = VERR_NOT_SUPPORTED;45 46 VBoxHGSMIBufferSubmit (&VBoxCommonFromDeviceExt(pDevExt)->guestCtx, p);47 48 if (bEnable)49 {50 rc = pEnable->i32Result;51 AssertRC(rc);52 }53 else54 rc = VINF_SUCCESS;55 56 VBoxHGSMIBufferFree (&VBoxCommonFromDeviceExt(pDevExt)->guestCtx, p);57 }58 return rc;59 }60 61 22 /* 62 23 * Public hardware buffer methods. … … 64 25 int vboxVbvaEnable (PVBOXMP_DEVEXT pDevExt, VBOXVBVAINFO *pVbva) 65 26 { 66 VBVABUFFER *pVBVA = pVbva->pVBVA; 27 if (VBoxVBVAEnable(&pVbva->Vbva, &VBoxCommonFromDeviceExt(pDevExt)->guestCtx, 28 pVbva->Vbva.pVBVA, pVbva->srcId)) 29 return VINF_SUCCESS; 67 30 68 // DISPDBG((1, "VBoxDisp::vboxVbvaEnable screen %p vbva off 0x%x\n", ppdev->pjScreen, ppdev->layout.offVBVABuffer)); 69 70 pVBVA->hostFlags.u32HostEvents = 0; 71 pVBVA->hostFlags.u32SupportedOrders = 0; 72 pVBVA->off32Data = 0; 73 pVBVA->off32Free = 0; 74 RtlZeroMemory (pVBVA->aRecords, sizeof (pVBVA->aRecords)); 75 pVBVA->indexRecordFirst = 0; 76 pVBVA->indexRecordFree = 0; 77 pVBVA->cbPartialWriteThreshold = 256; 78 pVBVA->cbData = pVbva->cbVBVA - sizeof (VBVABUFFER) + sizeof (pVBVA->au8Data); 79 80 pVbva->fHwBufferOverflow = FALSE; 81 pVbva->pRecord = NULL; 82 83 int rc = vboxVBVAInformHost (pDevExt, pVbva, TRUE); 84 AssertRC(rc); 85 86 if (!RT_SUCCESS(rc)) 87 vboxVbvaDisable (pDevExt, pVbva); 88 89 return rc; 31 WARN(("VBoxVBVAEnable failed!")); 32 return VERR_GENERAL_FAILURE; 90 33 } 91 34 92 35 int vboxVbvaDisable (PVBOXMP_DEVEXT pDevExt, VBOXVBVAINFO *pVbva) 93 36 { 94 // DISPDBG((1, "VBoxDisp::vbvaDisable called.\n")); 95 96 pVbva->fHwBufferOverflow = FALSE; 97 pVbva->pRecord = NULL; 98 // ppdev->pVBVA = NULL; 99 100 return vboxVBVAInformHost (pDevExt, pVbva, FALSE); 37 VBoxVBVADisable(&pVbva->Vbva, &VBoxCommonFromDeviceExt(pDevExt)->guestCtx, pVbva->srcId); 38 return VINF_SUCCESS; 101 39 } 102 40 … … 108 46 109 47 int rc = VBoxMPCmnMapAdapterMemory(VBoxCommonFromDeviceExt(pDevExt), 110 (void**)&pVbva-> pVBVA,48 (void**)&pVbva->Vbva.pVBVA, 111 49 offBuffer, 112 50 cbBuffer); … … 114 52 if (RT_SUCCESS(rc)) 115 53 { 116 Assert(pVbva->pVBVA); 117 pVbva->offVBVA = offBuffer; 118 pVbva->cbVBVA = cbBuffer; 54 Assert(pVbva->Vbva.pVBVA); 55 VBoxVBVASetupBufferContext(&pVbva->Vbva, offBuffer, cbBuffer); 119 56 pVbva->srcId = srcId; 120 57 } … … 126 63 { 127 64 int rc = VINF_SUCCESS; 128 VBoxMPCmnUnmapAdapterMemory(VBoxCommonFromDeviceExt(pDevExt), (void**)&pVbva-> pVBVA);129 memset(pVbva, 0, sizeof (VBOXVBVAINFO));65 VBoxMPCmnUnmapAdapterMemory(VBoxCommonFromDeviceExt(pDevExt), (void**)&pVbva->Vbva.pVBVA); 66 memset(pVbva, 0, sizeof (VBOXVBVAINFO)); 130 67 return rc; 131 68 } 132 69 133 /*134 * Private operations.135 */136 static uint32_t vboxHwBufferAvail (const VBVABUFFER *pVBVA)137 {138 int32_t i32Diff = pVBVA->off32Data - pVBVA->off32Free;139 140 return i32Diff > 0? i32Diff: pVBVA->cbData + i32Diff;141 }142 143 static void vboxHwBufferFlush (PVBOXMP_DEVEXT pDevExt, VBOXVBVAINFO *pVbva)144 {145 /* Issue the flush command. */146 void *p = VBoxHGSMIBufferAlloc (&VBoxCommonFromDeviceExt(pDevExt)->guestCtx,147 sizeof (VBVAFLUSH),148 HGSMI_CH_VBVA,149 VBVA_FLUSH);150 Assert(p);151 if (!p)152 {153 LOGREL(("HGSMIHeapAlloc failed"));154 }155 else156 {157 VBVAFLUSH *pFlush = (VBVAFLUSH *)p;158 159 pFlush->u32Reserved = 0;160 161 VBoxHGSMIBufferSubmit (&VBoxCommonFromDeviceExt(pDevExt)->guestCtx, p);162 163 VBoxHGSMIBufferFree (&VBoxCommonFromDeviceExt(pDevExt)->guestCtx, p);164 }165 166 return;167 }168 169 static void vboxHwBufferPlaceDataAt (VBVABUFFER *pVBVA, const void *p, uint32_t cb, uint32_t offset)170 {171 uint32_t u32BytesTillBoundary = pVBVA->cbData - offset;172 uint8_t *dst = &pVBVA->au8Data[offset];173 int32_t i32Diff = cb - u32BytesTillBoundary;174 175 if (i32Diff <= 0)176 {177 /* Chunk will not cross buffer boundary. */178 memcpy (dst, p, cb);179 }180 else181 {182 /* Chunk crosses buffer boundary. */183 memcpy (dst, p, u32BytesTillBoundary);184 memcpy (&pVBVA->au8Data[0], (uint8_t *)p + u32BytesTillBoundary, i32Diff);185 }186 187 return;188 }189 190 BOOL vboxVbvaBufferBeginUpdate (PVBOXMP_DEVEXT pDevExt, VBOXVBVAINFO *pVbva)191 {192 BOOL bRc = FALSE;193 194 // DISPDBG((1, "VBoxDisp::vboxHwBufferBeginUpdate called flags = 0x%08X\n",195 // ppdev->pVBVA? ppdev->pVBVA->u32HostEvents: -1));196 197 if ( pVbva->pVBVA198 && (pVbva->pVBVA->hostFlags.u32HostEvents & VBVA_F_MODE_ENABLED))199 {200 uint32_t indexRecordNext;201 202 Assert (!pVbva->fHwBufferOverflow);203 Assert (pVbva->pRecord == NULL);204 205 indexRecordNext = (pVbva->pVBVA->indexRecordFree + 1) % VBVA_MAX_RECORDS;206 207 if (indexRecordNext == pVbva->pVBVA->indexRecordFirst)208 {209 /* All slots in the records queue are used. */210 vboxHwBufferFlush (pDevExt, pVbva);211 }212 213 if (indexRecordNext == pVbva->pVBVA->indexRecordFirst)214 {215 // /* Even after flush there is no place. Fail the request. */216 // LOG(("no space in the queue of records!!! first %d, last %d",217 // ppdev->pVBVA->indexRecordFirst, ppdev->pVBVA->indexRecordFree));218 }219 else220 {221 /* Initialize the record. */222 VBVARECORD *pRecord = &pVbva->pVBVA->aRecords[pVbva->pVBVA->indexRecordFree];223 224 pRecord->cbRecord = VBVA_F_RECORD_PARTIAL;225 226 pVbva->pVBVA->indexRecordFree = indexRecordNext;227 228 // LOG(("indexRecordNext = %d\n", indexRecordNext));229 230 /* Remember which record we are using. */231 pVbva->pRecord = pRecord;232 233 bRc = TRUE;234 }235 }236 237 return bRc;238 }239 240 void vboxVbvaBufferEndUpdate (PVBOXMP_DEVEXT pDevExt, VBOXVBVAINFO *pVbva)241 {242 VBVARECORD *pRecord;243 244 // LOG(("VBoxDisp::vboxHwBufferEndUpdate called"));245 246 Assert(pVbva->pVBVA);247 248 pRecord = pVbva->pRecord;249 Assert (pRecord && (pRecord->cbRecord & VBVA_F_RECORD_PARTIAL));250 251 /* Mark the record completed. */252 pRecord->cbRecord &= ~VBVA_F_RECORD_PARTIAL;253 254 pVbva->fHwBufferOverflow = FALSE;255 pVbva->pRecord = NULL;256 257 return;258 }259 260 static int vboxHwBufferWrite (PVBOXMP_DEVEXT pDevExt, VBOXVBVAINFO *pVbva, const void *p, uint32_t cb)261 {262 VBVARECORD *pRecord;263 uint32_t cbHwBufferAvail;264 265 uint32_t cbWritten = 0;266 267 VBVABUFFER *pVBVA = pVbva->pVBVA;268 Assert(pVBVA);269 270 if (!pVBVA || pVbva->fHwBufferOverflow)271 {272 return VERR_INVALID_STATE;273 }274 275 Assert (pVBVA->indexRecordFirst != pVBVA->indexRecordFree);276 277 pRecord = pVbva->pRecord;278 Assert (pRecord && (pRecord->cbRecord & VBVA_F_RECORD_PARTIAL));279 280 // LOGF(("VW %d", cb));281 282 cbHwBufferAvail = vboxHwBufferAvail (pVBVA);283 284 while (cb > 0)285 {286 uint32_t cbChunk = cb;287 288 // LOG(("pVBVA->off32Free %d, pRecord->cbRecord 0x%08X, cbHwBufferAvail %d, cb %d, cbWritten %d\n",289 // pVBVA->off32Free, pRecord->cbRecord, cbHwBufferAvail, cb, cbWritten));290 291 if (cbChunk >= cbHwBufferAvail)292 {293 LOG(("1) avail %d, chunk %d", cbHwBufferAvail, cbChunk));294 295 vboxHwBufferFlush (pDevExt, pVbva);296 297 cbHwBufferAvail = vboxHwBufferAvail (pVBVA);298 299 if (cbChunk >= cbHwBufferAvail)300 {301 LOG(("no place for %d bytes. Only %d bytes available after flush. Going to partial writes.",302 cb, cbHwBufferAvail));303 304 if (cbHwBufferAvail <= pVBVA->cbPartialWriteThreshold)305 {306 LOGREL(("Buffer overflow!!!"));307 pVbva->fHwBufferOverflow = TRUE;308 Assert(FALSE);309 return VERR_NO_MEMORY;310 }311 312 cbChunk = cbHwBufferAvail - pVBVA->cbPartialWriteThreshold;313 }314 }315 316 Assert(cbChunk <= cb);317 Assert(cbChunk <= vboxHwBufferAvail (pVBVA));318 319 vboxHwBufferPlaceDataAt (pVbva->pVBVA, (uint8_t *)p + cbWritten, cbChunk, pVBVA->off32Free);320 321 pVBVA->off32Free = (pVBVA->off32Free + cbChunk) % pVBVA->cbData;322 pRecord->cbRecord += cbChunk;323 cbHwBufferAvail -= cbChunk;324 325 cb -= cbChunk;326 cbWritten += cbChunk;327 }328 329 return VINF_SUCCESS;330 }331 332 /*333 * Public writer to the hardware buffer.334 */335 int vboxWrite (PVBOXMP_DEVEXT pDevExt, VBOXVBVAINFO *pVbva, const void *pv, uint32_t cb)336 {337 return vboxHwBufferWrite (pDevExt, pVbva, pv, cb);338 }339 340 341 70 int vboxVbvaReportDirtyRect (PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_SOURCE pSrc, RECT *pRectOrig) 342 71 { 343 72 VBVACMDHDR hdr; 344 73 345 74 RECT rect = *pRectOrig; 346 75 347 76 // if (rect.left < 0) rect.left = 0; … … 350 79 // if (rect.bottom > (int)ppdev->cyScreen) rect.bottom = ppdev->cyScreen; 351 80 352 353 354 355 81 hdr.x = (int16_t)rect.left; 82 hdr.y = (int16_t)rect.top; 83 hdr.w = (uint16_t)(rect.right - rect.left); 84 hdr.h = (uint16_t)(rect.bottom - rect.top); 356 85 357 358 86 hdr.x += (int16_t)pSrc->VScreenPos.x; 87 hdr.y += (int16_t)pSrc->VScreenPos.y; 359 88 360 return vboxWrite (pDevExt, &pSrc->Vbva, &hdr, sizeof(hdr)); 89 if (VBoxVBVAWrite(&pSrc->Vbva.Vbva, &VBoxCommonFromDeviceExt(pDevExt)->guestCtx, &hdr, sizeof(hdr))) 90 return VINF_SUCCESS; 91 92 WARN(("VBoxVBVAWrite failed")); 93 return VERR_GENERAL_FAILURE; 361 94 } 362 95 -
trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPVbva.h
r37626 r49332 22 22 typedef struct VBOXVBVAINFO 23 23 { 24 VBOXVIDEOOFFSET offVBVA; 25 uint32_t cbVBVA; 26 VBVABUFFER *pVBVA; 27 BOOL fHwBufferOverflow; 28 VBVARECORD *pRecord; 24 VBVABUFFERCONTEXT Vbva; 29 25 D3DDDI_VIDEO_PRESENT_SOURCE_ID srcId; 30 26 KSPIN_LOCK Lock; … … 37 33 int vboxVbvaReportCmdOffset(PVBOXMP_DEVEXT pDevExt, VBOXVBVAINFO *pVbva, uint32_t offCmd); 38 34 int vboxVbvaReportDirtyRect(PVBOXMP_DEVEXT pDevExt, struct VBOXWDDM_SOURCE *pSrc, RECT *pRectOrig); 39 BOOL vboxVbvaBufferBeginUpdate(PVBOXMP_DEVEXT pDevExt, VBOXVBVAINFO *pVbva);40 void vboxVbvaBufferEndUpdate(PVBOXMP_DEVEXT pDevExt, VBOXVBVAINFO *pVbva);41 35 42 36 #define VBOXVBVA_OP(_op, _pdext, _psrc, _arg) \ 43 37 do { \ 44 if ( vboxVbvaBufferBeginUpdate(_pdext, &(_psrc)->Vbva)) \38 if (VBoxVBVABufferBeginUpdate(&(_psrc)->Vbva.Vbva, &VBoxCommonFromDeviceExt(_pdext)->guestCtx)) \ 45 39 { \ 46 40 vboxVbva##_op(_pdext, _psrc, _arg); \ 47 vboxVbvaBufferEndUpdate(_pdext, &(_psrc)->Vbva); \41 VBoxVBVABufferEndUpdate(&(_psrc)->Vbva.Vbva); \ 48 42 } \ 49 43 } while (0)
Note:
See TracChangeset
for help on using the changeset viewer.