VirtualBox

Changeset 91823 in vbox for trunk/src/VBox/Devices


Ignore:
Timestamp:
Oct 18, 2021 10:12:46 AM (3 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
147609
Message:

Devices/Graphics: parser improvements; logging: bugref:9830

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  
    118118    VGPUOperandIndex aOperandIndex[VGPU10_OPERAND_INDEX_3D]; /* Up to 3. */
    119119    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. */
    120122} VGPUOperand;
    121123
     
    125127    uint32_t cOpcodeToken;              /* Number of tokens for this operation. */
    126128    uint32_t opcodeType;                /* VGPU10_OPCODE_* */
     129    uint32_t opcodeSubtype;             /* For example VGPU10_VMWARE_OPCODE_* */
    127130    uint32_t semanticName;              /* SVGA3dDXSignatureSemanticName for system value declarations. */
    128131    uint32_t cOperand;                  /* Number of operands for this instruction. */
     
    11781181{
    11791182    uint8_t *pu8ByteCodeBegin; /* First byte of the buffer. */
    1180     uint8_t *pu8ByteCodePtr;   /* Next free byte. */
     1183    uint8_t *pu8ByteCodePtr;   /* Next byte to be written. */
    11811184    uint32_t cbAllocated;      /* How many bytes allocated in the buffer. */
    11821185    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                                */
    11831190    int32_t  rc;
    11841191} DXBCByteWriter;
    11851192
    11861193
     1194typedef struct DXBCByteWriterState
     1195{
     1196    uint32_t off;              /* Offset of the next free byte. */
     1197} DXBCByteWriterState;
     1198
     1199
    11871200DECLINLINE(void *) dxbcByteWriterPtr(DXBCByteWriter *w)
    11881201{
     
    11971210
    11981211
     1212static 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
     1233DECLINLINE(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
     1256DECLINLINE(void) dxbcByteWriterRestore(DXBCByteWriter *w, DXBCByteWriterState *pSavedWriterState)
     1257{
     1258    w->pu8ByteCodePtr = w->pu8ByteCodeBegin + pSavedWriterState->off;
     1259    w->cbRemaining = w->cbAllocated - pSavedWriterState->off;
     1260}
     1261
     1262
    11991263DECLINLINE(void) dxbcByteWriterCommit(DXBCByteWriter *w, uint32_t cbCommit)
    12001264{
     1265    if (RT_FAILURE(w->rc))
     1266        return;
     1267
    12011268    Assert(cbCommit < w->cbRemaining);
    12021269    cbCommit = RT_MIN(cbCommit, w->cbRemaining);
    12031270    w->pu8ByteCodePtr += cbCommit;
    12041271    w->cbRemaining -= cbCommit;
     1272    w->cbWritten = RT_MAX(w->cbWritten, w->cbAllocated - w->cbRemaining);
    12051273}
    12061274
     
    12081276DECLINLINE(bool) dxbcByteWriterCanWrite(DXBCByteWriter *w, uint32_t cbMore)
    12091277{
     1278    if (RT_FAILURE(w->rc))
     1279        return false;
     1280
    12101281    if (cbMore <= w->cbRemaining)
    12111282        return true;
     
    12161287
    12171288    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);
    12351290}
    12361291
     
    12681323{
    12691324    *ppv = w->pu8ByteCodeBegin;
    1270     *pcb = dxbcByteWriterSize(w);
     1325    *pcb = w->cbWritten;
    12711326
    12721327    w->pu8ByteCodeBegin = NULL;
     
    12871342
    12881343    ASSERT_GUEST_RETURN(dxbcTokenReaderCanRead(r, 1), VERR_INVALID_PARAMETER);
     1344
     1345    paOperand->paOperandToken = dxbcTokenReaderPtr(r);
     1346    paOperand->cOperandToken = 0;
    12891347
    12901348    VGPU10OperandToken0 operand0;
     
    14201478    }
    14211479
     1480    paOperand->cOperandToken = dxbcTokenReaderPtr(r) - paOperand->paOperandToken;
     1481
    14221482    *pcOperandRemain -= 1;
    14231483    return VINF_SUCCESS;
     
    14391499    ASSERT_GUEST_RETURN(pOpcode->opcodeType < VGPU10_NUM_OPCODES, VERR_INVALID_PARAMETER);
    14401500
     1501    Log6(("[%#x] %s length %d\n",
     1502          dxbcTokenReaderByteOffset(r) - 4, dxbcOpcodeToString(pOpcode->opcodeType), opcode.instructionLength));
     1503
    14411504    uint32_t const cOperand = g_aOpcodeInfo[pOpcode->opcodeType].cOperand;
    14421505    if (cOperand != UINT32_MAX)
    14431506    {
    1444 #ifdef LOG_ENABLED
    1445         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         else
    1449            Log6(("[%#x] %s length %d %s\n",
    1450                  dxbcTokenReaderByteOffset(r) - 4, dxbcOpcodeToString(pOpcode->opcodeType), opcode.instructionLength, dxbcInterpolationModeToString(opcode.interpolationMode)));
    1451 #endif
    1452 
    14531507        ASSERT_GUEST_RETURN(cOperand < RT_ELEMENTS(pOpcode->aIdxOperand), VERR_INVALID_PARAMETER);
    14541508
     
    14731527        ASSERT_GUEST_RETURN(dxbcTokenReaderCanRead(r, pOpcode->cOpcodeToken - 1), VERR_INVALID_PARAMETER);
    14741528
     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
    14751542        /* Additional tokens before operands. */
    14761543        switch (pOpcode->opcodeType)
     
    16111678        if (pOpcode->opcodeType == VGPU10_OPCODE_CUSTOMDATA)
    16121679        {
    1613             Log6(("[%#x] %s %s\n",
    1614                   dxbcTokenReaderByteOffset(r) - 4, dxbcOpcodeToString(pOpcode->opcodeType), dxbcCustomDataClassToString(opcode.customDataClass)));
    1615 
    16161680            ASSERT_GUEST_RETURN(dxbcTokenReaderCanRead(r, 1), VERR_INVALID_PARAMETER);
    16171681            pOpcode->cOpcodeToken = dxbcTokenReaderRead32(r);
     
    16211685            ASSERT_GUEST_RETURN(dxbcTokenReaderCanRead(r, pOpcode->cOpcodeToken - 2), VERR_INVALID_PARAMETER);
    16221686
     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
    16231696            dxbcTokenReaderSkip(r, pOpcode->cOpcodeToken - 2);
    16241697        }
    16251698        else if (pOpcode->opcodeType == VGPU10_OPCODE_VMWARE)
    16261699        {
    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            }
    16321736        }
    16331737        else
     
    16441748{
    16451749    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. */
    16471753} DXBCOUTPUTCTX;
    16481754
    16491755
    1650 void dxbcOutputInit(DXBCOUTPUTCTX *pOutctx, VGPU10ProgramToken const *pProgramToken, uint32_t cToken)
    1651 {
    1652     RT_NOREF(pProgramToken, cToken);
     1756static void dxbcOutputInit(DXBCOUTPUTCTX *pOutctx, VGPU10ProgramToken const *pProgramToken, uint32_t cToken)
     1757{
    16531758    RT_ZERO(*pOutctx);
    16541759    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
     1766static 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
     1838static int dxbcOutputOpcode(DXBCOUTPUTCTX *pOutctx, DXBCByteWriter *w, VGPUOpcode *pOpcode)
     1839{
     1840#ifdef DEBUG
     1841    void *pvBegin = dxbcByteWriterPtr(w);
     1842#endif
     1843
    16601844    if (   pOutctx->programToken.programType == VGPU10_PIXEL_SHADER
    16611845        && pOpcode->opcodeType == VGPU10_OPCODE_DCL_RESOURCE)
     
    16631847        /** @todo This is a workaround. */
    16641848        /* Sometimes the guest (Mesa) created a shader with  uninitialized resource dimension.
    1665          * Use texture 2d because buffer is not what a pixel shader normally uses.
     1849         * Use texture 2d because it is what a pixel shader normally uses.
    16661850         */
    16671851        ASSERT_GUEST_RETURN(pOpcode->cOpcodeToken == 4, VERR_INVALID_PARAMETER);
     
    16791863        }
    16801864    }
    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. */
    16821881    dxbcByteWriterAddTokens(w, pOpcode->paOpcodeToken, pOpcode->cOpcodeToken);
    16831882    return VINF_SUCCESS;
     
    16851884
    16861885
    1687 int dxbcOutputFinalize(DXBCOUTPUTCTX *pOutctx, DXBCByteWriter *w)
     1886static int dxbcOutputFinalize(DXBCOUTPUTCTX *pOutctx, DXBCByteWriter *w)
    16881887{
    16891888    RT_NOREF(pOutctx, w);
     
    18222021
    18232022    dxbcByteWriterFetchData(w, &pInfo->pvBytecode, &pInfo->cbBytecode);
     2023    uint32_t *pcOutputToken = (uint32_t *)pInfo->pvBytecode + 1;
     2024    *pcOutputToken = pInfo->cbBytecode / 4;
    18242025
    18252026#ifdef LOG_ENABLED
     
    21612362    int rc = DXShaderParse(pvShaderCode, cbShaderCode, &info);
    21622363    if (RT_SUCCESS(rc))
    2163         rc = DXShaderCreateDXBC(&info, info.pvBytecode, info.cbBytecode, ppvDXBC, pcbDXBC);
     2364        rc = DXShaderCreateDXBC(&info, ppvDXBC, pcbDXBC);
    21642365    return rc;
    21652366}
  • trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-win-dx.cpp

    r91607 r91823  
    63426342    if (pvShaderBytecode)
    63436343    {
    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));
    63636345
    63646346        rc = DXShaderCreateDXBC(&pShader->shaderInfo, &pDXShader->pvDXBC, &pDXShader->cbDXBC);
     
    63716353                HRESULT hr2 = pBackend->pfnD3DDisassemble(pDXShader->pvDXBC, pDXShader->cbDXBC, 0, NULL, &pBlob);
    63726354                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()));
    63776356                else
    63786357                    AssertFailed();
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette