Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

251 lines
7.3 KiB

  1. /*============================================================================
  2. *
  3. * Copyright (C) 1999 Microsoft Corporation. All Rights Reserved.
  4. *
  5. * File: pshader.cpp
  6. * Content: pixel shader runtime object init, including basic parsing
  7. * of pixel shader instructions
  8. *
  9. ****************************************************************************/
  10. #include "pch.cpp"
  11. #pragma hdrstop
  12. #include "fe.h"
  13. #include "ddibase.h"
  14. #include "vvm.h"
  15. //-----------------------------------------------------------------------------
  16. #undef DPF_MODNAME
  17. #define DPF_MODNAME "CreatePixelShader"
  18. HRESULT
  19. CPShader::Initialize(CONST DWORD* pCode, D3DDEVTYPE DevType)
  20. {
  21. // get shader code sizes
  22. DWORD dwCodeAndCommentSize;
  23. DWORD dwCodeOnlySize;
  24. HRESULT hr = ComputeShaderCodeSize(pCode, &dwCodeOnlySize, &dwCodeAndCommentSize,
  25. &m_dwNumConstDefs);
  26. if (hr != S_OK)
  27. return hr;
  28. // copy original code
  29. m_dwCodeSizeOrig = dwCodeAndCommentSize;
  30. m_pCodeOrig = new DWORD[m_dwCodeSizeOrig >> 2];
  31. if (NULL == m_pCodeOrig)
  32. {
  33. D3D_ERR("Cannot allocate memory for shader");
  34. return E_OUTOFMEMORY;
  35. }
  36. memcpy( m_pCodeOrig, pCode, m_dwCodeSizeOrig );
  37. if( m_dwNumConstDefs )
  38. {
  39. m_pConstDefs = new CONST_DEF[m_dwNumConstDefs];
  40. if (NULL == m_pConstDefs)
  41. {
  42. D3D_ERR("Cannot allocate memory for shader");
  43. return E_OUTOFMEMORY;
  44. }
  45. }
  46. // strip comments before sending on if (not CHECKED) or HAL.
  47. // Also, store def declarations in CPShader, and strip them.
  48. BOOL bIsCheckedBuild =
  49. #if DBG
  50. TRUE;
  51. #else
  52. FALSE;
  53. #endif
  54. BOOL bStripComments = (!bIsCheckedBuild) || (DevType == D3DDEVTYPE_HAL);
  55. if ( bStripComments )
  56. {
  57. // strip comments from version to pass on to DDI
  58. m_dwCodeSize = dwCodeOnlySize;
  59. }
  60. else
  61. {
  62. // pass comments through
  63. m_dwCodeSize = m_dwCodeSizeOrig;
  64. }
  65. m_pCode = new DWORD[m_dwCodeSize >> 2];
  66. if (NULL == m_pCode)
  67. {
  68. D3D_ERR("Cannot allocate memory for shader");
  69. return E_OUTOFMEMORY;
  70. }
  71. DWORD* pDst = m_pCode;
  72. CONST DWORD* pSrc = pCode;
  73. DWORD dwCurrConstDef = 0;
  74. *pDst++ = *pSrc++; // copy version
  75. while (*pSrc != 0x0000FFFF)
  76. {
  77. if(IsInstructionToken(*pSrc))
  78. {
  79. DWORD opCode = (*pSrc) & D3DSI_OPCODE_MASK;
  80. if (opCode == D3DSIO_COMMENT )
  81. {
  82. UINT DWordSize = ((*pSrc)&D3DSI_COMMENTSIZE_MASK)>>D3DSI_COMMENTSIZE_SHIFT;
  83. // strip comments from version to pass on to DDI
  84. if( !bStripComments )
  85. {
  86. memcpy( pDst, pSrc, (DWordSize + 1)*sizeof(DWORD) );
  87. pDst += (DWordSize+1);
  88. }
  89. pSrc += (DWordSize+1); // comment + instruction token
  90. }
  91. else if (opCode == D3DSIO_DEF)
  92. {
  93. *pDst++ = *pSrc++;
  94. DXGASSERT(m_pConstDefs && dwCurrConstDef < m_dwNumConstDefs);
  95. // Store reg. number
  96. m_pConstDefs[dwCurrConstDef].RegNum = (*pSrc & D3DSP_REGNUM_MASK);
  97. *pDst++ = *pSrc++;
  98. // Store the const vector
  99. memcpy( m_pConstDefs[dwCurrConstDef].f,pSrc,4*sizeof(DWORD) );
  100. memcpy( pDst,pSrc,4*sizeof(DWORD) );
  101. pSrc += 4;
  102. pDst += 4;
  103. dwCurrConstDef++;
  104. }
  105. else
  106. {
  107. *pDst++ = *pSrc++;
  108. }
  109. }
  110. else
  111. {
  112. *pDst++ = *pSrc++;
  113. }
  114. }
  115. *pDst++ = *pSrc++; // copy END
  116. DXGASSERT(dwCurrConstDef == m_dwNumConstDefs);
  117. return S_OK;
  118. }
  119. //-----------------------------------------------------------------------------
  120. #undef DPF_MODNAME
  121. #define DPF_MODNAME "CD3DHal::GetPixelShaderConstant"
  122. HRESULT D3DAPI
  123. CD3DHal::GetPixelShaderConstant(DWORD dwRegisterAddress,
  124. LPVOID lpvConstantData,
  125. DWORD dwConstantCount)
  126. {
  127. API_ENTER(this);
  128. #if DBG
  129. // Validate Parameters
  130. if (!VALID_WRITEPTR(lpvConstantData, 4*sizeof(D3DVALUE)*dwConstantCount))
  131. {
  132. D3D_ERR("Invalid constant data pointer. GetPixelShaderConstant failed.");
  133. return D3DERR_INVALIDCALL;
  134. }
  135. #endif
  136. GetPixelShaderConstantI( dwRegisterAddress, dwConstantCount,
  137. lpvConstantData );
  138. return S_OK;
  139. }
  140. //-----------------------------------------------------------------------------
  141. #undef DPF_MODNAME
  142. #define DPF_MODNAME "CD3DHal::SetPixelShaderFast"
  143. HRESULT D3DAPI
  144. CD3DHal::SetPixelShaderFast(DWORD dwHandle)
  145. {
  146. try
  147. {
  148. #if DBG
  149. CheckPixelShaderHandle(dwHandle);
  150. #endif
  151. // Update constants (if any were defined in the shader code)
  152. if( dwHandle )
  153. {
  154. CPShader* pShader = (CPShader*)m_pPShaderArray->GetObject(dwHandle);
  155. for(UINT i = 0; i < pShader->m_dwNumConstDefs; i++ )
  156. {
  157. CONST_DEF* pConstDef = &pShader->m_pConstDefs[i];
  158. memcpy(&(m_PShaderConstReg[pConstDef->RegNum]), pConstDef->f, 4*sizeof(D3DVALUE));
  159. }
  160. }
  161. // No redundant handle check because shader may have embedded constant definitions which
  162. // must always be applied.
  163. if (!(m_dwRuntimeFlags & D3DRT_EXECUTESTATEMODE))
  164. m_pDDI->SetPixelShader(dwHandle);
  165. m_dwCurrentPixelShaderHandle = dwHandle;
  166. }
  167. catch(HRESULT hr)
  168. {
  169. D3D_ERR("SetPixelShader failed.");
  170. m_dwCurrentPixelShaderHandle = 0;
  171. return hr;
  172. }
  173. return S_OK;
  174. }
  175. //-----------------------------------------------------------------------------
  176. #undef DPF_MODNAME
  177. #define DPF_MODNAME "CD3DHal::SetPixelShaderConstantFast"
  178. HRESULT D3DAPI
  179. CD3DHal::SetPixelShaderConstantFast(DWORD Register, CONST VOID* pData,
  180. DWORD count)
  181. {
  182. #if DBG
  183. // Validate Parameters
  184. if (!VALID_PTR(pData, sizeof(DWORD) * count))
  185. {
  186. D3D_ERR("Invalid constant data pointer. SetPixelShader failed.");
  187. return D3DERR_INVALIDCALL;
  188. }
  189. if(Register >= D3DPS_CONSTREG_MAX_DX8)
  190. {
  191. D3D_ERR("Invalid Constant Register number. SetPixelShader failed.");
  192. return D3DERR_INVALIDCALL;
  193. }
  194. if( (Register + count) > D3DPS_CONSTREG_MAX_DX8 )
  195. {
  196. D3D_ERR("Not that many constant registers in the pixel machine. SetPixelShader failed.");
  197. return D3DERR_INVALIDCALL;
  198. }
  199. #endif
  200. // Cache the constants in the CPShader structure.
  201. memcpy(&(m_PShaderConstReg[Register]), pData, count*4*sizeof(D3DVALUE));
  202. if (!(m_dwRuntimeFlags & D3DRT_EXECUTESTATEMODE))
  203. {
  204. try
  205. {
  206. m_pDDI->SetPixelShaderConstant(Register, pData, count);
  207. }
  208. catch(HRESULT hr)
  209. {
  210. D3D_ERR("SetPixelShaderConstant failed.");
  211. return hr;
  212. }
  213. }
  214. return S_OK;
  215. }
  216. //-----------------------------------------------------------------------------
  217. #undef DPF_MODNAME
  218. #define DPF_MODNAME "CD3DHal::GetPixelShaderConstantI"
  219. void
  220. CD3DHal::GetPixelShaderConstantI(DWORD Register, DWORD count, LPVOID pData )
  221. {
  222. // Cache the constants in the CPShader structure.
  223. memcpy( pData, &(m_PShaderConstReg[Register]), count*4*sizeof(D3DVALUE) );
  224. }
  225. //-----------------------------------------------------------------------------
  226. // end