VirtualBox

Changeset 57914 in vbox for trunk/src/VBox/Additions/WINNT


Ignore:
Timestamp:
Sep 27, 2015 3:06:57 PM (9 years ago)
Author:
vboxsync
Message:

WDDM: fixed vboxWddmDDevDrawIndexedPrimitive2 to correctly interpret input parameters.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3D.cpp

    r57633 r57914  
    29372937}
    29382938
     2939static UINT vboxWddmVertexCountFromPrimitive(D3DPRIMITIVETYPE PrimitiveType, UINT PrimitiveCount)
     2940{
     2941    Assert(PrimitiveCount > 0); /* Callers ensure this. */
     2942
     2943    UINT cVertices;
     2944    switch (PrimitiveType)
     2945    {
     2946        case D3DPT_POINTLIST:
     2947            cVertices = PrimitiveCount;     /* Vertex per point. */
     2948            break;
     2949
     2950        case D3DPT_LINELIST:
     2951            cVertices = PrimitiveCount * 2; /* Two vertices for each line. */
     2952            break;
     2953
     2954        case D3DPT_LINESTRIP:
     2955            cVertices = PrimitiveCount + 1; /* Two vertices for the first line and one vertex for each subsequent. */
     2956            break;
     2957
     2958        case D3DPT_TRIANGLELIST:
     2959            cVertices = PrimitiveCount * 3; /* Three vertices for each triangle. */
     2960            break;
     2961
     2962        case D3DPT_TRIANGLESTRIP:
     2963        case D3DPT_TRIANGLEFAN:
     2964            cVertices = PrimitiveCount + 2; /* Three vertices for the first triangle and one vertex for each subsequent. */
     2965            break;
     2966
     2967        default:
     2968            cVertices = 0; /* No such primitive in d3d9types.h. */
     2969            break;
     2970    }
     2971
     2972    return cVertices;
     2973}
     2974
    29392975static HRESULT APIENTRY vboxWddmDDevDrawIndexedPrimitive2(HANDLE hDevice, CONST D3DDDIARG_DRAWINDEXEDPRIMITIVE2* pData, UINT dwIndicesSize, CONST VOID* pIndexBuffer, CONST UINT* pFlagBuffer)
    29402976{
     
    29492985    DWORD cbVertexStride = 0;
    29502986
     2987    LOGF(("\n  PrimitiveType %d, BaseVertexOffset %d, MinIndex %d, NumVertices %d, StartIndexOffset %d, PrimitiveCount %d,\n"
     2988          "  dwIndicesSize %d, pIndexBuffer %p, pFlagBuffer %p\n",
     2989          pData->PrimitiveType,
     2990          pData->BaseVertexOffset,
     2991          pData->MinIndex,
     2992          pData->NumVertices,
     2993          pData->StartIndexOffset,
     2994          pData->PrimitiveCount,
     2995          dwIndicesSize,
     2996          pIndexBuffer,
     2997          pFlagBuffer));
     2998
    29512999    if (dwIndicesSize != 2 && dwIndicesSize != 4)
     3000    {
    29523001        WARN(("unsupported dwIndicesSize %d", dwIndicesSize));
    2953 
     3002        return E_INVALIDARG;
     3003    }
     3004
     3005    if (pData->PrimitiveCount == 0)
     3006    {
     3007        /* Nothing to draw. */
     3008        return S_OK;
     3009    }
     3010
     3011    /* Fetch the appropriate stream source:
     3012     * "Stream zero contains transform indices and is the only stream that should be accessed."
     3013     */
    29543014    if (pDevice->aStreamSourceUm[0].pvBuffer)
    29553015    {
     
    29583018        pvVertexBuffer = (const uint8_t *)pDevice->aStreamSourceUm[0].pvBuffer;
    29593019        cbVertexStride = pDevice->aStreamSourceUm[0].cbStride;
     3020        LOGF(("aStreamSourceUm %p, stride %d\n",
     3021              pvVertexBuffer, cbVertexStride));
    29603022    }
    29613023    else if (pDevice->aStreamSource[0])
     
    29673029            pvVertexBuffer = ((const uint8_t *)pAlloc->pvMem) + pDevice->StreamSourceInfo[0].uiOffset;
    29683030            cbVertexStride = pDevice->StreamSourceInfo[0].uiStride;
     3031            LOGF(("aStreamSource %p, cbSize %d, stride %d, uiOffset %d (elements %d)\n",
     3032                  pvVertexBuffer, pAlloc->SurfDesc.cbSize, cbVertexStride, pDevice->StreamSourceInfo[0].uiOffset,
     3033                  cbVertexStride? pAlloc->SurfDesc.cbSize / cbVertexStride: 0));
    29693034        }
    29703035        else
     
    29823047    if (SUCCEEDED(hr))
    29833048    {
    2984         pvVertexBuffer = pvVertexBuffer + pData->BaseVertexOffset /*  * cbVertexStride */;
    2985 
    2986         hr = pDevice9If->DrawIndexedPrimitiveUP(pData->PrimitiveType,
    2987                         pData->MinIndex,
    2988                         pData->NumVertices,
    2989                         pData->PrimitiveCount,
    2990                         ((uint8_t*)pIndexBuffer) + dwIndicesSize * pData->StartIndexOffset,
    2991                         dwIndicesSize == 2 ? D3DFMT_INDEX16 : D3DFMT_INDEX32,
    2992                         pvVertexBuffer,
    2993                         cbVertexStride);
    2994         if(SUCCEEDED(hr))
    2995             hr = S_OK;
     3049        /* Convert input data to appropriate DrawIndexedPrimitiveUP parameters.
     3050         * In particular prepare zero based vertex array becuase wine does not
     3051         * handle MinVertexIndex correctly.
     3052         */
     3053
     3054        /* Take the offset, which corresponds to the index == 0, into account. */
     3055        const uint8_t *pu8VertexStart = pvVertexBuffer + pData->BaseVertexOffset;
     3056
     3057        /* Where the pData->MinIndex starts. */
     3058        pu8VertexStart += pData->MinIndex * cbVertexStride;
     3059
     3060        /* Convert indexes to zero based relative to pData->MinIndex. */
     3061        const uint8_t *pu8IndicesStartSrc = (uint8_t *)pIndexBuffer + pData->StartIndexOffset;
     3062        UINT cIndices = vboxWddmVertexCountFromPrimitive(pData->PrimitiveType, pData->PrimitiveCount);
     3063
     3064        /* Allocate memory for converted indices. */
     3065        uint8_t *pu8IndicesStartConv = (uint8_t *)RTMemAlloc(cIndices * dwIndicesSize);
     3066        if (pu8IndicesStartConv != NULL)
     3067        {
     3068            UINT i;
     3069            if (dwIndicesSize == 2)
     3070            {
     3071                uint16_t *pu16Src = (uint16_t *)pu8IndicesStartSrc;
     3072                uint16_t *pu16Dst = (uint16_t *)pu8IndicesStartConv;
     3073                for (i = 0; i < cIndices; ++i, ++pu16Dst, ++pu16Src)
     3074                {
     3075                    *pu16Dst = *pu16Src - pData->MinIndex;
     3076                }
     3077            }
     3078            else
     3079            {
     3080                uint32_t *pu32Src = (uint32_t *)pu8IndicesStartSrc;
     3081                uint32_t *pu32Dst = (uint32_t *)pu8IndicesStartConv;
     3082                for (i = 0; i < cIndices; ++i, ++pu32Dst, ++pu32Src)
     3083                {
     3084                    *pu32Dst = *pu32Src - pData->MinIndex;
     3085                }
     3086            }
     3087
     3088            hr = pDevice9If->DrawIndexedPrimitiveUP(pData->PrimitiveType,
     3089                                                    0,
     3090                                                    pData->NumVertices,
     3091                                                    pData->PrimitiveCount,
     3092                                                    pu8IndicesStartConv,
     3093                                                    dwIndicesSize == 2 ? D3DFMT_INDEX16 : D3DFMT_INDEX32,
     3094                                                    pu8VertexStart,
     3095                                                    cbVertexStride);
     3096
     3097            if (SUCCEEDED(hr))
     3098                hr = S_OK;
     3099            else
     3100                WARN(("DrawIndexedPrimitiveUP failed hr = 0x%x", hr));
     3101
     3102            RTMemFree(pu8IndicesStartConv);
     3103
     3104            /* Following any IDirect3DDevice9::DrawIndexedPrimitiveUP call, the stream 0 settings,
     3105             * referenced by IDirect3DDevice9::GetStreamSource, are set to NULL. Also, the index
     3106             * buffer setting for IDirect3DDevice9::SetIndices is set to NULL.
     3107             */
     3108            if (pDevice->aStreamSource[0])
     3109            {
     3110                HRESULT tmpHr = pDevice9If->SetStreamSource(0, (IDirect3DVertexBuffer9*)pDevice->aStreamSource[0]->pD3DIf, pDevice->StreamSourceInfo[0].uiOffset, pDevice->StreamSourceInfo[0].uiStride);
     3111                if(!SUCCEEDED(tmpHr))
     3112                    WARN(("SetStreamSource failed hr = 0x%x", tmpHr));
     3113            }
     3114
     3115            if (pDevice->IndiciesInfo.pIndicesAlloc)
     3116            {
     3117                HRESULT tmpHr = pDevice9If->SetIndices((IDirect3DIndexBuffer9*)pDevice->IndiciesInfo.pIndicesAlloc->pD3DIf);
     3118                if(!SUCCEEDED(tmpHr))
     3119                    WARN(("SetIndices failed hr = 0x%x", tmpHr));
     3120            }
     3121        }
    29963122        else
    2997             WARN(("DrawIndexedPrimitiveUP failed hr = 0x%x", hr));
    2998 
    2999         if (pDevice->aStreamSource[0])
    3000         {
    3001             HRESULT tmpHr = pDevice9If->SetStreamSource(0, (IDirect3DVertexBuffer9*)pDevice->aStreamSource[0]->pD3DIf, pDevice->StreamSourceInfo[0].uiOffset, pDevice->StreamSourceInfo[0].uiStride);
    3002             if(!SUCCEEDED(tmpHr))
    3003                 WARN(("SetStreamSource failed hr = 0x%x", tmpHr));
    3004         }
    3005 
    3006         if (pDevice->IndiciesInfo.pIndicesAlloc)
    3007         {
    3008             HRESULT tmpHr = pDevice9If->SetIndices((IDirect3DIndexBuffer9*)pDevice->IndiciesInfo.pIndicesAlloc->pD3DIf);
    3009             if(!SUCCEEDED(tmpHr))
    3010                 WARN(("SetIndices failed hr = 0x%x", tmpHr));
     3123        {
     3124            hr = E_OUTOFMEMORY;
    30113125        }
    30123126    }
Note: See TracChangeset for help on using the changeset viewer.

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