BsSamplerOverrides.cpp 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #include "BsSamplerOverrides.h"
  4. #include "BsRenderBeastOptions.h"
  5. #include "BsMaterial.h"
  6. #include "BsGpuParams.h"
  7. #include "BsGpuParamsSet.h"
  8. #include "BsGpuParamDesc.h"
  9. #include "BsMaterialParams.h"
  10. #include "BsSamplerState.h"
  11. #include "BsRenderStateManager.h"
  12. namespace BansheeEngine
  13. {
  14. MaterialSamplerOverrides* SamplerOverrideUtility::generateSamplerOverrides(const SPtr<ShaderCore>& shader,
  15. const SPtr<MaterialParamsCore>& params, const SPtr<GpuParamsSetCore>& paramsSet,
  16. const SPtr<RenderBeastOptions>& options)
  17. {
  18. MaterialSamplerOverrides* output = nullptr;
  19. if (shader == nullptr)
  20. return nullptr;
  21. bs_frame_mark();
  22. {
  23. // Generate a list of all sampler state overrides
  24. FrameUnorderedMap<String, UINT32> overrideLookup;
  25. Vector<SamplerOverride> overrides;
  26. auto& samplerParams = shader->getSamplerParams();
  27. for(auto& samplerParam : samplerParams)
  28. {
  29. UINT32 paramIdx;
  30. auto result = params->getParamIndex(samplerParam.first, MaterialParams::ParamType::Sampler, GPDT_UNKNOWN,
  31. 0, paramIdx);
  32. // Parameter shouldn't be in the valid parameter list if it cannot be found
  33. assert(result == MaterialParams::GetParamResult::Success);
  34. const MaterialParamsBase::ParamData* materialParamData = params->getParamData(paramIdx);
  35. UINT32 overrideIdx = (UINT32)overrides.size();
  36. overrides.push_back(SamplerOverride());
  37. SamplerOverride& override = overrides.back();
  38. SPtr<SamplerStateCore> samplerState;
  39. params->getSamplerState(materialParamData->index, samplerState);
  40. if (samplerState == nullptr)
  41. samplerState = SamplerStateCore::getDefault();
  42. override.paramIdx = paramIdx;
  43. override.originalStateHash = samplerState->getProperties().getHash();
  44. if (checkNeedsOverride(samplerState, options))
  45. override.state = generateSamplerOverride(samplerState, options);
  46. else
  47. override.state = samplerState;
  48. overrideLookup[samplerParam.first] = overrideIdx;
  49. }
  50. UINT32 numPasses = paramsSet->getNumPasses();
  51. // First pass just determine if we even need to override and count the number of sampler states
  52. UINT32 totalNumSamplerStates = 0;
  53. for (UINT32 i = 0; i < numPasses; i++)
  54. {
  55. UINT32 maxSamplerSlot = 0;
  56. for (UINT32 j = 0; j < GpuParamsSetCore::NUM_STAGES; j++)
  57. {
  58. SPtr<GpuParamsCore> paramsPtr = paramsSet->getParamByIdx(j, i);
  59. if (paramsPtr == nullptr)
  60. continue;
  61. SPtr<GpuParamDesc> paramDesc = paramsPtr->getParamDesc();
  62. for (auto iter = paramDesc->samplers.begin(); iter != paramDesc->samplers.end(); ++iter)
  63. {
  64. UINT32 slot = iter->second.slot;
  65. maxSamplerSlot = std::max(maxSamplerSlot, slot + 1);
  66. }
  67. totalNumSamplerStates += maxSamplerSlot;
  68. }
  69. }
  70. UINT32 outputSize = sizeof(MaterialSamplerOverrides) +
  71. numPasses * (sizeof(PassSamplerOverrides) + GpuParamsSetCore::NUM_STAGES * sizeof(StageSamplerOverrides)) +
  72. totalNumSamplerStates * sizeof(UINT32) +
  73. (UINT32)overrides.size() * sizeof(SamplerOverride);
  74. UINT8* outputData = (UINT8*)bs_alloc(outputSize);
  75. output = (MaterialSamplerOverrides*)outputData;
  76. outputData += sizeof(MaterialSamplerOverrides);
  77. output->refCount = 0;
  78. output->numPasses = numPasses;
  79. output->passes = (PassSamplerOverrides*)outputData;
  80. outputData += sizeof(PassSamplerOverrides) * numPasses;
  81. for (UINT32 i = 0; i < numPasses; i++)
  82. {
  83. PassSamplerOverrides& passOverrides = output->passes[i];
  84. passOverrides.numStages = GpuParamsSetCore::NUM_STAGES;
  85. passOverrides.stages = (StageSamplerOverrides*)outputData;
  86. outputData += sizeof(StageSamplerOverrides) * GpuParamsSetCore::NUM_STAGES;
  87. for (UINT32 j = 0; j < passOverrides.numStages; j++)
  88. {
  89. StageSamplerOverrides& stageOverrides = passOverrides.stages[j];
  90. stageOverrides.numStates = 0;
  91. stageOverrides.stateOverrides = (UINT32*)outputData;
  92. SPtr<GpuParamsCore> paramsPtr = paramsSet->getParamByIdx(j, i);
  93. if (paramsPtr == nullptr)
  94. continue;
  95. SPtr<GpuParamDesc> paramDesc = paramsPtr->getParamDesc();
  96. for (auto iter = paramDesc->samplers.begin(); iter != paramDesc->samplers.end(); ++iter)
  97. {
  98. UINT32 slot = iter->second.slot;
  99. while (slot > stageOverrides.numStates)
  100. {
  101. stageOverrides.stateOverrides[stageOverrides.numStates] = (UINT32)-1;
  102. stageOverrides.numStates++;
  103. }
  104. stageOverrides.numStates = std::max(stageOverrides.numStates, slot + 1);
  105. auto iterFind = overrideLookup.find(iter->first);
  106. if (iterFind != overrideLookup.end())
  107. stageOverrides.stateOverrides[slot] = iterFind->second;
  108. else
  109. stageOverrides.stateOverrides[slot] = (UINT32)-1;
  110. }
  111. outputData += sizeof(UINT32) * stageOverrides.numStates;
  112. }
  113. }
  114. output->numOverrides = (UINT32)overrides.size();
  115. output->overrides = (SamplerOverride*)outputData;
  116. for(UINT32 i = 0; i < output->numOverrides; i++)
  117. {
  118. new (&output->overrides[i].state) SPtr<SamplerStateCore>();
  119. output->overrides[i] = overrides[i];
  120. }
  121. }
  122. bs_frame_clear();
  123. return output;
  124. }
  125. void SamplerOverrideUtility::destroySamplerOverrides(MaterialSamplerOverrides* overrides)
  126. {
  127. if (overrides != nullptr)
  128. {
  129. for (UINT32 i = 0; i < overrides->numOverrides; i++)
  130. overrides->overrides[i].state.~SPtr<SamplerStateCore>();
  131. bs_free(overrides);
  132. overrides = nullptr;
  133. }
  134. }
  135. bool SamplerOverrideUtility::checkNeedsOverride(const SPtr<SamplerStateCore>& samplerState, const SPtr<RenderBeastOptions>& options)
  136. {
  137. const SamplerProperties& props = samplerState->getProperties();
  138. switch (options->filtering)
  139. {
  140. case RenderBeastFiltering::Bilinear:
  141. {
  142. if (props.getTextureFiltering(FT_MIN) != FO_LINEAR)
  143. return true;
  144. if (props.getTextureFiltering(FT_MAG) != FO_LINEAR)
  145. return true;
  146. if (props.getTextureFiltering(FT_MIP) != FO_POINT)
  147. return true;
  148. }
  149. break;
  150. case RenderBeastFiltering::Trilinear:
  151. {
  152. if (props.getTextureFiltering(FT_MIN) != FO_LINEAR)
  153. return true;
  154. if (props.getTextureFiltering(FT_MAG) != FO_LINEAR)
  155. return true;
  156. if (props.getTextureFiltering(FT_MIP) != FO_LINEAR)
  157. return true;
  158. }
  159. break;
  160. case RenderBeastFiltering::Anisotropic:
  161. {
  162. if (props.getTextureFiltering(FT_MIN) != FO_ANISOTROPIC)
  163. return true;
  164. if (props.getTextureFiltering(FT_MAG) != FO_ANISOTROPIC)
  165. return true;
  166. if (props.getTextureFiltering(FT_MIP) != FO_ANISOTROPIC)
  167. return true;
  168. if (props.getTextureAnisotropy() != options->anisotropyMax)
  169. return true;
  170. }
  171. break;
  172. }
  173. return false;
  174. }
  175. SPtr<SamplerStateCore> SamplerOverrideUtility::generateSamplerOverride(const SPtr<SamplerStateCore>& samplerState, const SPtr<RenderBeastOptions>& options)
  176. {
  177. const SamplerProperties& props = samplerState->getProperties();
  178. SAMPLER_STATE_DESC desc = props.getDesc();
  179. switch (options->filtering)
  180. {
  181. case RenderBeastFiltering::Bilinear:
  182. desc.minFilter = FO_LINEAR;
  183. desc.magFilter = FO_LINEAR;
  184. desc.mipFilter = FO_POINT;
  185. break;
  186. case RenderBeastFiltering::Trilinear:
  187. desc.minFilter = FO_LINEAR;
  188. desc.magFilter = FO_LINEAR;
  189. desc.mipFilter = FO_LINEAR;
  190. break;
  191. case RenderBeastFiltering::Anisotropic:
  192. desc.minFilter = FO_ANISOTROPIC;
  193. desc.magFilter = FO_ANISOTROPIC;
  194. desc.mipFilter = FO_ANISOTROPIC;
  195. break;
  196. }
  197. desc.maxAniso = options->anisotropyMax;
  198. return RenderStateCoreManager::instance().createSamplerState(desc);
  199. }
  200. }