void RenderDeviceD3D11Impl :: CreateTexture(const TextureDesc& TexDesc, const TextureData &Data, ITexture **ppTexture) { CreateDeviceObject( "texture", TexDesc, ppTexture, [&]() { TextureBaseD3D11 *pTextureD3D11 = nullptr; switch( TexDesc.Type ) { case RESOURCE_DIM_TEX_1D: case RESOURCE_DIM_TEX_1D_ARRAY: pTextureD3D11 = NEW_RC_OBJ(m_TexObjAllocator, "Texture1D_D3D11 instance", Texture1D_D3D11) (m_TexViewObjAllocator, this, TexDesc, Data ); break; case RESOURCE_DIM_TEX_2D: case RESOURCE_DIM_TEX_2D_ARRAY: case RESOURCE_DIM_TEX_CUBE: case RESOURCE_DIM_TEX_CUBE_ARRAY: pTextureD3D11 = NEW_RC_OBJ(m_TexObjAllocator, "Texture2D_D3D11 instance", Texture2D_D3D11) (m_TexViewObjAllocator, this, TexDesc, Data ); break; case RESOURCE_DIM_TEX_3D: pTextureD3D11 = NEW_RC_OBJ(m_TexObjAllocator, "Texture3D_D3D11 instance", Texture3D_D3D11) (m_TexViewObjAllocator, this, TexDesc, Data ); break; default: LOG_ERROR_AND_THROW( "Unknown texture type. (Did you forget to initialize the Type member of TextureDesc structure?)" ); } pTextureD3D11->QueryInterface( IID_Texture, reinterpret_cast<IObject**>(ppTexture) ); pTextureD3D11->CreateDefaultViews(); OnCreateDeviceObject( pTextureD3D11 ); } ); }
void BufferGLImpl::CreateViewInternal( const BufferViewDesc &OrigViewDesc, class IBufferView **ppView, bool bIsDefaultView ) { VERIFY( ppView != nullptr, "Buffer view pointer address is null" ); if( !ppView )return; VERIFY( *ppView == nullptr, "Overwriting reference to existing object may cause memory leaks" ); *ppView = nullptr; try { auto ViewDesc = OrigViewDesc; CorrectBufferViewDesc( ViewDesc ); auto *pDeviceGLImpl = ValidatedCast<RenderDeviceGLImpl>(GetDevice()); auto &BuffViewAllocator = pDeviceGLImpl->GetBuffViewObjAllocator(); VERIFY( &BuffViewAllocator == &m_dbgBuffViewAllocator, "Buff view allocator does not match allocator provided at buffer initialization" ); auto pContext = pDeviceGLImpl->GetImmediateContext(); VERIFY( pContext, "Immediate context has been released" ); *ppView = NEW_RC_OBJ(BuffViewAllocator, "BufferViewGLImpl instance", BufferViewGLImpl, bIsDefaultView ? this : nullptr)(pDeviceGLImpl, pContext, ViewDesc, this, bIsDefaultView); if( !bIsDefaultView ) (*ppView)->AddRef(); } catch( const std::runtime_error & ) { const auto *ViewTypeName = GetBufferViewTypeLiteralName(OrigViewDesc.ViewType); LOG_ERROR("Failed to create view \"", OrigViewDesc.Name ? OrigViewDesc.Name : "", "\" (", ViewTypeName, ") for buffer \"", m_Desc.Name ? m_Desc.Name : "", "\""); } }
/// \param [in] CreationAttribs - Engine creation attributes. /// \param [out] ppDevice - Address of the memory location where pointer to /// the created device will be written. /// \param [out] ppImmediateContext - Address of the memory location where pointers to /// the immediate context will be written. void EngineFactoryOpenGLImpl::AttachToActiveGLContext( const EngineGLAttribs& CreationAttribs, IRenderDevice **ppDevice, IDeviceContext **ppImmediateContext ) { if (CreationAttribs.DebugMessageCallback != nullptr) SetDebugMessageCallback(CreationAttribs.DebugMessageCallback); VERIFY( ppDevice && ppImmediateContext, "Null pointer provided" ); if( !ppDevice || !ppImmediateContext ) return; *ppDevice = nullptr; *ppImmediateContext = nullptr; try { SetRawAllocator(CreationAttribs.pRawMemAllocator); auto &RawMemAllocator = GetRawAllocator(); RenderDeviceGLImpl *pRenderDeviceOpenGL( NEW_RC_OBJ(RawMemAllocator, "TRenderDeviceGLImpl instance", TRenderDeviceGLImpl)(RawMemAllocator, CreationAttribs) ); pRenderDeviceOpenGL->QueryInterface(IID_RenderDevice, reinterpret_cast<IObject**>(ppDevice) ); DeviceContextGLImpl *pDeviceContextOpenGL( NEW_RC_OBJ(RawMemAllocator, "DeviceContextGLImpl instance", DeviceContextGLImpl)(pRenderDeviceOpenGL, false ) ); // We must call AddRef() (implicitly through QueryInterface()) because pRenderDeviceOpenGL will // keep a weak reference to the context pDeviceContextOpenGL->QueryInterface(IID_DeviceContext, reinterpret_cast<IObject**>(ppImmediateContext) ); pRenderDeviceOpenGL->SetImmediateContext(pDeviceContextOpenGL); } catch( const std::runtime_error & ) { if( *ppDevice ) { (*ppDevice)->Release(); *ppDevice = nullptr; } if( *ppImmediateContext ) { (*ppImmediateContext)->Release(); *ppImmediateContext = nullptr; } LOG_ERROR( "Failed to initialize OpenGL-based render device" ); } }
void RenderDeviceD3D12Impl::CreateTexture(const TextureDesc& TexDesc, ID3D12Resource *pd3d12Texture, class TextureD3D12Impl **ppTexture) { CreateDeviceObject( "texture", TexDesc, ppTexture, [&]() { TextureD3D12Impl *pTextureD3D12 = NEW_RC_OBJ(m_TexObjAllocator, "TextureD3D12Impl instance", TextureD3D12Impl)(m_TexViewObjAllocator, this, TexDesc, pd3d12Texture ); pTextureD3D12->QueryInterface( IID_TextureD3D12, reinterpret_cast<IObject**>(ppTexture) ); } ); }
void RenderDeviceD3D12Impl::CreatePipelineState(const PipelineStateDesc &PipelineDesc, IPipelineState **ppPipelineState) { CreateDeviceObject("Pipeline State", PipelineDesc, ppPipelineState, [&]() { PipelineStateD3D12Impl *pPipelineStateD3D12( NEW_RC_OBJ(m_PSOAllocator, "PipelineStateD3D12Impl instance", PipelineStateD3D12Impl)(this, PipelineDesc ) ); pPipelineStateD3D12->QueryInterface( IID_PipelineState, reinterpret_cast<IObject**>(ppPipelineState) ); OnCreateDeviceObject( pPipelineStateD3D12 ); } ); }
void RenderDeviceD3D12Impl :: CreateShader(const ShaderCreationAttribs &ShaderCreationAttribs, IShader **ppShader) { CreateDeviceObject( "shader", ShaderCreationAttribs.Desc, ppShader, [&]() { ShaderD3D12Impl *pShaderD3D12( NEW_RC_OBJ(m_ShaderObjAllocator, "ShaderD3D12Impl instance", ShaderD3D12Impl)(this, ShaderCreationAttribs ) ); pShaderD3D12->QueryInterface( IID_Shader, reinterpret_cast<IObject**>(ppShader) ); OnCreateDeviceObject( pShaderD3D12 ); } ); }
void RenderDeviceD3D12Impl :: CreateBuffer(const BufferDesc& BuffDesc, const BufferData &BuffData, IBuffer **ppBuffer) { CreateDeviceObject("buffer", BuffDesc, ppBuffer, [&]() { BufferD3D12Impl *pBufferD3D12( NEW_RC_OBJ(m_BufObjAllocator, "BufferD3D12Impl instance", BufferD3D12Impl)(m_BuffViewObjAllocator, this, BuffDesc, BuffData ) ); pBufferD3D12->QueryInterface( IID_Buffer, reinterpret_cast<IObject**>(ppBuffer) ); pBufferD3D12->CreateDefaultViews(); OnCreateDeviceObject( pBufferD3D12 ); } ); }
void RenderDeviceD3D11Impl :: CreateBufferFromD3DResource(ID3D11Buffer *pd3d11Buffer, const BufferDesc& BuffDesc, IBuffer **ppBuffer) { CreateDeviceObject("buffer", BuffDesc, ppBuffer, [&]() { BufferD3D11Impl *pBufferD3D11( NEW_RC_OBJ(m_BufObjAllocator, "BufferD3D11Impl instance", BufferD3D11Impl) (m_BuffViewObjAllocator, this, BuffDesc, pd3d11Buffer ) ); pBufferD3D11->QueryInterface( IID_Buffer, reinterpret_cast<IObject**>(ppBuffer) ); pBufferD3D11->CreateDefaultViews(); OnCreateDeviceObject( pBufferD3D11 ); } ); }
void RenderDeviceD3D12Impl :: CreateTexture(const TextureDesc& TexDesc, const TextureData &Data, ITexture **ppTexture) { CreateDeviceObject( "texture", TexDesc, ppTexture, [&]() { TextureD3D12Impl *pTextureD3D12 = NEW_RC_OBJ(m_TexObjAllocator, "TextureD3D12Impl instance", TextureD3D12Impl)(m_TexViewObjAllocator, this, TexDesc, Data ); pTextureD3D12->QueryInterface( IID_Texture, reinterpret_cast<IObject**>(ppTexture) ); pTextureD3D12->CreateDefaultViews(); OnCreateDeviceObject( pTextureD3D12 ); } ); }
void BufferD3D11Impl::CreateViewInternal( const BufferViewDesc &OrigViewDesc, IBufferView **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 *pDeviceD3D11Impl = ValidatedCast<RenderDeviceD3D11Impl>(GetDevice()); auto &BuffViewAllocator = pDeviceD3D11Impl->GetBuffViewObjAllocator(); VERIFY( &BuffViewAllocator == &m_dbgBuffViewAllocator, "Buff view allocator does not match allocator provided at buffer initialization" ); BufferViewDesc ViewDesc = OrigViewDesc; if( ViewDesc.ViewType == BUFFER_VIEW_UNORDERED_ACCESS ) { CComPtr<ID3D11UnorderedAccessView> pUAV; CreateUAV( ViewDesc, &pUAV ); *ppView = NEW_RC_OBJ(BuffViewAllocator, "BufferViewD3D11Impl instance", BufferViewD3D11Impl, bIsDefaultView ? this : nullptr) ( pDeviceD3D11Impl, ViewDesc, this, pUAV, bIsDefaultView ); } else if( ViewDesc.ViewType == BUFFER_VIEW_SHADER_RESOURCE ) { CComPtr<ID3D11ShaderResourceView> pSRV; CreateSRV( ViewDesc, &pSRV ); *ppView = NEW_RC_OBJ(BuffViewAllocator, "BufferViewD3D11Impl instance", BufferViewD3D11Impl, bIsDefaultView ? this : nullptr) (pDeviceD3D11Impl, ViewDesc, this, pSRV, bIsDefaultView ); } if( !bIsDefaultView && *ppView ) (*ppView)->AddRef(); } catch( const std::runtime_error & ) { const auto *ViewTypeName = GetBufferViewTypeLiteralName(OrigViewDesc.ViewType); LOG_ERROR("Failed to create view \"", OrigViewDesc.Name ? OrigViewDesc.Name : "", "\" (", ViewTypeName, ") for buffer \"", m_Desc.Name, "\"" ); } }
void RenderDeviceD3D12Impl::CreateTextureFromD3DResource(ID3D12Resource *pd3d12Texture, ITexture **ppTexture) { TextureDesc TexDesc; TexDesc.Name = "Texture from d3d12 resource"; CreateDeviceObject( "texture", TexDesc, ppTexture, [&]() { TextureD3D12Impl *pTextureD3D12 = NEW_RC_OBJ(m_TexObjAllocator, "TextureD3D12Impl instance", TextureD3D12Impl)(m_TexViewObjAllocator, this, TexDesc, pd3d12Texture ); pTextureD3D12->QueryInterface( IID_Texture, reinterpret_cast<IObject**>(ppTexture) ); pTextureD3D12->CreateDefaultViews(); OnCreateDeviceObject( pTextureD3D12 ); } ); }
void RenderDeviceD3D12Impl :: CreateSampler(const SamplerDesc& SamplerDesc, ISampler **ppSampler) { CreateDeviceObject( "sampler", SamplerDesc, ppSampler, [&]() { m_SamplersRegistry.Find( SamplerDesc, reinterpret_cast<IDeviceObject**>(ppSampler) ); if( *ppSampler == nullptr ) { SamplerD3D12Impl *pSamplerD3D12( NEW_RC_OBJ(m_SamplerObjAllocator, "SamplerD3D12Impl instance", SamplerD3D12Impl)(this, SamplerDesc ) ); pSamplerD3D12->QueryInterface( IID_Sampler, reinterpret_cast<IObject**>(ppSampler) ); OnCreateDeviceObject( pSamplerD3D12 ); m_SamplersRegistry.Add( SamplerDesc, *ppSampler ); } } ); }
void RenderDeviceD3D11Impl::CreateTextureFromD3DResource(ID3D11Texture3D *pd3d11Texture, ITexture **ppTexture) { if (pd3d11Texture == nullptr) return; TextureDesc TexDesc; TexDesc.Name = "Texture3D from native d3d11 texture"; CreateDeviceObject( "texture", TexDesc, ppTexture, [&]() { TextureBaseD3D11 *pTextureD3D11 = NEW_RC_OBJ(m_TexObjAllocator, "Texture3D_D3D11 instance", Texture3D_D3D11) (m_TexViewObjAllocator, this, pd3d11Texture); pTextureD3D11->QueryInterface( IID_Texture, reinterpret_cast<IObject**>(ppTexture) ); pTextureD3D11->CreateDefaultViews(); OnCreateDeviceObject( pTextureD3D11 ); } ); }
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 : "", "\"" ) } }
/// \param [in] CreationAttribs - Engine creation attributes. /// \param [out] ppDevice - Address of the memory location where pointer to /// the created device will be written. /// \param [out] ppImmediateContext - Address of the memory location where pointers to /// the immediate context will be written. /// \param [in] SCDesc - Swap chain description. /// \param [out] ppSwapChain - Address of the memory location where pointer to the new /// swap chain will be written. void EngineFactoryOpenGLImpl::CreateDeviceAndSwapChainGL(const EngineGLAttribs& CreationAttribs, IRenderDevice **ppDevice, IDeviceContext **ppImmediateContext, const SwapChainDesc& SCDesc, ISwapChain **ppSwapChain ) { if (CreationAttribs.DebugMessageCallback != nullptr) SetDebugMessageCallback(CreationAttribs.DebugMessageCallback); VERIFY( ppDevice && ppImmediateContext && ppSwapChain, "Null pointer provided" ); if( !ppDevice || !ppImmediateContext || !ppSwapChain ) return; *ppDevice = nullptr; *ppImmediateContext = nullptr; *ppSwapChain = nullptr; try { SetRawAllocator(CreationAttribs.pRawMemAllocator); auto &RawMemAllocator = GetRawAllocator(); RenderDeviceGLImpl *pRenderDeviceOpenGL( NEW_RC_OBJ(RawMemAllocator, "TRenderDeviceGLImpl instance", TRenderDeviceGLImpl)(RawMemAllocator, CreationAttribs) ); pRenderDeviceOpenGL->QueryInterface(IID_RenderDevice, reinterpret_cast<IObject**>(ppDevice) ); DeviceContextGLImpl *pDeviceContextOpenGL( NEW_RC_OBJ(RawMemAllocator, "DeviceContextGLImpl instance", DeviceContextGLImpl)(pRenderDeviceOpenGL, false ) ); // We must call AddRef() (implicitly through QueryInterface()) because pRenderDeviceOpenGL will // keep a weak reference to the context pDeviceContextOpenGL->QueryInterface(IID_DeviceContext, reinterpret_cast<IObject**>(ppImmediateContext) ); pRenderDeviceOpenGL->SetImmediateContext(pDeviceContextOpenGL); TSwapChain *pSwapChainGL = NEW_RC_OBJ(RawMemAllocator, "SwapChainGLImpl instance", TSwapChain)(CreationAttribs, SCDesc, pRenderDeviceOpenGL, pDeviceContextOpenGL ); pSwapChainGL->QueryInterface(IID_SwapChain, reinterpret_cast<IObject**>(ppSwapChain) ); pDeviceContextOpenGL->SetSwapChain(pSwapChainGL); // Bind default framebuffer and viewport pDeviceContextOpenGL->SetRenderTargets( 0, nullptr, nullptr ); pDeviceContextOpenGL->SetViewports( 1, nullptr, 0, 0 ); } catch( const std::runtime_error & ) { if( *ppDevice ) { (*ppDevice)->Release(); *ppDevice = nullptr; } if( *ppImmediateContext ) { (*ppImmediateContext)->Release(); *ppImmediateContext = nullptr; } if( *ppSwapChain ) { (*ppSwapChain)->Release(); *ppSwapChain = nullptr; } LOG_ERROR( "Failed to initialize OpenGL-based render device" ); } }
void EngineFactoryOpenGLImpl::CreateHLSL2GLSLConverter(IHLSL2GLSLConverter **ppConverter) { HLSL2GLSLConverterObject *pConverter( NEW_RC_OBJ(GetRawAllocator(), "HLSL2GLSLConverterObject instance", HLSL2GLSLConverterObject)() ); pConverter->QueryInterface( IID_HLSL2GLSLConverter, reinterpret_cast<IObject**>(ppConverter) ); }