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; }
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 : "", "\"" ) } }