Exemplo n.º 1
0
    uint32_t DirectXInputLayoutRegistry::create(const Vertices& vertices)
    {
        TB::runtimeCheck(vertices.size() > 0);

        const char* semantics[] = { "POSITION", "NORMAL", "TEXCOORD", "COLOR" };
        const DXGI_FORMAT formats[] = { DXGI_FORMAT(0), DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_R32G32_FLOAT, DXGI_FORMAT_R32G32B32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT };

        // Input layout elements
        std::vector<D3D11_INPUT_ELEMENT_DESC> elements;
        for (size_t i = 0; i < vertices.size(); i++)
        {
            const auto& stream = vertices[i];
            elements.push_back({ semantics[(int)stream.semantic], (UINT)stream.usageIndex, formats[stream.elements], (UINT)i, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 });
        }

        // Hash the memory bytes of the element
        uint32_t id = hash(reinterpret_cast<uint8_t*>(&elements[0]), elements.size() * sizeof(D3D11_INPUT_ELEMENT_DESC));
        auto item = mRegistry.find(id);
        if (item == mRegistry.end())
        {
            std::stringstream fakeVSCode;
            const char* memberTypes[] = { nullptr, "float", "float2", "float3", "float4" };

            // Create a fake vertex shader for the input layout
            fakeVSCode << "struct VSInput";
            fakeVSCode << "{";
            for (size_t i = 0; i < vertices.size(); i++)
            {
                const auto& stream = vertices[i];
                fakeVSCode << memberTypes[stream.elements] << " _" << i << " : " << semantics[(int)stream.semantic] << stream.usageIndex << ";";
            }
            fakeVSCode << "};";

            fakeVSCode << "float4 MainVS(VSInput input) : SV_POSITION { return float4(0, 0, 0, 1); }";

            DirectXShader fakeVS(mRenderer, DataChunk(fakeVSCode.str()), "MainVS", ShaderType::Vertex);

            ComPtr<ID3D11InputLayout> inputLayout;
            HRESULT hr = mRenderer->getDevice()->CreateInputLayout(&elements[0], (UINT)elements.size(), fakeVS.getBlob()->GetBufferPointer(), fakeVS.getBlob()->GetBufferSize(), inputLayout.getInitRef());
            TB::runtimeCheck(hr == S_OK);

            mRegistry.emplace(id, inputLayout);
        }

        return id;
    }
//-----------------------------------------------
HRESULT CPUTRenderTargetDepth::CreateRenderTarget(
    std::string     textureName,
    UINT        width,
    UINT        height,
    DXGI_FORMAT depthFormat,
    UINT        multiSampleCount,
    bool        recreate
)
{
    HRESULT result;

    mName             = textureName;
    mWidth            = width;
    mHeight           = height;
    mDepthFormat      = depthFormat;
    mMultiSampleCount = multiSampleCount;


    // NOTE: The following doesn't work for DX10.0 devices.
    // They don't support binding an MSAA depth texture as 

    // If we have a DX 10.1 or no MSAA, then create a shader resource view, and add a CPUTTexture to the AssetLibrary
    D3D_FEATURE_LEVEL featureLevel = gpSample->GetFeatureLevel();
    bool supportsResourceView = ( featureLevel >= D3D_FEATURE_LEVEL_10_1) || (mMultiSampleCount==1);

    D3D11_TEXTURE2D_DESC depthDesc = {
        width,
        height,
        1, // MIP Levels
        1, // Array Size
        DXGI_FORMAT(depthFormat - 1), //  DXGI_FORMAT_R32_TYPELESS
        mMultiSampleCount, 0,
        D3D11_USAGE_DEFAULT,
        D3D11_BIND_DEPTH_STENCIL | (supportsResourceView ? D3D11_BIND_SHADER_RESOURCE : 0),
        0, // CPU Access flags
        0 // Misc flags
    };

    // Create either a Texture2D, or Texture2DMS, depending on multisample count.
    D3D11_DSV_DIMENSION dsvDimension = (mMultiSampleCount>1) ? D3D11_DSV_DIMENSION_TEXTURE2DMS : D3D11_DSV_DIMENSION_TEXTURE2D;

    ID3D11Device *pD3dDevice = CPUT_DX11::GetDevice();
    result = pD3dDevice->CreateTexture2D( &depthDesc, NULL, &mpDepthTextureDX );
    ASSERT( SUCCEEDED(result), "Failed creating depth texture.\nAre you using MSAA with a DX10.0 GPU?\nOnly DX10.1 and above can create a shader resource view for an MSAA depth texture." );

    D3D11_DEPTH_STENCIL_VIEW_DESC dsvd = { depthFormat, dsvDimension, 0 };
    result = pD3dDevice->CreateDepthStencilView( mpDepthTextureDX, &dsvd, &mpDepthStencilView );
    ASSERT( SUCCEEDED(result), "Failed creating depth stencil view" );
    CPUTSetDebugName( mpDepthStencilView, mName );

    if( supportsResourceView )
    {
        D3D11_SRV_DIMENSION srvDimension = (mMultiSampleCount>1) ? D3D11_SRV_DIMENSION_TEXTURE2DMS : D3D11_SRV_DIMENSION_TEXTURE2D;
        // Create the shader-resource view
        D3D11_SHADER_RESOURCE_VIEW_DESC depthRsDesc =
        {
            DXGI_FORMAT(depthFormat + 1),
            srvDimension,
            0
        };
        // TODO: Support optionally creating MIP chain.  Then, support MIP generation (e.g., GenerateMIPS()).
        depthRsDesc.Texture2D.MipLevels = 1;

        result = pD3dDevice->CreateShaderResourceView( mpDepthTextureDX, &depthRsDesc, &mpDepthResourceView );
        ASSERT( SUCCEEDED(result), "Failed creating render target shader resource view" );
        CPUTSetDebugName( mpDepthResourceView, textureName + " Depth" );

        if( !recreate )
        {
            CPUTAssetLibrary *pAssetLibrary = CPUTAssetLibrary::GetAssetLibrary();

            mpDepthTexture = CPUTTextureDX11::Create(mName);
            pAssetLibrary->AddTexture( mName, "", "", mpDepthTexture );
        }
        ((CPUTTextureDX11*)mpDepthTexture)->SetTextureAndShaderResourceView(mpDepthTextureDX, mpDepthResourceView);
    }
    return S_OK;
}