int TextureViewParser::GetDefaultView( lua_State *L )
    {
        INIT_LUA_STACK_TRACKING( L );

        // Texture should be the first argument
        auto *pTexture = *GetUserData<ITexture**>( L, 1, m_TextureLibMetatableName.c_str() );
        
        // View type should be the second argument
        TEXTURE_VIEW_TYPE ViewType;
        m_ViewTypeParser.SetValue( L, 2, &ViewType );

        auto pView = pTexture->GetDefaultView( ViewType );
        if( !pView )
            SCRIPT_PARSING_ERROR( L, "Failed to get default texture view of type ", GetTexViewTypeLiteralName( ViewType ) );

        // Push existing object
        PushObject(L, pView);

        CHECK_LUA_STACK_HEIGHT( +1 );

        // Returning one value to Lua
        return 1;
    }
Esempio n. 2
0
void TextureBaseGL::CreateViewInternal( const struct TextureViewDesc &OrigViewDesc, class ITextureView **ppView, bool bIsDefaultView )
{
    VERIFY( ppView != nullptr, "Null pointer provided" );
    if( !ppView )return;
    VERIFY( *ppView == nullptr, "Overwriting reference to existing object may cause memory leaks" );

    *ppView = nullptr;

    try
    {
        auto ViewDesc = OrigViewDesc;
        CorrectTextureViewDesc(ViewDesc);

        auto *pDeviceGLImpl = ValidatedCast<RenderDeviceGLImpl>(GetDevice());
        auto &TexViewAllocator = pDeviceGLImpl->GetTexViewObjAllocator();
        VERIFY( &TexViewAllocator == &m_dbgTexViewObjAllocator, "Texture view allocator does not match allocator provided during texture initialization" );

        // http://www.opengl.org/wiki/Texture_Storage#Texture_views

        GLenum GLViewFormat = TexFormatToGLInternalTexFormat( ViewDesc.Format, m_Desc.BindFlags );
        VERIFY( GLViewFormat != 0, "Unsupported texture format" );
        
        TextureViewGLImpl *pViewOGL = nullptr;
        if( ViewDesc.ViewType == TEXTURE_VIEW_SHADER_RESOURCE )
        {
            bool bIsFullTextureView =
                ViewDesc.TextureDim     == m_Desc.Type       &&
                ViewDesc.Format          == GetDefaultTextureViewFormat( m_Desc.Format, ViewDesc.ViewType, m_Desc.BindFlags ) &&
                ViewDesc.MostDetailedMip == 0                &&
                ViewDesc.NumMipLevels    == m_Desc.MipLevels &&
                ViewDesc.FirstArraySlice == 0                &&
                ViewDesc.NumArraySlices  == m_Desc.ArraySize;

            pViewOGL = NEW_RC_OBJ(TexViewAllocator, "TextureViewGLImpl instance", TextureViewGLImpl, bIsDefaultView ? this : nullptr)(
                                               pDeviceGLImpl, ViewDesc, this, 
                                               !bIsFullTextureView, // Create OpenGL texture view object if view
                                                                    // does not address the whole texture
                                               bIsDefaultView
                                               );
            if( !bIsFullTextureView )
            {
                GLenum GLViewTarget = 0;
                switch(ViewDesc.TextureDim)
                {
                    case RESOURCE_DIM_TEX_1D:
                        GLViewTarget = GL_TEXTURE_1D;
                        ViewDesc.NumArraySlices = 1;
                        break;
        
                    case RESOURCE_DIM_TEX_1D_ARRAY:
                        GLViewTarget = GL_TEXTURE_1D_ARRAY;
                        break;

                    case RESOURCE_DIM_TEX_2D:
                        GLViewTarget = m_Desc.SampleCount > 1 ? GL_TEXTURE_2D_MULTISAMPLE : GL_TEXTURE_2D;
                        ViewDesc.NumArraySlices = 1;
                        break;
        
                    case RESOURCE_DIM_TEX_2D_ARRAY:
                        GLViewTarget = m_Desc.SampleCount > 1 ? GL_TEXTURE_2D_MULTISAMPLE_ARRAY : GL_TEXTURE_2D_ARRAY;
                        break;

                    case RESOURCE_DIM_TEX_3D:
                        GLViewTarget = GL_TEXTURE_3D;
                        break;

                    case RESOURCE_DIM_TEX_CUBE:
                        GLViewTarget = GL_TEXTURE_CUBE_MAP;
                        break;

                    case RESOURCE_DIM_TEX_CUBE_ARRAY:
                        GLViewTarget = GL_TEXTURE_CUBE_MAP_ARRAY;
                        break;

                    default: UNEXPECTED("Unsupported texture view type");
                }

                glTextureView( pViewOGL->GetHandle(), GLViewTarget, m_GlTexture, GLViewFormat, ViewDesc.MostDetailedMip, ViewDesc.NumMipLevels, ViewDesc.FirstArraySlice, ViewDesc.NumArraySlices );
                CHECK_GL_ERROR_AND_THROW( "Failed to create texture view" );
                pViewOGL->SetBindTarget(GLViewTarget);
            }
        }
        else if( ViewDesc.ViewType == TEXTURE_VIEW_UNORDERED_ACCESS )
        {
            VERIFY( ViewDesc.NumArraySlices == 1 || ViewDesc.NumArraySlices == m_Desc.ArraySize,
                    "Only single array/depth slice or the whole texture can be bound as UAV in OpenGL");
            VERIFY( ViewDesc.AccessFlags != 0, "At least one access flag must be specified" );
            pViewOGL = NEW_RC_OBJ(TexViewAllocator, "TextureViewGLImpl instance", TextureViewGLImpl, bIsDefaultView ? this : nullptr)(
                                               pDeviceGLImpl, ViewDesc, this, 
                                               false, // Do NOT create texture view OpenGL object
                                               bIsDefaultView
                                               );
        }
        else if( ViewDesc.ViewType == TEXTURE_VIEW_RENDER_TARGET )
        {
            VERIFY( ViewDesc.NumMipLevels == 1, "Only single mip level can be bound as RTV" );
            pViewOGL = NEW_RC_OBJ(TexViewAllocator, "TextureViewGLImpl instance", TextureViewGLImpl, bIsDefaultView ? this : nullptr)(
                                               pDeviceGLImpl, ViewDesc, this, 
                                               false, // Do NOT create texture view OpenGL object
                                               bIsDefaultView
                                              );
        }
        else if( ViewDesc.ViewType == TEXTURE_VIEW_DEPTH_STENCIL )
        {
            VERIFY( ViewDesc.NumMipLevels == 1, "Only single mip level can be bound as DSV" );
            pViewOGL = NEW_RC_OBJ(TexViewAllocator, "TextureViewGLImpl instance", TextureViewGLImpl, bIsDefaultView ? this : nullptr)(
                                               pDeviceGLImpl, ViewDesc, this, 
                                               false, // Do NOT create texture view OpenGL object
                                               bIsDefaultView
                                              );
        }

        if( bIsDefaultView )
            *ppView = pViewOGL;
        else
        {
            if( pViewOGL )
            {
                pViewOGL->QueryInterface( IID_TextureView, reinterpret_cast<IObject**>(ppView) );
            }
        }
    }
    catch( const std::runtime_error& )
    {
        const auto *ViewTypeName = GetTexViewTypeLiteralName(OrigViewDesc.ViewType);
        LOG_ERROR("Failed to create view \"", OrigViewDesc.Name ? OrigViewDesc.Name : "", "\" (", ViewTypeName, ") for texture \"", m_Desc.Name ? m_Desc.Name : "", "\"" )
    }
}