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);
		}

	}
Exemple #2
0
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);


				}


			}

		}
	}
Exemple #5
0
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;
		}
	}
Exemple #7
0
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 );
	}