mirror of https://github.com/mosra/magnum.git
Browse Source
Yay? It's funny, what produces correct result causes validation errors. I suppose this will be very similar for all other workarounds.pull/494/head
18 changed files with 563 additions and 19 deletions
@ -0,0 +1,58 @@ |
|||||||
|
/* |
||||||
|
This file is part of Magnum. |
||||||
|
|
||||||
|
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, |
||||||
|
2020, 2021 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. |
||||||
|
*/ |
||||||
|
|
||||||
|
namespace Magnum { |
||||||
|
/** @page vulkan-workarounds Driver workarounds |
||||||
|
@brief List of Vulkan driver workarounds used by Magnum |
||||||
|
@m_since_latest |
||||||
|
|
||||||
|
@m_footernavigation |
||||||
|
|
||||||
|
Driver workarounds used by a particular app are listed in the engine startup |
||||||
|
log such as here: |
||||||
|
|
||||||
|
@code{.shell-session} |
||||||
|
Device: SwiftShader Device (LLVM 10.0.0) |
||||||
|
Device version: Vulkan 1.1 |
||||||
|
Enabled device extensions: |
||||||
|
VK_KHR_create_renderpass2 |
||||||
|
... |
||||||
|
Using driver workarounds: |
||||||
|
swiftshader-image-copy-extent-instead-of-layers |
||||||
|
... |
||||||
|
@endcode |
||||||
|
|
||||||
|
These identifiers correspond to the strings in the listing below. For debugging |
||||||
|
and diagnostic purposes it's possible to disable particular workarounds by |
||||||
|
passing their identifier string to the `--magnum-disable-workarounds` |
||||||
|
command-line option. See @ref Vk-Instance-command-line for more information. |
||||||
|
|
||||||
|
@m_class{m-console-wrap} |
||||||
|
|
||||||
|
@snippet src/Magnum/Vk/Implementation/DriverWorkaround.cpp workarounds |
||||||
|
|
||||||
|
@see @ref opengl-workarounds |
||||||
|
*/ |
||||||
|
} |
||||||
@ -0,0 +1,114 @@ |
|||||||
|
/*
|
||||||
|
This file is part of Magnum. |
||||||
|
|
||||||
|
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, |
||||||
|
2020, 2021 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 <Corrade/Containers/GrowableArray.h> |
||||||
|
#include <Corrade/Containers/StringView.h> |
||||||
|
#include <Corrade/Utility/Debug.h> |
||||||
|
|
||||||
|
#include "Magnum/Magnum.h" |
||||||
|
#include "Magnum/Vk/Implementation/DriverWorkaround.h" |
||||||
|
|
||||||
|
namespace Magnum { namespace Vk { namespace Implementation { |
||||||
|
|
||||||
|
namespace { |
||||||
|
|
||||||
|
using namespace Containers::Literals; |
||||||
|
|
||||||
|
/* Search the code for the following strings to see where they are implemented */ |
||||||
|
constexpr Containers::StringView KnownWorkarounds[]{ |
||||||
|
/* [workarounds] */ |
||||||
|
/* For layered image copies, SwiftShader (5.0? the version reporting is messy)
|
||||||
|
expects the layer offsets/counts to be included as second/third dimension of |
||||||
|
the image offset/extent instead. Actually, having the Vulkan API contain |
||||||
|
just 3D offset and extent with no layer offset/count would make more sense |
||||||
|
to me as well -- the last dimension can be either in the offset/extent or |
||||||
|
layer offset/count, but never in both, so the extra fields feel redundant. |
||||||
|
Or maybe it's reserving space for layered 3D images? */ |
||||||
|
"swiftshader-image-copy-extent-instead-of-layers"_s, |
||||||
|
/* [workarounds] */ |
||||||
|
}; |
||||||
|
|
||||||
|
/* I could use std::find(), right? Well, it'd be a whole lot more typing and
|
||||||
|
an #include <algorithm> *and* #include <iterator> or whatever as well, |
||||||
|
because apparently ONE CAN'T GET std::begin() / std::end() without including |
||||||
|
tens thousands lines of irrelevant shit, FFS. |
||||||
|
|
||||||
|
Also the comparison to array end to discover if it wasn't found is just a |
||||||
|
useless verbose crap shit as well, so we'll do better here and return a null |
||||||
|
view instead. |
||||||
|
|
||||||
|
Moreover, based on the experience with GL, I don't expect there being too |
||||||
|
many workarounds used heavily (10 at most, maybe?) so I won't bother with |
||||||
|
some binary search, which needs extra testing effort. */ |
||||||
|
Containers::StringView findWorkaround(Containers::StringView workaround) { |
||||||
|
for(Containers::StringView i: KnownWorkarounds) |
||||||
|
if(workaround == i) return i; |
||||||
|
return {}; |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
void disableWorkaround(Containers::Array<std::pair<Containers::StringView, bool>>& encounteredWorkarounds, const Containers::StringView workaround) { |
||||||
|
/* Find the workaround. Note that we'll add the found view to the array
|
||||||
|
and not the passed view, as the found view is guaranteed to stay in |
||||||
|
scope */ |
||||||
|
Containers::StringView found = findWorkaround(workaround); |
||||||
|
|
||||||
|
/* Ignore unknown workarounds */ |
||||||
|
/** @todo this will probably cause false positives when both GL and Vulkan
|
||||||
|
is used together? */ |
||||||
|
if(found.isEmpty()) { |
||||||
|
Warning{} << "Vk: unknown workaround" << workaround; |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
arrayAppend(encounteredWorkarounds, Containers::InPlaceInit, found, true); |
||||||
|
} |
||||||
|
|
||||||
|
Containers::Array<std::pair<Containers::StringView, bool>> disableAllWorkarounds() { |
||||||
|
Containers::Array<std::pair<Containers::StringView, bool>> encounteredWorkarounds; |
||||||
|
for(Containers::StringView i: KnownWorkarounds) |
||||||
|
arrayAppend(encounteredWorkarounds, Containers::InPlaceInit, i, true); |
||||||
|
return encounteredWorkarounds; |
||||||
|
} |
||||||
|
|
||||||
|
bool isDriverWorkaroundDisabled(Containers::Array<std::pair<Containers::StringView, bool>>& encounteredWorkarounds, const Containers::StringView workaround) { |
||||||
|
/* Find the workaround. Note that we'll add the found view to the array
|
||||||
|
and not the passed view, as the found view is guaranteed to stay in |
||||||
|
scope */ |
||||||
|
Containers::StringView found = findWorkaround(workaround); |
||||||
|
CORRADE_INTERNAL_ASSERT(!found.isEmpty()); |
||||||
|
|
||||||
|
/* If the workaround was already asked for or disabled, return its state,
|
||||||
|
otherwise add it to the list as used one. Here we again cheat a bit and |
||||||
|
compare just data pointers instead of the whole string as we store only |
||||||
|
the views in the KnownWorkarounds list. */ |
||||||
|
for(const auto& i: encounteredWorkarounds) |
||||||
|
if(i.first.data() == found.data()) return i.second; |
||||||
|
arrayAppend(encounteredWorkarounds, Containers::InPlaceInit, found, false); |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
}}} |
||||||
@ -0,0 +1,43 @@ |
|||||||
|
#ifndef Magnum_Vk_Implementation_DriverWorkaround_h |
||||||
|
#define Magnum_Vk_Implementation_DriverWorkaround_h |
||||||
|
/*
|
||||||
|
This file is part of Magnum. |
||||||
|
|
||||||
|
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, |
||||||
|
2020, 2021 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 "Magnum/Magnum.h" |
||||||
|
|
||||||
|
namespace Magnum { namespace Vk { namespace Implementation { |
||||||
|
|
||||||
|
void disableWorkaround(Containers::Array<std::pair<Containers::StringView, bool>>& encounteredWorkarounds, Containers::StringView workaround); |
||||||
|
|
||||||
|
bool isDriverWorkaroundDisabled(Containers::Array<std::pair<Containers::StringView, bool>>& encounteredWorkarounds, Containers::StringView workaround); |
||||||
|
|
||||||
|
/* Used by Device::wrap() -- because device extension setup is outside of our
|
||||||
|
control and the function doesn't print anything on the output, it's better |
||||||
|
to just do nothing at all than silently enabling some subset */ |
||||||
|
Containers::Array<std::pair<Containers::StringView, bool>> disableAllWorkarounds(); |
||||||
|
|
||||||
|
}}} |
||||||
|
|
||||||
|
#endif |
||||||
Loading…
Reference in new issue