BsSamplerOverrides.cpp 6.9 KB

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