diff --git a/include/LLGL/Backend/RenderSystem.Internal.inl b/include/LLGL/Backend/RenderSystem.Internal.inl new file mode 100644 index 0000000000..5655aacf8a --- /dev/null +++ b/include/LLGL/Backend/RenderSystem.Internal.inl @@ -0,0 +1,17 @@ +/* + * RenderSystem.Internal.inl + * + * Copyright (c) 2015 Lukas Hermanns. All rights reserved. + * Licensed under the terms of the BSD 3-Clause license (see LICENSE.txt). + */ + +/* ----- Internal ------ */ + +virtual bool QueryRendererDetails( + LLGL::RendererInfo* outInfo, + LLGL::RenderingCapabilities* outCaps) +override final; + + + +// ================================================================================ diff --git a/include/LLGL/RenderSystem.h b/include/LLGL/RenderSystem.h index 60f2f64b76..8415311da3 100644 --- a/include/LLGL/RenderSystem.h +++ b/include/LLGL/RenderSystem.h @@ -192,17 +192,17 @@ class LLGL_EXPORT RenderSystem : public Interface /** \brief Returns basic renderer information. - \remarks The validity of these information is only guaranteed if this function is called - after a valid swap-chain has been created. Otherwise the behavior is undefined! + \remarks This is not a constant member function because the first call will invoke the query, + while subsequent calls with return the cached information. */ - const RendererInfo& GetRendererInfo() const; + const RendererInfo& GetRendererInfo(); /** \brief Returns the rendering capabilities. - \remarks The validity of these information is only guaranteed if this function is called - after a valid swap-chain has been created. Otherwise the behavior is undefined! + \remarks This is not a constant member function because the first call will invoke the query, + while subsequent calls with return the cached information. */ - const RenderingCapabilities& GetRenderingCaps() const; + const RenderingCapabilities& GetRenderingCaps(); /** \brief Returns a pointer to the report or null if there is none. @@ -641,12 +641,25 @@ class LLGL_EXPORT RenderSystem : public Interface */ void Errorf(const char* format, ...); - //! Sets the renderer information. + //! \deprecated Since 0.04b; Implement QueryRendererDetails() instead! + LLGL_DEPRECATED("RenderSystem::SetRendererInfo is deprecated since 0.04b; Implement QueryRendererDetails() instead!") void SetRendererInfo(const RendererInfo& info); - //! Sets the rendering capabilities. + //! \deprecated Since 0.04b; Implement QueryRendererDetails() instead! + LLGL_DEPRECATED("RenderSystem::SetRendererInfo is deprecated since 0.04b; Implement QueryRendererDetails() instead!") void SetRenderingCaps(const RenderingCapabilities& caps); + protected: + + /** + \brief Queries the renderer information and capacilities. + \param[out] outInfo Specifies the output parameter for the renderer info. This may be null. + \param[out] outCaps Specifies the output parameter for the renderer capabilities. This may be null. + \remarks This function may be called separately for both the information and capabilities query. + \return True on success. Otherwise, the backend is not reasy yet to provide the requested details. + */ + virtual bool QueryRendererDetails(RendererInfo* outInfo, RenderingCapabilities* outCaps) = 0; + protected: //! Validates the specified buffer descriptor to be used for buffer creation. diff --git a/sources/Renderer/DebugLayer/DbgRenderSystem.cpp b/sources/Renderer/DebugLayer/DbgRenderSystem.cpp index 61fdc342c6..ef5cd3172e 100644 --- a/sources/Renderer/DebugLayer/DbgRenderSystem.cpp +++ b/sources/Renderer/DebugLayer/DbgRenderSystem.cpp @@ -34,14 +34,13 @@ All the actual render system objects are stored in the members named "instance", */ DbgRenderSystem::DbgRenderSystem(RenderSystemPtr&& instance, RenderingDebugger* debugger) : - instance_ { std::forward(instance) }, - debugger_ { debugger }, - caps_ { GetRenderingCaps() }, - features_ { caps_.features }, - limits_ { caps_.limits } + instance_ { std::forward(instance) }, + debugger_ { debugger }, + caps_ { GetRenderingCaps() }, + features_ { caps_.features }, + limits_ { caps_.limits }, + commandQueue_ { MakeUnique(*(instance_->GetCommandQueue()), profile_, debugger_) } { - /* Initialize rendering capabilities from wrapped instance */ - UpdateRenderingCaps(); } void DbgRenderSystem::FlushProfile() @@ -55,18 +54,12 @@ void DbgRenderSystem::FlushProfile() SwapChain* DbgRenderSystem::CreateSwapChain(const SwapChainDescriptor& swapChainDesc, const std::shared_ptr& surface) { - /* Create primary swap-chain */ - auto* swapChainInstance = instance_->CreateSwapChain(swapChainDesc, surface); - - /* Instantiate command queue if not done and update rendering capabilities from wrapped instance */ - if (!commandQueue_) - { - UpdateRenderingCaps(); - commandQueue_ = MakeUnique(*(instance_->GetCommandQueue()), profile_, debugger_); - } - - /* Flush frame profile on SwapChain::Present() calls */ - return swapChains_.emplace(*swapChainInstance, swapChainDesc, std::bind(&DbgRenderSystem::FlushProfile, this)); + /* Create swap-chain and flush frame profile on SwapChain::Present() calls */ + return swapChains_.emplace( + *instance_->CreateSwapChain(swapChainDesc, surface), + swapChainDesc, + std::bind(&DbgRenderSystem::FlushProfile, this) + ); } void DbgRenderSystem::Release(SwapChain& swapChain) @@ -602,6 +595,15 @@ bool DbgRenderSystem::GetNativeHandle(void* nativeHandle, std::size_t nativeHand * ======= Private: ======= */ +bool DbgRenderSystem::QueryRendererDetails(RendererInfo* outInfo, RenderingCapabilities* outCaps) +{ + if (outInfo != nullptr) + *outInfo = instance_->GetRendererInfo(); + if (outCaps != nullptr) + *outCaps = instance_->GetRenderingCaps(); + return true; +} + void DbgRenderSystem::ValidateBindFlags(long flags) { constexpr long bufferOnlyFlags = @@ -2170,13 +2172,6 @@ void DbgRenderSystem::ReleaseDbg(HWObjectContainer& cont, TBase& entry) cont.erase(&entry); } -void DbgRenderSystem::UpdateRenderingCaps() -{ - /* Store meta data about render system */ - SetRendererInfo(instance_->GetRendererInfo()); - SetRenderingCaps(instance_->GetRenderingCaps()); -} - } // /namespace LLGL diff --git a/sources/Renderer/DebugLayer/DbgRenderSystem.h b/sources/Renderer/DebugLayer/DbgRenderSystem.h index 3a76886a3f..f28d70a5ab 100644 --- a/sources/Renderer/DebugLayer/DbgRenderSystem.h +++ b/sources/Renderer/DebugLayer/DbgRenderSystem.h @@ -48,6 +48,10 @@ class DbgRenderSystem final : public RenderSystem void FlushProfile(); + private: + + #include + private: void ValidateBindFlags(long flags); @@ -114,8 +118,6 @@ class DbgRenderSystem final : public RenderSystem std::vector GetResourceViewInstanceCopy(const ArrayView& resourceViews); - void UpdateRenderingCaps(); - private: /* ----- Common objects ----- */ diff --git a/sources/Renderer/Direct3D11/D3D11RenderSystem.cpp b/sources/Renderer/Direct3D11/D3D11RenderSystem.cpp index fb396f60be..672aadade3 100644 --- a/sources/Renderer/Direct3D11/D3D11RenderSystem.cpp +++ b/sources/Renderer/Direct3D11/D3D11RenderSystem.cpp @@ -70,8 +70,6 @@ D3D11RenderSystem::D3D11RenderSystem(const RenderSystemDescriptor& renderSystemD /* Initialize states and renderer information */ CreateStateManagerAndCommandQueue(); - QueryRendererInfo(); - QueryRenderingCaps(); /* Initialize MIP-map generator singleton */ D3D11MipGenerator::Get().InitializeDevice(device_); @@ -551,6 +549,15 @@ void D3D11RenderSystem::ClearStateForAllContexts() * ======= Private: ======= */ +bool D3D11RenderSystem::QueryRendererDetails(RendererInfo* outInfo, RenderingCapabilities* outCaps) +{ + if (outInfo != nullptr) + QueryRendererInfo(*outInfo); + if (outCaps != nullptr) + QueryRenderingCaps(*outCaps); + return true; +} + void D3D11RenderSystem::CreateFactory() { /* Create DXGI factory */ @@ -740,18 +747,24 @@ static const char* DXFeatureLevelToShaderModel(D3D_FEATURE_LEVEL featureLevel) return ""; } -void D3D11RenderSystem::QueryRendererInfo() +void D3D11RenderSystem::QueryRendererInfo(RendererInfo& info) { - RendererInfo info; - /* Initialize Direct3D version string */ const int minorVersion = GetMinorVersion(); switch (minorVersion) { - case 3: info.rendererName = "Direct3D 11.3"; break; - case 2: info.rendererName = "Direct3D 11.2"; break; - case 1: info.rendererName = "Direct3D 11.1"; break; - default: info.rendererName = "Direct3D 11.0"; break; + case 3: + info.rendererName = "Direct3D 11.3"; + break; + case 2: + info.rendererName = "Direct3D 11.2"; + break; + case 1: + info.rendererName = "Direct3D 11.1"; + break; + default: + info.rendererName = "Direct3D 11.0"; + break; } /* Initialize HLSL version string */ @@ -760,8 +773,6 @@ void D3D11RenderSystem::QueryRendererInfo() /* Initialize video adapter strings */ info.deviceName = videoAdatperInfo_.name.c_str(); info.vendorName = GetVendorName(videoAdatperInfo_.vendor); - - SetRendererInfo(info); } // Returns the HLSL version for the specified Direct3D feature level. @@ -828,80 +839,76 @@ static std::uint32_t GetMaxRenderTargets(D3D_FEATURE_LEVEL featureLevel) } // see https://msdn.microsoft.com/en-us/library/windows/desktop/ff476876(v=vs.85).aspx -void D3D11RenderSystem::QueryRenderingCaps() +void D3D11RenderSystem::QueryRenderingCaps(RenderingCapabilities& caps) { - RenderingCapabilities caps; - { - const D3D_FEATURE_LEVEL featureLevel = GetFeatureLevel(); - const int minorVersion = GetMinorVersion(); - - const std::uint32_t maxThreadGroups = 65535u;//D3D11_CS_DISPATCH_MAX_THREAD_GROUPS_PER_DIMENSION; - - /* Query common attributes */ - caps.screenOrigin = ScreenOrigin::UpperLeft; - caps.clippingRange = ClippingRange::ZeroToOne; - caps.shadingLanguages = DXGetHLSLVersions(featureLevel); - caps.textureFormats = GetDefaultSupportedDXTextureFormats(featureLevel); - - caps.features.hasRenderTargets = true; - caps.features.has3DTextures = true; - caps.features.hasCubeTextures = true; - caps.features.hasArrayTextures = (featureLevel >= D3D_FEATURE_LEVEL_10_0); - caps.features.hasCubeArrayTextures = (featureLevel >= D3D_FEATURE_LEVEL_10_1); - caps.features.hasMultiSampleTextures = (featureLevel >= D3D_FEATURE_LEVEL_10_0); - caps.features.hasMultiSampleArrayTextures = (featureLevel >= D3D_FEATURE_LEVEL_10_0); - caps.features.hasTextureViews = true; - caps.features.hasTextureViewSwizzle = false; // not supported by D3D11 - caps.features.hasBufferViews = true; - caps.features.hasConstantBuffers = true; - caps.features.hasStorageBuffers = true; - caps.features.hasGeometryShaders = (featureLevel >= D3D_FEATURE_LEVEL_10_0); - caps.features.hasTessellationShaders = (featureLevel >= D3D_FEATURE_LEVEL_11_0); - caps.features.hasTessellatorStage = (featureLevel >= D3D_FEATURE_LEVEL_11_0); - caps.features.hasComputeShaders = (featureLevel >= D3D_FEATURE_LEVEL_10_0); - caps.features.hasInstancing = (featureLevel >= D3D_FEATURE_LEVEL_9_3); - caps.features.hasOffsetInstancing = (featureLevel >= D3D_FEATURE_LEVEL_9_3); - caps.features.hasIndirectDrawing = (featureLevel >= D3D_FEATURE_LEVEL_10_0);//??? - caps.features.hasViewportArrays = true; - caps.features.hasConservativeRasterization = (minorVersion >= 3); - caps.features.hasStreamOutputs = (featureLevel >= D3D_FEATURE_LEVEL_10_0); - caps.features.hasLogicOp = (featureLevel >= D3D_FEATURE_LEVEL_11_1); - caps.features.hasPipelineStatistics = true; - caps.features.hasRenderCondition = true; - - /* Query limits */ - caps.limits.lineWidthRange[0] = 1.0f; - caps.limits.lineWidthRange[1] = 1.0f; - caps.limits.maxTextureArrayLayers = (featureLevel >= D3D_FEATURE_LEVEL_10_0 ? 2048u : 256u); - caps.limits.maxColorAttachments = GetMaxRenderTargets(featureLevel); - caps.limits.maxPatchVertices = 32u; - caps.limits.max1DTextureSize = GetMaxTextureDimension(featureLevel); - caps.limits.max2DTextureSize = GetMaxTextureDimension(featureLevel); - caps.limits.max3DTextureSize = (featureLevel >= D3D_FEATURE_LEVEL_10_0 ? 2048u : 256u); - caps.limits.maxCubeTextureSize = GetMaxCubeTextureDimension(featureLevel); - caps.limits.maxAnisotropy = (featureLevel >= D3D_FEATURE_LEVEL_9_2 ? 16u : 2u); - caps.limits.maxComputeShaderWorkGroups[0] = maxThreadGroups; - caps.limits.maxComputeShaderWorkGroups[1] = maxThreadGroups; - caps.limits.maxComputeShaderWorkGroups[2] = (featureLevel >= D3D_FEATURE_LEVEL_11_0 ? maxThreadGroups : 1u); - caps.limits.maxComputeShaderWorkGroupSize[0] = 1024u; - caps.limits.maxComputeShaderWorkGroupSize[1] = 1024u; - caps.limits.maxComputeShaderWorkGroupSize[2] = 1024u; - caps.limits.maxViewports = D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE; - caps.limits.maxViewportSize[0] = D3D11_VIEWPORT_BOUNDS_MAX; - caps.limits.maxViewportSize[1] = D3D11_VIEWPORT_BOUNDS_MAX; - caps.limits.maxBufferSize = UINT_MAX; - caps.limits.maxConstantBufferSize = D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT * 16; - caps.limits.maxStreamOutputs = 4u; - caps.limits.maxTessFactor = 64u; - caps.limits.minConstantBufferAlignment = 256u; - caps.limits.minSampledBufferAlignment = 32u; - caps.limits.minStorageBufferAlignment = 32u; - caps.limits.maxColorBufferSamples = FindSuitableSampleDesc(device_.Get(), DXGI_FORMAT_R8G8B8A8_UNORM).Count; - caps.limits.maxDepthBufferSamples = FindSuitableSampleDesc(device_.Get(), DXGI_FORMAT_D32_FLOAT).Count; - caps.limits.maxStencilBufferSamples = FindSuitableSampleDesc(device_.Get(), DXGI_FORMAT_D32_FLOAT_S8X24_UINT).Count; - caps.limits.maxNoAttachmentSamples = D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT; - } - SetRenderingCaps(caps); + const D3D_FEATURE_LEVEL featureLevel = GetFeatureLevel(); + const int minorVersion = GetMinorVersion(); + + const std::uint32_t maxThreadGroups = 65535u;//D3D11_CS_DISPATCH_MAX_THREAD_GROUPS_PER_DIMENSION; + + /* Query common attributes */ + caps.screenOrigin = ScreenOrigin::UpperLeft; + caps.clippingRange = ClippingRange::ZeroToOne; + caps.shadingLanguages = DXGetHLSLVersions(featureLevel); + caps.textureFormats = GetDefaultSupportedDXTextureFormats(featureLevel); + + caps.features.hasRenderTargets = true; + caps.features.has3DTextures = true; + caps.features.hasCubeTextures = true; + caps.features.hasArrayTextures = (featureLevel >= D3D_FEATURE_LEVEL_10_0); + caps.features.hasCubeArrayTextures = (featureLevel >= D3D_FEATURE_LEVEL_10_1); + caps.features.hasMultiSampleTextures = (featureLevel >= D3D_FEATURE_LEVEL_10_0); + caps.features.hasMultiSampleArrayTextures = (featureLevel >= D3D_FEATURE_LEVEL_10_0); + caps.features.hasTextureViews = true; + caps.features.hasTextureViewSwizzle = false; // not supported by D3D11 + caps.features.hasBufferViews = true; + caps.features.hasConstantBuffers = true; + caps.features.hasStorageBuffers = true; + caps.features.hasGeometryShaders = (featureLevel >= D3D_FEATURE_LEVEL_10_0); + caps.features.hasTessellationShaders = (featureLevel >= D3D_FEATURE_LEVEL_11_0); + caps.features.hasTessellatorStage = (featureLevel >= D3D_FEATURE_LEVEL_11_0); + caps.features.hasComputeShaders = (featureLevel >= D3D_FEATURE_LEVEL_10_0); + caps.features.hasInstancing = (featureLevel >= D3D_FEATURE_LEVEL_9_3); + caps.features.hasOffsetInstancing = (featureLevel >= D3D_FEATURE_LEVEL_9_3); + caps.features.hasIndirectDrawing = (featureLevel >= D3D_FEATURE_LEVEL_10_0);//??? + caps.features.hasViewportArrays = true; + caps.features.hasConservativeRasterization = (minorVersion >= 3); + caps.features.hasStreamOutputs = (featureLevel >= D3D_FEATURE_LEVEL_10_0); + caps.features.hasLogicOp = (featureLevel >= D3D_FEATURE_LEVEL_11_1); + caps.features.hasPipelineStatistics = true; + caps.features.hasRenderCondition = true; + + /* Query limits */ + caps.limits.lineWidthRange[0] = 1.0f; + caps.limits.lineWidthRange[1] = 1.0f; + caps.limits.maxTextureArrayLayers = (featureLevel >= D3D_FEATURE_LEVEL_10_0 ? 2048u : 256u); + caps.limits.maxColorAttachments = GetMaxRenderTargets(featureLevel); + caps.limits.maxPatchVertices = 32u; + caps.limits.max1DTextureSize = GetMaxTextureDimension(featureLevel); + caps.limits.max2DTextureSize = GetMaxTextureDimension(featureLevel); + caps.limits.max3DTextureSize = (featureLevel >= D3D_FEATURE_LEVEL_10_0 ? 2048u : 256u); + caps.limits.maxCubeTextureSize = GetMaxCubeTextureDimension(featureLevel); + caps.limits.maxAnisotropy = (featureLevel >= D3D_FEATURE_LEVEL_9_2 ? 16u : 2u); + caps.limits.maxComputeShaderWorkGroups[0] = maxThreadGroups; + caps.limits.maxComputeShaderWorkGroups[1] = maxThreadGroups; + caps.limits.maxComputeShaderWorkGroups[2] = (featureLevel >= D3D_FEATURE_LEVEL_11_0 ? maxThreadGroups : 1u); + caps.limits.maxComputeShaderWorkGroupSize[0] = 1024u; + caps.limits.maxComputeShaderWorkGroupSize[1] = 1024u; + caps.limits.maxComputeShaderWorkGroupSize[2] = 1024u; + caps.limits.maxViewports = D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE; + caps.limits.maxViewportSize[0] = D3D11_VIEWPORT_BOUNDS_MAX; + caps.limits.maxViewportSize[1] = D3D11_VIEWPORT_BOUNDS_MAX; + caps.limits.maxBufferSize = UINT_MAX; + caps.limits.maxConstantBufferSize = D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT * 16; + caps.limits.maxStreamOutputs = 4u; + caps.limits.maxTessFactor = 64u; + caps.limits.minConstantBufferAlignment = 256u; + caps.limits.minSampledBufferAlignment = 32u; + caps.limits.minStorageBufferAlignment = 32u; + caps.limits.maxColorBufferSamples = FindSuitableSampleDesc(device_.Get(), DXGI_FORMAT_R8G8B8A8_UNORM).Count; + caps.limits.maxDepthBufferSamples = FindSuitableSampleDesc(device_.Get(), DXGI_FORMAT_D32_FLOAT).Count; + caps.limits.maxStencilBufferSamples = FindSuitableSampleDesc(device_.Get(), DXGI_FORMAT_D32_FLOAT_S8X24_UINT).Count; + caps.limits.maxNoAttachmentSamples = D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT; } int D3D11RenderSystem::GetMinorVersion() const diff --git a/sources/Renderer/Direct3D11/D3D11RenderSystem.h b/sources/Renderer/Direct3D11/D3D11RenderSystem.h index 91bd6dfd50..2e4d308664 100644 --- a/sources/Renderer/Direct3D11/D3D11RenderSystem.h +++ b/sources/Renderer/Direct3D11/D3D11RenderSystem.h @@ -100,6 +100,10 @@ class D3D11RenderSystem final : public RenderSystem return tearingSupported_; } + private: + + #include + private: void CreateFactory(); @@ -110,8 +114,8 @@ class D3D11RenderSystem final : public RenderSystem void QueryDXDeviceVersion(); void CreateStateManagerAndCommandQueue(); - void QueryRendererInfo(); - void QueryRenderingCaps(); + void QueryRendererInfo(RendererInfo& outInfo); + void QueryRenderingCaps(RenderingCapabilities& outCaps); // Returns the minor version of Direct3D 11.X. int GetMinorVersion() const; diff --git a/sources/Renderer/Direct3D12/D3D12RenderSystem.cpp b/sources/Renderer/Direct3D12/D3D12RenderSystem.cpp index dea23987aa..e32350d539 100644 --- a/sources/Renderer/Direct3D12/D3D12RenderSystem.cpp +++ b/sources/Renderer/Direct3D12/D3D12RenderSystem.cpp @@ -75,10 +75,6 @@ D3D12RenderSystem::D3D12RenderSystem(const RenderSystemDescriptor& renderSystemD stagingBufferPool_.InitializeDevice(device_.GetNative(), 0); D3D12MipGenerator::Get().InitializeDevice(device_.GetNative()); D3D12BufferConstantsPool::Get().InitializeDevice(device_.GetNative(), *commandContext_, *commandQueue_, stagingBufferPool_); - - /* Initialize renderer information */ - QueryRendererInfo(); - QueryRenderingCaps(); } D3D12RenderSystem::~D3D12RenderSystem() @@ -481,6 +477,15 @@ void D3D12RenderSystem::SyncGPU() * ======= Private: ======= */ +bool D3D12RenderSystem::QueryRendererDetails(RendererInfo* outInfo, RenderingCapabilities* outCaps) +{ + if (outInfo != nullptr) + QueryRendererInfo(*outInfo); + if (outCaps != nullptr) + QueryRenderingCaps(*outCaps); + return true; +} + void D3D12RenderSystem::EnableDebugLayer() { ComPtr debugController0; @@ -530,7 +535,7 @@ HRESULT D3D12RenderSystem::CreateDevice(IDXGIAdapter* preferredAdapter) D3D_FEATURE_LEVEL_9_1, }; HRESULT hr = S_OK; - +#if 0 if (preferredAdapter != nullptr) { /* Try to create device with perferred adatper */ @@ -547,7 +552,7 @@ HRESULT D3D12RenderSystem::CreateDevice(IDXGIAdapter* preferredAdapter) videoAdatperInfo_ = DXGetVideoAdapterInfo(factory_.Get()); return hr; } - +#endif /* Use software adapter as fallback */ ComPtr adapter; factory_->EnumWarpAdapter(IID_PPV_ARGS(adapter.ReleaseAndGetAddressOf())); @@ -646,10 +651,8 @@ int D3D12RenderSystem::GetMinorVersion() const return 0; } -void D3D12RenderSystem::QueryRendererInfo() +void D3D12RenderSystem::QueryRendererInfo(RendererInfo& info) { - RendererInfo info; - /* Get D3D version */ info.rendererName = "Direct3D " + std::string(DXFeatureLevelToVersion(GetFeatureLevel())); @@ -662,8 +665,6 @@ void D3D12RenderSystem::QueryRendererInfo() /* Get device and vendor name from adapter */ info.deviceName = videoAdatperInfo_.name.c_str(); info.vendorName = GetVendorName(videoAdatperInfo_.vendor); - - SetRendererInfo(info); } // Returns the HLSL version for the specified Direct3D feature level. @@ -726,81 +727,77 @@ static std::uint32_t GetMaxRenderTargets(D3D_FEATURE_LEVEL featureLevel) else return 1; } -void D3D12RenderSystem::QueryRenderingCaps() -{ - RenderingCapabilities caps; - { - const D3D_FEATURE_LEVEL featureLevel = GetFeatureLevel(); - //const int minorVersion = GetMinorVersion(); - - const std::uint32_t maxThreadGroups = 65535u; - - /* Query common attributes */ - caps.screenOrigin = ScreenOrigin::UpperLeft; - caps.clippingRange = ClippingRange::ZeroToOne; - caps.shadingLanguages = DXGetHLSLVersions(featureLevel); - caps.textureFormats = GetDefaultSupportedDXTextureFormats(); - - caps.features.hasRenderTargets = true; - caps.features.has3DTextures = true; - caps.features.hasCubeTextures = true; - caps.features.hasArrayTextures = (featureLevel >= D3D_FEATURE_LEVEL_10_0); - caps.features.hasCubeArrayTextures = (featureLevel >= D3D_FEATURE_LEVEL_10_1); - caps.features.hasMultiSampleTextures = (featureLevel >= D3D_FEATURE_LEVEL_10_0); - caps.features.hasMultiSampleArrayTextures = (featureLevel >= D3D_FEATURE_LEVEL_10_0); - caps.features.hasTextureViews = true; - caps.features.hasTextureViewSwizzle = true; - caps.features.hasBufferViews = true; - caps.features.hasConstantBuffers = true; - caps.features.hasStorageBuffers = true; - caps.features.hasGeometryShaders = (featureLevel >= D3D_FEATURE_LEVEL_10_0); - caps.features.hasTessellationShaders = (featureLevel >= D3D_FEATURE_LEVEL_11_0); - caps.features.hasTessellatorStage = (featureLevel >= D3D_FEATURE_LEVEL_11_0); - caps.features.hasComputeShaders = (featureLevel >= D3D_FEATURE_LEVEL_10_0); - caps.features.hasInstancing = (featureLevel >= D3D_FEATURE_LEVEL_9_3); - caps.features.hasOffsetInstancing = (featureLevel >= D3D_FEATURE_LEVEL_9_3); - caps.features.hasIndirectDrawing = (featureLevel >= D3D_FEATURE_LEVEL_10_0);//??? - caps.features.hasViewportArrays = true; - caps.features.hasConservativeRasterization = (GetFeatureLevel() >= D3D_FEATURE_LEVEL_12_0); - caps.features.hasStreamOutputs = (featureLevel >= D3D_FEATURE_LEVEL_10_0); - caps.features.hasLogicOp = (featureLevel >= D3D_FEATURE_LEVEL_11_1); - caps.features.hasPipelineCaching = true; - caps.features.hasPipelineStatistics = true; - caps.features.hasRenderCondition = true; - - /* Query limits */ - caps.limits.lineWidthRange[0] = 1.0f; - caps.limits.lineWidthRange[1] = 1.0f; - caps.limits.maxTextureArrayLayers = (featureLevel >= D3D_FEATURE_LEVEL_10_0 ? 2048u : 256u); - caps.limits.maxColorAttachments = GetMaxRenderTargets(featureLevel); - caps.limits.maxPatchVertices = 32u; - caps.limits.max1DTextureSize = GetMaxTextureDimension(featureLevel); - caps.limits.max2DTextureSize = GetMaxTextureDimension(featureLevel); - caps.limits.max3DTextureSize = (featureLevel >= D3D_FEATURE_LEVEL_10_0 ? 2048u : 256u); - caps.limits.maxCubeTextureSize = GetMaxCubeTextureDimension(featureLevel); - caps.limits.maxAnisotropy = (featureLevel >= D3D_FEATURE_LEVEL_9_2 ? 16u : 2u); - caps.limits.maxComputeShaderWorkGroups[0] = maxThreadGroups; - caps.limits.maxComputeShaderWorkGroups[1] = maxThreadGroups; - caps.limits.maxComputeShaderWorkGroups[2] = (featureLevel >= D3D_FEATURE_LEVEL_11_0 ? maxThreadGroups : 1u); - caps.limits.maxComputeShaderWorkGroupSize[0] = 1024u; - caps.limits.maxComputeShaderWorkGroupSize[1] = 1024u; - caps.limits.maxComputeShaderWorkGroupSize[2] = 1024u; - caps.limits.maxViewports = D3D12_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE; - caps.limits.maxViewportSize[0] = D3D12_VIEWPORT_BOUNDS_MAX; - caps.limits.maxViewportSize[1] = D3D12_VIEWPORT_BOUNDS_MAX; - caps.limits.maxBufferSize = ULLONG_MAX; - caps.limits.maxConstantBufferSize = D3D12_REQ_CONSTANT_BUFFER_ELEMENT_COUNT * 16; - caps.limits.maxStreamOutputs = 4u; - caps.limits.maxTessFactor = 64u; - caps.limits.minConstantBufferAlignment = 256u; - caps.limits.minSampledBufferAlignment = 32u; - caps.limits.minStorageBufferAlignment = 32u; - caps.limits.maxColorBufferSamples = device_.FindSuitableSampleDesc(DXGI_FORMAT_R8G8B8A8_UNORM).Count; - caps.limits.maxDepthBufferSamples = device_.FindSuitableSampleDesc(DXGI_FORMAT_D32_FLOAT).Count; - caps.limits.maxStencilBufferSamples = device_.FindSuitableSampleDesc(DXGI_FORMAT_D32_FLOAT_S8X24_UINT).Count; - caps.limits.maxNoAttachmentSamples = D3D12_MAX_MULTISAMPLE_SAMPLE_COUNT; - } - SetRenderingCaps(caps); +void D3D12RenderSystem::QueryRenderingCaps(RenderingCapabilities& caps) +{ + const D3D_FEATURE_LEVEL featureLevel = GetFeatureLevel(); + //const int minorVersion = GetMinorVersion(); + + const std::uint32_t maxThreadGroups = 65535u; + + /* Query common attributes */ + caps.screenOrigin = ScreenOrigin::UpperLeft; + caps.clippingRange = ClippingRange::ZeroToOne; + caps.shadingLanguages = DXGetHLSLVersions(featureLevel); + caps.textureFormats = GetDefaultSupportedDXTextureFormats(); + + caps.features.hasRenderTargets = true; + caps.features.has3DTextures = true; + caps.features.hasCubeTextures = true; + caps.features.hasArrayTextures = (featureLevel >= D3D_FEATURE_LEVEL_10_0); + caps.features.hasCubeArrayTextures = (featureLevel >= D3D_FEATURE_LEVEL_10_1); + caps.features.hasMultiSampleTextures = (featureLevel >= D3D_FEATURE_LEVEL_10_0); + caps.features.hasMultiSampleArrayTextures = (featureLevel >= D3D_FEATURE_LEVEL_10_0); + caps.features.hasTextureViews = true; + caps.features.hasTextureViewSwizzle = true; + caps.features.hasBufferViews = true; + caps.features.hasConstantBuffers = true; + caps.features.hasStorageBuffers = true; + caps.features.hasGeometryShaders = (featureLevel >= D3D_FEATURE_LEVEL_10_0); + caps.features.hasTessellationShaders = (featureLevel >= D3D_FEATURE_LEVEL_11_0); + caps.features.hasTessellatorStage = (featureLevel >= D3D_FEATURE_LEVEL_11_0); + caps.features.hasComputeShaders = (featureLevel >= D3D_FEATURE_LEVEL_10_0); + caps.features.hasInstancing = (featureLevel >= D3D_FEATURE_LEVEL_9_3); + caps.features.hasOffsetInstancing = (featureLevel >= D3D_FEATURE_LEVEL_9_3); + caps.features.hasIndirectDrawing = (featureLevel >= D3D_FEATURE_LEVEL_10_0);//??? + caps.features.hasViewportArrays = true; + caps.features.hasConservativeRasterization = (GetFeatureLevel() >= D3D_FEATURE_LEVEL_12_0); + caps.features.hasStreamOutputs = (featureLevel >= D3D_FEATURE_LEVEL_10_0); + caps.features.hasLogicOp = (featureLevel >= D3D_FEATURE_LEVEL_11_1); + caps.features.hasPipelineCaching = true; + caps.features.hasPipelineStatistics = true; + caps.features.hasRenderCondition = true; + + /* Query limits */ + caps.limits.lineWidthRange[0] = 1.0f; + caps.limits.lineWidthRange[1] = 1.0f; + caps.limits.maxTextureArrayLayers = (featureLevel >= D3D_FEATURE_LEVEL_10_0 ? 2048u : 256u); + caps.limits.maxColorAttachments = GetMaxRenderTargets(featureLevel); + caps.limits.maxPatchVertices = 32u; + caps.limits.max1DTextureSize = GetMaxTextureDimension(featureLevel); + caps.limits.max2DTextureSize = GetMaxTextureDimension(featureLevel); + caps.limits.max3DTextureSize = (featureLevel >= D3D_FEATURE_LEVEL_10_0 ? 2048u : 256u); + caps.limits.maxCubeTextureSize = GetMaxCubeTextureDimension(featureLevel); + caps.limits.maxAnisotropy = (featureLevel >= D3D_FEATURE_LEVEL_9_2 ? 16u : 2u); + caps.limits.maxComputeShaderWorkGroups[0] = maxThreadGroups; + caps.limits.maxComputeShaderWorkGroups[1] = maxThreadGroups; + caps.limits.maxComputeShaderWorkGroups[2] = (featureLevel >= D3D_FEATURE_LEVEL_11_0 ? maxThreadGroups : 1u); + caps.limits.maxComputeShaderWorkGroupSize[0] = 1024u; + caps.limits.maxComputeShaderWorkGroupSize[1] = 1024u; + caps.limits.maxComputeShaderWorkGroupSize[2] = 1024u; + caps.limits.maxViewports = D3D12_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE; + caps.limits.maxViewportSize[0] = D3D12_VIEWPORT_BOUNDS_MAX; + caps.limits.maxViewportSize[1] = D3D12_VIEWPORT_BOUNDS_MAX; + caps.limits.maxBufferSize = ULLONG_MAX; + caps.limits.maxConstantBufferSize = D3D12_REQ_CONSTANT_BUFFER_ELEMENT_COUNT * 16; + caps.limits.maxStreamOutputs = 4u; + caps.limits.maxTessFactor = 64u; + caps.limits.minConstantBufferAlignment = 256u; + caps.limits.minSampledBufferAlignment = 32u; + caps.limits.minStorageBufferAlignment = 32u; + caps.limits.maxColorBufferSamples = device_.FindSuitableSampleDesc(DXGI_FORMAT_R8G8B8A8_UNORM).Count; + caps.limits.maxDepthBufferSamples = device_.FindSuitableSampleDesc(DXGI_FORMAT_D32_FLOAT).Count; + caps.limits.maxStencilBufferSamples = device_.FindSuitableSampleDesc(DXGI_FORMAT_D32_FLOAT_S8X24_UINT).Count; + caps.limits.maxNoAttachmentSamples = D3D12_MAX_MULTISAMPLE_SAMPLE_COUNT; } void D3D12RenderSystem::ExecuteCommandListAndSync() diff --git a/sources/Renderer/Direct3D12/D3D12RenderSystem.h b/sources/Renderer/Direct3D12/D3D12RenderSystem.h index 515a25f43f..6962c122a5 100644 --- a/sources/Renderer/Direct3D12/D3D12RenderSystem.h +++ b/sources/Renderer/Direct3D12/D3D12RenderSystem.h @@ -119,6 +119,10 @@ class D3D12RenderSystem final : public RenderSystem return tearingSupported_; } + private: + + #include + private: void EnableDebugLayer(); @@ -132,8 +136,8 @@ class D3D12RenderSystem final : public RenderSystem // Returns the minor version of Direct3D 12.X. int GetMinorVersion() const; - void QueryRendererInfo(); - void QueryRenderingCaps(); + void QueryRendererInfo(RendererInfo& outInfo); + void QueryRenderingCaps(RenderingCapabilities& outCaps); // Close, execute, and reset command list. void ExecuteCommandListAndSync(); diff --git a/sources/Renderer/Metal/MTRenderSystem.h b/sources/Renderer/Metal/MTRenderSystem.h index b29300f732..5c918df6e7 100644 --- a/sources/Renderer/Metal/MTRenderSystem.h +++ b/sources/Renderer/Metal/MTRenderSystem.h @@ -54,10 +54,14 @@ class MTRenderSystem final : public RenderSystem MTRenderSystem(const RenderSystemDescriptor& renderSystemDesc); ~MTRenderSystem(); + private: + + #include + private: void CreateDeviceResources(id sharedDevice = nil); - void QueryRenderingCaps(); + void QueryRendererInfo(RendererInfo& outInfo); const char* QueryMetalVersion() const; diff --git a/sources/Renderer/Metal/MTRenderSystem.mm b/sources/Renderer/Metal/MTRenderSystem.mm index 28e64fdc5f..92deba480f 100644 --- a/sources/Renderer/Metal/MTRenderSystem.mm +++ b/sources/Renderer/Metal/MTRenderSystem.mm @@ -37,7 +37,6 @@ CreateDeviceResources(customNativeHandle->device); else CreateDeviceResources(); - QueryRenderingCaps(); } MTRenderSystem::~MTRenderSystem() @@ -364,16 +363,6 @@ LLGL_TRAP("failed to create Metal device"); } - /* Initialize renderer information */ - RendererInfo info; - { - info.rendererName = "Metal " + std::string(QueryMetalVersion()); - info.deviceName = [[device_ name] cStringUsingEncoding:NSUTF8StringEncoding]; - info.vendorName = "Apple"; - info.shadingLanguageName = "Metal Shading Language"; - } - SetRendererInfo(info); - /* Create command queue */ commandQueue_ = MakeUnique(device_); @@ -385,16 +374,26 @@ intermediateBuffer_ = MakeUnique(device_, MTLResourceStorageModeShared, intermediateBufferAlignment); } -void MTRenderSystem::QueryRenderingCaps() +void MTRenderSystem::QueryRendererInfo(RendererInfo& info) +{ + info.rendererName = "Metal " + std::string(QueryMetalVersion()); + info.deviceName = [[device_ name] cStringUsingEncoding:NSUTF8StringEncoding]; + info.vendorName = "Apple"; + info.shadingLanguageName = "Metal Shading Language"; +} + +bool MTRenderSystem::QueryRendererDetails(RendererInfo* outInfo, RenderingCapabilities* outCaps) { - RenderingCapabilities caps; - LoadFeatureSetCaps(device_, QueryHighestFeatureSet(), caps); - SetRenderingCaps(caps); + if (outInfo != nullptr) + QueryRendererInfo(*outInfo); + if (outCaps != nullptr) + LoadFeatureSetCaps(device_, QueryHighestFeatureSet(), *outCaps); + return true; } const char* MTRenderSystem::QueryMetalVersion() const { - const auto featureSet = QueryHighestFeatureSet(); + const MTLFeatureSet featureSet = QueryHighestFeatureSet(); #ifdef LLGL_OS_IOS diff --git a/sources/Renderer/Null/NullRenderSystem.cpp b/sources/Renderer/Null/NullRenderSystem.cpp index c21c8eb1fb..def1c9fc1e 100644 --- a/sources/Renderer/Null/NullRenderSystem.cpp +++ b/sources/Renderer/Null/NullRenderSystem.cpp @@ -98,39 +98,33 @@ static void InitNullRendererLimits(RenderingLimits& limits) limits.maxNoAttachmentSamples = 1; } -static RenderingCapabilities GetNullRenderingCaps() +static void GetNullRenderingCaps(RenderingCapabilities& caps) { - RenderingCapabilities caps; InitNullRendererShadingLanguages(caps.shadingLanguages); InitNullRendererTextureFormats(caps.textureFormats); InitNullRendererFeatures(caps.features); InitNullRendererLimits(caps.limits); - return caps; } -static RendererInfo GetNullRendererInfo() +static void GetNullRendererInfo(RendererInfo& info) { - RendererInfo info; info.rendererName = "Null"; info.deviceName = "CPU"; info.vendorName = "LLGL"; info.shadingLanguageName = "Dummy"; - return info; } NullRenderSystem::NullRenderSystem(const RenderSystemDescriptor& renderSystemDesc) : desc_ { renderSystemDesc }, commandQueue_ { MakeUnique() } { - SetRendererInfo(GetNullRendererInfo()); - SetRenderingCaps(GetNullRenderingCaps()); } /* ----- Swap-chain ----- */ SwapChain* NullRenderSystem::CreateSwapChain(const SwapChainDescriptor& swapChainDesc, const std::shared_ptr& surface) { - return swapChains_.emplace(swapChainDesc, surface, GetNullRendererInfo()); + return swapChains_.emplace(swapChainDesc, surface, GetRendererInfo()); } void NullRenderSystem::Release(SwapChain& swapChain) @@ -374,6 +368,20 @@ bool NullRenderSystem::GetNativeHandle(void* nativeHandle, std::size_t nativeHan } +/* + * ======= Private: ======= + */ + +bool NullRenderSystem::QueryRendererDetails(RendererInfo* outInfo, RenderingCapabilities* outCaps) +{ + if (outInfo != nullptr) + GetNullRendererInfo(*outInfo); + if (outCaps != nullptr) + GetNullRenderingCaps(*outCaps); + return true; +} + + } // /namespace LLGL diff --git a/sources/Renderer/Null/NullRenderSystem.h b/sources/Renderer/Null/NullRenderSystem.h index d25a874c43..59352698e6 100644 --- a/sources/Renderer/Null/NullRenderSystem.h +++ b/sources/Renderer/Null/NullRenderSystem.h @@ -45,6 +45,10 @@ class NullRenderSystem final : public RenderSystem NullRenderSystem(const RenderSystemDescriptor& renderSystemDesc); + private: + + #include + private: /* ----- Common objects ----- */ diff --git a/sources/Renderer/OpenGL/Ext/GLExtensionLoader.h b/sources/Renderer/OpenGL/Ext/GLExtensionLoader.h index cc8e90c0a7..6a3ccace42 100644 --- a/sources/Renderer/OpenGL/Ext/GLExtensionLoader.h +++ b/sources/Renderer/OpenGL/Ext/GLExtensionLoader.h @@ -9,6 +9,9 @@ #define LLGL_GL_EXTENSION_LOADER_H +#include + + namespace LLGL { @@ -22,6 +25,12 @@ bool LoadSupportedOpenGLExtensions(bool isCoreProfile, bool abortOnFailure = fal // Returns true if all available extensions have been loaded. bool AreOpenGLExtensionsLoaded(); +// Returns the set of OpenGL extensions that are supported by the GL context that was active during the last call to LoadSupportedOpenGLExtensions(). +const std::set& GetSupportedOpenGLExtensions(); + +// Returns the set of OpenGL extensions that were loaded during the last call to LoadSupportedOpenGLExtensions(). +const std::set& GetLoadedOpenGLExtensions(); + /* --- Common GL extensions --- */ #ifndef __APPLE__ diff --git a/sources/Renderer/OpenGL/GLCoreProfile/GLCoreExtensionLoader.cpp b/sources/Renderer/OpenGL/GLCoreProfile/GLCoreExtensionLoader.cpp index e85384d669..7010373b19 100644 --- a/sources/Renderer/OpenGL/GLCoreProfile/GLCoreExtensionLoader.cpp +++ b/sources/Renderer/OpenGL/GLCoreProfile/GLCoreExtensionLoader.cpp @@ -975,7 +975,10 @@ static void IncludeImpliedExtensions(GLExtensionMap& extensions) #endif // /__APPLE__ // Global member to store if the extension have already been loaded -static bool g_OpenGLExtensionsLoaded = false; +static bool g_OpenGLExtensionsLoaded = false; +static GLExtensionMap g_OpenGLExtensionsMap; +static std::set g_supportedOpenGLExtensions; +static std::set g_loadedOpenGLExtensions; bool LoadSupportedOpenGLExtensions(bool isCoreProfile, bool abortOnFailure) { @@ -983,7 +986,8 @@ bool LoadSupportedOpenGLExtensions(bool isCoreProfile, bool abortOnFailure) if (g_OpenGLExtensionsLoaded) return true; - GLExtensionMap extensions = QuerySupportedOpenGLExtensions(isCoreProfile); + /* Query supported OpenGL extension names */ + g_OpenGLExtensionsMap = QuerySupportedOpenGLExtensions(isCoreProfile); #ifdef __APPLE__ @@ -1056,11 +1060,11 @@ bool LoadSupportedOpenGLExtensions(bool isCoreProfile, bool abortOnFailure) #else // __APPLE__ - auto LoadExtension = [&extensions, abortOnFailure](const char* extName, const LoadGLExtensionProc& extLoadingProc, GLExt extensionID) -> void + auto LoadExtension = [abortOnFailure](const char* extName, const LoadGLExtensionProc& extLoadingProc, GLExt extensionID) -> void { /* Try to load OpenGL extension */ - auto it = extensions.find(extName); - if (it != extensions.end()) + auto it = g_OpenGLExtensionsMap.find(extName); + if (it != g_OpenGLExtensionsMap.end()) { if (extLoadingProc(extName, abortOnFailure, /*usePlaceholder:*/ false)) { @@ -1084,7 +1088,7 @@ bool LoadSupportedOpenGLExtensions(bool isCoreProfile, bool abortOnFailure) auto EnableExtension = [&](const std::string& extName, GLExt extensionID) -> void { /* Try to enable OpenGL extension */ - if (extensions.find(extName) != extensions.end()) + if (g_OpenGLExtensionsMap.find(extName) != g_OpenGLExtensionsMap.end()) RegisterExtension(extensionID); }; @@ -1096,9 +1100,9 @@ bool LoadSupportedOpenGLExtensions(bool isCoreProfile, bool abortOnFailure) /* Add standard extensions */ if (isCoreProfile) - IncludeDefaultCoreProfileExtensions(extensions); + IncludeDefaultCoreProfileExtensions(g_OpenGLExtensionsMap); - IncludeImpliedExtensions(extensions); + IncludeImpliedExtensions(g_OpenGLExtensionsMap); #if defined(GL_VERSION_3_1) && !defined(GL_GLEXT_PROTOTYPES) LOAD_GLEXT( ARB_compatibility ); @@ -1201,8 +1205,16 @@ bool LoadSupportedOpenGLExtensions(bool isCoreProfile, bool abortOnFailure) #endif // /__APPLE__ + /* Cache supported and loaded extensions */ g_OpenGLExtensionsLoaded = true; + for (const auto& it : g_OpenGLExtensionsMap) + { + g_supportedOpenGLExtensions.insert(it.first.c_str()); + if (it.second) + g_loadedOpenGLExtensions.insert(it.first.c_str()); + } + return true; } @@ -1211,6 +1223,16 @@ bool AreOpenGLExtensionsLoaded() return g_OpenGLExtensionsLoaded; } +const std::set& GetSupportedOpenGLExtensions() +{ + return g_supportedOpenGLExtensions; +} + +const std::set& GetLoadedOpenGLExtensions() +{ + return g_loadedOpenGLExtensions; +} + } // /namespace LLGL diff --git a/sources/Renderer/OpenGL/GLRenderSystem.cpp b/sources/Renderer/OpenGL/GLRenderSystem.cpp index ddc4a062bf..e854cd1ed2 100644 --- a/sources/Renderer/OpenGL/GLRenderSystem.cpp +++ b/sources/Renderer/OpenGL/GLRenderSystem.cpp @@ -27,6 +27,7 @@ #include "../../Core/Assertion.h" #include "../../Platform/Debug.h" #include "GLRenderingCaps.h" +#include "Ext/GLExtensionLoader.h" #include "Command/GLImmediateCommandBuffer.h" #include "Command/GLDeferredCommandBuffer.h" #include "RenderState/GLGraphicsPSO.h" @@ -602,15 +603,11 @@ void GLRenderSystem::CreateGLContextWithPixelFormatOnce(const GLPixelFormat& pix (void)contextMngr_.AllocContext(&pixelFormat, /*acceptCompatibleFormat:*/ true); } -void GLRenderSystem::RegisterNewGLContext(GLContext& context, const GLPixelFormat& pixelFormat) +void GLRenderSystem::RegisterNewGLContext(GLContext& /*context*/, const GLPixelFormat& /*pixelFormat*/) { /* Enable debug callback function */ if (debugContext_) EnableDebugCallback(); - - /* Query renderer information and limits */ - QueryRendererInfo(); - QueryRenderingCaps(); } #ifdef GL_KHR_debug @@ -685,7 +682,7 @@ static void AppendCacheIDValue(std::vector& cacheID, const T& val) AppendCacheIDBytes(cacheID, &val, sizeof(val)); } -void GLQueryPipelineCacheID(std::vector& cacheID) +static void GLQueryPipelineCacheID(std::vector& cacheID) { #ifdef GL_ARB_get_program_binary if (HasExtension(GLExt::ARB_get_program_binary)) @@ -711,24 +708,31 @@ void GLQueryPipelineCacheID(std::vector& cacheID) #endif // /GL_ARB_get_program_binary } -void GLRenderSystem::QueryRendererInfo() +static void GLQueryRendererInfo(RendererInfo& info) { - RendererInfo info; - info.rendererName = GLProfile::GetAPIName() + std::string(" ") + GLGetString(GL_VERSION); info.deviceName = GLGetString(GL_RENDERER); info.vendorName = GLGetString(GL_VENDOR); info.shadingLanguageName = GLProfile::GetShadingLanguageName() + std::string(" ") + GLGetString(GL_SHADING_LANGUAGE_VERSION); - GLQueryPipelineCacheID(info.pipelineCacheID); - SetRendererInfo(info); + const std::set& extensionNames = GetLoadedOpenGLExtensions(); + info.extensionNames = std::vector(extensionNames.begin(), extensionNames.end()); + + GLQueryPipelineCacheID(info.pipelineCacheID); } -void GLRenderSystem::QueryRenderingCaps() +bool GLRenderSystem::QueryRendererDetails(RendererInfo* outInfo, RenderingCapabilities* outCaps) { - RenderingCapabilities caps; - GLQueryRenderingCaps(caps); - SetRenderingCaps(caps); + if (outInfo != nullptr || outCaps != nullptr) + { + /* Make sure we have a GL context before querying information from it */ + CreateGLContextOnce(); + if (outInfo != nullptr) + GLQueryRendererInfo(*outInfo); + if (outCaps != nullptr) + GLQueryRenderingCaps(*outCaps); + } + return true; } diff --git a/sources/Renderer/OpenGL/GLRenderSystem.h b/sources/Renderer/OpenGL/GLRenderSystem.h index 0ab8eb43b6..0abcf24002 100644 --- a/sources/Renderer/OpenGL/GLRenderSystem.h +++ b/sources/Renderer/OpenGL/GLRenderSystem.h @@ -66,6 +66,10 @@ class GLRenderSystem final : public RenderSystem GLRenderSystem(const RenderSystemDescriptor& renderSystemDesc); ~GLRenderSystem(); + private: + + #include + private: // Creates a GL context once or creates a new one if there is no compatible one with the specified pixel format. @@ -77,9 +81,6 @@ class GLRenderSystem final : public RenderSystem void EnableDebugCallback(bool enable = true); - void QueryRendererInfo(); - void QueryRenderingCaps(); - GLBuffer* CreateGLBuffer(const BufferDescriptor& desc, const void* initialData); void ValidateGLTextureType(const TextureType type); diff --git a/sources/Renderer/RenderSystem.cpp b/sources/Renderer/RenderSystem.cpp index 67213d2dfd..dffe21c433 100644 --- a/sources/Renderer/RenderSystem.cpp +++ b/sources/Renderer/RenderSystem.cpp @@ -46,9 +46,11 @@ namespace LLGL struct RenderSystem::Pimpl { - int rendererID = 0; + int rendererID = 0; std::string name; + bool hasInfo = false; RendererInfo info; + bool hasCaps = false; RenderingCapabilities caps; Report report; }; @@ -322,13 +324,23 @@ const char* RenderSystem::GetName() const return pimpl_->name.c_str(); } -const RendererInfo& RenderSystem::GetRendererInfo() const +const RendererInfo& RenderSystem::GetRendererInfo() { + if (!pimpl_->hasInfo) + { + if (QueryRendererDetails(&(pimpl_->info), nullptr)) + pimpl_->hasInfo = true; + } return pimpl_->info; } -const RenderingCapabilities& RenderSystem::GetRenderingCaps() const +const RenderingCapabilities& RenderSystem::GetRenderingCaps() { + if (!pimpl_->hasCaps) + { + if (QueryRendererDetails(nullptr, &(pimpl_->caps))) + pimpl_->hasCaps = true; + } return pimpl_->caps; } @@ -356,12 +368,14 @@ void RenderSystem::Errorf(const char* format, ...) void RenderSystem::SetRendererInfo(const RendererInfo& info) { - pimpl_->info = info; + pimpl_->hasInfo = true; + pimpl_->info = info; } void RenderSystem::SetRenderingCaps(const RenderingCapabilities& caps) { - pimpl_->caps = caps; + pimpl_->hasCaps = true; + pimpl_->caps = caps; } void RenderSystem::AssertCreateBuffer(const BufferDescriptor& bufferDesc, std::uint64_t maxSize) diff --git a/sources/Renderer/Vulkan/VKPhysicalDevice.cpp b/sources/Renderer/Vulkan/VKPhysicalDevice.cpp index 02f72920b9..1f3d612329 100644 --- a/sources/Renderer/Vulkan/VKPhysicalDevice.cpp +++ b/sources/Renderer/Vulkan/VKPhysicalDevice.cpp @@ -213,10 +213,7 @@ static void GetVKPipelineCacheID(const VkPhysicalDeviceProperties& properties, s } } -void VKPhysicalDevice::QueryDeviceProperties( - RendererInfo& info, - RenderingCapabilities& caps, - VKGraphicsPipelineLimits& pipelineLimits) +void VKPhysicalDevice::QueryRendererInfo(RendererInfo& info) { /* Map properties to output renderer info */ info.rendererName = ("Vulkan " + VKApiVersionToString(properties_.apiVersion)); @@ -224,7 +221,10 @@ void VKPhysicalDevice::QueryDeviceProperties( info.vendorName = GetVendorName(GetVendorByID(properties_.vendorID)); info.shadingLanguageName = "SPIR-V"; GetVKPipelineCacheID(properties_, info.pipelineCacheID); +} +void VKPhysicalDevice::QueryRenderingCaps(RenderingCapabilities& caps) +{ /* Map limits to output rendering capabilites */ const VkPhysicalDeviceLimits& limits = properties_.limits; @@ -300,6 +300,12 @@ void VKPhysicalDevice::QueryDeviceProperties( caps.limits.maxDepthBufferSamples = VKTypes::GetMaxVkSampleCounts(limits.framebufferDepthSampleCounts); caps.limits.maxStencilBufferSamples = VKTypes::GetMaxVkSampleCounts(limits.framebufferStencilSampleCounts); caps.limits.maxNoAttachmentSamples = VKTypes::GetMaxVkSampleCounts(limits.framebufferNoAttachmentsSampleCounts); +} + +void VKPhysicalDevice::QueryPipelineLimits(VKGraphicsPipelineLimits& pipelineLimits) +{ + /* Map limits to output rendering capabilites */ + const VkPhysicalDeviceLimits& limits = properties_.limits; /* Store graphics pipeline spcific limitations */ pipelineLimits.lineWidthRange[0] = limits.lineWidthRange[0]; diff --git a/sources/Renderer/Vulkan/VKPhysicalDevice.h b/sources/Renderer/Vulkan/VKPhysicalDevice.h index daa4e14141..7c58376b87 100644 --- a/sources/Renderer/Vulkan/VKPhysicalDevice.h +++ b/sources/Renderer/Vulkan/VKPhysicalDevice.h @@ -36,11 +36,9 @@ class VKPhysicalDevice // Loads the physical Vulkan device from a custom native handle. void LoadPhysicalDeviceWeakRef(VkPhysicalDevice physicalDevice); - void QueryDeviceProperties( - RendererInfo& info, - RenderingCapabilities& caps, - VKGraphicsPipelineLimits& pipelineLimits - ); + void QueryRendererInfo(RendererInfo& outInfo); + void QueryRenderingCaps(RenderingCapabilities& outCaps); + void QueryPipelineLimits(VKGraphicsPipelineLimits& outPipelineLimits); VKDevice CreateLogicalDevice(VkDevice customLogicalDevice = VK_NULL_HANDLE); diff --git a/sources/Renderer/Vulkan/VKRenderSystem.cpp b/sources/Renderer/Vulkan/VKRenderSystem.cpp index 4adad273fc..61137a53c9 100644 --- a/sources/Renderer/Vulkan/VKRenderSystem.cpp +++ b/sources/Renderer/Vulkan/VKRenderSystem.cpp @@ -657,7 +657,7 @@ PipelineState* VKRenderSystem::CreatePipelineState(const GraphicsPipelineDescrip device_, (!swapChains_.empty() ? (*swapChains_.begin())->GetRenderPass() : nullptr), pipelineStateDesc, - gfxPipelineLimits_, + graphicsPipelineLimits_, pipelineCache ); } @@ -898,18 +898,8 @@ bool VKRenderSystem::PickPhysicalDevice(long preferredDeviceFlags, VkPhysicalDev return false; } - /* Query and store rendering capabilities */ - RendererInfo info; - RenderingCapabilities caps; - - physicalDevice_.QueryDeviceProperties(info, caps, gfxPipelineLimits_); - - /* Store Vulkan extension names */ - const auto& extensions = physicalDevice_.GetExtensionNames(); - info.extensionNames = std::vector(extensions.begin(), extensions.end()); - - SetRendererInfo(info); - SetRenderingCaps(caps); + /* Store graphics pipeline limits for this physical device */ + physicalDevice_.QueryPipelineLimits(graphicsPipelineLimits_); return true; } @@ -984,6 +974,23 @@ void VKRenderSystem::FlushCommandBuffer(VkCommandBuffer commandBuffer) device_.FlushCommandBuffer(commandBuffer); } +bool VKRenderSystem::QueryRendererDetails(RendererInfo* outInfo, RenderingCapabilities* outCaps) +{ + if (outInfo != nullptr) + { + /* Query rendering information from selected physical device and store Vulkan extension names */ + physicalDevice_.QueryRendererInfo(*outInfo); + const std::vector& extensions = physicalDevice_.GetExtensionNames(); + outInfo->extensionNames = std::vector(extensions.begin(), extensions.end()); + } + if (outCaps != nullptr) + { + /* Query rendering capabilities from selected physical device */ + physicalDevice_.QueryRenderingCaps(*outCaps); + } + return true; +} + } // /namespace LLGL diff --git a/sources/Renderer/Vulkan/VKRenderSystem.h b/sources/Renderer/Vulkan/VKRenderSystem.h index e30e173182..6bb501a18f 100644 --- a/sources/Renderer/Vulkan/VKRenderSystem.h +++ b/sources/Renderer/Vulkan/VKRenderSystem.h @@ -60,6 +60,10 @@ class VKRenderSystem final : public RenderSystem VKRenderSystem(const RenderSystemDescriptor& renderSystemDesc); ~VKRenderSystem(); + private: + + #include + private: void CreateInstance(const RendererConfigurationVulkan* config); @@ -95,7 +99,7 @@ class VKRenderSystem final : public RenderSystem std::unique_ptr deviceMemoryMngr_; - VKGraphicsPipelineLimits gfxPipelineLimits_; + VKGraphicsPipelineLimits graphicsPipelineLimits_; /* ----- Hardware object containers ----- */