VirtualBox

Changeset 95032 in vbox for trunk


Ignore:
Timestamp:
May 17, 2022 4:12:49 PM (3 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
151479
Message:

Devices/Graphics: shader signatures: bugref:9830

Location:
trunk/src/VBox/Devices/Graphics
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-dx-shader.cpp

    r95024 r95032  
    2727#include <iprt/md5.h>
    2828#include <iprt/mem.h>
     29#include <iprt/sort.h>
    2930#include <iprt/string.h>
    3031
     
    18191820    opcode.opcodeType = VGPU10_OPCODE_NOP;
    18201821    opcode.instructionLength = 1;
    1821     for (int i = 0; i < 8 - 3; ++i)
     1822    for (unsigned i = 0; i < pOpcode->cOpcodeToken - 3; ++i)
    18221823        dxbcByteWriterAddTokens(w, &opcode.value, 1);
    18231824
     
    19181919
    19191920
     1921static DECLCALLBACK(int) signatureEntryCmp(void const *pvElement1, void const *pvElement2, void *pvUser)
     1922{
     1923    SVGA3dDXSignatureEntry const *e1 = (SVGA3dDXSignatureEntry *)pvElement1;
     1924    SVGA3dDXSignatureEntry const *e2 = (SVGA3dDXSignatureEntry *)pvElement2;
     1925    RT_NOREF(pvUser);
     1926
     1927    if (e1->registerIndex < e2->registerIndex)
     1928        return -1;
     1929    if (e1->registerIndex > e2->registerIndex)
     1930        return 1;
     1931    if ((e1->mask & 0xf) < (e2->mask & 0xf))
     1932        return -1;
     1933    if ((e1->mask & 0xf) > (e2->mask & 0xf))
     1934        return 1;
     1935    return 0;
     1936}
     1937
     1938
     1939static void dxbcGenerateSemantics(DXShaderInfo *pInfo, uint32_t cSignature,
     1940                                  SVGA3dDXSignatureEntry const *paSignature,
     1941                                  DXShaderAttributeSemantic *paSemantic,
     1942                                  uint32_t u32BlobType);
     1943
     1944
    19201945/*
    19211946 * Parse and verify the shader byte code. Extract input and output signatures into pInfo.
     
    19902015            {
    19912016                case VGPU10_OPCODE_DCL_INPUT:
     2017                case VGPU10_OPCODE_DCL_INPUT_SIV:
     2018                //case VGPU10_OPCODE_DCL_INPUT_SGV:
    19922019                case VGPU10_OPCODE_DCL_INPUT_PS:
    1993                 case VGPU10_OPCODE_DCL_INPUT_SIV:
     2020                //case VGPU10_OPCODE_DCL_INPUT_PS_SIV:
     2021                //case VGPU10_OPCODE_DCL_INPUT_PS_SGV:
     2022                //case VGPU10_OPCODE_DCL_INPUT_CONTROL_POINT_COUNT:
    19942023                    ASSERT_GUEST_STMT_BREAK(pInfo->cInputSignature < RT_ELEMENTS(pInfo->aInputSignature), rc = VERR_INVALID_PARAMETER);
    19952024                    pSignatureEntry = &pInfo->aInputSignature[pInfo->cInputSignature++];
     
    19982027                case VGPU10_OPCODE_DCL_OUTPUT_SIV:
    19992028                case VGPU10_OPCODE_DCL_OUTPUT_SGV:
     2029                //case VGPU10_OPCODE_DCL_OUTPUT_CONTROL_POINT_COUNT:
    20002030                    ASSERT_GUEST_STMT_BREAK(pInfo->cOutputSignature < RT_ELEMENTS(pInfo->aOutputSignature), rc = VERR_INVALID_PARAMETER);
    20012031                    pSignatureEntry = &pInfo->aOutputSignature[pInfo->cOutputSignature++];
     
    20682098    *pcOutputToken = pInfo->cbBytecode / 4;
    20692099
     2100    /* Sort signatures by register index and mask because the host API need them to be sorted. */
     2101    if (pInfo->cInputSignature)
     2102    {
     2103        RTSortShell(pInfo->aInputSignature, pInfo->cInputSignature, sizeof(pInfo->aInputSignature[0]),
     2104                    signatureEntryCmp, NULL);
     2105        dxbcGenerateSemantics(pInfo, pInfo->cInputSignature,
     2106                              pInfo->aInputSignature,
     2107                              pInfo->aInputSemantic, DXBC_BLOB_TYPE_ISGN);
     2108    }
     2109    if (pInfo->cOutputSignature)
     2110    {
     2111        RTSortShell(pInfo->aOutputSignature, pInfo->cOutputSignature, sizeof(pInfo->aOutputSignature[0]),
     2112                    signatureEntryCmp, NULL);
     2113        dxbcGenerateSemantics(pInfo, pInfo->cOutputSignature,
     2114                              pInfo->aOutputSignature,
     2115                              pInfo->aOutputSemantic, DXBC_BLOB_TYPE_OSGN);
     2116    }
     2117    if (pInfo->cPatchConstantSignature)
     2118    {
     2119        RTSortShell(pInfo->aPatchConstantSignature, pInfo->cPatchConstantSignature, sizeof(pInfo->aPatchConstantSignature[0]),
     2120                    signatureEntryCmp, NULL);
     2121        dxbcGenerateSemantics(pInfo, pInfo->cPatchConstantSignature,
     2122                              pInfo->aPatchConstantSignature,
     2123                              pInfo->aPatchConstantSemantic, DXBC_BLOB_TYPE_PCSG);
     2124    }
     2125
    20702126#ifdef LOG_ENABLED
    20712127    if (pInfo->cInputSignature)
     
    20732129        Log6(("Input signatures:\n"));
    20742130        for (uint32_t i = 0; i < pInfo->cInputSignature; ++i)
    2075             Log6(("  [%u]: %u %u 0x%X\n", i, pInfo->aInputSignature[i].registerIndex, pInfo->aInputSignature[i].semanticName, pInfo->aInputSignature[i].mask));
     2131            Log6(("  [%u]: %u %u 0x%X, %s %d\n",
     2132                  i, pInfo->aInputSignature[i].registerIndex, pInfo->aInputSignature[i].semanticName, pInfo->aInputSignature[i].mask,
     2133                  pInfo->aInputSemantic[i].pcszSemanticName, pInfo->aInputSemantic[i].SemanticIndex));
    20762134    }
    20772135    if (pInfo->cOutputSignature)
     
    20792137        Log6(("Output signatures:\n"));
    20802138        for (uint32_t i = 0; i < pInfo->cOutputSignature; ++i)
    2081             Log6(("  [%u]: %u %u 0x%X\n", i, pInfo->aOutputSignature[i].registerIndex, pInfo->aOutputSignature[i].semanticName, pInfo->aOutputSignature[i].mask));
     2139            Log6(("  [%u]: %u %u 0x%X, %s %d\n",
     2140                  i, pInfo->aOutputSignature[i].registerIndex, pInfo->aOutputSignature[i].semanticName, pInfo->aOutputSignature[i].mask,
     2141                  pInfo->aOutputSemantic[i].pcszSemanticName, pInfo->aOutputSemantic[i].SemanticIndex));
    20822142    }
    20832143    if (pInfo->cPatchConstantSignature)
     
    20852145        Log6(("Patch constant signatures:\n"));
    20862146        for (uint32_t i = 0; i < pInfo->cPatchConstantSignature; ++i)
    2087             Log6(("  [%u]: %u %u 0x%X\n", i, pInfo->aPatchConstantSignature[i].registerIndex, pInfo->aPatchConstantSignature[i].semanticName, pInfo->aPatchConstantSignature[i].mask));
     2147            Log6(("  [%u]: %u %u 0x%X, %s %d\n",
     2148                  i, pInfo->aPatchConstantSignature[i].registerIndex, pInfo->aPatchConstantSignature[i].semanticName, pInfo->aPatchConstantSignature[i].mask,
     2149                  pInfo->aPatchConstantSemantic[i].pcszSemanticName, pInfo->aPatchConstantSemantic[i].SemanticIndex));
    20882150    }
    20892151#endif
     
    20922154}
    20932155
     2156void DXShaderGenerateSemantics(DXShaderInfo *pInfo)
     2157{
     2158    if (pInfo->cInputSignature)
     2159        dxbcGenerateSemantics(pInfo, pInfo->cInputSignature,
     2160                              pInfo->aInputSignature,
     2161                              pInfo->aInputSemantic, DXBC_BLOB_TYPE_ISGN);
     2162    if (pInfo->cOutputSignature)
     2163        dxbcGenerateSemantics(pInfo, pInfo->cOutputSignature,
     2164                              pInfo->aOutputSignature,
     2165                              pInfo->aOutputSemantic, DXBC_BLOB_TYPE_OSGN);
     2166    if (pInfo->cPatchConstantSignature)
     2167        dxbcGenerateSemantics(pInfo, pInfo->cPatchConstantSignature,
     2168                              pInfo->aPatchConstantSignature,
     2169                              pInfo->aPatchConstantSemantic, DXBC_BLOB_TYPE_PCSG);
     2170}
    20942171
    20952172void DXShaderFree(DXShaderInfo *pInfo)
     
    21972274
    21982275
    2199 static int dxbcCreateIOSGNBlob(DXShaderInfo const *pInfo, DXBCHeader *pHdr, uint32_t u32BlobType,
    2200                                uint32_t cSignature, SVGA3dDXSignatureEntry const *paSignature, DXBCByteWriter *w)
    2201 {
     2276static void dxbcGenerateSemantics(DXShaderInfo *pInfo, uint32_t cSignature,
     2277                                  SVGA3dDXSignatureEntry const *paSignature,
     2278                                  DXShaderAttributeSemantic *paSemantic,
     2279                                  uint32_t u32BlobType)
     2280{
     2281    for (uint32_t iSignatureEntry = 0; iSignatureEntry < cSignature; ++iSignatureEntry)
     2282    {
     2283        SVGA3dDXSignatureEntry const *src = &paSignature[iSignatureEntry];
     2284        DXShaderAttributeSemantic *dst = &paSemantic[iSignatureEntry];
     2285
     2286        ASSERT_GUEST_RETURN_VOID(src->semanticName < SVGADX_SIGNATURE_SEMANTIC_NAME_MAX);
     2287
     2288        VGPUSemanticInfo const *pSemanticInfo = dxbcSemanticInfo(pInfo, src->semanticName, u32BlobType);
     2289        dst->pcszSemanticName = pSemanticInfo->pszName;
     2290        dst->SemanticIndex = 0;
     2291        for (uint32_t i = 0; i < iSignatureEntry; ++i)
     2292        {
     2293            DXShaderAttributeSemantic const *pSemantic = &paSemantic[i];
     2294            if (RTStrCmp(pSemantic->pcszSemanticName, dst->pcszSemanticName) == 0)
     2295                ++dst->SemanticIndex;
     2296        }
     2297    }
     2298}
     2299
     2300
     2301static int dxbcCreateIOSGNBlob(DXShaderInfo const *pInfo, DXBCHeader *pHdr, uint32_t u32BlobType, uint32_t cSignature,
     2302                               SVGA3dDXSignatureEntry const *paSignature, DXShaderAttributeSemantic const *paSemantic, DXBCByteWriter *w)
     2303{
     2304    RT_NOREF(pInfo);
    22022305    AssertReturn(cSignature <= SVGA3D_DX_SM41_MAX_VERTEXINPUTREGISTERS, VERR_INVALID_PARAMETER);
    22032306
     
    22142317    pHdrISGN->offElement = RT_UOFFSETOF(DXBCBlobIOSGN, aElement[0]);
    22152318
    2216     if (pInfo->fGuestSignatures)
    2217     {
    2218         uint32_t aSemanticIdx[SVGADX_SIGNATURE_SEMANTIC_NAME_MAX];
    2219         RT_ZERO(aSemanticIdx);
    2220         for (uint32_t iSignature = 0; iSignature < cSignature; ++iSignature)
     2319    for (uint32_t iSignatureEntry = 0; iSignatureEntry < cSignature; ++iSignatureEntry)
     2320    {
     2321        SVGA3dDXSignatureEntry const *srcEntry = &paSignature[iSignatureEntry];
     2322        DXShaderAttributeSemantic const *srcSemantic = &paSemantic[iSignatureEntry];
     2323        DXBCBlobIOSGNElement *dst = &pHdrISGN->aElement[iSignatureEntry];
     2324
     2325        dst->offElementName = 0;
     2326        for (uint32_t i = 0; i < iSignatureEntry; ++i)
    22212327        {
    2222             SVGA3dDXSignatureEntry const *src = &paSignature[iSignature];
    2223             DXBCBlobIOSGNElement *dst = &pHdrISGN->aElement[iSignature];
    2224 
    2225             ASSERT_GUEST_RETURN(src->semanticName < SVGADX_SIGNATURE_SEMANTIC_NAME_MAX, VERR_INVALID_PARAMETER);
    2226             VGPUSemanticInfo const *pSemanticInfo = dxbcSemanticInfo(pInfo, src->semanticName, u32BlobType);
    2227 
    2228             dst->offElementName   = cbBlob; /* Offset of the semantic's name relative to the start of the blob (without hdr). */
    2229             /* Use the register index as the semantic index for generic attributes in order to
    2230              * produce compatible semantic names between shaders.
    2231              */
    2232             dst->idxSemantic      = src->semanticName == SVGADX_SIGNATURE_SEMANTIC_NAME_UNDEFINED
    2233                                   ? src->registerIndex
    2234                                   : aSemanticIdx[src->semanticName]++;
    2235             dst->enmSystemValue   = src->semanticName;
    2236             dst->enmComponentType = src->componentType;
    2237             dst->idxRegister      = src->registerIndex;
    2238             dst->u.mask           = src->mask;
    2239 
    2240             /* Figure out the semantic name for this element. */
    2241             char const * const pszElementName = pSemanticInfo->pszName;
    2242             uint32_t const cbElementName = (uint32_t)strlen(pszElementName) + 1;
    2243 
    2244             if (!dxbcByteWriterCanWrite(w, cbBlob + cbElementName))
     2328            DXBCBlobIOSGNElement const *pElement = &pHdrISGN->aElement[i];
     2329            char const *pszElementName = (char *)pHdrISGN + pElement->offElementName;
     2330            if (RTStrCmp(pszElementName, srcSemantic->pcszSemanticName) == 0)
     2331            {
     2332                dst->offElementName = pElement->offElementName;
     2333                break;
     2334            }
     2335        }
     2336        dst->idxSemantic      = srcSemantic->SemanticIndex;
     2337        dst->enmSystemValue   = srcEntry->semanticName;
     2338        dst->enmComponentType = srcEntry->componentType;
     2339        dst->idxRegister      = srcEntry->registerIndex;
     2340        dst->u.mask           = srcEntry->mask;
     2341
     2342        if (dst->offElementName == 0)
     2343        {
     2344            /* Store the semantic name for this element. */
     2345            dst->offElementName = cbBlob; /* Offset of the semantic's name relative to the start of the blob (without DXBCBlobHeader). */
     2346            uint32_t const cbElementName = (uint32_t)strlen(srcSemantic->pcszSemanticName) + 1;
     2347            if (!dxbcByteWriterCanWrite(w, sizeof(DXBCBlobHeader) + cbBlob + cbElementName))
    22452348                return VERR_NO_MEMORY;
    22462349
    2247             char *pszElementNameDst = (char *)pHdrISGN + dst->offElementName;
    2248             memcpy(pszElementNameDst, pszElementName, cbElementName);
    2249 
     2350            memcpy((char *)pHdrISGN + dst->offElementName, srcSemantic->pcszSemanticName, cbElementName);
    22502351            cbBlob += cbElementName;
    2251         }
    2252     }
    2253     else
    2254     {
    2255         /* If the signature has been created from the shader code, then sort the signature entries
    2256          * by the register index, because 3D API requires this.
    2257          *
    2258          * signature semantic reg -> signature semantic reg
    2259          * [0]       0        2      [5]       0        0
    2260          * [1]       1        1      [3]       1        0
    2261          * [2]       2        0      [2]       2        0
    2262          * [3]       1        0      [4]       0        1
    2263          * [4]       0        1      [1]       1        1
    2264          * [5]       0        0      [0]       0        2
    2265          */
    2266 
    2267         /* aIdxSignature contains signature indices. aIdxSignature[s][0] = signature index for register 0 for semantic s. */
    2268         uint32_t aIdxSignature[SVGADX_SIGNATURE_SEMANTIC_NAME_MAX][SVGA3D_DX_SM41_MAX_VERTEXINPUTREGISTERS];
    2269         memset(aIdxSignature, 0xFF, sizeof(aIdxSignature));
    2270         for (uint32_t i = 0; i < cSignature; ++i)
    2271         {
    2272             SVGA3dDXSignatureEntry const *src = &paSignature[i];
    2273             ASSERT_GUEST_RETURN(src->semanticName < SVGADX_SIGNATURE_SEMANTIC_NAME_MAX, VERR_INVALID_PARAMETER);
    2274             if (src->registerIndex == 0xFFFFFFFF)
    2275             {
    2276                 /* oDepth for PS output. */
    2277                 ASSERT_GUEST_RETURN(pInfo->enmProgramType == VGPU10_PIXEL_SHADER, VERR_INVALID_PARAMETER);
    2278 
    2279                 /* Must be placed last in the signature. */
    2280                 ASSERT_GUEST_RETURN(aIdxSignature[src->semanticName][cSignature - 1] == 0xFFFFFFFF, VERR_INVALID_PARAMETER);
    2281                 aIdxSignature[src->semanticName][cSignature - 1] = i;
    2282                 continue;
    2283             }
    2284 
    2285             ASSERT_GUEST_RETURN(src->registerIndex < SVGA3D_DX_SM41_MAX_VERTEXINPUTREGISTERS, VERR_INVALID_PARAMETER);
    2286             ASSERT_GUEST_RETURN(aIdxSignature[src->semanticName][src->registerIndex] == 0xFFFFFFFF, VERR_INVALID_PARAMETER);
    2287             aIdxSignature[src->semanticName][src->registerIndex] = i;
    2288         }
    2289 
    2290         uint32_t aSemanticIdx[SVGADX_SIGNATURE_SEMANTIC_NAME_MAX];
    2291         RT_ZERO(aSemanticIdx);
    2292         uint32_t iElement = 0;
    2293         for (uint32_t iReg = 0; iReg < SVGA3D_DX_SM41_MAX_VERTEXINPUTREGISTERS; ++iReg)
    2294         {
    2295             for (unsigned iSemanticName = 0; iSemanticName < SVGADX_SIGNATURE_SEMANTIC_NAME_MAX; ++iSemanticName)
    2296             {
    2297                 if (aIdxSignature[iSemanticName][iReg] == 0xFFFFFFFF) /* This register is unused. */
    2298                     continue;
    2299 
    2300                 SVGA3dDXSignatureEntry const *src = &paSignature[aIdxSignature[iSemanticName][iReg]];
    2301 
    2302                 AssertReturn(iElement < cSignature, VERR_INTERNAL_ERROR);
    2303                 DXBCBlobIOSGNElement *dst = &pHdrISGN->aElement[iElement];
    2304 
    2305                 ASSERT_GUEST_RETURN(src->semanticName < SVGADX_SIGNATURE_SEMANTIC_NAME_MAX, VERR_INVALID_PARAMETER);
    2306                 VGPUSemanticInfo const *pSemanticInfo = dxbcSemanticInfo(pInfo, src->semanticName, u32BlobType);
    2307 
    2308                 dst->offElementName   = cbBlob; /* Offset of the semantic's name relative to the start of the blob (without hdr). */
    2309                 /* Use the register index as the semantic index for generic attributes in order to
    2310                  * produce compatible semantic names between shaders.
    2311                  */
    2312                 dst->idxSemantic      = src->semanticName == SVGADX_SIGNATURE_SEMANTIC_NAME_UNDEFINED
    2313                                       ? src->registerIndex
    2314                                       : aSemanticIdx[src->semanticName]++;
    2315                 dst->enmSystemValue   = src->semanticName;
    2316                 /* Set type = 'undefined' to make the type match types between shader stages.
    2317                  * ('src->componentType ? src->componentType : pSemanticInfo->u32Type;' was used in the past)
    2318                  */
    2319                 dst->enmComponentType = 0;
    2320                 dst->idxRegister      = src->registerIndex;
    2321                 dst->u.m.mask         = src->mask;
    2322                 if (u32BlobType == DXBC_BLOB_TYPE_OSGN)
    2323                     dst->u.m.mask2    = 0;
    2324                 else
    2325                     dst->u.m.mask2    = src->mask;
    2326 
    2327                 /* Figure out the semantic name for this element. */
    2328                 char const * const pszElementName = pSemanticInfo->pszName;
    2329                 uint32_t const cbElementName = (uint32_t)strlen(pszElementName) + 1;
    2330 
    2331                 Log(("[%d] semantic %d, register %d, %s%d\n", iElement, dst->enmSystemValue, dst->idxRegister, pszElementName, dst->idxSemantic));
    2332 
    2333                 if (!dxbcByteWriterCanWrite(w, cbBlob + cbElementName))
    2334                     return VERR_NO_MEMORY;
    2335 
    2336                 char *pszElementNameDst = (char *)pHdrISGN + dst->offElementName;
    2337                 memcpy(pszElementNameDst, pszElementName, cbElementName);
    2338 
    2339                 cbBlob += cbElementName;
    2340                 ++iElement;
    2341             }
    23422352        }
    23432353    }
     
    24062416        Log6(("Input signatures:\n"));
    24072417        for (uint32_t i = 0; i < pInfo->cInputSignature; ++i)
    2408             Log6(("  [%u]: %u %u 0x%X\n", i, pInfo->aInputSignature[i].registerIndex, pInfo->aInputSignature[i].semanticName, pInfo->aInputSignature[i].mask));
     2418            Log6(("  [%u]: %u %u 0x%X, %s %d\n",
     2419                  i, pInfo->aInputSignature[i].registerIndex, pInfo->aInputSignature[i].semanticName, pInfo->aInputSignature[i].mask,
     2420                  pInfo->aInputSemantic[i].pcszSemanticName, pInfo->aInputSemantic[i].SemanticIndex));
    24092421    }
    24102422    if (pInfo->cOutputSignature)
     
    24122424        Log6(("Output signatures:\n"));
    24132425        for (uint32_t i = 0; i < pInfo->cOutputSignature; ++i)
    2414             Log6(("  [%u]: %u %u 0x%X\n", i, pInfo->aOutputSignature[i].registerIndex, pInfo->aOutputSignature[i].semanticName, pInfo->aOutputSignature[i].mask));
     2426            Log6(("  [%u]: %u %u 0x%X, %s %d\n",
     2427                  i, pInfo->aOutputSignature[i].registerIndex, pInfo->aOutputSignature[i].semanticName, pInfo->aOutputSignature[i].mask,
     2428                  pInfo->aOutputSemantic[i].pcszSemanticName, pInfo->aOutputSemantic[i].SemanticIndex));
    24152429    }
    24162430    if (pInfo->cPatchConstantSignature)
     
    24182432        Log6(("Patch constant signatures:\n"));
    24192433        for (uint32_t i = 0; i < pInfo->cPatchConstantSignature; ++i)
    2420             Log6(("  [%u]: %u %u 0x%X\n", i, pInfo->aPatchConstantSignature[i].registerIndex, pInfo->aPatchConstantSignature[i].semanticName, pInfo->aPatchConstantSignature[i].mask));
     2434            Log6(("  [%u]: %u %u 0x%X, %s %d\n",
     2435                  i, pInfo->aPatchConstantSignature[i].registerIndex, pInfo->aPatchConstantSignature[i].semanticName, pInfo->aPatchConstantSignature[i].mask,
     2436                  pInfo->aPatchConstantSemantic[i].pcszSemanticName, pInfo->aPatchConstantSemantic[i].SemanticIndex));
    24212437    }
    24222438#endif
     
    24262442
    24272443    pHdr->aBlobOffset[iBlob++] = dxbcByteWriterSize(w);
    2428     rc = dxbcCreateIOSGNBlob(pInfo, pHdr, DXBC_BLOB_TYPE_ISGN, pInfo->cInputSignature, &pInfo->aInputSignature[0], w);
     2444    rc = dxbcCreateIOSGNBlob(pInfo, pHdr, DXBC_BLOB_TYPE_ISGN, pInfo->cInputSignature, &pInfo->aInputSignature[0], pInfo->aInputSemantic, w);
    24292445    AssertRCReturn(rc, rc);
    24302446
    24312447    pHdr->aBlobOffset[iBlob++] = dxbcByteWriterSize(w);
    2432     rc = dxbcCreateIOSGNBlob(pInfo, pHdr, DXBC_BLOB_TYPE_OSGN, pInfo->cOutputSignature, &pInfo->aOutputSignature[0], w);
     2448    rc = dxbcCreateIOSGNBlob(pInfo, pHdr, DXBC_BLOB_TYPE_OSGN, pInfo->cOutputSignature, &pInfo->aOutputSignature[0], pInfo->aOutputSemantic, w);
    24332449    AssertRCReturn(rc, rc);
    24342450
     
    24372453    {
    24382454        pHdr->aBlobOffset[iBlob++] = dxbcByteWriterSize(w);
    2439         rc = dxbcCreateIOSGNBlob(pInfo, pHdr, DXBC_BLOB_TYPE_PCSG, pInfo->cPatchConstantSignature, &pInfo->aPatchConstantSignature[0], w);
     2455        rc = dxbcCreateIOSGNBlob(pInfo, pHdr, DXBC_BLOB_TYPE_PCSG, pInfo->cPatchConstantSignature, &pInfo->aPatchConstantSignature[0], pInfo->aPatchConstantSemantic, w);
    24402456        AssertRCReturn(rc, rc);
    24412457    }
  • trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-dx-shader.h

    r94989 r95032  
    3535#include "vmsvga_headers_end.h"
    3636
     37typedef struct DXShaderAttributeSemantic
     38{
     39    const char *pcszSemanticName;
     40    uint32_t SemanticIndex;
     41} DXShaderAttributeSemantic;
     42
    3743typedef struct DXShaderInfo
    3844{
     
    4854    SVGA3dDXSignatureEntry aOutputSignature[32];
    4955    SVGA3dDXSignatureEntry aPatchConstantSignature[32];
     56    DXShaderAttributeSemantic aInputSemantic[32];
     57    DXShaderAttributeSemantic aOutputSemantic[32];
     58    DXShaderAttributeSemantic aPatchConstantSemantic[32];
    5059    uint32_t aOffDclResource[SVGA3D_DX_MAX_SRVIEWS];
    5160} DXShaderInfo;
    5261
    5362int DXShaderParse(void const *pvCode, uint32_t cbCode, DXShaderInfo *pInfo);
     63void DXShaderGenerateSemantics(DXShaderInfo *pInfo);
    5464void DXShaderFree(DXShaderInfo *pInfo);
    5565int DXShaderUpdateResources(DXShaderInfo const *pInfo, VGPU10_RESOURCE_DIMENSION *paResourceDimension,
  • trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-dx.cpp

    r95023 r95032  
    12441244    AssertRCReturn(rc, rc);
    12451245
    1246     ASSERT_GUEST_RETURN(cSoTarget < SVGA3D_DX_MAX_SOTARGETS, VERR_INVALID_PARAMETER);
     1246    ASSERT_GUEST_RETURN(cSoTarget <= SVGA3D_DX_MAX_SOTARGETS, VERR_INVALID_PARAMETER);
    12471247    RT_UNTRUSTED_VALIDATED_FENCE();
    12481248
     
    20452045                pShaderInfo->cPatchConstantSignature = pSignatureHeader->numPatchConstantSignatures;
    20462046                memcpy(pShaderInfo->aPatchConstantSignature, pu8Signatures, pSignatureHeader->numPatchConstantSignatures * sizeof(SVGA3dDXSignatureEntry));
     2047
     2048                DXShaderGenerateSemantics(pShaderInfo);
    20472049            }
    20482050        }
  • trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-win-dx.cpp

    r95023 r95032  
    906906                    D3D11_MESSAGE_ID_DEVICE_DRAW_SAMPLER_MISMATCH,    /* U. */
    907907                    D3D11_MESSAGE_ID_CREATEINPUTLAYOUT_EMPTY_LAYOUT,  /* P. */
     908                    D3D11_MESSAGE_ID_DEVICE_SHADER_LINKAGE_REGISTERMASK, /* S. */
    908909                };
    909910
     
    17811782                SVGACOTableDXStreamOutputEntry const *pEntry = &pDXContext->cot.paStreamOutput[soid];
    17821783                DXSTREAMOUTPUT *pDXStreamOutput = &pDXContext->pBackendDXContext->paStreamOutput[soid];
    1783 
    1784                 for (uint32_t i = 0; i < pDXStreamOutput->cDeclarationEntry; ++i)
    1785                 {
    1786                     D3D11_SO_DECLARATION_ENTRY *p = &pDXStreamOutput->aDeclarationEntry[i];
    1787                     SVGA3dStreamOutputDeclarationEntry const *decl = &pEntry->decl[i];
    1788                     SVGA3dDXSignatureSemanticName enmSemanticName;
    1789                     p->SemanticName = DXShaderGetOutputSemanticName(&pDXShader->shaderInfo, decl->registerIndex, &enmSemanticName);
    1790                     if (enmSemanticName == SVGADX_SIGNATURE_SEMANTIC_NAME_UNDEFINED)
    1791                         p->SemanticIndex = decl->registerIndex;
    1792                     else
    1793                         p->SemanticIndex = 0;
    1794                 }
    17951784
    17961785                hr = pDevice->pDevice->CreateGeometryShaderWithStreamOutput(pDXShader->pvDXBC, pDXShader->cbDXBC,
     
    52805269
    52815270
    5282 static void vboxDXMatchGuestShaderSignatures(PVMSVGA3DDXCONTEXT pDXContext, DXSHADER *pDXShader)
    5283 {
    5284     if (pDXShader->enmShaderType == SVGA3D_SHADERTYPE_GS)
    5285     {
    5286         /* Output signature of a GS shader is the input of the pixel shader. */
    5287         SVGA3dShaderId const shaderIdPS = pDXContext->svgaDXContext.shaderState[SVGA3D_SHADERTYPE_PS - SVGA3D_SHADERTYPE_MIN].shaderId;
    5288         SVGA3dShaderId const shaderIdDS = pDXContext->svgaDXContext.shaderState[SVGA3D_SHADERTYPE_DS - SVGA3D_SHADERTYPE_MIN].shaderId;
    5289         SVGA3dShaderId const shaderIdVS = pDXContext->svgaDXContext.shaderState[SVGA3D_SHADERTYPE_VS - SVGA3D_SHADERTYPE_MIN].shaderId;
    5290 
    5291         if (shaderIdPS != SVGA3D_INVALID_ID)
    5292         {
    5293             DXSHADER const *pDXShaderPS = &pDXContext->pBackendDXContext->paShader[shaderIdPS];
    5294             pDXShader->shaderInfo.cOutputSignature = pDXShaderPS->shaderInfo.cInputSignature;
    5295             memcpy(pDXShader->shaderInfo.aOutputSignature,
    5296                    pDXShaderPS->shaderInfo.aInputSignature,
    5297                    pDXShaderPS->shaderInfo.cInputSignature * sizeof(SVGA3dDXSignatureEntry));
    5298         }
    5299 
    5300         /* Input signature of a GS shader is the output of DS or VS. */
    5301         if (shaderIdDS != SVGA3D_INVALID_ID)
    5302         {
    5303             DXSHADER *pDXShaderDS = &pDXContext->pBackendDXContext->paShader[shaderIdDS];
    5304             pDXShader->shaderInfo.cInputSignature = pDXShaderDS->shaderInfo.cOutputSignature;
    5305             memcpy(pDXShader->shaderInfo.aInputSignature,
    5306                    pDXShaderDS->shaderInfo.aOutputSignature,
    5307                    pDXShaderDS->shaderInfo.cOutputSignature * sizeof(SVGA3dDXSignatureEntry));
    5308         }
    5309         else if (shaderIdVS != SVGA3D_INVALID_ID)
    5310         {
    5311             DXSHADER *pDXShaderVS = &pDXContext->pBackendDXContext->paShader[shaderIdVS];
    5312             pDXShader->shaderInfo.cInputSignature = pDXShaderVS->shaderInfo.cOutputSignature;
    5313             memcpy(pDXShader->shaderInfo.aInputSignature,
    5314                    pDXShaderVS->shaderInfo.aOutputSignature,
    5315                    pDXShaderVS->shaderInfo.cOutputSignature * sizeof(SVGA3dDXSignatureEntry));
    5316         }
    5317     }
     5271static void vboxDXMatchShaderInput(DXSHADER *pDXShader, DXSHADER *pDXShaderPrior)
     5272{
     5273    /* For each input generic attribute of the shader find corresponding entry in the prior shader. */
     5274    for (uint32_t i = 0; i < pDXShader->shaderInfo.cInputSignature; ++i)
     5275    {
     5276        SVGA3dDXSignatureEntry const *pSignatureEntry = &pDXShader->shaderInfo.aInputSignature[i];
     5277        DXShaderAttributeSemantic *pSemantic = &pDXShader->shaderInfo.aInputSemantic[i];
     5278
     5279        if (pSignatureEntry->semanticName != SVGADX_SIGNATURE_SEMANTIC_NAME_UNDEFINED)
     5280            continue;
     5281
     5282        int iMatch = -1;
     5283        for (uint32_t iPrior = 0; iPrior < pDXShaderPrior->shaderInfo.cOutputSignature; ++iPrior)
     5284        {
     5285            SVGA3dDXSignatureEntry const *pPriorSignatureEntry = &pDXShaderPrior->shaderInfo.aOutputSignature[iPrior];
     5286
     5287            if (pPriorSignatureEntry->semanticName != SVGADX_SIGNATURE_SEMANTIC_NAME_UNDEFINED)
     5288                continue;
     5289
     5290            if (pPriorSignatureEntry->registerIndex == pSignatureEntry->registerIndex)
     5291            {
     5292                iMatch = iPrior;
     5293                if (pPriorSignatureEntry->mask == pSignatureEntry->mask)
     5294                    break; /* Exact match, no need to continue search. */
     5295            }
     5296        }
     5297
     5298        if (iMatch >= 0)
     5299        {
     5300            SVGA3dDXSignatureEntry const *pPriorSignatureEntry = &pDXShaderPrior->shaderInfo.aOutputSignature[iMatch];
     5301            DXShaderAttributeSemantic const *pPriorSemantic = &pDXShaderPrior->shaderInfo.aOutputSemantic[iMatch];
     5302
     5303            Assert(pPriorSignatureEntry->registerIndex == pSignatureEntry->registerIndex);
     5304            Assert(pPriorSignatureEntry->mask == pSignatureEntry->mask);
     5305            RT_NOREF(pPriorSignatureEntry);
     5306
     5307            pSemantic->SemanticIndex = pPriorSemantic->SemanticIndex;
     5308        }
     5309    }
     5310}
     5311
     5312
     5313static void vboxDXMatchShaderSignatures(PVMSVGA3DDXCONTEXT pDXContext, DXSHADER *pDXShader)
     5314{
     5315    SVGA3dShaderId const shaderIdVS = pDXContext->svgaDXContext.shaderState[SVGA3D_SHADERTYPE_VS - SVGA3D_SHADERTYPE_MIN].shaderId;
     5316    SVGA3dShaderId const shaderIdHS = pDXContext->svgaDXContext.shaderState[SVGA3D_SHADERTYPE_HS - SVGA3D_SHADERTYPE_MIN].shaderId;
     5317    SVGA3dShaderId const shaderIdDS = pDXContext->svgaDXContext.shaderState[SVGA3D_SHADERTYPE_DS - SVGA3D_SHADERTYPE_MIN].shaderId;
     5318    SVGA3dShaderId const shaderIdGS = pDXContext->svgaDXContext.shaderState[SVGA3D_SHADERTYPE_GS - SVGA3D_SHADERTYPE_MIN].shaderId;
     5319    SVGA3dShaderId const shaderIdPS = pDXContext->svgaDXContext.shaderState[SVGA3D_SHADERTYPE_PS - SVGA3D_SHADERTYPE_MIN].shaderId;
     5320
     5321    /* Try to fix the input semantic indices. Output is usually not changed. */
     5322    switch (pDXShader->enmShaderType)
     5323    {
     5324        case SVGA3D_SHADERTYPE_VS:
     5325        {
     5326            /* Match input to input layout, which sets generic semantic indices to the source registerIndex (dxCreateInputLayout). */
     5327            for (uint32_t i = 0; i < pDXShader->shaderInfo.cInputSignature; ++i)
     5328            {
     5329                SVGA3dDXSignatureEntry const *pSignatureEntry = &pDXShader->shaderInfo.aInputSignature[i];
     5330                DXShaderAttributeSemantic *pSemantic = &pDXShader->shaderInfo.aInputSemantic[i];
     5331
     5332                if (pSignatureEntry->semanticName != SVGADX_SIGNATURE_SEMANTIC_NAME_UNDEFINED)
     5333                    continue;
     5334
     5335                pSemantic->SemanticIndex = pSignatureEntry->registerIndex;
     5336            }
     5337            break;
     5338        }
     5339        case SVGA3D_SHADERTYPE_HS:
     5340        {
     5341            /* Input of a HS shader is the output of VS. */
     5342            DXSHADER *pDXShaderPrior;
     5343            if (shaderIdVS != SVGA3D_INVALID_ID)
     5344                pDXShaderPrior = &pDXContext->pBackendDXContext->paShader[shaderIdVS];
     5345            else
     5346                pDXShaderPrior = NULL;
     5347
     5348            if (pDXShaderPrior)
     5349                vboxDXMatchShaderInput(pDXShader, pDXShaderPrior);
     5350
     5351            break;
     5352        }
     5353        case SVGA3D_SHADERTYPE_DS:
     5354        {
     5355            /* Input of a DS shader is the output of HS. */
     5356            DXSHADER *pDXShaderPrior;
     5357            if (shaderIdHS != SVGA3D_INVALID_ID)
     5358                pDXShaderPrior = &pDXContext->pBackendDXContext->paShader[shaderIdHS];
     5359            else
     5360                pDXShaderPrior = NULL;
     5361
     5362            if (pDXShaderPrior)
     5363                vboxDXMatchShaderInput(pDXShader, pDXShaderPrior);
     5364
     5365            break;
     5366        }
     5367        case SVGA3D_SHADERTYPE_GS:
     5368        {
     5369            /* Input signature of a GS shader is the output of DS or VS. */
     5370            DXSHADER *pDXShaderPrior;
     5371            if (shaderIdDS != SVGA3D_INVALID_ID)
     5372                 pDXShaderPrior = &pDXContext->pBackendDXContext->paShader[shaderIdDS];
     5373            else if (shaderIdVS != SVGA3D_INVALID_ID)
     5374                pDXShaderPrior = &pDXContext->pBackendDXContext->paShader[shaderIdVS];
     5375            else
     5376                pDXShaderPrior = NULL;
     5377
     5378            if (pDXShaderPrior)
     5379            {
     5380                /* If GS shader does not have input signature (Windows guest can do that),
     5381                 * then assign the prior shader signature as GS input.
     5382                 */
     5383                if (pDXShader->shaderInfo.cInputSignature == 0)
     5384                {
     5385                    pDXShader->shaderInfo.cInputSignature = pDXShaderPrior->shaderInfo.cOutputSignature;
     5386                    memcpy(pDXShader->shaderInfo.aInputSignature,
     5387                           pDXShaderPrior->shaderInfo.aOutputSignature,
     5388                           pDXShaderPrior->shaderInfo.cOutputSignature * sizeof(SVGA3dDXSignatureEntry));
     5389                    memcpy(pDXShader->shaderInfo.aInputSemantic,
     5390                           pDXShaderPrior->shaderInfo.aOutputSemantic,
     5391                           pDXShaderPrior->shaderInfo.cOutputSignature * sizeof(DXShaderAttributeSemantic));
     5392                }
     5393                else
     5394                    vboxDXMatchShaderInput(pDXShader, pDXShaderPrior);
     5395            }
     5396
     5397            /* Output signature of a GS shader is the input of the pixel shader. */
     5398            if (shaderIdPS != SVGA3D_INVALID_ID)
     5399            {
     5400                /* If GS shader does not have output signature (Windows guest can do that),
     5401                 * then assign the PS shader signature as GS output.
     5402                 */
     5403                if (pDXShader->shaderInfo.cOutputSignature == 0)
     5404                {
     5405                    DXSHADER const *pDXShaderPosterior = &pDXContext->pBackendDXContext->paShader[shaderIdPS];
     5406                    pDXShader->shaderInfo.cOutputSignature = pDXShaderPosterior->shaderInfo.cInputSignature;
     5407                    memcpy(pDXShader->shaderInfo.aOutputSignature,
     5408                           pDXShaderPosterior->shaderInfo.aInputSignature,
     5409                           pDXShaderPosterior->shaderInfo.cInputSignature * sizeof(SVGA3dDXSignatureEntry));
     5410                    memcpy(pDXShader->shaderInfo.aOutputSemantic,
     5411                           pDXShaderPosterior->shaderInfo.aInputSemantic,
     5412                           pDXShaderPosterior->shaderInfo.cInputSignature * sizeof(DXShaderAttributeSemantic));
     5413                }
     5414            }
     5415
     5416            SVGA3dStreamOutputId const soid = pDXContext->svgaDXContext.streamOut.soid;
     5417            if (soid != SVGA3D_INVALID_ID)
     5418            {
     5419                ASSERT_GUEST_RETURN_VOID(soid < pDXContext->pBackendDXContext->cStreamOutput);
     5420
     5421                /* Set semantic names and indices for SO declaration entries according to the shader output. */
     5422                SVGACOTableDXStreamOutputEntry const *pStreamOutputEntry = &pDXContext->cot.paStreamOutput[soid];
     5423                DXSTREAMOUTPUT *pDXStreamOutput = &pDXContext->pBackendDXContext->paStreamOutput[soid];
     5424
     5425                for (uint32_t i = 0; i < pDXStreamOutput->cDeclarationEntry; ++i)
     5426                {
     5427                    D3D11_SO_DECLARATION_ENTRY *pDeclarationEntry = &pDXStreamOutput->aDeclarationEntry[i];
     5428                    SVGA3dStreamOutputDeclarationEntry const *decl = &pStreamOutputEntry->decl[i];
     5429
     5430                    /* Find the corresponding register and mask in the GS shader output. */
     5431                    int idxFound = -1;
     5432                    for (uint32_t iOutputEntry = 0; iOutputEntry < pDXShader->shaderInfo.cOutputSignature; ++iOutputEntry)
     5433                    {
     5434                        SVGA3dDXSignatureEntry const *pOutputEntry = &pDXShader->shaderInfo.aOutputSignature[iOutputEntry];
     5435                        if (   pOutputEntry->registerIndex == decl->registerIndex
     5436                            && (decl->registerMask & ~pOutputEntry->mask) == 0) /* SO decl mask is a subset of shader output mask. */
     5437                        {
     5438                            idxFound = iOutputEntry;
     5439                            break;
     5440                        }
     5441                    }
     5442
     5443                    if (idxFound >= 0)
     5444                    {
     5445                        DXShaderAttributeSemantic const *pOutputSemantic = &pDXShader->shaderInfo.aOutputSemantic[idxFound];
     5446                        pDeclarationEntry->SemanticName = pOutputSemantic->pcszSemanticName;
     5447                        pDeclarationEntry->SemanticIndex = pOutputSemantic->SemanticIndex;
     5448                    }
     5449                    else
     5450                        AssertFailed();
     5451                }
     5452            }
     5453            break;
     5454        }
     5455        case SVGA3D_SHADERTYPE_PS:
     5456        {
     5457            /* Input of a PS shader is the output of GS, DS or VS. */
     5458            DXSHADER *pDXShaderPrior;
     5459            if (shaderIdGS != SVGA3D_INVALID_ID)
     5460                pDXShaderPrior = &pDXContext->pBackendDXContext->paShader[shaderIdGS];
     5461            else if (shaderIdDS != SVGA3D_INVALID_ID)
     5462                 pDXShaderPrior = &pDXContext->pBackendDXContext->paShader[shaderIdDS];
     5463            else if (shaderIdVS != SVGA3D_INVALID_ID)
     5464                pDXShaderPrior = &pDXContext->pBackendDXContext->paShader[shaderIdVS];
     5465            else
     5466                pDXShaderPrior = NULL;
     5467
     5468            if (pDXShaderPrior)
     5469                vboxDXMatchShaderInput(pDXShader, pDXShaderPrior);
     5470            break;
     5471        }
     5472        default:
     5473           break;
     5474    }
     5475
     5476    /* Intermediate shaders normally have both input and output signatures. However it is ok if they do not.
     5477     * Just catch this unusual case in order to see if everything is fine.
     5478     */
    53185479    Assert(   (pDXShader->enmShaderType == SVGA3D_SHADERTYPE_VS || pDXShader->enmShaderType == SVGA3D_SHADERTYPE_PS)
    53195480           || (pDXShader->shaderInfo.cInputSignature && pDXShader->shaderInfo.cOutputSignature));
     
    56055766
    56065767                /* Apply resource types to a pixel shader. */
    5607                 if (shaderType == SVGA3D_SHADERTYPE_PS)
     5768                if (shaderType == SVGA3D_SHADERTYPE_PS) /* Others too? */
    56085769                {
    56095770                    VGPU10_RESOURCE_DIMENSION aResourceDimension[SVGA3D_DX_MAX_SRVIEWS];
     
    56675828                }
    56685829
    5669                 if (pDXShader->shaderInfo.fGuestSignatures)
    5670                     vboxDXMatchGuestShaderSignatures(pDXContext, pDXShader);
     5830                vboxDXMatchShaderSignatures(pDXContext, pDXShader);
    56715831
    56725832                rc = DXShaderCreateDXBC(&pDXShader->shaderInfo, &pDXShader->pvDXBC, &pDXShader->cbDXBC);
     
    57085868     */
    57095869    SVGA3dElementLayoutId const elementLayoutId = pDXContext->svgaDXContext.inputAssembly.layoutId;
     5870    LogFunc(("Input layout id %u\n", elementLayoutId));
    57105871    ID3D11InputLayout *pInputLayout = NULL;
    57115872    if (elementLayoutId != SVGA3D_INVALID_ID)
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