Changeset 91823 in vbox for trunk/src/VBox/Devices
- Timestamp:
- Oct 18, 2021 10:12:46 AM (3 years ago)
- svn:sync-xref-src-repo-rev:
- 147609
- Location:
- trunk/src/VBox/Devices/Graphics
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-dx-shader.cpp
r91607 r91823 118 118 VGPUOperandIndex aOperandIndex[VGPU10_OPERAND_INDEX_3D]; /* Up to 3. */ 119 119 uint32_t aImm[4]; /* Immediate values for VGPU10_OPERAND_TYPE_IMMEDIATE* */ 120 uint32_t cOperandToken; /* Number of tokens in this operand. */ 121 uint32_t const *paOperandToken; /* Pointer to operand tokens in the input buffer. */ 120 122 } VGPUOperand; 121 123 … … 125 127 uint32_t cOpcodeToken; /* Number of tokens for this operation. */ 126 128 uint32_t opcodeType; /* VGPU10_OPCODE_* */ 129 uint32_t opcodeSubtype; /* For example VGPU10_VMWARE_OPCODE_* */ 127 130 uint32_t semanticName; /* SVGA3dDXSignatureSemanticName for system value declarations. */ 128 131 uint32_t cOperand; /* Number of operands for this instruction. */ … … 1178 1181 { 1179 1182 uint8_t *pu8ByteCodeBegin; /* First byte of the buffer. */ 1180 uint8_t *pu8ByteCodePtr; /* Next free byte. */1183 uint8_t *pu8ByteCodePtr; /* Next byte to be written. */ 1181 1184 uint32_t cbAllocated; /* How many bytes allocated in the buffer. */ 1182 1185 uint32_t cbRemaining; /* How many bytes remain in the buffer. */ 1186 uint32_t cbWritten; /* Offset of first never written byte. 1187 * Since the writer allows to jump in the buffer, this field tracks 1188 * the upper boundary of the written data. 1189 */ 1183 1190 int32_t rc; 1184 1191 } DXBCByteWriter; 1185 1192 1186 1193 1194 typedef struct DXBCByteWriterState 1195 { 1196 uint32_t off; /* Offset of the next free byte. */ 1197 } DXBCByteWriterState; 1198 1199 1187 1200 DECLINLINE(void *) dxbcByteWriterPtr(DXBCByteWriter *w) 1188 1201 { … … 1197 1210 1198 1211 1212 static bool dxbcByteWriterRealloc(DXBCByteWriter *w, uint32_t cbNew) 1213 { 1214 void *pvNew = RTMemAllocZ(cbNew); 1215 if (!pvNew) 1216 { 1217 w->rc = VERR_NO_MEMORY; 1218 return false; 1219 } 1220 1221 uint32_t const cbCurrent = dxbcByteWriterSize(w); 1222 memcpy(pvNew, w->pu8ByteCodeBegin, cbCurrent); 1223 RTMemFree(w->pu8ByteCodeBegin); 1224 1225 w->pu8ByteCodeBegin = (uint8_t *)pvNew; 1226 w->pu8ByteCodePtr = w->pu8ByteCodeBegin + cbCurrent; 1227 w->cbAllocated = cbNew; 1228 w->cbRemaining = cbNew - cbCurrent; 1229 return true; 1230 } 1231 1232 1233 DECLINLINE(bool) dxbcByteWriterSetOffset(DXBCByteWriter *w, uint32_t off, DXBCByteWriterState *pSavedWriterState) 1234 { 1235 if (RT_FAILURE(w->rc)) 1236 return false; 1237 1238 uint32_t const cbNew = RT_ALIGN_32(off, 1024); 1239 uint32_t const cbMax = 2 * SVGA3D_MAX_SHADER_MEMORY_BYTES; 1240 AssertReturnStmt(off < cbMax && cbNew < cbMax, w->rc = VERR_INVALID_PARAMETER, false); 1241 1242 if (cbNew > w->cbAllocated) 1243 { 1244 if (!dxbcByteWriterRealloc(w, cbNew)) 1245 return false; 1246 } 1247 1248 pSavedWriterState->off = dxbcByteWriterSize(w); 1249 1250 w->pu8ByteCodePtr = w->pu8ByteCodeBegin + off; 1251 w->cbRemaining = w->cbAllocated - off; 1252 return true; 1253 } 1254 1255 1256 DECLINLINE(void) dxbcByteWriterRestore(DXBCByteWriter *w, DXBCByteWriterState *pSavedWriterState) 1257 { 1258 w->pu8ByteCodePtr = w->pu8ByteCodeBegin + pSavedWriterState->off; 1259 w->cbRemaining = w->cbAllocated - pSavedWriterState->off; 1260 } 1261 1262 1199 1263 DECLINLINE(void) dxbcByteWriterCommit(DXBCByteWriter *w, uint32_t cbCommit) 1200 1264 { 1265 if (RT_FAILURE(w->rc)) 1266 return; 1267 1201 1268 Assert(cbCommit < w->cbRemaining); 1202 1269 cbCommit = RT_MIN(cbCommit, w->cbRemaining); 1203 1270 w->pu8ByteCodePtr += cbCommit; 1204 1271 w->cbRemaining -= cbCommit; 1272 w->cbWritten = RT_MAX(w->cbWritten, w->cbAllocated - w->cbRemaining); 1205 1273 } 1206 1274 … … 1208 1276 DECLINLINE(bool) dxbcByteWriterCanWrite(DXBCByteWriter *w, uint32_t cbMore) 1209 1277 { 1278 if (RT_FAILURE(w->rc)) 1279 return false; 1280 1210 1281 if (cbMore <= w->cbRemaining) 1211 1282 return true; … … 1216 1287 1217 1288 uint32_t cbNew = w->cbAllocated + RT_ALIGN_32(cbMore, 4096); 1218 void *pvNew = RTMemAllocZ(cbNew); 1219 if (!pvNew) 1220 { 1221 w->rc = VERR_NO_MEMORY; 1222 return false; 1223 } 1224 1225 uint32_t const cbCurrent = dxbcByteWriterSize(w); 1226 memcpy(pvNew, w->pu8ByteCodeBegin, cbCurrent); 1227 RTMemFree(w->pu8ByteCodeBegin); 1228 1229 w->pu8ByteCodeBegin = (uint8_t *)pvNew; 1230 w->pu8ByteCodePtr = w->pu8ByteCodeBegin + cbCurrent; 1231 w->cbAllocated = cbNew; 1232 w->cbRemaining = cbNew - cbCurrent; 1233 1234 return true; 1289 return dxbcByteWriterRealloc(w, cbNew); 1235 1290 } 1236 1291 … … 1268 1323 { 1269 1324 *ppv = w->pu8ByteCodeBegin; 1270 *pcb = dxbcByteWriterSize(w);1325 *pcb = w->cbWritten; 1271 1326 1272 1327 w->pu8ByteCodeBegin = NULL; … … 1287 1342 1288 1343 ASSERT_GUEST_RETURN(dxbcTokenReaderCanRead(r, 1), VERR_INVALID_PARAMETER); 1344 1345 paOperand->paOperandToken = dxbcTokenReaderPtr(r); 1346 paOperand->cOperandToken = 0; 1289 1347 1290 1348 VGPU10OperandToken0 operand0; … … 1420 1478 } 1421 1479 1480 paOperand->cOperandToken = dxbcTokenReaderPtr(r) - paOperand->paOperandToken; 1481 1422 1482 *pcOperandRemain -= 1; 1423 1483 return VINF_SUCCESS; … … 1439 1499 ASSERT_GUEST_RETURN(pOpcode->opcodeType < VGPU10_NUM_OPCODES, VERR_INVALID_PARAMETER); 1440 1500 1501 Log6(("[%#x] %s length %d\n", 1502 dxbcTokenReaderByteOffset(r) - 4, dxbcOpcodeToString(pOpcode->opcodeType), opcode.instructionLength)); 1503 1441 1504 uint32_t const cOperand = g_aOpcodeInfo[pOpcode->opcodeType].cOperand; 1442 1505 if (cOperand != UINT32_MAX) 1443 1506 { 1444 #ifdef LOG_ENABLED1445 if (pOpcode->opcodeType == VGPU10_OPCODE_DCL_RESOURCE)1446 Log6(("[%#x] %s length %d %s\n",1447 dxbcTokenReaderByteOffset(r) - 4, dxbcOpcodeToString(pOpcode->opcodeType), opcode.instructionLength, dxbcResourceDimensionToString(opcode.resourceDimension)));1448 else1449 Log6(("[%#x] %s length %d %s\n",1450 dxbcTokenReaderByteOffset(r) - 4, dxbcOpcodeToString(pOpcode->opcodeType), opcode.instructionLength, dxbcInterpolationModeToString(opcode.interpolationMode)));1451 #endif1452 1453 1507 ASSERT_GUEST_RETURN(cOperand < RT_ELEMENTS(pOpcode->aIdxOperand), VERR_INVALID_PARAMETER); 1454 1508 … … 1473 1527 ASSERT_GUEST_RETURN(dxbcTokenReaderCanRead(r, pOpcode->cOpcodeToken - 1), VERR_INVALID_PARAMETER); 1474 1528 1529 #ifdef LOG_ENABLED 1530 Log6((" %08X", opcode.value)); 1531 for (uint32_t i = 1; i < pOpcode->cOpcodeToken; ++i) 1532 Log6((" %08X", r->pToken[i - 1])); 1533 Log6(("\n")); 1534 1535 if (pOpcode->opcodeType == VGPU10_OPCODE_DCL_RESOURCE) 1536 Log6((" %s\n", 1537 dxbcResourceDimensionToString(opcode.resourceDimension))); 1538 else 1539 Log6((" %s\n", 1540 dxbcInterpolationModeToString(opcode.interpolationMode))); 1541 #endif 1475 1542 /* Additional tokens before operands. */ 1476 1543 switch (pOpcode->opcodeType) … … 1611 1678 if (pOpcode->opcodeType == VGPU10_OPCODE_CUSTOMDATA) 1612 1679 { 1613 Log6(("[%#x] %s %s\n",1614 dxbcTokenReaderByteOffset(r) - 4, dxbcOpcodeToString(pOpcode->opcodeType), dxbcCustomDataClassToString(opcode.customDataClass)));1615 1616 1680 ASSERT_GUEST_RETURN(dxbcTokenReaderCanRead(r, 1), VERR_INVALID_PARAMETER); 1617 1681 pOpcode->cOpcodeToken = dxbcTokenReaderRead32(r); … … 1621 1685 ASSERT_GUEST_RETURN(dxbcTokenReaderCanRead(r, pOpcode->cOpcodeToken - 2), VERR_INVALID_PARAMETER); 1622 1686 1687 #ifdef LOG_ENABLED 1688 Log6((" %08X", opcode.value)); 1689 for (uint32_t i = 1; i < pOpcode->cOpcodeToken; ++i) 1690 Log6((" %08X", r->pToken[i - 1])); 1691 Log6(("\n")); 1692 1693 Log6((" %s\n", 1694 dxbcCustomDataClassToString(opcode.customDataClass))); 1695 #endif 1623 1696 dxbcTokenReaderSkip(r, pOpcode->cOpcodeToken - 2); 1624 1697 } 1625 1698 else if (pOpcode->opcodeType == VGPU10_OPCODE_VMWARE) 1626 1699 { 1627 Log6(("[%#x] %s %s(%d)\n", 1628 dxbcTokenReaderByteOffset(r) - 4, dxbcOpcodeToString(pOpcode->opcodeType), dxbcVmwareOpcodeTypeToString(opcode.vmwareOpcodeType), opcode.vmwareOpcodeType)); 1629 1630 /** @todo implement */ 1631 ASSERT_GUEST_FAILED_RETURN(VERR_INVALID_PARAMETER); 1700 pOpcode->cOpcodeToken = opcode.instructionLength; 1701 pOpcode->opcodeSubtype = opcode.vmwareOpcodeType; 1702 1703 #ifdef LOG_ENABLED 1704 Log6((" %08X", opcode.value)); 1705 for (uint32_t i = 1; i < pOpcode->cOpcodeToken; ++i) 1706 Log6((" %08X", r->pToken[i - 1])); 1707 Log6(("\n")); 1708 1709 Log6((" %s(%d)\n", 1710 dxbcVmwareOpcodeTypeToString(opcode.vmwareOpcodeType), opcode.vmwareOpcodeType)); 1711 #endif 1712 1713 if (opcode.vmwareOpcodeType == VGPU10_VMWARE_OPCODE_IDIV) 1714 { 1715 /* Integer divide. */ 1716 pOpcode->cOperand = 4; /* dstQuit, dstRem, src0, src1. */ 1717 1718 /* Operands. */ 1719 uint32_t cOperandRemain = RT_ELEMENTS(pOpcode->aValOperand); 1720 for (uint32_t i = 0; i < pOpcode->cOperand; ++i) 1721 { 1722 Log6((" [operand %d]\n", i)); 1723 uint32_t const idxOperand = RT_ELEMENTS(pOpcode->aValOperand) - cOperandRemain; 1724 pOpcode->aIdxOperand[i] = idxOperand; 1725 int rc = dxbcParseOperand(r, &pOpcode->aValOperand[idxOperand], &cOperandRemain); 1726 ASSERT_GUEST_RETURN(RT_SUCCESS(rc), VERR_INVALID_PARAMETER); 1727 } 1728 } 1729 //else if (opcode.vmwareOpcodeType == VGPU10_VMWARE_OPCODE_DFRC) 1730 //else if (opcode.vmwareOpcodeType == VGPU10_VMWARE_OPCODE_DRSQ) 1731 else 1732 { 1733 /** @todo implement */ 1734 ASSERT_GUEST_FAILED_RETURN(VERR_INVALID_PARAMETER); 1735 } 1632 1736 } 1633 1737 else … … 1644 1748 { 1645 1749 VGPU10ProgramToken programToken; 1646 bool fEmulateOpcodeVmware; 1750 uint32_t cToken; /* Number of tokens in the original shader code. */ 1751 1752 uint32_t offSubroutine; /* Current offset where to write subroutines. */ 1647 1753 } DXBCOUTPUTCTX; 1648 1754 1649 1755 1650 void dxbcOutputInit(DXBCOUTPUTCTX *pOutctx, VGPU10ProgramToken const *pProgramToken, uint32_t cToken) 1651 { 1652 RT_NOREF(pProgramToken, cToken); 1756 static void dxbcOutputInit(DXBCOUTPUTCTX *pOutctx, VGPU10ProgramToken const *pProgramToken, uint32_t cToken) 1757 { 1653 1758 RT_ZERO(*pOutctx); 1654 1759 pOutctx->programToken = *pProgramToken; 1655 } 1656 1657 1658 int dxbcOutputOpcode(DXBCOUTPUTCTX *pOutctx, DXBCByteWriter *w, VGPUOpcode *pOpcode) 1659 { 1760 pOutctx->cToken = cToken; 1761 1762 pOutctx->offSubroutine = cToken * 4; 1763 } 1764 1765 1766 static int dxbcEmitVmwareIDIV(DXBCOUTPUTCTX *pOutctx, DXBCByteWriter *w, VGPUOpcode *pOpcode) 1767 { 1768 /* Insert a call and append a subroutne. */ 1769 VGPU10OpcodeToken0 opcode; 1770 VGPU10OperandToken0 operand; 1771 1772 uint32_t const label = (pOutctx->offSubroutine - dxbcByteWriterSize(w)) / 4; 1773 1774 /* 1775 * Call 1776 */ 1777 opcode.value = 0; 1778 opcode.opcodeType = VGPU10_OPCODE_CALL; 1779 opcode.instructionLength = 3; 1780 dxbcByteWriterAddTokens(w, &opcode.value, 1); 1781 1782 operand.value = 0; 1783 operand.numComponents = VGPU10_OPERAND_1_COMPONENT; 1784 operand.operandType = VGPU10_OPERAND_TYPE_LABEL; 1785 operand.indexDimension = VGPU10_OPERAND_INDEX_1D; 1786 operand.index0Representation = VGPU10_OPERAND_INDEX_IMMEDIATE32; 1787 dxbcByteWriterAddTokens(w, &operand.value, 1); 1788 1789 dxbcByteWriterAddTokens(w, &label, 1); 1790 1791 opcode.value = 0; 1792 opcode.opcodeType = VGPU10_OPCODE_NOP; 1793 opcode.instructionLength = 1; 1794 for (int i = 0; i < 8 - 3; ++i) 1795 dxbcByteWriterAddTokens(w, &opcode.value, 1); 1796 1797 /* 1798 * Subroutine. 1799 */ 1800 DXBCByteWriterState savedWriterState; 1801 if (!dxbcByteWriterSetOffset(w, pOutctx->offSubroutine, &savedWriterState)) 1802 return w->rc; 1803 1804 /* label */ 1805 opcode.value = 0; 1806 opcode.opcodeType = VGPU10_OPCODE_LABEL; 1807 opcode.instructionLength = 3; 1808 dxbcByteWriterAddTokens(w, &opcode.value, 1); 1809 1810 operand.value = 0; 1811 operand.numComponents = VGPU10_OPERAND_1_COMPONENT; 1812 operand.operandType = VGPU10_OPERAND_TYPE_LABEL; 1813 operand.indexDimension = VGPU10_OPERAND_INDEX_1D; 1814 operand.index0Representation = VGPU10_OPERAND_INDEX_IMMEDIATE32; 1815 dxbcByteWriterAddTokens(w, &operand.value, 1); 1816 dxbcByteWriterAddTokens(w, &label, 1); 1817 1818 /* Just output UDIV for now. */ 1819 opcode.value = 0; 1820 opcode.opcodeType = VGPU10_OPCODE_UDIV; 1821 opcode.instructionLength = pOpcode->cOpcodeToken; 1822 dxbcByteWriterAddTokens(w, &opcode.value, 1); 1823 dxbcByteWriterAddTokens(w, &pOpcode->paOpcodeToken[1], pOpcode->cOpcodeToken - 1); 1824 1825 /* ret */ 1826 opcode.value = 0; 1827 opcode.opcodeType = VGPU10_OPCODE_RET; 1828 opcode.instructionLength = 1; 1829 dxbcByteWriterAddTokens(w, &opcode.value, 1); 1830 1831 pOutctx->offSubroutine = dxbcByteWriterSize(w); 1832 dxbcByteWriterRestore(w, &savedWriterState); 1833 1834 return w->rc; 1835 } 1836 1837 1838 static int dxbcOutputOpcode(DXBCOUTPUTCTX *pOutctx, DXBCByteWriter *w, VGPUOpcode *pOpcode) 1839 { 1840 #ifdef DEBUG 1841 void *pvBegin = dxbcByteWriterPtr(w); 1842 #endif 1843 1660 1844 if ( pOutctx->programToken.programType == VGPU10_PIXEL_SHADER 1661 1845 && pOpcode->opcodeType == VGPU10_OPCODE_DCL_RESOURCE) … … 1663 1847 /** @todo This is a workaround. */ 1664 1848 /* Sometimes the guest (Mesa) created a shader with uninitialized resource dimension. 1665 * Use texture 2d because buffer is notwhat a pixel shader normally uses.1849 * Use texture 2d because it is what a pixel shader normally uses. 1666 1850 */ 1667 1851 ASSERT_GUEST_RETURN(pOpcode->cOpcodeToken == 4, VERR_INVALID_PARAMETER); … … 1679 1863 } 1680 1864 } 1681 1865 else if (pOpcode->opcodeType == VGPU10_OPCODE_VMWARE) 1866 { 1867 if (pOpcode->opcodeSubtype == VGPU10_VMWARE_OPCODE_IDIV) 1868 { 1869 return dxbcEmitVmwareIDIV(pOutctx, w, pOpcode); 1870 } 1871 1872 ASSERT_GUEST_FAILED_RETURN(VERR_NOT_SUPPORTED); 1873 } 1874 1875 #ifdef DEBUG 1876 /* The code above must emit either nothing or everything. */ 1877 Assert((uintptr_t)pvBegin == (uintptr_t)dxbcByteWriterPtr(w)); 1878 #endif 1879 1880 /* Just emit the unmodified instruction. */ 1682 1881 dxbcByteWriterAddTokens(w, pOpcode->paOpcodeToken, pOpcode->cOpcodeToken); 1683 1882 return VINF_SUCCESS; … … 1685 1884 1686 1885 1687 int dxbcOutputFinalize(DXBCOUTPUTCTX *pOutctx, DXBCByteWriter *w)1886 static int dxbcOutputFinalize(DXBCOUTPUTCTX *pOutctx, DXBCByteWriter *w) 1688 1887 { 1689 1888 RT_NOREF(pOutctx, w); … … 1822 2021 1823 2022 dxbcByteWriterFetchData(w, &pInfo->pvBytecode, &pInfo->cbBytecode); 2023 uint32_t *pcOutputToken = (uint32_t *)pInfo->pvBytecode + 1; 2024 *pcOutputToken = pInfo->cbBytecode / 4; 1824 2025 1825 2026 #ifdef LOG_ENABLED … … 2161 2362 int rc = DXShaderParse(pvShaderCode, cbShaderCode, &info); 2162 2363 if (RT_SUCCESS(rc)) 2163 rc = DXShaderCreateDXBC(&info, info.pvBytecode, info.cbBytecode,ppvDXBC, pcbDXBC);2364 rc = DXShaderCreateDXBC(&info, ppvDXBC, pcbDXBC); 2164 2365 return rc; 2165 2366 } -
trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-win-dx.cpp
r91607 r91823 6342 6342 if (pvShaderBytecode) 6343 6343 { 6344 #ifdef LOG_ENABLED 6345 Log(("Shader: cid=%u shid=%u type=%d:\n", pDXContext->cid, pShader->id, pDXShader->enmShaderType)); 6346 uint8_t *pu8 = (uint8_t *)pvShaderBytecode; 6347 for (uint32_t i = 0; i < pShader->cbData; ++i) 6348 { 6349 if ((i % 16) == 0) 6350 { 6351 if (i > 0) 6352 Log6((",\n")); 6353 6354 Log6((" %#04x", pu8[i])); 6355 } 6356 else 6357 { 6358 Log6((", %#04x", pu8[i])); 6359 } 6360 } 6361 Log6(("\n")); 6362 #endif 6344 Log(("Shader: cid=%u shid=%u type=%d\n", pDXContext->cid, pShader->id, pDXShader->enmShaderType)); 6363 6345 6364 6346 rc = DXShaderCreateDXBC(&pShader->shaderInfo, &pDXShader->pvDXBC, &pDXShader->cbDXBC); … … 6371 6353 HRESULT hr2 = pBackend->pfnD3DDisassemble(pDXShader->pvDXBC, pDXShader->cbDXBC, 0, NULL, &pBlob); 6372 6354 if (SUCCEEDED(hr2) && pBlob && pBlob->GetBufferSize()) 6373 { 6374 Log6(("Shader: cid=%u shid=%u type=%d:\n%s\n", 6375 pDXContext->cid, pShader->id, pDXShader->enmShaderType, pBlob->GetBufferPointer())); 6376 } 6355 Log6(("%s\n", pBlob->GetBufferPointer())); 6377 6356 else 6378 6357 AssertFailed();
Note:
See TracChangeset
for help on using the changeset viewer.