示例#1
0
	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;
			}
		}
	}
示例#2
0
	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);
		}

	}
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);
}
示例#4
0
	bool CShaderHLSL::Create(P3D::sShaderDesc &desc)
	{
		const char *pData;
		ULONG fsize;
		IFileSystem* pFS = CRenderer::mEngine()->mFilesystem();
		wchar path[P3DMAX_PATH];
		wsprintf(path, P3DMAX_PATH-1, _W("shaders/%s.rshader"), desc.ShaderFile.Get());
		FSFILE *fp = pFS->Load(path, (BYTE *&)pData, fsize, true);
		if (!fp)
		{
			CON(MSG_ERR, _W("Can't open %s.hlsl shader file from data/shaders directory!"), desc.ShaderFile.Get());
			return false;
		}

		ID3D10Blob *pShaderBlob = NULL;
		ID3D10Blob *pErrors = NULL;
		UINT flags = D3D10_SHADER_DEBUG;  //D3D10_SHADER_OPTIMIZATION_LEVEL3

		char profile[128];
		switch(desc.ShaderType)
		{
		case SHADERTYPE_VERTEX_SHADER:
			strcpy(profile, D3D10GetVertexShaderProfile(g_pD3ddev));
			break;
		case SHADERTYPE_GEOMETRY_SHADER:
			strcpy(profile, D3D10GetGeometryShaderProfile(g_pD3ddev));
			break;
		case SHADERTYPE_PIXEL_SHADER:
			strcpy(profile, D3D10GetPixelShaderProfile(g_pD3ddev));
			break;
		default:
			CON(MSG_ERR, _W("Chader creation failed. No apropriate ShaderType given."));
			return false;
		}

		CIncludeHandler includeHandler;
		
		D3D10_SHADER_MACRO Shader_Macros[] = 
		{
			{ "DX10", NULL },
			{ "SM4", NULL },
			NULL
		};

		if(!CheckHRResult(D3DX10CompileFromMemory(
			pData, 
			fsize, 
			NULL, 
			Shader_Macros, 
			&includeHandler, 
			_W2A(desc.EntryFunction.Get()), 
			profile, 
			flags,
			0,
			NULL,
			&pShaderBlob, 
			&pErrors,
			NULL
			)))
		{
			if(pErrors) CON(MSG_ERR, _W("%s"), _A2W((char*)pErrors->GetBufferPointer()));
			else CON(MSG_ERR, _W("Error description not given"));
			CON(MSG_ERR, _W("Shader %s could not be compiled"), desc.ShaderFile.Get());
			SAFE_RELEASE(pErrors);
			return false;
		}

		pFS->UnLoad(fp, (BYTE *)pData);

		//save to cache
		fp = pFS->Open(_W("cache/shaders/hlsl"), _W("wb"));
		const char* cs = (const char*)pShaderBlob->GetBufferPointer();
		pFS->Write(cs, 1, pShaderBlob->GetBufferSize(), fp);
		pFS->Close(fp);

		bool shaderCreated = false;
		switch(desc.ShaderType)
		{
		case SHADERTYPE_VERTEX_SHADER:
			shaderCreated = CheckHRResult(g_pD3ddev->CreateVertexShader(pShaderBlob->GetBufferPointer(), pShaderBlob->GetBufferSize(), &m_pVS));
			break;
		case SHADERTYPE_GEOMETRY_SHADER:
			shaderCreated = CheckHRResult(g_pD3ddev->CreateGeometryShader(pShaderBlob->GetBufferPointer(), pShaderBlob->GetBufferSize(), &m_pGS));
			break;
		case SHADERTYPE_PIXEL_SHADER:
			shaderCreated = CheckHRResult(g_pD3ddev->CreatePixelShader(pShaderBlob->GetBufferPointer(), pShaderBlob->GetBufferSize(), &m_pPS));
			break;
		}
		
		if(!shaderCreated)
		{
			CON(MSG_ERR, _W("Shader creation error"));
			return false;
		}

		//if(!CheckHRResult(D3DReflect((DWORD*)pShaderBlob->GetBufferPointer(), pShaderBlob->GetBufferSize(), __uuidof(ID3D10ShaderReflection), &m_pReflection)))
		if(!CheckHRResult(D3D10ReflectShader(pShaderBlob->GetBufferPointer(), pShaderBlob->GetBufferSize(), &m_pReflection)))
		{
			CON(MSG_ERR, _W("Could not create a Shader reflection"));
			return false;
		}
		//HRESULT D3DReflect(LPCVOID pSrcData, SIZE_T SrcDataSize, REFIID pInterface,	void **ppReflector);
		D3D10_SHADER_DESC shDesc;
		m_pReflection->GetDesc(&shDesc);
		m_numResources = shDesc.BoundResources; //not sure about this

		if(desc.ShaderType == SHADERTYPE_VERTEX_SHADER)
			m_pVertDecl = new CVertexDeclaration(CRenderer::cGraphicsManager()->GetVertexDescByID(desc.VertexDescID), pShaderBlob);
		
		SAFE_RELEASE(pShaderBlob);

		m_desc = desc;

		CON(MSG_INFO, _W("Shader '%s' created"), desc.ShaderFile);
		
		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;
		}
	}
示例#6
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 );
	}