1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-03-03 16:09:39 +00:00

Use reserveGlobalTextureUnits for shadow maps

This commit is contained in:
AnyOldName3 2023-02-09 01:32:48 +00:00
parent 9be3d2668a
commit 7d4410d4fb
4 changed files with 20 additions and 25 deletions

View file

@ -13,7 +13,7 @@ namespace SceneUtil
{
using namespace osgShadow;
void ShadowManager::setupShadowSettings()
void ShadowManager::setupShadowSettings(Shader::ShaderManager& shaderManager)
{
mEnableShadows = Settings::Manager::getBool("enable shadows", "Shadows");
@ -32,8 +32,7 @@ namespace SceneUtil
= std::clamp(Settings::Manager::getInt("number of shadow maps", "Shadows"), 1, 8);
mShadowSettings->setNumShadowMapsPerLight(numberOfShadowMapsPerLight);
mShadowSettings->setBaseShadowTextureUnit(
osg::GLExtensions::Get(0, false)->glMaxTextureUnits - numberOfShadowMapsPerLight);
mShadowSettings->setBaseShadowTextureUnit(shaderManager.reserveGlobalTextureUnits(Shader::ShaderManager::Slot::ShadowMaps, numberOfShadowMapsPerLight));
const float maximumShadowMapDistance = Settings::Manager::getFloat("maximum shadow map distance", "Shadows");
if (maximumShadowMapDistance > 0)
@ -122,7 +121,7 @@ namespace SceneUtil
mShadowedScene->setNodeMask(sceneRoot->getNodeMask());
mShadowSettings = mShadowedScene->getShadowSettings();
setupShadowSettings();
setupShadowSettings(shaderManager);
mShadowTechnique->setupCastingShader(shaderManager);
mShadowTechnique->setWorldMask(worldMask);

View file

@ -29,7 +29,7 @@ namespace SceneUtil
Shader::ShaderManager& shaderManager);
~ShadowManager();
void setupShadowSettings();
void setupShadowSettings(Shader::ShaderManager& shaderManager);
Shader::ShaderManager::DefineMap getShadowDefines();

View file

@ -636,31 +636,24 @@ namespace Shader
program->addShader(linkedShader);
}
int ShaderManager::reserveGlobalTextureUnits(Slot slot)
int ShaderManager::reserveGlobalTextureUnits(Slot slot, int count)
{
int unit = mReservedTextureUnitsBySlot[static_cast<int>(slot)];
if (unit >= 0)
return unit;
// TODO: Reuse units when count increase forces reallocation
// TODO: Warn if trampling on the ~8 units needed by model textures
auto unit = mReservedTextureUnitsBySlot[static_cast<int>(slot)];
if (unit.index >= 0 && unit.count >= count)
return unit.index;
{
// Texture units from `8 - numberOfShadowMaps` to `8` are used for shadows, so we skip them here.
// TODO: Maybe instead of fixed texture units use `reserveGlobalTextureUnits` for shadows as well.
static const int numberOfShadowMaps = Settings::Manager::getBool("enable shadows", "Shadows")
? std::clamp(Settings::Manager::getInt("number of shadow maps", "Shadows"), 1, 8)
: 0;
if (getAvailableTextureUnits() >= 8 && getAvailableTextureUnits() - 1 < 8)
mReservedTextureUnits = mMaxTextureUnits - (8 - numberOfShadowMaps);
}
if (getAvailableTextureUnits() < 2)
if (getAvailableTextureUnits() < count + 1)
throw std::runtime_error("Can't reserve texture unit; no available units");
mReservedTextureUnits++;
mReservedTextureUnits += count;
unit = mMaxTextureUnits - mReservedTextureUnits;
unit.index = mMaxTextureUnits - mReservedTextureUnits;
unit.count = count;
mReservedTextureUnitsBySlot[static_cast<int>(slot)] = unit;
return unit;
return unit.index;
}
void ShaderManager::update(osgViewer::Viewer& viewer)

View file

@ -76,9 +76,11 @@ namespace Shader
{
OpaqueDepthTexture,
SkyTexture,
ShadowMaps,
SLOT_COUNT
};
int reserveGlobalTextureUnits(Slot slot);
int reserveGlobalTextureUnits(Slot slot, int count = 1);
void update(osgViewer::Viewer& viewer);
void setHotReloadEnabled(bool value);
@ -116,7 +118,8 @@ namespace Shader
int mMaxTextureUnits = 0;
int mReservedTextureUnits = 0;
std::unique_ptr<HotReloadManager> mHotReloadManager;
std::array<int, 2> mReservedTextureUnitsBySlot = { -1, -1 };
struct ReservedTextureUnits { int index = -1; int count = 0; };
std::array<ReservedTextureUnits, static_cast<int>(Slot::SLOT_COUNT) > mReservedTextureUnitsBySlot = {};
};
bool parseForeachDirective(std::string& source, const std::string& templateName, size_t foundPos);