| // Copyright 2022 The Dawn Authors |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| #include "dawn/native/opengl/AdapterGL.h" |
| |
| #include <memory> |
| #include <string> |
| #include <utility> |
| |
| #include "dawn/common/GPUInfo.h" |
| #include "dawn/native/Instance.h" |
| #include "dawn/native/opengl/ContextEGL.h" |
| #include "dawn/native/opengl/DeviceGL.h" |
| |
| namespace dawn::native::opengl { |
| |
| namespace { |
| |
| struct Vendor { |
| const char* vendorName; |
| uint32_t vendorId; |
| }; |
| |
| const Vendor kVendors[] = {{"ATI", gpu_info::kVendorID_AMD}, |
| {"ARM", gpu_info::kVendorID_ARM}, |
| {"Imagination", gpu_info::kVendorID_ImgTec}, |
| {"Intel", gpu_info::kVendorID_Intel}, |
| {"NVIDIA", gpu_info::kVendorID_Nvidia}, |
| {"Qualcomm", gpu_info::kVendorID_Qualcomm}}; |
| |
| uint32_t GetVendorIdFromVendors(const char* vendor) { |
| uint32_t vendorId = 0; |
| for (const auto& it : kVendors) { |
| // Matching vendor name with vendor string |
| if (strstr(vendor, it.vendorName) != nullptr) { |
| vendorId = it.vendorId; |
| break; |
| } |
| } |
| return vendorId; |
| } |
| |
| } // anonymous namespace |
| |
| Adapter::Adapter(InstanceBase* instance, wgpu::BackendType backendType) |
| : AdapterBase(instance, backendType) {} |
| |
| MaybeError Adapter::InitializeGLFunctions(void* (*getProc)(const char*)) { |
| // Use getProc to populate the dispatch table |
| mEGLFunctions.Init(getProc); |
| return mFunctions.Initialize(getProc); |
| } |
| |
| bool Adapter::SupportsExternalImages() const { |
| // Via dawn::native::opengl::WrapExternalEGLImage |
| return GetBackendType() == wgpu::BackendType::OpenGLES; |
| } |
| |
| MaybeError Adapter::InitializeImpl() { |
| if (mFunctions.GetVersion().IsES()) { |
| ASSERT(GetBackendType() == wgpu::BackendType::OpenGLES); |
| } else { |
| ASSERT(GetBackendType() == wgpu::BackendType::OpenGL); |
| } |
| |
| mName = reinterpret_cast<const char*>(mFunctions.GetString(GL_RENDERER)); |
| |
| // Workaroud to find vendor id from vendor name |
| const char* vendor = reinterpret_cast<const char*>(mFunctions.GetString(GL_VENDOR)); |
| mVendorId = GetVendorIdFromVendors(vendor); |
| |
| mDriverDescription = std::string("OpenGL version ") + |
| reinterpret_cast<const char*>(mFunctions.GetString(GL_VERSION)); |
| |
| if (mName.find("SwiftShader") != std::string::npos) { |
| mAdapterType = wgpu::AdapterType::CPU; |
| } |
| |
| return {}; |
| } |
| |
| MaybeError Adapter::InitializeSupportedFeaturesImpl() { |
| // TextureCompressionBC |
| { |
| // BC1, BC2 and BC3 are not supported in OpenGL or OpenGL ES core features. |
| bool supportsS3TC = |
| mFunctions.IsGLExtensionSupported("GL_EXT_texture_compression_s3tc") || |
| (mFunctions.IsGLExtensionSupported("GL_EXT_texture_compression_dxt1") && |
| mFunctions.IsGLExtensionSupported("GL_ANGLE_texture_compression_dxt3") && |
| mFunctions.IsGLExtensionSupported("GL_ANGLE_texture_compression_dxt5")); |
| |
| // COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT and |
| // COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT requires both GL_EXT_texture_sRGB and |
| // GL_EXT_texture_compression_s3tc on desktop OpenGL drivers. |
| // (https://www.khronos.org/registry/OpenGL/extensions/EXT/EXT_texture_sRGB.txt) |
| bool supportsTextureSRGB = mFunctions.IsGLExtensionSupported("GL_EXT_texture_sRGB"); |
| |
| // GL_EXT_texture_compression_s3tc_srgb is an extension in OpenGL ES. |
| // NVidia GLES drivers don't support this extension, but they do support |
| // GL_NV_sRGB_formats. (Note that GL_EXT_texture_sRGB does not exist on ES. |
| // GL_EXT_sRGB does (core in ES 3.0), but it does not automatically provide S3TC |
| // SRGB support even if S3TC is supported; see |
| // https://www.khronos.org/registry/OpenGL/extensions/EXT/EXT_sRGB.txt.) |
| bool supportsS3TCSRGB = |
| mFunctions.IsGLExtensionSupported("GL_EXT_texture_compression_s3tc_srgb") || |
| mFunctions.IsGLExtensionSupported("GL_NV_sRGB_formats"); |
| |
| // BC4 and BC5 |
| bool supportsRGTC = mFunctions.IsAtLeastGL(3, 0) || |
| mFunctions.IsGLExtensionSupported("GL_ARB_texture_compression_rgtc") || |
| mFunctions.IsGLExtensionSupported("GL_EXT_texture_compression_rgtc"); |
| |
| // BC6 and BC7 |
| bool supportsBPTC = mFunctions.IsAtLeastGL(4, 2) || |
| mFunctions.IsGLExtensionSupported("GL_ARB_texture_compression_bptc") || |
| mFunctions.IsGLExtensionSupported("GL_EXT_texture_compression_bptc"); |
| |
| if (supportsS3TC && (supportsTextureSRGB || supportsS3TCSRGB) && supportsRGTC && |
| supportsBPTC) { |
| mSupportedFeatures.EnableFeature(dawn::native::Feature::TextureCompressionBC); |
| } |
| } |
| |
| // Non-zero baseInstance requires at least desktop OpenGL 4.2, and it is not supported in |
| // OpenGL ES OpenGL: |
| // https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glDrawElementsIndirect.xhtml |
| // OpenGL ES: |
| // https://www.khronos.org/registry/OpenGL-Refpages/es3/html/glDrawElementsIndirect.xhtml |
| if (mFunctions.IsAtLeastGL(4, 2)) { |
| mSupportedFeatures.EnableFeature(Feature::IndirectFirstInstance); |
| } |
| |
| // ShaderF16 |
| if (mFunctions.IsGLExtensionSupported("GL_AMD_gpu_shader_half_float")) { |
| mSupportedFeatures.EnableFeature(Feature::ShaderF16); |
| } |
| |
| return {}; |
| } |
| |
| MaybeError Adapter::InitializeSupportedLimitsImpl(CombinedLimits* limits) { |
| GetDefaultLimits(&limits->v1); |
| return {}; |
| } |
| |
| ResultOrError<Ref<DeviceBase>> Adapter::CreateDeviceImpl( |
| const DeviceDescriptor* descriptor, |
| const TripleStateTogglesSet& userProvidedToggles) { |
| EGLenum api = |
| GetBackendType() == wgpu::BackendType::OpenGL ? EGL_OPENGL_API : EGL_OPENGL_ES_API; |
| std::unique_ptr<Device::Context> context; |
| DAWN_TRY_ASSIGN(context, ContextEGL::Create(mEGLFunctions, api)); |
| return Device::Create(this, descriptor, mFunctions, std::move(context), userProvidedToggles); |
| } |
| |
| MaybeError Adapter::ValidateFeatureSupportedWithTogglesImpl( |
| wgpu::FeatureName feature, |
| const TripleStateTogglesSet& userProvidedToggles) { |
| return {}; |
| } |
| |
| } // namespace dawn::native::opengl |