mirror of https://github.com/mosra/magnum.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
573 lines
28 KiB
573 lines
28 KiB
/* |
|
This file is part of Magnum. |
|
|
|
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, |
|
2020, 2021, 2022, 2023, 2024, 2025 |
|
Vladimír Vondruš <mosra@centrum.cz> |
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a |
|
copy of this software and associated documentation files (the "Software"), |
|
to deal in the Software without restriction, including without limitation |
|
the rights to use, copy, modify, merge, publish, distribute, sublicense, |
|
and/or sell copies of the Software, and to permit persons to whom the |
|
Software is furnished to do so, subject to the following conditions: |
|
|
|
The above copyright notice and this permission notice shall be included |
|
in all copies or substantial portions of the Software. |
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
|
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
|
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
|
DEALINGS IN THE SOFTWARE. |
|
*/ |
|
|
|
#include "TextureState.h" |
|
|
|
#include <Corrade/Containers/StringView.h> |
|
#include <Corrade/Utility/Assert.h> |
|
|
|
#include "Magnum/GL/AbstractTexture.h" |
|
#include "Magnum/GL/CubeMapTexture.h" |
|
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) |
|
#include "Magnum/GL/BufferTexture.h" |
|
#endif |
|
#include "Magnum/GL/Context.h" |
|
#include "Magnum/GL/Extensions.h" |
|
|
|
#include "State.h" |
|
|
|
namespace Magnum { namespace GL { namespace Implementation { |
|
|
|
using namespace Containers::Literals; |
|
|
|
TextureState::TextureState(Context& context, |
|
Containers::ArrayView<Containers::Pair<GLenum, GLuint>> bindings, |
|
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) |
|
Containers::ArrayView<ImageBinding> imageBindings, |
|
#endif |
|
Containers::StaticArrayView<Implementation::ExtensionCount, const char*> extensions): |
|
maxSize{}, |
|
#if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2)) |
|
max3DSize{}, |
|
#endif |
|
maxCubeMapSize{}, |
|
#ifndef MAGNUM_TARGET_GLES2 |
|
maxArrayLayers{}, |
|
#endif |
|
#ifndef MAGNUM_TARGET_GLES |
|
maxRectangleSize{}, maxBufferSize{}, |
|
#endif |
|
/* This value got queried in State already to allocate the bindings array, |
|
reuse it here */ |
|
maxTextureUnits{GLint(bindings.size())}, |
|
#ifndef MAGNUM_TARGET_GLES2 |
|
maxLodBias{0.0f}, |
|
#endif |
|
maxMaxAnisotropy(0.0f), currentTextureUnit(0), |
|
#ifndef MAGNUM_TARGET_GLES2 |
|
maxColorSamples(0), maxDepthSamples(0), maxIntegerSamples(0), |
|
#endif |
|
#ifndef MAGNUM_TARGET_GLES |
|
bufferOffsetAlignment(0), |
|
#endif |
|
bindings{bindings} |
|
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) |
|
, imageBindings{imageBindings} |
|
#endif |
|
{ |
|
/* Create implementation */ |
|
#ifndef MAGNUM_TARGET_GLES |
|
if(context.isExtensionSupported<Extensions::ARB::direct_state_access>()) { |
|
extensions[Extensions::ARB::direct_state_access::Index] = |
|
Extensions::ARB::direct_state_access::string(); |
|
createImplementation = &AbstractTexture::createImplementationDSA; |
|
|
|
} else |
|
#endif |
|
{ |
|
createImplementation = &AbstractTexture::createImplementationDefault; |
|
} |
|
|
|
/* Single bind implementation */ |
|
#ifndef MAGNUM_TARGET_GLES |
|
if(context.isExtensionSupported<Extensions::ARB::direct_state_access>()) { |
|
/* Extension name added below */ |
|
|
|
#ifdef CORRADE_TARGET_WINDOWS |
|
if((context.detectedDriver() & Context::DetectedDriver::IntelWindows) && |
|
!context.isDriverWorkaroundDisabled("intel-windows-half-baked-dsa-texture-bind"_s)) |
|
{ |
|
unbindImplementation = &AbstractTexture::unbindImplementationDefault; |
|
bindImplementation = &AbstractTexture::bindImplementationDSAIntelWindows; |
|
} else |
|
#endif |
|
{ |
|
unbindImplementation = &AbstractTexture::unbindImplementationDSA; |
|
bindImplementation = &AbstractTexture::bindImplementationDSA; |
|
} |
|
|
|
} else if(context.isExtensionSupported<Extensions::ARB::multi_bind>()) { |
|
/* Extension name added below */ |
|
|
|
unbindImplementation = &AbstractTexture::unbindImplementationMulti; |
|
bindImplementation = &AbstractTexture::bindImplementationMulti; |
|
|
|
} else |
|
#endif |
|
{ |
|
unbindImplementation = &AbstractTexture::unbindImplementationDefault; |
|
/* This is additionally modified below for the |
|
apple-buffer-texture-unbind-on-buffer-modify workaround */ |
|
bindImplementation = &AbstractTexture::bindImplementationDefault; |
|
} |
|
|
|
/* Multi bind implementation */ |
|
#ifndef MAGNUM_TARGET_GLES |
|
if(context.isExtensionSupported<Extensions::ARB::multi_bind>()) { |
|
extensions[Extensions::ARB::multi_bind::Index] = |
|
Extensions::ARB::multi_bind::string(); |
|
|
|
bindMultiImplementation = &AbstractTexture::bindImplementationMulti; |
|
|
|
} else |
|
#endif |
|
{ |
|
bindMultiImplementation = &AbstractTexture::bindImplementationFallback; |
|
} |
|
|
|
/* DSA/non-DSA implementation */ |
|
#ifndef MAGNUM_TARGET_GLES |
|
if(context.isExtensionSupported<Extensions::ARB::direct_state_access>()) { |
|
extensions[Extensions::ARB::direct_state_access::Index] = |
|
Extensions::ARB::direct_state_access::string(); |
|
|
|
parameteriImplementation = &AbstractTexture::parameterImplementationDSA; |
|
parameterfImplementation = &AbstractTexture::parameterImplementationDSA; |
|
parameterivImplementation = &AbstractTexture::parameterImplementationDSA; |
|
parameterfvImplementation = &AbstractTexture::parameterImplementationDSA; |
|
parameterIuivImplementation = &AbstractTexture::parameterIImplementationDSA; |
|
parameterIivImplementation = &AbstractTexture::parameterIImplementationDSA; |
|
getLevelParameterivImplementation = &AbstractTexture::getLevelParameterImplementationDSA; |
|
mipmapImplementation = &AbstractTexture::mipmapImplementationDSA; |
|
subImage1DImplementation = &AbstractTexture::subImageImplementationDSA; |
|
subImage2DImplementation = &AbstractTexture::subImage2DImplementationDSA; |
|
subImage3DImplementation = &AbstractTexture::subImage3DImplementationDSA; |
|
compressedSubImage1DImplementation = &AbstractTexture::compressedSubImageImplementationDSA; |
|
compressedSubImage2DImplementation = &AbstractTexture::compressedSubImageImplementationDSA; |
|
compressedSubImage3DImplementation = &AbstractTexture::compressedSubImageImplementationDSA; |
|
|
|
setBufferImplementation = &BufferTexture::setBufferImplementationDSA; |
|
setBufferRangeImplementation = &BufferTexture::setBufferRangeImplementationDSA; |
|
|
|
} else |
|
#endif |
|
{ |
|
parameteriImplementation = &AbstractTexture::parameterImplementationDefault; |
|
parameterfImplementation = &AbstractTexture::parameterImplementationDefault; |
|
#ifndef MAGNUM_TARGET_GLES2 |
|
parameterivImplementation = &AbstractTexture::parameterImplementationDefault; |
|
#endif |
|
parameterfvImplementation = &AbstractTexture::parameterImplementationDefault; |
|
#ifndef MAGNUM_TARGET_GLES |
|
parameterIuivImplementation = &AbstractTexture::parameterIImplementationDefault; |
|
parameterIivImplementation = &AbstractTexture::parameterIImplementationDefault; |
|
#endif |
|
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) |
|
getLevelParameterivImplementation = &AbstractTexture::getLevelParameterImplementationDefault; |
|
#endif |
|
mipmapImplementation = &AbstractTexture::mipmapImplementationDefault; |
|
#ifndef MAGNUM_TARGET_GLES |
|
subImage1DImplementation = &AbstractTexture::subImageImplementationDefault; |
|
compressedSubImage1DImplementation = &AbstractTexture::compressedSubImageImplementationDefault; |
|
#endif |
|
subImage2DImplementation = &AbstractTexture::subImage2DImplementationDefault; |
|
compressedSubImage2DImplementation = &AbstractTexture::compressedSubImageImplementationDefault; |
|
#if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2)) |
|
subImage3DImplementation = &AbstractTexture::subImage3DImplementationDefault; |
|
compressedSubImage3DImplementation = &AbstractTexture::compressedSubImageImplementationDefault; |
|
#endif |
|
|
|
#ifndef MAGNUM_TARGET_GLES |
|
setBufferImplementation = &BufferTexture::setBufferImplementationDefault; |
|
setBufferRangeImplementation = &BufferTexture::setBufferRangeImplementationDefault; |
|
#endif |
|
} |
|
|
|
/* DSA/non-DSA implementation for cubemaps, because ... well, basically all |
|
non-Mesa drivers have to be broken in a special way */ |
|
#ifndef MAGNUM_TARGET_GLES |
|
if(context.isExtensionSupported<Extensions::ARB::direct_state_access>()) { |
|
#ifdef CORRADE_TARGET_WINDOWS |
|
if((context.detectedDriver() & Context::DetectedDriver::IntelWindows) && !context.isDriverWorkaroundDisabled("intel-windows-broken-dsa-for-cubemaps"_s)) { |
|
getCubeLevelParameterivImplementation = &CubeMapTexture::getLevelParameterImplementationDefault; |
|
cubeSubImageImplementation = &CubeMapTexture::subImageImplementationDefault; |
|
cubeCompressedSubImageImplementation = &CubeMapTexture::compressedSubImageImplementationDefault; |
|
} else if((context.detectedDriver() & Context::DetectedDriver::Amd) && !context.isDriverWorkaroundDisabled("amd-windows-cubemap-image3d-slice-by-slice"_s)) { |
|
/* This one is not broken, but the others are */ |
|
getCubeLevelParameterivImplementation = &CubeMapTexture::getLevelParameterImplementationDSA; |
|
cubeSubImageImplementation = &CubeMapTexture::subImageImplementationDefault; |
|
cubeCompressedSubImageImplementation = &CubeMapTexture::compressedSubImageImplementationDefault; |
|
} else |
|
#endif |
|
if((context.detectedDriver() & Context::DetectedDriver::NVidia) && !context.isDriverWorkaroundDisabled("nv-cubemap-broken-dsa-compressed-subimage-upload"_s)) { |
|
getCubeLevelParameterivImplementation = &CubeMapTexture::getLevelParameterImplementationDSA; |
|
cubeSubImageImplementation = &CubeMapTexture::subImageImplementationDSA; |
|
/* This one is broken, the others are not */ |
|
cubeCompressedSubImageImplementation = &CubeMapTexture::compressedSubImageImplementationDefault; |
|
} else { |
|
/* Extension name added above */ |
|
|
|
getCubeLevelParameterivImplementation = &CubeMapTexture::getLevelParameterImplementationDSA; |
|
cubeSubImageImplementation = &CubeMapTexture::subImageImplementationDSA; |
|
cubeCompressedSubImageImplementation = &CubeMapTexture::compressedSubImageImplementationDSA; |
|
} |
|
} else |
|
#endif |
|
{ |
|
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) |
|
getCubeLevelParameterivImplementation = &CubeMapTexture::getLevelParameterImplementationDefault; |
|
#endif |
|
cubeSubImageImplementation = &CubeMapTexture::subImageImplementationDefault; |
|
cubeCompressedSubImageImplementation = &CubeMapTexture::compressedSubImageImplementationDefault; |
|
} |
|
|
|
#if defined(MAGNUM_TARGET_GLES) && !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) |
|
/* Integer parameter implementation for ES3 */ |
|
if(context.isVersionSupported(Version::GLES320)) { |
|
parameterIuivImplementation = &AbstractTexture::parameterIImplementationDefault; |
|
parameterIivImplementation = &AbstractTexture::parameterIImplementationDefault; |
|
} else if(context.isExtensionSupported<Extensions::EXT::texture_border_clamp>()) { |
|
extensions[Extensions::EXT::texture_border_clamp::Index] = |
|
Extensions::EXT::texture_border_clamp::string(); |
|
parameterIuivImplementation = &AbstractTexture::parameterIImplementationEXT; |
|
parameterIivImplementation = &AbstractTexture::parameterIImplementationEXT; |
|
} else { |
|
parameterIuivImplementation = nullptr; |
|
parameterIivImplementation = nullptr; |
|
} |
|
|
|
/* Buffer texture implementation for ES3 */ |
|
if(context.isVersionSupported(Version::GLES320)) { |
|
setBufferImplementation = &BufferTexture::setBufferImplementationDefault; |
|
setBufferRangeImplementation = &BufferTexture::setBufferRangeImplementationDefault; |
|
} else if(context.isExtensionSupported<Extensions::EXT::texture_buffer>()) { |
|
extensions[Extensions::EXT::texture_buffer::Index] = |
|
Extensions::EXT::texture_buffer::string(); |
|
setBufferImplementation = &BufferTexture::setBufferImplementationEXT; |
|
setBufferRangeImplementation = &BufferTexture::setBufferRangeImplementationEXT; |
|
} else { |
|
setBufferImplementation = nullptr; |
|
setBufferRangeImplementation = nullptr; |
|
} |
|
#endif |
|
|
|
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) |
|
/* Texture view implementation */ |
|
#ifndef MAGNUM_TARGET_GLES |
|
if(context.isExtensionSupported<Extensions::ARB::texture_view>()) { |
|
extensions[Extensions::ARB::texture_view::Index] = |
|
Extensions::ARB::texture_view::string(); |
|
viewImplementation = glTextureView; |
|
} |
|
#else |
|
if(context.isExtensionSupported<Extensions::EXT::texture_view>()) { |
|
extensions[Extensions::EXT::texture_view::Index] = |
|
Extensions::EXT::texture_view::string(); |
|
viewImplementation = glTextureViewEXT; |
|
} else if(context.isExtensionSupported<Extensions::OES::texture_view>()) { |
|
extensions[Extensions::OES::texture_view::Index] = |
|
Extensions::OES::texture_view::string(); |
|
viewImplementation = glTextureViewOES; |
|
} |
|
#endif |
|
else { |
|
viewImplementation = nullptr; |
|
} |
|
#endif |
|
|
|
/* Data invalidation implementation */ |
|
#ifndef MAGNUM_TARGET_GLES |
|
if(context.isExtensionSupported<Extensions::ARB::invalidate_subdata>()) { |
|
extensions[Extensions::ARB::invalidate_subdata::Index] = |
|
Extensions::ARB::invalidate_subdata::string(); |
|
|
|
invalidateImageImplementation = &AbstractTexture::invalidateImageImplementationARB; |
|
invalidateSubImageImplementation = &AbstractTexture::invalidateSubImageImplementationARB; |
|
} else |
|
#endif |
|
{ |
|
invalidateImageImplementation = &AbstractTexture::invalidateImageImplementationNoOp; |
|
invalidateSubImageImplementation = &AbstractTexture::invalidateSubImageImplementationNoOp; |
|
} |
|
|
|
#ifndef MAGNUM_TARGET_GLES |
|
/* Image retrieval implementation */ |
|
if(context.isExtensionSupported<Extensions::ARB::direct_state_access>()) { |
|
/* Extension name added above */ |
|
getImageImplementation = &AbstractTexture::getImageImplementationDSA; |
|
getCompressedImageImplementation = &AbstractTexture::getCompressedImageImplementationDSA; |
|
|
|
} else if(context.isExtensionSupported<Extensions::ARB::robustness>()) { |
|
extensions[Extensions::ARB::robustness::Index] = |
|
Extensions::ARB::robustness::string(); |
|
|
|
getImageImplementation = &AbstractTexture::getImageImplementationRobustness; |
|
getCompressedImageImplementation = &AbstractTexture::getCompressedImageImplementationRobustness; |
|
|
|
} else { |
|
getImageImplementation = &AbstractTexture::getImageImplementationDefault; |
|
getCompressedImageImplementation = &AbstractTexture::getCompressedImageImplementationDefault; |
|
} |
|
|
|
/* Image retrieval implementation for cube map */ |
|
if(context.isExtensionSupported<Extensions::ARB::get_texture_sub_image>()) { |
|
extensions[Extensions::ARB::get_texture_sub_image::Index] = |
|
Extensions::ARB::get_texture_sub_image::string(); |
|
|
|
getCubeImageImplementation = &CubeMapTexture::getImageImplementationDSA; |
|
getCompressedCubeImageImplementation = &CubeMapTexture::getCompressedImageImplementationDSA; |
|
|
|
} else if(context.isExtensionSupported<Extensions::ARB::robustness>()) { |
|
/* Extension name added above */ |
|
getCubeImageImplementation = &CubeMapTexture::getImageImplementationRobustness; |
|
getCompressedCubeImageImplementation = &CubeMapTexture::getCompressedImageImplementationRobustness; |
|
|
|
} else { |
|
getCubeImageImplementation = &CubeMapTexture::getImageImplementationDefault; |
|
getCompressedCubeImageImplementation = &CubeMapTexture::getCompressedImageImplementationDefault; |
|
} |
|
|
|
/* 3D compressed cubemap image query implementation (extensions added |
|
above) */ |
|
if((context.detectedDriver() & Context::DetectedDriver::NVidia) && |
|
context.isExtensionSupported<Extensions::ARB::direct_state_access>() && |
|
!context.isDriverWorkaroundDisabled("nv-cubemap-broken-full-compressed-image-query"_s)) |
|
getCompressedCubeImage3DImplementation = &CubeMapTexture::getCompressedImageImplementationDSASingleSliceWorkaround; |
|
else |
|
getCompressedCubeImage3DImplementation = &CubeMapTexture::getCompressedImageImplementationDSA; |
|
|
|
#ifdef CORRADE_TARGET_WINDOWS |
|
/** @todo those *might* be happening with the proprietary AMD driver on |
|
linux as well, test */ |
|
if((context.detectedDriver() & Context::DetectedDriver::Amd) && |
|
context.isExtensionSupported<Extensions::ARB::direct_state_access>() && |
|
!context.isDriverWorkaroundDisabled("amd-windows-cubemap-image3d-slice-by-slice"_s)) |
|
getCubeImage3DImplementation = &CubeMapTexture::getImageImplementationDSAAmdSliceBySlice; |
|
else if((context.detectedDriver() & Context::DetectedDriver::IntelWindows) && |
|
context.isExtensionSupported<Extensions::ARB::direct_state_access>() && |
|
!context.isDriverWorkaroundDisabled("intel-windows-broken-dsa-for-cubemaps"_s)) |
|
getCubeImage3DImplementation = &CubeMapTexture::getImageImplementationSliceBySlice; |
|
else |
|
#endif |
|
if(context.isExtensionSupported<Extensions::ARB::direct_state_access>()) { |
|
getCubeImage3DImplementation = &CubeMapTexture::getImageImplementationDSA; |
|
} else { |
|
getCubeImage3DImplementation = &CubeMapTexture::getImageImplementationSliceBySlice; |
|
} |
|
#endif |
|
|
|
/* Texture storage implementation for desktop and ES */ |
|
#ifndef MAGNUM_TARGET_WEBGL |
|
#ifndef MAGNUM_TARGET_GLES |
|
if(context.isExtensionSupported<Extensions::ARB::texture_storage>()) |
|
#elif defined(MAGNUM_TARGET_GLES2) |
|
if(context.isExtensionSupported<Extensions::EXT::texture_storage>()) |
|
#endif |
|
{ |
|
#ifndef MAGNUM_TARGET_GLES |
|
extensions[Extensions::ARB::texture_storage::Index] = |
|
Extensions::ARB::texture_storage::string(); |
|
#elif defined(MAGNUM_TARGET_GLES2) |
|
extensions[Extensions::EXT::texture_storage::Index] = |
|
Extensions::EXT::texture_storage::string(); |
|
#endif |
|
|
|
#ifndef MAGNUM_TARGET_GLES |
|
if(context.isExtensionSupported<Extensions::ARB::direct_state_access>()) { |
|
storage1DImplementation = &AbstractTexture::storageImplementationDSA; |
|
storage2DImplementation = &AbstractTexture::storageImplementationDSA; |
|
storage3DImplementation = &AbstractTexture::storageImplementationDSA; |
|
|
|
} else |
|
#endif |
|
{ |
|
#ifndef MAGNUM_TARGET_GLES |
|
storage1DImplementation = &AbstractTexture::storageImplementationDefault; |
|
#endif |
|
storage2DImplementation = &AbstractTexture::storageImplementationDefault; |
|
storage3DImplementation = &AbstractTexture::storageImplementationDefault; |
|
} |
|
} |
|
#if !defined(MAGNUM_TARGET_GLES) || defined(MAGNUM_TARGET_GLES2) |
|
else { |
|
#ifndef MAGNUM_TARGET_GLES |
|
storage1DImplementation = &AbstractTexture::storageImplementationFallback; |
|
#endif |
|
storage2DImplementation = &AbstractTexture::storageImplementationFallback; |
|
storage3DImplementation = &AbstractTexture::storageImplementationFallback; |
|
} |
|
#endif |
|
|
|
/* Texture storage implementation for WebGL 1.0 */ |
|
#elif defined(MAGNUM_TARGET_GLES2) |
|
storage2DImplementation = &AbstractTexture::storageImplementationFallback; |
|
|
|
/* Texture storage implementation for WebGL 2.0 */ |
|
#else |
|
storage2DImplementation = &AbstractTexture::storageImplementationDefault; |
|
storage3DImplementation = &AbstractTexture::storageImplementationDefault; |
|
#endif |
|
|
|
#ifndef MAGNUM_TARGET_GLES |
|
/* Storage implementation for multisample textures. The fallback doesn't |
|
have DSA alternative, so it must be handled specially. */ |
|
if(context.isExtensionSupported<Extensions::ARB::texture_storage_multisample>()) { |
|
extensions[Extensions::ARB::texture_storage_multisample::Index] = |
|
Extensions::ARB::texture_storage_multisample::string(); |
|
|
|
if(context.isExtensionSupported<Extensions::ARB::direct_state_access>()) { |
|
storage2DMultisampleImplementation = &AbstractTexture::storageMultisampleImplementationDSA; |
|
storage3DMultisampleImplementation = &AbstractTexture::storageMultisampleImplementationDSA; |
|
} else { |
|
storage2DMultisampleImplementation = &AbstractTexture::storageMultisampleImplementationDefault; |
|
storage3DMultisampleImplementation = &AbstractTexture::storageMultisampleImplementationDefault; |
|
} |
|
} else { |
|
storage2DMultisampleImplementation = &AbstractTexture::storageMultisampleImplementationFallback; |
|
storage3DMultisampleImplementation = &AbstractTexture::storageMultisampleImplementationFallback; |
|
} |
|
#elif !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) |
|
storage2DMultisampleImplementation = &AbstractTexture::storageMultisampleImplementationDefault; |
|
|
|
if(context.isVersionSupported(Version::GLES320)) { |
|
storage3DMultisampleImplementation = &AbstractTexture::storageMultisampleImplementationDefault; |
|
} else if(context.isExtensionSupported<Extensions::OES::texture_storage_multisample_2d_array>()) { |
|
extensions[Extensions::OES::texture_storage_multisample_2d_array::Index] = |
|
Extensions::OES::texture_storage_multisample_2d_array::string(); |
|
|
|
storage3DMultisampleImplementation = &AbstractTexture::storageMultisampleImplementationOES; |
|
} else { |
|
storage3DMultisampleImplementation = nullptr; |
|
} |
|
#endif |
|
|
|
/* Anisotropic filter implementation */ |
|
#ifndef MAGNUM_TARGET_GLES |
|
if(context.isExtensionSupported<Extensions::ARB::texture_filter_anisotropic>()) { |
|
extensions[Extensions::ARB::texture_filter_anisotropic::Index] = |
|
Extensions::ARB::texture_filter_anisotropic::string(); |
|
|
|
setMaxAnisotropyImplementation = &AbstractTexture::setMaxAnisotropyImplementationArbOrExt; |
|
} else |
|
#endif |
|
if(context.isExtensionSupported<Extensions::EXT::texture_filter_anisotropic>()) { |
|
extensions[Extensions::EXT::texture_filter_anisotropic::Index] = |
|
Extensions::EXT::texture_filter_anisotropic::string(); |
|
|
|
setMaxAnisotropyImplementation = &AbstractTexture::setMaxAnisotropyImplementationArbOrExt; |
|
} else setMaxAnisotropyImplementation = &AbstractTexture::setMaxAnisotropyImplementationNoOp; |
|
|
|
#ifndef MAGNUM_TARGET_GLES |
|
/* NVidia workaround for compressed block data size implementation */ |
|
if((context.detectedDriver() & Context::DetectedDriver::NVidia) && |
|
!context.isDriverWorkaroundDisabled("nv-compressed-block-size-in-bits"_s)) |
|
compressedBlockDataSizeImplementation = &AbstractTexture::compressedBlockDataSizeImplementationBitsWorkaround; |
|
else |
|
compressedBlockDataSizeImplementation = &AbstractTexture::compressedBlockDataSizeImplementationDefault; |
|
#endif |
|
|
|
#ifndef MAGNUM_TARGET_WEBGL |
|
/* SVGA3D workaround for array / 3D / cube map texture upload. Overrides |
|
the DSA / non-DSA function pointers set above. */ |
|
if((context.detectedDriver() & Context::DetectedDriver::Svga3D) && |
|
!context.isDriverWorkaroundDisabled("svga3d-texture-upload-slice-by-slice"_s)) { |
|
#ifndef MAGNUM_TARGET_GLES |
|
image2DImplementation = &AbstractTexture::imageImplementationSvga3DSliceBySlice; |
|
#endif |
|
image3DImplementation = &AbstractTexture::imageImplementationSvga3DSliceBySlice; |
|
#ifndef MAGNUM_TARGET_GLES |
|
if(context.isExtensionSupported<Extensions::ARB::direct_state_access>()) { |
|
#ifndef MAGNUM_TARGET_GLES |
|
subImage2DImplementation = &AbstractTexture::subImageImplementationSvga3DSliceBySlice<&AbstractTexture::subImage2DImplementationDSA>; |
|
#endif |
|
subImage3DImplementation = &AbstractTexture::subImageImplementationSvga3DSliceBySlice<&AbstractTexture::subImage3DImplementationDSA>; |
|
|
|
} else |
|
#endif |
|
{ |
|
#ifndef MAGNUM_TARGET_GLES |
|
subImage2DImplementation = &AbstractTexture::subImageImplementationSvga3DSliceBySlice<&AbstractTexture::subImage2DImplementationDefault>; |
|
#endif |
|
subImage3DImplementation = &AbstractTexture::subImageImplementationSvga3DSliceBySlice<&AbstractTexture::subImage3DImplementationDefault>; |
|
} |
|
} else |
|
#endif |
|
{ |
|
/* These need to be set up in any case */ |
|
image2DImplementation = &AbstractTexture::imageImplementationDefault; |
|
#if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2)) |
|
image3DImplementation = &AbstractTexture::imageImplementationDefault; |
|
#endif |
|
} |
|
|
|
#ifndef MAGNUM_TARGET_GLES |
|
/* SVGA3D and Intel workaround for cube map texture upload. Overrides the |
|
DSA / non-DSA function pointers set above. */ |
|
if((context.detectedDriver() & Context::DetectedDriver::Svga3D) && |
|
context.isExtensionSupported<Extensions::ARB::direct_state_access>() && |
|
!context.isDriverWorkaroundDisabled("svga3d-texture-upload-slice-by-slice"_s) |
|
) { |
|
cubeSubImage3DImplementation = &CubeMapTexture::subImageImplementationDSASliceBySlice; |
|
} else if((context.detectedDriver() & Context::DetectedDriver::IntelWindows) && |
|
context.isExtensionSupported<Extensions::ARB::direct_state_access>() && |
|
!context.isDriverWorkaroundDisabled("intel-windows-broken-dsa-for-cubemaps"_s) |
|
) { |
|
cubeSubImage3DImplementation = &CubeMapTexture::subImageImplementationSliceBySlice; |
|
} |
|
#ifdef CORRADE_TARGET_WINDOWS |
|
/** @todo those *might* be happening with the proprietary AMD driver on |
|
linux as well, test */ |
|
else if((context.detectedDriver() & Context::DetectedDriver::Amd) && |
|
!context.isDriverWorkaroundDisabled("amd-windows-cubemap-image3d-slice-by-slice"_s)) { |
|
/* DSA version is broken (non-zero Z offset not allowed), need to |
|
emulate using classic APIs */ |
|
cubeSubImage3DImplementation = &CubeMapTexture::subImageImplementationSliceBySlice; |
|
} |
|
#endif |
|
else if(context.isExtensionSupported<Extensions::ARB::direct_state_access>()) { |
|
cubeSubImage3DImplementation = &CubeMapTexture::subImageImplementationDSA; |
|
} else |
|
#endif |
|
{ |
|
cubeSubImage3DImplementation = &CubeMapTexture::subImageImplementationSliceBySlice; |
|
} |
|
|
|
#if defined(CORRADE_TARGET_APPLE) && !defined(MAGNUM_TARGET_GLES) |
|
if(!context.isDriverWorkaroundDisabled("apple-buffer-texture-unbind-on-buffer-modify"_s)) { |
|
CORRADE_INTERNAL_ASSERT(std::size_t(maxTextureUnits) <= decltype(bufferTextureBound)::Size); |
|
/* Assume ARB_multi_bind is not supported, otherwise we'd need to |
|
implement the workaround also for bindMultiImplementation */ |
|
CORRADE_INTERNAL_ASSERT(!context.isExtensionSupported<Extensions::ARB::multi_bind>()); |
|
bindImplementation = &AbstractTexture::bindImplementationAppleBufferTextureWorkaround; |
|
bindInternalImplementation = &AbstractTexture::bindImplementationAppleBufferTextureWorkaround; |
|
} else |
|
#endif |
|
{ |
|
/* bindImplementation already set above */ |
|
bindInternalImplementation = &AbstractTexture::bindImplementationDefault; |
|
} |
|
} |
|
|
|
void TextureState::reset() { |
|
for(Containers::Pair<GLenum, GLuint>& i: bindings) |
|
i = {{}, State::DisengagedBinding}; |
|
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) |
|
for(ImageBinding& i: imageBindings) |
|
i = {State::DisengagedBinding, 0, false, 0, 0}; |
|
#endif |
|
} |
|
|
|
}}}
|
|
|