DFORCEINLINE static void getContants(ID3D10Device *d3dDevice, const String& prefix, DUNORDERED_MAP <String, size_t>& mapVars, ID3D10Blob* pCode, ID3D10Buffer** pBuffer, size_t& size){ HRESULT hr; ID3D10ShaderReflection* pReflection = NULL; hr = D3D10ReflectShader((void*)pCode->GetBufferPointer(), pCode->GetBufferSize(), &pReflection); if (FAILED(hr)) { DEBUG_ASSERT_MSG(0, "Shader reflection could not be obtained. Reason: " << DXGetErrorDescription(hr)); return; } D3D10_SHADER_DESC desc; DX_ASSERT_MSG(pReflection->GetDesc(&desc)); //init ID3D10ShaderReflectionConstantBuffer* pConstantBuffer = NULL; size_t valueOffset = 0; size = 0; //calc size for (uint i = 0; i < desc.ConstantBuffers; ++i) { pConstantBuffer = pReflection->GetConstantBufferByIndex(i); uint count = 0; D3D10_SHADER_BUFFER_DESC bufferDesc; DX_ASSERT_MSG(pConstantBuffer->GetDesc(&bufferDesc)); if (bufferDesc.Type == D3D10_CT_TBUFFER) continue; count = bufferDesc.Variables; ID3D10ShaderReflectionVariable* pConstant = NULL; D3D10_SHADER_VARIABLE_DESC constantDesc; for (uint j = 0; j < count; ++j) { pConstant = pConstantBuffer->GetVariableByIndex(j); pConstant->GetDesc(&constantDesc); mapVars[prefix + '.' + constantDesc.Name] = valueOffset; valueOffset += constantDesc.Size; } } //save size buffer size = Math::multipleOfX(valueOffset, 16); // if (valueOffset) { (*pBuffer) = genBufferObject(d3dDevice, size); } }
dx10ConstantBuffer::dx10ConstantBuffer(ID3D10ShaderReflectionConstantBuffer* pTable) : m_bChanged(true) { D3D10_SHADER_BUFFER_DESC Desc; CHK_DX(pTable->GetDesc(&Desc)); m_strBufferName._set(Desc.Name); m_eBufferType = Desc.Type; m_uiBufferSize = Desc.Size; // Fill member list with variable descriptions m_MembersList.resize(Desc.Variables); m_MembersNames.resize(Desc.Variables); for (u32 i=0; i<Desc.Variables; ++i) { ID3D10ShaderReflectionVariable* pVar; ID3D10ShaderReflectionType* pType; D3D10_SHADER_VARIABLE_DESC var_desc; pVar = pTable->GetVariableByIndex(i); VERIFY(pVar); pType = pVar->GetType(); VERIFY(pType); pType->GetDesc(&m_MembersList[i]); // Buffers with the same layout can contain totally different members CHK_DX(pVar->GetDesc(&var_desc)); m_MembersNames[i] = var_desc.Name; } m_uiMembersCRC = crc32( &m_MembersList[0], Desc.Variables*sizeof(m_MembersList[0])); R_CHK(dx10BufferUtils::CreateConstantBuffer(&m_pBuffer, Desc.Size)); VERIFY(m_pBuffer); m_pBufferData = xr_malloc(Desc.Size); VERIFY(m_pBufferData); }
void ShaderBase::InitUniforms(ID3D10Blob* s) { ID3D10ShaderReflection* ref = NULL; D3D10ReflectShader(s->GetBufferPointer(), s->GetBufferSize(), &ref); ID3D10ShaderReflectionConstantBuffer* buf = ref->GetConstantBufferByIndex(0); D3D10_SHADER_BUFFER_DESC bufd; if (FAILED(buf->GetDesc(&bufd))) { UniformsSize = 0; if (UniformData) { OVR_FREE(UniformData); UniformData = 0; } return; } for(unsigned i = 0; i < bufd.Variables; i++) { ID3D10ShaderReflectionVariable* var = buf->GetVariableByIndex(i); if (var) { D3D10_SHADER_VARIABLE_DESC vd; if (SUCCEEDED(var->GetDesc(&vd))) { Uniform u; u.Name = vd.Name; u.Offset = vd.StartOffset; u.Size = vd.Size; UniformInfo.PushBack(u); } } } UniformsSize = bufd.Size; UniformData = (unsigned char*)OVR_ALLOC(bufd.Size); }
//----------------------------------------------------------------------- void D3D10HLSLProgram::buildConstantDefinitions() const { mFloatLogicalToPhysical.bufferSize = 0; mIntLogicalToPhysical.bufferSize = 0; mConstantDefs.floatBufferSize = 0; mConstantDefs.intBufferSize = 0; if (mShaderReflectionConstantBuffer) { // if (!FAILED(hr)) { for(unsigned int i = 0; i < mConstantBufferDesc.Variables ; i++) { ID3D10ShaderReflectionVariable* varRef; varRef = mShaderReflectionConstantBuffer->GetVariableByIndex(i); D3D10_SHADER_VARIABLE_DESC shaderVerDesc; unsigned int numParams = 1; HRESULT hr = varRef->GetDesc(&shaderVerDesc); ID3D10ShaderReflectionType* varRefType; varRefType = varRef->GetType(); // Recursively descend through the structure levels processParamElement( "", shaderVerDesc.Name, i, varRefType); } } } }
BOOL R_constant_table::parseConstants(ID3D10ShaderReflectionConstantBuffer* pTable, u16 destination) { //VERIFY(_desc); //ID3D10ShaderReflectionConstantBuffer *pTable = (ID3D10ShaderReflectionConstantBuffer *)_desc; VERIFY(pTable); D3D10_SHADER_BUFFER_DESC TableDesc; CHK_DX(pTable->GetDesc(&TableDesc)); //D3DXSHADER_CONSTANTTABLE* desc = (D3DXSHADER_CONSTANTTABLE*) _desc; //D3DXSHADER_CONSTANTINFO* it = (D3DXSHADER_CONSTANTINFO*) (LPBYTE(desc)+desc->ConstantInfo); //LPBYTE ptr = LPBYTE(desc); //for (u32 dwCount = desc->Constants; dwCount; dwCount--,it++) for (u32 i = 0; i < TableDesc.Variables; ++i) { ID3D10ShaderReflectionVariable* pVar; D3D10_SHADER_VARIABLE_DESC VarDesc; ID3D10ShaderReflectionType* pType; D3D10_SHADER_TYPE_DESC TypeDesc; pVar = pTable->GetVariableByIndex(i); VERIFY(pVar); pVar->GetDesc(&VarDesc); pType = pVar->GetType(); VERIFY(pType); pType->GetDesc(&TypeDesc); // Name //LPCSTR name = LPCSTR(ptr+it->Name); LPCSTR name = VarDesc.Name; // Type //u16 type = RC_float; u16 type = u16(-1); switch(TypeDesc.Type) { case D3D10_SVT_FLOAT: type = RC_float; break; case D3D10_SVT_BOOL: type = RC_bool; break; case D3D10_SVT_INT: type = RC_int; break; default: fatal ("R_constant_table::parse: unexpected shader variable type."); } // Rindex,Rcount //u16 r_index = it->RegisterIndex; // Used as byte offset in constant buffer VERIFY(VarDesc.StartOffset<0x10000); u16 r_index = u16(VarDesc.StartOffset); u16 r_type = u16(-1); // TypeInfo + class //D3DXSHADER_TYPEINFO* T = (D3DXSHADER_TYPEINFO*)(ptr+it->TypeInfo); BOOL bSkip = FALSE; //switch (T->Class) switch (TypeDesc.Class) { case D3D10_SVC_SCALAR: r_type = RC_1x1; break; case D3D10_SVC_VECTOR: { switch(TypeDesc.Columns) { case 4: r_type = RC_1x4; break; case 3: r_type = RC_1x3; break; case 2: r_type = RC_1x2; break; default: fatal("Vector: 1 components is scalar - there is special case for this!!!!!"); break; } } break; case D3D10_SVC_MATRIX_ROWS: { switch (TypeDesc.Columns) { case 4: switch (TypeDesc.Rows) { case 2: r_type = RC_2x4; break; case 3: r_type = RC_3x4; break; /* switch (it->RegisterCount) { case 2: r_type = RC_2x4; break; case 3: r_type = RC_3x4; break; default: fatal ("MATRIX_ROWS: unsupported number of RegisterCount"); break; } break; */ case 4: r_type = RC_4x4; //VERIFY(4 == it->RegisterCount); break; default: fatal ("MATRIX_ROWS: unsupported number of Rows"); break; } break; default: fatal ("MATRIX_ROWS: unsupported number of Columns"); break; } } break; case D3D10_SVC_MATRIX_COLUMNS: fatal ("Pclass MATRIX_COLUMNS unsupported"); break; case D3D10_SVC_STRUCT: fatal ("Pclass D3DXPC_STRUCT unsupported"); break; case D3D10_SVC_OBJECT: { // TODO: DX10: VERIFY(!"Implement shader object parsing."); /* switch (T->Type) { case D3DXPT_SAMPLER: case D3DXPT_SAMPLER1D: case D3DXPT_SAMPLER2D: case D3DXPT_SAMPLER3D: case D3DXPT_SAMPLERCUBE: { // ***Register sampler*** // We have determined all valuable info, search if constant already created ref_constant C = get (name); if (!C) { C = new R_constant();//.g_constant_allocator.create(); C->name = name; C->destination = RC_dest_sampler; C->type = RC_sampler; R_constant_load& L = C->samp; L.index = u16(r_index + ( (destination&1)? 0 : D3DVERTEXTEXTURESAMPLER0 )); L.cls = RC_sampler ; table.push_back (C); } else { R_ASSERT (C->destination == RC_dest_sampler); R_ASSERT (C->type == RC_sampler); R_constant_load& L = C->samp; R_ASSERT (L.index == r_index); R_ASSERT (L.cls == RC_sampler); } } break; default: fatal ("Pclass D3DXPC_OBJECT - object isn't of 'sampler' type"); break; } */ } bSkip = TRUE; break; default: bSkip = TRUE; break; } if (bSkip) continue; // We have determined all valuable info, search if constant already created ref_constant C = get (name); if (!C) { C = new R_constant();//.g_constant_allocator.create(); C->name = name; C->destination = destination; C->type = type; //R_constant_load& L = (destination&1)?C->ps:C->vs; R_constant_load& L = ((destination&RC_dest_pixel) ? C->ps : (destination&RC_dest_vertex) ? C->vs : C->gs); L.index = r_index; L.cls = r_type; table.push_back (C); } else { C->destination |= destination; VERIFY (C->type == type); //R_constant_load& L = (destination&1)?C->ps:C->vs; R_constant_load& L = ((destination&RC_dest_pixel) ? C->ps : (destination&RC_dest_vertex) ? C->vs : C->gs); L.index = r_index; L.cls = r_type; } } return TRUE; }
//----------------------------------------------------------------------- void D3D10HLSLProgram::loadFromSource(void) { class HLSLIncludeHandler : public ID3D10Include { public: HLSLIncludeHandler(Resource* sourceProgram) : mProgram(sourceProgram) {} ~HLSLIncludeHandler() {} STDMETHOD(Open)(D3D10_INCLUDE_TYPE IncludeType, LPCSTR pFileName, LPCVOID pParentData, LPCVOID *ppData, UINT *pByteLen ) { // find & load source code DataStreamPtr stream = ResourceGroupManager::getSingleton().openResource( String(pFileName), mProgram->getGroup(), true, mProgram); String source = stream->getAsString(); // copy into separate c-string // Note - must NOT copy the null terminator, otherwise this will terminate // the entire program string! *pByteLen = static_cast<UINT>(source.length()); char* pChar = new char[*pByteLen]; memcpy(pChar, source.c_str(), *pByteLen); *ppData = pChar; return S_OK; } STDMETHOD(Close)(LPCVOID pData) { char* pChar = (char*)pData; delete [] pChar; return S_OK; } protected: Resource* mProgram; }; // include handler HLSLIncludeHandler includeHandler(this); ID3D10Blob * errors = 0; /*String profile; // Instruction set to be used when generating code. Possible values: "vs_4_0", "ps_4_0", or "gs_4_0". switch(mType) { case GPT_VERTEX_PROGRAM: profile = "vs_4_0"; break; case GPT_FRAGMENT_PROGRAM: profile = "ps_4_0"; break; }*/ HRESULT hr = D3DX10CompileFromMemory( mSource.c_str(), // [in] Pointer to the shader in memory. mSource.size(), // [in] Size of the shader in memory. NULL, // [in] The name of the file that contains the shader code. NULL, // [in] Optional. Pointer to a NULL-terminated array of macro definitions. See D3D10_SHADER_MACRO. If not used, set this to NULL. &includeHandler, // [in] Optional. Pointer to an ID3D10Include Interface interface for handling include files. Setting this to NULL will cause a compile error if a shader contains a #include. mEntryPoint.c_str(), // [in] Name of the shader-entrypoint function where shader execution begins. mTarget.c_str(), // [in] A string that specifies the shader model; can be any profile in shader model 2, shader model 3, or shader model 4. 0, // [in] Effect compile flags - no D3D10_SHADER_ENABLE_BACKWARDS_COMPATIBILITY at the first try... NULL, // [in] Effect compile flags NULL, // [in] A pointer to a thread pump interface (see ID3DX10ThreadPump Interface). Use NULL to specify that this function should not return until it is completed. &mpMicroCode, // [out] A pointer to an ID3D10Blob Interface which contains the compiled shader, as well as any embedded debug and symbol-table information. &errors, // [out] A pointer to an ID3D10Blob Interface which contains a listing of errors and warnings that occured during compilation. These errors and warnings are identical to the the debug output from a debugger. NULL // [out] A pointer to the return value. May be NULL. If pPump is not NULL, then pHResult must be a valid memory location until the asynchronous execution completes. ); if (FAILED(hr)) // if fails - try with backwards compatibility flag { hr = D3DX10CompileFromMemory( mSource.c_str(), // [in] Pointer to the shader in memory. mSource.size(), // [in] Size of the shader in memory. NULL, // [in] The name of the file that contains the shader code. NULL, // [in] Optional. Pointer to a NULL-terminated array of macro definitions. See D3D10_SHADER_MACRO. If not used, set this to NULL. &includeHandler, // [in] Optional. Pointer to an ID3D10Include Interface interface for handling include files. Setting this to NULL will cause a compile error if a shader contains a #include. mEntryPoint.c_str(), // [in] Name of the shader-entrypoint function where shader execution begins. mTarget.c_str(), // [in] A string that specifies the shader model; can be any profile in shader model 2, shader model 3, or shader model 4. D3D10_SHADER_ENABLE_BACKWARDS_COMPATIBILITY, // [in] Effect compile flags - D3D10_SHADER_ENABLE_BACKWARDS_COMPATIBILITY enables older shaders to compile to 4_0 targets NULL, // [in] Effect compile flags NULL, // [in] A pointer to a thread pump interface (see ID3DX10ThreadPump Interface). Use NULL to specify that this function should not return until it is completed. &mpMicroCode, // [out] A pointer to an ID3D10Blob Interface which contains the compiled shader, as well as any embedded debug and symbol-table information. &errors, // [out] A pointer to an ID3D10Blob Interface which contains a listing of errors and warnings that occured during compilation. These errors and warnings are identical to the the debug output from a debugger. NULL // [out] A pointer to the return value. May be NULL. If pPump is not NULL, then pHResult must be a valid memory location until the asynchronous execution completes. ); } #if 0 // this is how you disassemble LPCSTR commentString = NULL; ID3D10Blob* pIDisassembly = NULL; char* pDisassembly = NULL; if( mpMicroCode ) { D3D10DisassembleShader( (UINT*) mpMicroCode->GetBufferPointer(), mpMicroCode->GetBufferSize(), TRUE, commentString, &pIDisassembly ); } const char* assemblyCode = static_cast<const char*>(pIDisassembly->GetBufferPointer()); #endif if (FAILED(hr)) { mErrorsInCompile = true; String message = "Cannot assemble D3D10 high-level shader " + mName + " Errors:\n" + static_cast<const char*>(errors->GetBufferPointer()); errors->Release(); OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, message, "D3D10HLSLProgram::loadFromSource"); } SIZE_T BytecodeLength = mpMicroCode->GetBufferSize(); // this is a temp patch for the nov 08 DX SDK #ifdef D3DX10ReflectShader hr = D3DX10ReflectShader( (void*) mpMicroCode->GetBufferPointer(), BytecodeLength, &mpIShaderReflection ); #else hr = D3D10ReflectShader( (void*) mpMicroCode->GetBufferPointer(), BytecodeLength, &mpIShaderReflection ); #endif if (!FAILED(hr)) { hr = mpIShaderReflection->GetDesc( &mShaderDesc ); if (!FAILED(hr)) { if (mShaderDesc.ConstantBuffers == 1) { mShaderReflectionConstantBuffer = mpIShaderReflection->GetConstantBufferByIndex(0); hr = mShaderReflectionConstantBuffer->GetDesc(&mConstantBufferDesc); createConstantBuffer(mConstantBufferDesc.Size); for(unsigned int i = 0; i < mConstantBufferDesc.Variables ; i++) { ID3D10ShaderReflectionVariable* varRef; varRef = mShaderReflectionConstantBuffer->GetVariableByIndex(i); D3D10_SHADER_VARIABLE_DESC shaderVerDesc; HRESULT hr = varRef->GetDesc(&shaderVerDesc); ShaderVarWithPosInBuf newVar; newVar.var = shaderVerDesc; newVar.wasInit = false; mShaderVars.push_back(newVar); } } } } switch(mType) { case GPT_VERTEX_PROGRAM: CreateVertexShader(); break; case GPT_FRAGMENT_PROGRAM: CreatePixelShader(); break; } }
void CShaderCreator::FinalizeRes( TResource * pRes ) { // Компилируем шейдер -------------------------------------------------- ID3D10Blob * pByteCode = NULL; CShader * pShader = (CShader *)pRes->pResource; uint nConstBufferSize; const char * szEntry = NULL; const char * szProfile = NULL; bool bIsVertexShader = true; if ( CStr::FinishWith( pRes->sFileName.GetString(), ".vsh" ) ) { szEntry = "Ripple"; szProfile = "vs_4_0"; } else if ( CStr::FinishWith( pRes->sFileName.GetString(), ".psh" ) ) { szEntry = "main"; szProfile = "ps_4_0"; bIsVertexShader = false; } EResult rStatus = CompileShader( pRes->sFileName.GetString(), (const char *)pRes->pBuffer, szEntry, szProfile, &pByteCode ); // После компиляции исходный код уже не нужен DEL_ARRAY( pRes->pBuffer ); if ( R_OK != rStatus ) { // Компиляция провалилась pRes->eState = TResource::FAILED; return; } ID3D10ShaderReflection * pRef = NULL; HRESULT hRes; if ( bIsVertexShader ) { pShader->m_pByteCodeVS = pByteCode; // Обрабатываем переменные --------------------------------------------- hRes = D3D10ReflectShader( pByteCode->GetBufferPointer(), pByteCode->GetBufferSize(), &pRef ); if ( ( S_OK == hRes ) && ( NULL != pRef ) ) { D3D10_SHADER_DESC desc; pRef->GetDesc( &desc ); DEBUG_ASSERT( 1 == desc.ConstantBuffers ) // Перебираем каждый буффер констант for ( uint i = 0; i < desc.ConstantBuffers; ++i ) { ID3D10ShaderReflectionConstantBuffer * pCBuf = pRef->GetConstantBufferByIndex( i ); D3D10_SHADER_BUFFER_DESC bufDesc; pCBuf->GetDesc( &bufDesc ); const char * szCBName = bufDesc.Name; nConstBufferSize = bufDesc.Size; pShader->m_nUniformCount = bufDesc.Variables; pShader->m_pUniforms = NEW CShader::TUniform [ pShader->m_nUniformCount ]; // Перебираем каждую переменную в буффере for ( uint nVar = 0; nVar < bufDesc.Variables; ++nVar ) { ID3D10ShaderReflectionVariable * pVar = pCBuf->GetVariableByIndex( nVar ); D3D10_SHADER_VARIABLE_DESC varDesc; pVar->GetDesc( &varDesc ); CShader::TUniform & tUniform = pShader->m_pUniforms[ nVar ]; tUniform.sName = varDesc.Name; tUniform.nCount = varDesc.Size / sizeof( vec4 ); tUniform.nLoc = varDesc.StartOffset / sizeof( vec4 ); } } } hRes = g_pDevice->CreateVertexShader( pByteCode->GetBufferPointer(), pByteCode->GetBufferSize(), &pShader->m_pVS ); }