CmD3D11HLSLProgram.cpp 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. #include "CmD3D11HLSLProgram.h"
  2. #include "CmD3D11HLSLProgramRTTI.h"
  3. #include "CmRenderSystem.h"
  4. #include "CmGpuProgramManager.h"
  5. #include "CmD3D11GpuProgram.h"
  6. #include "CmHardwareBufferManager.h"
  7. #include "CmD3D11RenderSystem.h"
  8. #include "CmD3D11HLSLParamParser.h"
  9. #include "CmD3D11Mappings.h"
  10. #include "CmGpuParams.h"
  11. #include "CmException.h"
  12. #include "CmDebug.h"
  13. namespace CamelotEngine
  14. {
  15. UINT32 D3D11HLSLProgram::globalProgramId = 0;
  16. D3D11HLSLProgram::D3D11HLSLProgram(const String& source, const String& entryPoint, const String& language,
  17. GpuProgramType gptype, GpuProgramProfile profile, bool isAdjacencyInfoRequired)
  18. : HighLevelGpuProgram(source, entryPoint, language, gptype, profile, isAdjacencyInfoRequired),
  19. mColumnMajorMatrices(true), mEnableBackwardsCompatibility(false), mProgramId(0)
  20. {
  21. }
  22. D3D11HLSLProgram::~D3D11HLSLProgram()
  23. {
  24. unload_internal();
  25. }
  26. void D3D11HLSLProgram::loadFromSource()
  27. {
  28. String hlslProfile = GpuProgramManager::instance().gpuProgProfileToRSSpecificProfile(mProfile);
  29. ID3DBlob* microcode = compileMicrocode(hlslProfile);
  30. mMicrocode.resize(microcode->GetBufferSize());
  31. memcpy(&mMicrocode[0], microcode->GetBufferPointer(), microcode->GetBufferSize());
  32. populateParametersAndConstants(microcode);
  33. mAssemblerProgram = GpuProgramManager::instance().createProgram("", "", hlslProfile, mType, GPP_NONE); // We load it from microcode, so none of this matters
  34. D3D11RenderSystem* rs = static_cast<D3D11RenderSystem*>(RenderSystem::instancePtr());
  35. switch(mType)
  36. {
  37. case GPT_VERTEX_PROGRAM:
  38. {
  39. D3D11GpuVertexProgramPtr vertProgram = std::static_pointer_cast<D3D11GpuVertexProgram>(mAssemblerProgram);
  40. vertProgram->loadFromMicrocode(rs->getPrimaryDevice(), microcode);
  41. }
  42. break;
  43. case GPT_FRAGMENT_PROGRAM:
  44. {
  45. D3D11GpuFragmentProgramPtr fragProgram = std::static_pointer_cast<D3D11GpuFragmentProgram>(mAssemblerProgram);
  46. fragProgram->loadFromMicrocode(rs->getPrimaryDevice(), microcode);
  47. }
  48. break;
  49. case GPT_GEOMETRY_PROGRAM:
  50. {
  51. D3D11GpuGeometryProgramPtr geomProgram = std::static_pointer_cast<D3D11GpuGeometryProgram>(mAssemblerProgram);
  52. geomProgram->loadFromMicrocode(rs->getPrimaryDevice(), microcode);
  53. }
  54. break;
  55. case GPT_HULL_PROGRAM:
  56. {
  57. D3D11GpuHullProgramPtr hullProgram = std::static_pointer_cast<D3D11GpuHullProgram>(mAssemblerProgram);
  58. hullProgram->loadFromMicrocode(rs->getPrimaryDevice(), microcode);
  59. }
  60. break;
  61. case GPT_DOMAIN_PROGRAM:
  62. {
  63. D3D11GpuDomainProgramPtr domainProgram = std::static_pointer_cast<D3D11GpuDomainProgram>(mAssemblerProgram);
  64. domainProgram->loadFromMicrocode(rs->getPrimaryDevice(), microcode);
  65. }
  66. break;
  67. }
  68. mProgramId = globalProgramId++;
  69. SAFE_RELEASE(microcode);
  70. }
  71. void D3D11HLSLProgram::unload_internal()
  72. {
  73. mAssemblerProgram = nullptr;
  74. mMicrocode.clear();
  75. }
  76. const String& D3D11HLSLProgram::getLanguage() const
  77. {
  78. static String name = "hlsl";
  79. return name;
  80. }
  81. bool D3D11HLSLProgram::isSupported() const
  82. {
  83. RenderSystem* rs = RenderSystem::instancePtr();
  84. return rs->getCapabilities()->isShaderProfileSupported(getSyntaxCode()) && HighLevelGpuProgram::isSupported();
  85. }
  86. ID3DBlob* D3D11HLSLProgram::compileMicrocode(const String& profile)
  87. {
  88. // TODO - Preprocessor defines aren't supported
  89. UINT compileFlags = 0;
  90. #if defined(CM_DEBUG_MODE)
  91. compileFlags |= D3DCOMPILE_DEBUG;
  92. compileFlags |= D3DCOMPILE_SKIP_OPTIMIZATION;
  93. #endif
  94. if (mColumnMajorMatrices)
  95. compileFlags |= D3DCOMPILE_PACK_MATRIX_COLUMN_MAJOR;
  96. else
  97. compileFlags |= D3DCOMPILE_PACK_MATRIX_ROW_MAJOR;
  98. if (mEnableBackwardsCompatibility)
  99. compileFlags |= D3DCOMPILE_ENABLE_BACKWARDS_COMPATIBILITY;
  100. ID3DBlob* microCode = nullptr;
  101. ID3DBlob* errors = nullptr;
  102. HRESULT hr = D3DCompile(
  103. mSource.c_str(), // [in] Pointer to the shader in memory.
  104. mSource.size(), // [in] Size of the shader in memory.
  105. nullptr, // [in] The name of the file that contains the shader code.
  106. nullptr, // [in] Optional. Pointer to a NULL-terminated array of macro definitions. See D3D_SHADER_MACRO. If not used, set this to NULL.
  107. nullptr, // [in] Optional. Pointer to an ID3DInclude Interface interface for handling include files. Setting this to NULL will cause a compile error if a shader contains a #include.
  108. mEntryPoint.c_str(),// [in] Name of the shader-entrypoint function where shader execution begins.
  109. profile.c_str(),// [in] A string that specifies the shader model; can be any profile in shader model 4 or higher.
  110. compileFlags, // [in] Effect compile flags - no D3DCOMPILE_ENABLE_BACKWARDS_COMPATIBILITY at the first try...
  111. 0, // [in] Effect compile flags
  112. &microCode, // [out] A pointer to an ID3DBlob Interface which contains the compiled shader, as well as any embedded debug and symbol-table information.
  113. &errors // [out] A pointer to an ID3DBlob Interface which contains a listing of errors and warnings that occurred during compilation. These errors and warnings are identical to the the debug output from a debugger.
  114. );
  115. if (FAILED(hr))
  116. {
  117. String message = "Cannot assemble D3D11 high-level shader. Errors:\n" +
  118. String(static_cast<const char*>(errors->GetBufferPointer()));
  119. SAFE_RELEASE(errors);
  120. CM_EXCEPT(RenderingAPIException, message);
  121. }
  122. SAFE_RELEASE(errors);
  123. return microCode;
  124. }
  125. void D3D11HLSLProgram::populateParametersAndConstants(ID3DBlob* microcode)
  126. {
  127. assert(microcode != nullptr);
  128. D3D11HLSLParamParser parser;
  129. if(mType == GPT_VERTEX_PROGRAM)
  130. mInputDeclaration = HardwareBufferManager::instance().createVertexDeclaration();
  131. parser.parse(microcode, mParametersDesc, mInputDeclaration);
  132. }
  133. GpuParamsPtr D3D11HLSLProgram::createParameters()
  134. {
  135. GpuParamsPtr params(new GpuParams(mParametersDesc));
  136. params->setTransposeMatrices(mColumnMajorMatrices);
  137. return params;
  138. }
  139. /************************************************************************/
  140. /* SERIALIZATION */
  141. /************************************************************************/
  142. RTTITypeBase* D3D11HLSLProgram::getRTTIStatic()
  143. {
  144. return D3D11HLSLProgramRTTI::instance();
  145. }
  146. RTTITypeBase* D3D11HLSLProgram::getRTTI() const
  147. {
  148. return D3D11HLSLProgram::getRTTIStatic();
  149. }
  150. }