2
0

BsSamplerOverrides.cpp 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  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 "BsSamplerState.h"
  10. #include "BsRenderStateManager.h"
  11. namespace BansheeEngine
  12. {
  13. MaterialSamplerOverrides* SamplerOverrideUtility::generateSamplerOverrides(const SPtr<GpuParamsSetCore>& paramsSet, const SPtr<RenderBeastOptions>& options)
  14. {
  15. UINT32 numPasses = paramsSet->getNumPasses();
  16. // First pass just determine if we even need to override and count the number of sampler states
  17. UINT32 totalNumSamplerStates = 0;
  18. for (UINT32 i = 0; i < numPasses; i++)
  19. {
  20. UINT32 maxSamplerSlot = 0;
  21. for (UINT32 j = 0; j < GpuParamsSetCore::NUM_STAGES; j++)
  22. {
  23. SPtr<GpuParamsCore> params = paramsSet->getParamByIdx(j, i);
  24. if (params == nullptr)
  25. continue;
  26. const GpuParamDesc& paramDesc = params->getParamDesc();
  27. for (auto iter = paramDesc.samplers.begin(); iter != paramDesc.samplers.end(); ++iter)
  28. {
  29. UINT32 slot = iter->second.slot;
  30. maxSamplerSlot = std::max(maxSamplerSlot, slot + 1);
  31. }
  32. totalNumSamplerStates += maxSamplerSlot;
  33. }
  34. }
  35. UINT32 outputSize = sizeof(MaterialSamplerOverrides) +
  36. numPasses * (sizeof(PassSamplerOverrides) + GpuParamsSetCore::NUM_STAGES * sizeof(StageSamplerOverrides)) +
  37. totalNumSamplerStates * sizeof(SPtr<SamplerStateCore>);
  38. UINT8* outputData = (UINT8*)bs_alloc(outputSize);
  39. MaterialSamplerOverrides* output = (MaterialSamplerOverrides*)outputData;
  40. outputData += sizeof(MaterialSamplerOverrides);
  41. output->refCount = 0;
  42. output->numPasses = numPasses;
  43. output->passes = (PassSamplerOverrides*)outputData;
  44. outputData += sizeof(PassSamplerOverrides) * numPasses;
  45. bs_frame_mark();
  46. {
  47. FrameUnorderedMap<SPtr<SamplerStateCore>, SPtr<SamplerStateCore>> overrideMap;
  48. for (UINT32 i = 0; i < numPasses; i++)
  49. {
  50. PassSamplerOverrides& passOverrides = output->passes[i];
  51. passOverrides.numStages = GpuParamsSetCore::NUM_STAGES;
  52. passOverrides.stages = (StageSamplerOverrides*)outputData;
  53. outputData += sizeof(StageSamplerOverrides) * GpuParamsSetCore::NUM_STAGES;
  54. for (UINT32 j = 0; j < passOverrides.numStages; j++)
  55. {
  56. StageSamplerOverrides& stageOverrides = passOverrides.stages[j];
  57. stageOverrides.numStates = 0;
  58. stageOverrides.stateOverrides = (SPtr<SamplerStateCore>*)outputData;
  59. SPtr<GpuParamsCore> params = paramsSet->getParamByIdx(j, i);
  60. if (params == nullptr)
  61. continue;
  62. const GpuParamDesc& paramDesc = params->getParamDesc();
  63. for (auto iter = paramDesc.samplers.begin(); iter != paramDesc.samplers.end(); ++iter)
  64. {
  65. UINT32 slot = iter->second.slot;
  66. while (slot >= stageOverrides.numStates)
  67. {
  68. new (&stageOverrides.stateOverrides[stageOverrides.numStates]) SPtr<SamplerStateCore>();
  69. stageOverrides.numStates++;
  70. }
  71. stageOverrides.numStates = std::max(stageOverrides.numStates, slot + 1);
  72. SPtr<SamplerStateCore> samplerState = params->getSamplerState(slot);
  73. if (samplerState == nullptr)
  74. samplerState = SamplerStateCore::getDefault();
  75. bool needsOverride = checkNeedsOverride(samplerState, options);
  76. if (needsOverride)
  77. {
  78. auto findIter = overrideMap.find(samplerState);
  79. if (findIter != overrideMap.end())
  80. {
  81. stageOverrides.stateOverrides[slot] = findIter->second;
  82. }
  83. else
  84. {
  85. SPtr<SamplerStateCore> newState = generateSamplerOverride(samplerState, options);
  86. overrideMap[samplerState] = newState;
  87. stageOverrides.stateOverrides[slot] = newState;
  88. }
  89. }
  90. else
  91. {
  92. stageOverrides.stateOverrides[slot] = samplerState;
  93. }
  94. }
  95. outputData += sizeof(SPtr<SamplerStateCore>) * stageOverrides.numStates;
  96. }
  97. }
  98. }
  99. bs_frame_clear();
  100. return output;
  101. }
  102. void SamplerOverrideUtility::destroySamplerOverrides(MaterialSamplerOverrides* overrides)
  103. {
  104. if (overrides != nullptr)
  105. {
  106. for (UINT32 i = 0; i < overrides->numPasses; i++)
  107. {
  108. PassSamplerOverrides& passOverrides = overrides->passes[i];
  109. for (UINT32 j = 0; j < passOverrides.numStages; j++)
  110. {
  111. StageSamplerOverrides& stageOverrides = passOverrides.stages[j];
  112. for (UINT32 k = 0; k < stageOverrides.numStates; k++)
  113. stageOverrides.stateOverrides[k].~SPtr<SamplerStateCore>();
  114. }
  115. }
  116. bs_free(overrides);
  117. }
  118. }
  119. bool SamplerOverrideUtility::checkNeedsOverride(const SPtr<SamplerStateCore>& samplerState, const SPtr<RenderBeastOptions>& options)
  120. {
  121. const SamplerProperties& props = samplerState->getProperties();
  122. switch (options->filtering)
  123. {
  124. case RenderBeastFiltering::Bilinear:
  125. {
  126. if (props.getTextureFiltering(FT_MIN) != FO_LINEAR)
  127. return true;
  128. if (props.getTextureFiltering(FT_MAG) != FO_LINEAR)
  129. return true;
  130. if (props.getTextureFiltering(FT_MIP) != FO_POINT)
  131. return true;
  132. }
  133. break;
  134. case RenderBeastFiltering::Trilinear:
  135. {
  136. if (props.getTextureFiltering(FT_MIN) != FO_LINEAR)
  137. return true;
  138. if (props.getTextureFiltering(FT_MAG) != FO_LINEAR)
  139. return true;
  140. if (props.getTextureFiltering(FT_MIP) != FO_LINEAR)
  141. return true;
  142. }
  143. break;
  144. case RenderBeastFiltering::Anisotropic:
  145. {
  146. if (props.getTextureFiltering(FT_MIN) != FO_ANISOTROPIC)
  147. return true;
  148. if (props.getTextureFiltering(FT_MAG) != FO_ANISOTROPIC)
  149. return true;
  150. if (props.getTextureFiltering(FT_MIP) != FO_ANISOTROPIC)
  151. return true;
  152. if (props.getTextureAnisotropy() != options->anisotropyMax)
  153. return true;
  154. }
  155. break;
  156. }
  157. return false;
  158. }
  159. SPtr<SamplerStateCore> SamplerOverrideUtility::generateSamplerOverride(const SPtr<SamplerStateCore>& samplerState, const SPtr<RenderBeastOptions>& options)
  160. {
  161. const SamplerProperties& props = samplerState->getProperties();
  162. SAMPLER_STATE_DESC desc = props.getDesc();
  163. switch (options->filtering)
  164. {
  165. case RenderBeastFiltering::Bilinear:
  166. desc.minFilter = FO_LINEAR;
  167. desc.magFilter = FO_LINEAR;
  168. desc.mipFilter = FO_POINT;
  169. break;
  170. case RenderBeastFiltering::Trilinear:
  171. desc.minFilter = FO_LINEAR;
  172. desc.magFilter = FO_LINEAR;
  173. desc.mipFilter = FO_LINEAR;
  174. break;
  175. case RenderBeastFiltering::Anisotropic:
  176. desc.minFilter = FO_ANISOTROPIC;
  177. desc.magFilter = FO_ANISOTROPIC;
  178. desc.mipFilter = FO_ANISOTROPIC;
  179. break;
  180. }
  181. desc.maxAniso = options->anisotropyMax;
  182. return RenderStateCoreManager::instance().createSamplerState(desc);
  183. }
  184. }