void SlateMaterial::CreateDeviceDependentResources()

in Shared/Rendering/SlateMaterial.cpp [75:178]


    void SlateMaterial::CreateDeviceDependentResources()
    {
        _usingVprtShaders = _deviceResources->GetDeviceSupportsVprt();

        // On devices that do support the D3D11_FEATURE_D3D11_OPTIONS3::
        // VPAndRTArrayIndexFromAnyShaderFeedingRasterizer optional feature
        // we can avoid using a pass-through geometry shader to set the render
        // target array index, thus avoiding any overhead that would be 
        // incurred by setting the geometry shader stage.
        const std::wstring vertexShaderFileName =
            _usingVprtShaders
            ? L"ms-appx:///Rendering/SlateMaterial.VPRT.vs.cso"
            : L"ms-appx:///Rendering/SlateMaterial.Default.vs.cso";

        // Load shaders asynchronously.
        Concurrency::task<std::vector<byte>> loadVSTask =
            Io::ReadDataAsync(
                vertexShaderFileName);

        Concurrency::task<std::vector<byte>> loadPSTask =
            Io::ReadDataAsync(
                L"ms-appx:///Rendering/SlateMaterial.Default.ps.cso");

        Concurrency::task<std::vector<byte>> loadGSTask;
        if (!_usingVprtShaders)
        {
            // Load the pass-through geometry shader.
            loadGSTask =
                Io::ReadDataAsync(
                    L"ms-appx:///Rendering/SlateMaterial.Default.gs.cso");
        }

        // After the vertex shader file is loaded, create the shader and input layout.
        Concurrency::task<void> createVSTask = loadVSTask.then([this](const std::vector<byte>& fileData)
        {
            ASSERT_SUCCEEDED(
                _deviceResources->GetD3DDevice()->CreateVertexShader(
                    fileData.data(),
                    fileData.size(),
                    nullptr,
                    &_vertexShader
                )
            );

            constexpr std::array<D3D11_INPUT_ELEMENT_DESC, 3> vertexDesc =
            { {
                { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },
                { "COLOR",    0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },
                { "TEXCOORD",    0, DXGI_FORMAT_R32G32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },
            } };

            ASSERT_SUCCEEDED(
                _deviceResources->GetD3DDevice()->CreateInputLayout(
                    vertexDesc.data(),
                    static_cast<uint32_t>(vertexDesc.size()),
                    fileData.data(),
                    fileData.size(),
                    &_inputLayout
                )
            );
        });

        Concurrency::task<void> createGSTask;
        if (!_usingVprtShaders)
        {
            // After the pass-through geometry shader file is loaded, create the shader.
            createGSTask = loadGSTask.then([this](const std::vector<byte>& fileData)
            {
                ASSERT_SUCCEEDED(
                    _deviceResources->GetD3DDevice()->CreateGeometryShader(
                        fileData.data(),
                        fileData.size(),
                        nullptr,
                        &_geometryShader
                    )
                );
            });
        }

        // After the pixel shader file is loaded, create the shader and constant buffer.
        Concurrency::task<void> createPSTask = loadPSTask.then([this](const std::vector<byte>& fileData)
        {
            ASSERT_SUCCEEDED(
                _deviceResources->GetD3DDevice()->CreatePixelShader(
                    fileData.data(),
                    fileData.size(),
                    nullptr,
                    &_pixelShader
                )
            );
        });

        // Once all shaders are loaded, create the mesh.
        Concurrency::task<void> shaderTaskGroup =
            _usingVprtShaders
            ? (createPSTask && createVSTask)
            : (createPSTask && createGSTask && createVSTask);

        // Once the cube is loaded, the object is ready to be rendered.
        shaderTaskGroup.then([this]()
        {
            _loadingComplete = true;
        });
    }