DFORCEINLINE static void getResources(ID3D10Device *d3dDevice, const String& prefix, DUNORDERED_MAP <String, size_t>& mapResource, DUNORDERED_MAP <String, size_t>& mapSampler, ID3D10Blob* pCode){ 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 size_t valueOffset = 0; //calc size for (uint i = 0; i < desc.BoundResources; ++i) { D3D10_SHADER_INPUT_BIND_DESC resourceDesc; pReflection->GetResourceBindingDesc(i, &resourceDesc); if (resourceDesc.Type == D3D10_SIT_TEXTURE){ mapResource[prefix + '.' + resourceDesc.Name] = resourceDesc.BindPoint; } else if (resourceDesc.Type == D3D10_SIT_SAMPLER){ mapSampler[resourceDesc.Name] = resourceDesc.BindPoint; } } }
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); } }
BOOL R_constant_table::parse (void* _desc, u16 destination) { ID3D10ShaderReflection *pReflection = (ID3D10ShaderReflection *)_desc; D3D10_SHADER_DESC ShaderDesc; pReflection->GetDesc(&ShaderDesc); if (ShaderDesc.ConstantBuffers) { m_CBTable.reserve(ShaderDesc.ConstantBuffers); // Parse single constant table ID3D10ShaderReflectionConstantBuffer *pTable=0; for (u16 iBuf = 0; iBuf<ShaderDesc.ConstantBuffers; ++iBuf) { pTable = pReflection->GetConstantBufferByIndex(iBuf); if (pTable) { // Encode buffer index into destination u16 updatedDest = destination; updatedDest |= iBuf << ((destination&RC_dest_pixel) ? RC_dest_pixel_cb_index_shift : (destination&RC_dest_vertex) ? RC_dest_vertex_cb_index_shift : RC_dest_geometry_cb_index_shift); // Encode bind dest (pixel/vertex buffer) and bind point index u32 uiBufferIndex = iBuf; uiBufferIndex |= (destination&RC_dest_pixel) ? CB_BufferPixelShader : (destination&RC_dest_vertex) ? CB_BufferVertexShader : CB_BufferGeometryShader; parseConstants(pTable,updatedDest); ref_cbuffer tempBuffer = dxRenderDeviceRender::Instance().Resources->_CreateConstantBuffer(pTable); m_CBTable.push_back(cb_table_record(uiBufferIndex, tempBuffer)); } } } if (ShaderDesc.BoundResources) { parseResources(pReflection, ShaderDesc.BoundResources, destination); } std::sort (table.begin(),table.end(),p_sort); return TRUE; }
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 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 ); }