void TexRegionRender::Render( DeviceContextGLImpl *pCtxGL,
                                   ITextureView *pSrcSRV,
                                   RESOURCE_DIMENSION TexType,
                                   TEXTURE_FORMAT TexFormat,
                                   Int32 DstToSrcXOffset,
                                   Int32 DstToSrcYOffset,
                                   Int32 SrcZ,
                                   Int32 SrcMipLevel)
    {
        {
            MapHelper< int > pConstant( pCtxGL, m_pConstantBuffer, MAP_WRITE_DISCARD, 0 );
            pConstant[0] = DstToSrcXOffset;
            pConstant[1] = DstToSrcYOffset;
            pConstant[2] = SrcZ;
            pConstant[3] = SrcMipLevel;
        }

        const auto &TexFmtAttribs = GetTextureFormatAttribs(TexFormat);
        Uint32 FSInd = TexType * 3;
        if( TexFmtAttribs.ComponentType == COMPONENT_TYPE_SINT )
            FSInd += 1;
        else if( TexFmtAttribs.ComponentType == COMPONENT_TYPE_UINT )
            FSInd += 2;

        if( TexFmtAttribs.ComponentType == COMPONENT_TYPE_SNORM )
        {
            LOG_WARNING_MESSAGE("CopyData() is performed by rendering to texture.\n"
                                "There might be an issue in OpenGL driver on NVidia hardware: when rendering to SNORM textures, all negative values are clamped to zero.")
        }

        pCtxGL->SetPipelineState(m_pPSO[FSInd]);
        auto SrcTexVar = m_pFragmentShaders[FSInd]->GetShaderVariable( "gSourceTex" );
        SrcTexVar->Set( pSrcSRV );

        DrawAttribs DrawAttrs;
        DrawAttrs.NumVertices = 4;
        DrawAttrs.Topology = PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
        pCtxGL->Draw( DrawAttrs );

        SrcTexVar->Set( nullptr );
    }
static TextureDesc GetTextureDescFromGLHandle(DeviceContextGLImpl *pDeviceContextGL, TextureDesc TexDesc, GLuint GLHandle, GLenum BindTarget)
{
    auto &ContextState = pDeviceContextGL->GetContextState();
    
    VERIFY(BindTarget != GL_TEXTURE_CUBE_MAP_ARRAY, "Cubemap arrays are not currently supported")

    GLObjectWrappers::GLTextureObj TmpGLTexWrapper(true, GLObjectWrappers::GLTextureCreateReleaseHelper(GLHandle));
    ContextState.BindTexture(-1, BindTarget, TmpGLTexWrapper);

    GLenum QueryBindTarget = BindTarget;
    if (BindTarget == GL_TEXTURE_CUBE_MAP)
        QueryBindTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X;

    GLint TexWidth = 0, TexHeight = 0, TexDepth = 0;
    glGetTexLevelParameteriv(QueryBindTarget, 0, GL_TEXTURE_WIDTH, &TexWidth);
    if (TexDesc.Type >= RESOURCE_DIM_TEX_2D)
        glGetTexLevelParameteriv(QueryBindTarget, 0, GL_TEXTURE_HEIGHT, &TexHeight);
    else
        TexHeight = 1;

    if (TexDesc.Type == RESOURCE_DIM_TEX_3D)
        glGetTexLevelParameteriv(QueryBindTarget, 0, GL_TEXTURE_DEPTH, &TexDepth);
    else
        TexDepth = 1;
    
    GLint GlFormat = 0;
    glGetTexLevelParameteriv(QueryBindTarget, 0, GL_TEXTURE_INTERNAL_FORMAT, &GlFormat);
    CHECK_GL_ERROR( "Failed to get texture level 0 parameters through glGetTexLevelParameteriv()" );

    VERIFY(GlFormat != 0, "Unable to get texture format")
    if (TexDesc.Format != TEX_FORMAT_UNKNOWN)
        VERIFY(static_cast<GLenum>(GlFormat) == TexFormatToGLInternalTexFormat(TexDesc.Format), "Specified texture format (", GetTextureFormatAttribs(TexDesc.Format).Name,") does not match GL texture internal format (", GlFormat, ")")
    else
        TexDesc.Format = GLInternalTexFormatToTexFormat(GlFormat);

    VERIFY_EXPR(TexWidth > 0 && TexHeight > 0 && TexDepth > 0);
    VERIFY(TexDesc.Width == 0 || TexDesc.Width == static_cast<Uint32>(TexWidth), "Specified texture width (", TexDesc.Width, ") does not match the actual width (", TexWidth, ")");
    VERIFY(TexDesc.Height == 0 || TexDesc.Height == static_cast<Uint32>(TexHeight), "Specified texture height (", TexDesc.Height,") does not match the actual height (", TexHeight, ")");
    TexDesc.Width = static_cast<Uint32>(TexWidth);
    TexDesc.Height = static_cast<Uint32>(TexHeight);
    if (TexDesc.Type == RESOURCE_DIM_TEX_3D)
    {
        VERIFY(TexDesc.Depth == 0 || TexDesc.Depth == static_cast<Uint32>(TexDepth), "Specified texture depth (", TexDesc.Depth, ") does not match the actual depth (", TexDepth, ")");
        TexDesc.Depth = static_cast<Uint32>(TexDepth);
    }

    GLint MipLevels = 0;
    glGetTexParameteriv(BindTarget, GL_TEXTURE_IMMUTABLE_LEVELS, &MipLevels);
    CHECK_GL_ERROR( "Failed to get texture parameters through glGetTexParameteriv()" );
    VERIFY(TexDesc.MipLevels == 0 || TexDesc.MipLevels == static_cast<Uint32>(MipLevels), "Specified number of mip levels (", TexDesc.MipLevels, ") does not match the actual number of mip levels (", MipLevels, ")");
    TexDesc.MipLevels = static_cast<Uint32>(MipLevels);
    
    ContextState.BindTexture(-1, BindTarget, GLObjectWrappers::GLTextureObj(false) );
    return TexDesc;
}