| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224 |
- #include "BsSamplerOverrides.h"
- #include "BsRenderBeastOptions.h"
- #include "BsMaterial.h"
- #include "BsGpuParams.h"
- #include "BsGpuParamDesc.h"
- #include "BsSamplerState.h"
- #include "BsRenderStateManager.h"
- namespace BansheeEngine
- {
- MaterialSamplerOverrides* SamplerOverrideUtility::generateSamplerOverrides(const SPtr<MaterialCore>& material, const SPtr<RenderBeastOptions>& options)
- {
- UINT32 numPasses = material->getNumPasses();
- // First pass just determine if we even need to override and count the number of sampler states
- UINT32 totalNumSamplerStates = 0;
- for (UINT32 i = 0; i < numPasses; i++)
- {
- SPtr<PassParametersCore> passParams = material->getPassParameters(i);
- UINT32 maxSamplerSlot = 0;
- for (UINT32 j = 0; j < PassParametersCore::NUM_PARAMS; j++)
- {
- SPtr<GpuParamsCore> params = passParams->getParamByIdx(j);
- if (params == nullptr)
- continue;
- const GpuParamDesc& paramDesc = params->getParamDesc();
- for (auto iter = paramDesc.samplers.begin(); iter != paramDesc.samplers.end(); ++iter)
- {
- UINT32 slot = iter->second.slot;
- maxSamplerSlot = std::max(maxSamplerSlot, slot + 1);
- }
- totalNumSamplerStates += maxSamplerSlot;
- }
- }
- UINT32 outputSize = sizeof(MaterialSamplerOverrides) +
- numPasses * (sizeof(PassSamplerOverrides) + PassParametersCore::NUM_PARAMS * sizeof(StageSamplerOverrides)) +
- totalNumSamplerStates * sizeof(SPtr<SamplerStateCore>);
- UINT8* outputData = (UINT8*)bs_alloc(outputSize);
- MaterialSamplerOverrides* output = (MaterialSamplerOverrides*)outputData;
- outputData += sizeof(MaterialSamplerOverrides);
- output->refCount = 0;
- output->numPasses = numPasses;
- output->passes = (PassSamplerOverrides*)outputData;
- outputData += sizeof(PassSamplerOverrides) * numPasses;
- bs_frame_mark();
- {
- FrameUnorderedMap<SPtr<SamplerStateCore>, SPtr<SamplerStateCore>> overrideMap;
- for (UINT32 i = 0; i < numPasses; i++)
- {
- PassSamplerOverrides& passOverrides = output->passes[i];
- passOverrides.numStages = PassParametersCore::NUM_PARAMS;
- passOverrides.stages = (StageSamplerOverrides*)outputData;
- outputData += sizeof(StageSamplerOverrides) * PassParametersCore::NUM_PARAMS;
- SPtr<PassParametersCore> passParams = material->getPassParameters(i);
- for (UINT32 j = 0; j < passOverrides.numStages; j++)
- {
- StageSamplerOverrides& stageOverrides = passOverrides.stages[j];
- stageOverrides.numStates = 0;
- stageOverrides.stateOverrides = (SPtr<SamplerStateCore>*)outputData;
- SPtr<GpuParamsCore> params = passParams->getParamByIdx(j);
- if (params == nullptr)
- continue;
- const GpuParamDesc& paramDesc = params->getParamDesc();
- for (auto iter = paramDesc.samplers.begin(); iter != paramDesc.samplers.end(); ++iter)
- {
- UINT32 slot = iter->second.slot;
- while (slot >= stageOverrides.numStates)
- {
- new (&stageOverrides.stateOverrides[stageOverrides.numStates]) SPtr<SamplerStateCore>();
- stageOverrides.numStates++;
- }
- stageOverrides.numStates = std::max(stageOverrides.numStates, slot + 1);
- SPtr<SamplerStateCore> samplerState = params->getSamplerState(slot);
- if (samplerState == nullptr)
- samplerState = SamplerStateCore::getDefault();
- bool needsOverride = checkNeedsOverride(samplerState, options);
- if (needsOverride)
- {
- auto findIter = overrideMap.find(samplerState);
- if (findIter != overrideMap.end())
- {
- stageOverrides.stateOverrides[slot] = findIter->second;
- }
- else
- {
- SPtr<SamplerStateCore> newState = generateSamplerOverride(samplerState, options);
- overrideMap[samplerState] = newState;
- stageOverrides.stateOverrides[slot] = newState;
- }
- }
- else
- {
- stageOverrides.stateOverrides[slot] = samplerState;
- }
- }
- outputData += sizeof(SPtr<SamplerStateCore>) * stageOverrides.numStates;
- }
- }
- }
- bs_frame_clear();
- return output;
- }
- void SamplerOverrideUtility::destroySamplerOverrides(MaterialSamplerOverrides* overrides)
- {
- if (overrides != nullptr)
- {
- for (UINT32 i = 0; i < overrides->numPasses; i++)
- {
- PassSamplerOverrides& passOverrides = overrides->passes[i];
- for (UINT32 j = 0; j < passOverrides.numStages; j++)
- {
- StageSamplerOverrides& stageOverrides = passOverrides.stages[j];
- for (UINT32 k = 0; k < stageOverrides.numStates; k++)
- stageOverrides.stateOverrides[k].~SPtr<SamplerStateCore>();
- }
- }
- bs_free(overrides);
- }
- }
- bool SamplerOverrideUtility::checkNeedsOverride(const SPtr<SamplerStateCore>& samplerState, const SPtr<RenderBeastOptions>& options)
- {
- const SamplerProperties& props = samplerState->getProperties();
- switch (options->filtering)
- {
- case RenderBeastFiltering::Bilinear:
- {
- if (props.getTextureFiltering(FT_MIN) != FO_LINEAR)
- return true;
- if (props.getTextureFiltering(FT_MAG) != FO_LINEAR)
- return true;
- if (props.getTextureFiltering(FT_MIP) != FO_POINT)
- return true;
- }
- break;
- case RenderBeastFiltering::Trilinear:
- {
- if (props.getTextureFiltering(FT_MIN) != FO_LINEAR)
- return true;
- if (props.getTextureFiltering(FT_MAG) != FO_LINEAR)
- return true;
- if (props.getTextureFiltering(FT_MIP) != FO_LINEAR)
- return true;
- }
- break;
- case RenderBeastFiltering::Anisotropic:
- {
- if (props.getTextureFiltering(FT_MIN) != FO_ANISOTROPIC)
- return true;
- if (props.getTextureFiltering(FT_MAG) != FO_ANISOTROPIC)
- return true;
- if (props.getTextureFiltering(FT_MIP) != FO_ANISOTROPIC)
- return true;
- if (props.getTextureAnisotropy() != options->anisotropyMax)
- return true;
- }
- break;
- }
- return false;
- }
- SPtr<SamplerStateCore> SamplerOverrideUtility::generateSamplerOverride(const SPtr<SamplerStateCore>& samplerState, const SPtr<RenderBeastOptions>& options)
- {
- const SamplerProperties& props = samplerState->getProperties();
- SAMPLER_STATE_DESC desc = props.getDesc();
- switch (options->filtering)
- {
- case RenderBeastFiltering::Bilinear:
- desc.minFilter = FO_LINEAR;
- desc.magFilter = FO_LINEAR;
- desc.mipFilter = FO_POINT;
- break;
- case RenderBeastFiltering::Trilinear:
- desc.minFilter = FO_LINEAR;
- desc.magFilter = FO_LINEAR;
- desc.mipFilter = FO_LINEAR;
- break;
- case RenderBeastFiltering::Anisotropic:
- desc.minFilter = FO_ANISOTROPIC;
- desc.magFilter = FO_ANISOTROPIC;
- desc.mipFilter = FO_ANISOTROPIC;
- break;
- }
- desc.maxAniso = options->anisotropyMax;
- return RenderStateCoreManager::instance().createSamplerState(desc);
- }
- }
|