Esempio n. 1
0
void StateManager11::SRVCache::update(size_t resourceIndex, ID3D11ShaderResourceView *srv)
{
    ASSERT(resourceIndex < mCurrentSRVs.size());
    SRVRecord *record = &mCurrentSRVs[resourceIndex];

    record->srv = reinterpret_cast<uintptr_t>(srv);
    if (srv)
    {
        record->resource = reinterpret_cast<uintptr_t>(GetViewResource(srv));
        srv->GetDesc(&record->desc);
        mHighestUsedSRV = std::max(resourceIndex + 1, mHighestUsedSRV);
    }
    else
    {
        record->resource = 0;

        if (resourceIndex + 1 == mHighestUsedSRV)
        {
            do
            {
                --mHighestUsedSRV;
            } while (mHighestUsedSRV > 0 && mCurrentSRVs[mHighestUsedSRV].srv == 0);
        }
    }
}
Esempio n. 2
0
gl::Error StateManager11::syncFramebuffer(const gl::Framebuffer *framebuffer)
{
    // Get the color render buffer and serial
    // Also extract the render target dimensions and view
    unsigned int renderTargetWidth  = 0;
    unsigned int renderTargetHeight = 0;
    DXGI_FORMAT renderTargetFormat  = DXGI_FORMAT_UNKNOWN;
    RenderTargetArray framebufferRTVs;
    bool missingColorRenderTarget = true;

    framebufferRTVs.fill(nullptr);

    const Framebuffer11 *framebuffer11     = GetImplAs<Framebuffer11>(framebuffer);
    const gl::AttachmentList &colorbuffers = framebuffer11->getColorAttachmentsForRender();

    for (size_t colorAttachment = 0; colorAttachment < colorbuffers.size(); ++colorAttachment)
    {
        const gl::FramebufferAttachment *colorbuffer = colorbuffers[colorAttachment];

        if (colorbuffer)
        {
            // the draw buffer must be either "none", "back" for the default buffer or the same
            // index as this color (in order)

            // check for zero-sized default framebuffer, which is a special case.
            // in this case we do not wish to modify any state and just silently return false.
            // this will not report any gl error but will cause the calling method to return.
            const gl::Extents &size = colorbuffer->getSize();
            if (size.width == 0 || size.height == 0)
            {
                return gl::Error(GL_NO_ERROR);
            }

            // Extract the render target dimensions and view
            RenderTarget11 *renderTarget = NULL;
            gl::Error error = colorbuffer->getRenderTarget(&renderTarget);
            if (error.isError())
            {
                return error;
            }
            ASSERT(renderTarget);

            framebufferRTVs[colorAttachment] = renderTarget->getRenderTargetView();
            ASSERT(framebufferRTVs[colorAttachment]);

            if (missingColorRenderTarget)
            {
                renderTargetWidth        = renderTarget->getWidth();
                renderTargetHeight       = renderTarget->getHeight();
                renderTargetFormat       = renderTarget->getDXGIFormat();
                missingColorRenderTarget = false;
            }

            // Unbind render target SRVs from the shader here to prevent D3D11 warnings.
            if (colorbuffer->type() == GL_TEXTURE)
            {
                uintptr_t rtResource =
                    reinterpret_cast<uintptr_t>(GetViewResource(framebufferRTVs[colorAttachment]));
                const gl::ImageIndex &index = colorbuffer->getTextureImageIndex();
                // The index doesn't need to be corrected for the small compressed texture
                // workaround
                // because a rendertarget is never compressed.
                unsetConflictingSRVs(gl::SAMPLER_VERTEX, rtResource, index);
                unsetConflictingSRVs(gl::SAMPLER_PIXEL, rtResource, index);
            }
        }
    }

    // Get the depth stencil buffers
    ID3D11DepthStencilView *framebufferDSV        = NULL;
    const gl::FramebufferAttachment *depthStencil = framebuffer->getDepthOrStencilbuffer();
    if (depthStencil)
    {
        RenderTarget11 *depthStencilRenderTarget = NULL;
        gl::Error error = depthStencil->getRenderTarget(&depthStencilRenderTarget);
        if (error.isError())
        {
            return error;
        }
        ASSERT(depthStencilRenderTarget);

        framebufferDSV = depthStencilRenderTarget->getDepthStencilView();
        ASSERT(framebufferDSV);

        // If there is no render buffer, the width, height and format values come from
        // the depth stencil
        if (missingColorRenderTarget)
        {
            renderTargetWidth  = depthStencilRenderTarget->getWidth();
            renderTargetHeight = depthStencilRenderTarget->getHeight();
        }

        // Unbind render target SRVs from the shader here to prevent D3D11 warnings.
        if (depthStencil->type() == GL_TEXTURE)
        {
            uintptr_t depthStencilResource =
                reinterpret_cast<uintptr_t>(GetViewResource(framebufferDSV));
            const gl::ImageIndex &index = depthStencil->getTextureImageIndex();
            // The index doesn't need to be corrected for the small compressed texture workaround
            // because a rendertarget is never compressed.
            unsetConflictingSRVs(gl::SAMPLER_VERTEX, depthStencilResource, index);
            unsetConflictingSRVs(gl::SAMPLER_PIXEL, depthStencilResource, index);
        }
    }

    if (setRenderTargets(framebufferRTVs, framebufferDSV))
    {
        setViewportBounds(renderTargetWidth, renderTargetHeight);
    }

    gl::Error error = framebuffer11->invalidateSwizzles();
    if (error.isError())
    {
        return error;
    }

    return gl::Error(GL_NO_ERROR);
}