⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 clfragmentvector.cpp

📁 在GPU上实现数值模拟技术(线性方程组)的通用架构
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/************************************************************
 *															*
 * decr     : abstract base class for all fragment based	*
 *            vector clases									*
 * version  : 1.2											*
 * author   : Jens Kr黦er									*
 * date     : 16.09.2003									*
 * modified	: 10.06.2004									*
 * e-mail   : jens.krueger@in.tum.de						*
 *															*
 ************************************************************/
#include "clFragmentVector.h"


int						clFragmentVector::s_iFragmentVectorCount=0;
LPD3DXEFFECT			clFragmentVector::ms_pShaderClVector=NULL;

D3DXHANDLE				clFragmentVector::ms_fMultiply;
D3DXHANDLE				clFragmentVector::ms_fMultiply2;
D3DXHANDLE				clFragmentVector::ms_fReduceStep;
D3DXHANDLE				clFragmentVector::ms_f4ReduceStep;
D3DXHANDLE				clFragmentVector::ms_f4TexShift;
D3DXHANDLE				clFragmentVector::ms_fShift;
D3DXHANDLE				clFragmentVector::ms_fSize;
D3DXHANDLE				clFragmentVector::ms_tVector;
D3DXHANDLE				clFragmentVector::ms_tVector2;
D3DXHANDLE				clFragmentVector::ms_tLastPass;
D3DXHANDLE				clFragmentVector::ms_tMultiply;

D3DXHANDLE				clFragmentVector::ms_tMultiplyScal;
D3DXHANDLE				clFragmentVector::ms_tReduceAddFirst;
D3DXHANDLE				clFragmentVector::ms_tReduceAddRest;
D3DXHANDLE				clFragmentVector::ms_tReduceAddLast;
D3DXHANDLE				clFragmentVector::ms_tReduceAddRestX;
D3DXHANDLE				clFragmentVector::ms_tReduceAddRestY;
D3DXHANDLE				clFragmentVector::ms_tVectorAdd;
D3DXHANDLE				clFragmentVector::ms_tVectorMultiply;
D3DXHANDLE				clFragmentVector::ms_tVectorMultiplyMatPosOnly;
D3DXHANDLE				clFragmentVector::ms_tVectorMultiplyMatAllCases;
D3DXHANDLE				clFragmentVector::ms_tVectorMultiplyMatPosOnly_noadd;
D3DXHANDLE				clFragmentVector::ms_tVectorMultiplyMatAllCases_noadd;
D3DXHANDLE				clFragmentVector::ms_tUnpackVector;
D3DXHANDLE				clFragmentVector::ms_tPackVector;


/*******************************************************************************************
   Name:    init
   Purpose: init for a vector of length iSize, automaticly finds the best layout
********************************************************************************************/
HRESULT clFragmentVector::init(LPDIRECT3DDEVICE9 pd3dDevice, int iSize, bool bConstant, D3DFORMAT pD3DFormat) {
	float fLog = DirectXUtils::log2(iSize)/2.0f;
	return init(pd3dDevice,1<<(int)ceil(fLog),1<<(int)floor(fLog),bConstant,pD3DFormat);
}

/*******************************************************************************************
   Name:    loadShaders
   Purpose: loads all shaders required for this vector, if loaded already use the old one
********************************************************************************************/
void clFragmentVector::loadShaders() {
    

	if (s_iFragmentVectorCount < 1)	{
		if (FAILED(DirectXUtils::checkLoadShader(_T("clVector.fx"), ms_pShaderClVector, m_pd3dDevice, clFrameworkShaderPath, NULL, clClass::ms_clPSProfile))) exit(-1);;
		// precache shader parameters 

		// parameters 
		ms_fMultiply 			= ms_pShaderClVector->GetParameterByName(NULL,"fMultiply");
		ms_fMultiply2 			= ms_pShaderClVector->GetParameterByName(NULL,"fMultiply2");
		ms_fReduceStep 			= ms_pShaderClVector->GetParameterByName(NULL,"fReduceStep");
		ms_f4ReduceStep 		= ms_pShaderClVector->GetParameterByName(NULL,"f4ReduceStep");
		ms_f4TexShift 			= ms_pShaderClVector->GetParameterByName(NULL,"f4TexShift");
		ms_fShift 				= ms_pShaderClVector->GetParameterByName(NULL,"fShift");
		ms_fSize 				= ms_pShaderClVector->GetParameterByName(NULL,"fSize");

		// textures
		ms_tVector 				= ms_pShaderClVector->GetParameterByName(NULL,"tVector");
		ms_tVector2 			= ms_pShaderClVector->GetParameterByName(NULL,"tVector2");
		ms_tLastPass 			= ms_pShaderClVector->GetParameterByName(NULL,"tLastPass");
		ms_tMultiply 			= ms_pShaderClVector->GetParameterByName(NULL,"tMultiply");

		// techniques
		ms_tMultiplyScal						= ms_pShaderClVector->GetTechniqueByName("tMultiplyScal");
		ms_tReduceAddFirst						= ms_pShaderClVector->GetTechniqueByName("tReduceAddFirst");
		ms_tReduceAddRest						= ms_pShaderClVector->GetTechniqueByName("tReduceAddRest");
		ms_tReduceAddLast						= ms_pShaderClVector->GetTechniqueByName("tReduceAddLast");
		ms_tReduceAddRestX						= ms_pShaderClVector->GetTechniqueByName("tReduceAddRestX");
		ms_tReduceAddRestY						= ms_pShaderClVector->GetTechniqueByName("tReduceAddRestY");
		ms_tVectorAdd							= ms_pShaderClVector->GetTechniqueByName("tVectorAdd");
		ms_tVectorMultiply						= ms_pShaderClVector->GetTechniqueByName("tVectorMultiply");
		ms_tVectorMultiplyMatPosOnly			= ms_pShaderClVector->GetTechniqueByName("tVectorMultiplyMatPosOnly");
		ms_tVectorMultiplyMatAllCases			= ms_pShaderClVector->GetTechniqueByName("tVectorMultiplyMatAllCases");
		ms_tVectorMultiplyMatPosOnly_noadd		= ms_pShaderClVector->GetTechniqueByName("tVectorMultiplyMatPosOnly_noadd");
		ms_tVectorMultiplyMatAllCases_noadd		= ms_pShaderClVector->GetTechniqueByName("tVectorMultiplyMatAllCases_noadd");
		ms_tUnpackVector						= ms_pShaderClVector->GetTechniqueByName("tUnpackVector");
		ms_tPackVector							= ms_pShaderClVector->GetTechniqueByName("tPackVector");
	}
}

/*******************************************************************************************
   Name:    init
   Purpose: initializes this vector, should be called explitly only if default constructor
            has been used to create this object
********************************************************************************************/
HRESULT clFragmentVector::init(LPDIRECT3DDEVICE9 pd3dDevice, int iSizeX, int iSizeY, bool bConstant, D3DFORMAT pD3DFormat) {
	// store values
	m_pd3dDevice		  = pd3dDevice;
	pd3dDevice->GetRenderTarget(0, &m_lpBackBuffer);

	m_memDesc.m_iWidth    = iSizeX;
	m_memDesc.m_iHeight	  = iSizeY;
	m_memDesc.m_d3dFormat = pD3DFormat;

	#ifdef optNVIDIA
		m_memDesc.m_dUsage	  = (bConstant) ? NULL : D3DUSAGE_RENDERTARGET;
	#else
		UNREFERENCED_PARAMETER(bConstant);
		m_memDesc.m_dUsage	  = D3DUSAGE_RENDERTARGET;
	#endif

	// needed for various shaders
	m_vSize	     = D3DXVECTOR4((float)iSizeX,(float)iSizeY,1.0f/(float)iSizeX,1.0f/(float)iSizeY);

	// setup variables
	m_iTempActive = 0;

	// create render target, textures and surface
	m_iMemID = ms_memoryMananger->getTextureTarget(m_memDesc, m_pVectorTexture, m_pVectorTextureSurface);

	for (int i = 0;i<2;i++) {
		m_pTempTexture[i] = NULL;
		m_pTempTextureSurface[i] = NULL;
		m_ID[i] = -1;
	}

	// init static variables
	loadShaders();

	// count the active incarnations of this class
	s_iFragmentVectorCount++;

	return S_OK;
}


/*******************************************************************************************
   Name:    BeginScene
   Purpose: initialazes the scene for rendering i.e. allocating a render to surace,
            retrieving a write surface, calling begin scene on the render to surface
********************************************************************************************/
HRESULT clFragmentVector::BeginScene() {
	HRESULT hr;
	CHECK_HR(m_pd3dDevice->SetRenderTarget(0,getWriteSurface()));
	return S_OK;
}

/*******************************************************************************************
   Name:    EndScene
   Purpose: finalizes a rendering pass i.e. calling end-scene on the render to surface
            freeing the render to surace, swapping the wrte surface and the read surface
********************************************************************************************/
HRESULT clFragmentVector::EndScene() {
	HRESULT hr;
	CHECK_HR(m_pd3dDevice->SetRenderTarget(0,m_lpBackBuffer));
	swapSurfaces();
	return S_OK;
}


/*******************************************************************************************
   Name:    clear
   Purpose: sets all vector elements to zero
********************************************************************************************/
void clFragmentVector::clear() {
	m_pd3dDevice->SetRenderTarget(0,m_pVectorTextureSurface);
		m_pd3dDevice->Clear( 0L, NULL, D3DCLEAR_TARGET,0x00000000, 1.0f, 0L );
	m_pd3dDevice->SetRenderTarget(0,m_lpBackBuffer);

}

/*******************************************************************************************
   Name:    default destructor
   Purpose: destroyes this object
********************************************************************************************/
clFragmentVector::~clFragmentVector(void)	{

	ms_memoryMananger->releaseTextureTarget(m_iMemID, m_pVectorTexture, m_pVectorTextureSurface);
	SAFE_RELEASE( m_lpBackBuffer );

	// if this is the last vector object alive, destroy static members
	s_iFragmentVectorCount--;
	if (s_iFragmentVectorCount==0) SAFE_RELEASE( ms_pShaderClVector);
}

/*******************************************************************************************
   Name:    reduceInXDirection
   Purpose: reduces only in y-diretion, this method is required with rectangular textures
********************************************************************************************/
void clFragmentVector::reduceInXDirection(int &iDepth, CL_TEX2D_VERTEX *hQuad) {
	/* try to reduce in x-direction
	 precon: FVF is set to CL_TEX2D_VERTEX_FVF
	         because reduceInXDirection is allways called afer reduceAdd */

	while (iDepth*2 < m_memDesc.m_iWidth) {
		splitQuadX(hQuad);

		ms_pShaderClVector->SetTechnique(ms_tReduceAddRestX);
		m_pd3dDevice->SetRenderTarget(0, m_pTempTextureSurface[m_iTempActive]);

			ms_pShaderClVector->SetFloat(ms_fReduceStep, 1.0f/(iDepth*2.0f));
			UINT cPasses;
			ms_pShaderClVector->Begin(&cPasses, 0);
				ms_pShaderClVector->BeginPass(0);
				m_pd3dDevice->DrawPrimitiveUP( D3DPT_TRIANGLESTRIP, 2, hQuad, sizeof( CL_TEX2D_VERTEX ) );
				ms_pShaderClVector->EndPass();
			ms_pShaderClVector->End();
		iDepth *= 2;

		ms_pShaderClVector->SetTexture(ms_tLastPass, m_pTempTexture[m_iTempActive]);
		m_iTempActive = 1-m_iTempActive; // swap temp-surface
	}
}


/*******************************************************************************************
   Name:    reduceInYDirection
   Purpose: reduces only in y-diretion, this method is required with rectangular textures
********************************************************************************************/
void clFragmentVector::reduceInYDirection(int &iDepth, CL_TEX2D_VERTEX *hQuad) {
	/* try to reduce in y-direction
	 precon: FVF is set to CL_TEX2D_VERTEX_FVF
	         because reduceInYDirection is allways called afer reduceAdd */


	while (iDepth*2 < m_memDesc.m_iHeight) {
		splitQuadY(hQuad);

		ms_pShaderClVector->SetTechnique(ms_tReduceAddRestY);
		m_pd3dDevice->SetRenderTarget(0, m_pTempTextureSurface[m_iTempActive]);

			ms_pShaderClVector->SetFloat(ms_fReduceStep, 1.0f/(iDepth*2.0f));
			UINT cPasses;
			ms_pShaderClVector->Begin(&cPasses, 0);
				ms_pShaderClVector->BeginPass(0);
				m_pd3dDevice->DrawPrimitiveUP( D3DPT_TRIANGLESTRIP, 2, hQuad, sizeof( CL_TEX2D_VERTEX ) );
				ms_pShaderClVector->EndPass();
			ms_pShaderClVector->End();

		iDepth *= 2;

		ms_pShaderClVector->SetTexture(ms_tLastPass, m_pTempTexture[m_iTempActive]);
		m_iTempActive = 1-m_iTempActive; // swap temp-surface
	}
}

/*******************************************************************************************
   Name:    combineLastPoints
   Purpose: the last step in the reduction process requires reduction to a specified 1x1 
			texture, because only whole textures can be read back into main mem
********************************************************************************************/
void clFragmentVector::combineLastPointsGeneral(int iDepth, 
										 LPDIRECT3DSURFACE9 pMiniTextureSurface,
										 int iType) {

	CL_TEX2D_VERTEX hQuad[]		= {	{ -1, -1, 0, 0, 0},
									{  1, -1, 0, 0, 0},
									{ -1,  1, 0, 0, 0},
									{  1,  1, 0, 0, 0}};

	ms_pShaderClVector->SetTechnique(ms_tReduceAddLast);

	m_pd3dDevice->SetRenderTarget(0, pMiniTextureSurface);

		// if the vector was not "quadratic" take the aspect ratio into account for the texture coordinates
		D3DXVECTOR4 f4ReduceStep = D3DXVECTOR4((float)MAX(1,(m_memDesc.m_iHeight/m_memDesc.m_iWidth))/(iDepth*2.0f),
			                                   (float)MAX(1,(m_memDesc.m_iWidth/m_memDesc.m_iHeight))/(iDepth*2.0f),0,0);

		ms_pShaderClVector->SetVector(ms_f4ReduceStep, &f4ReduceStep);
		UINT cPasses;
		ms_pShaderClVector->Begin(&cPasses, 0);
			ms_pShaderClVector->BeginPass(iType);
			m_pd3dDevice->DrawPrimitiveUP( D3DPT_TRIANGLESTRIP, 2, hQuad, sizeof( CL_TEX2D_VERTEX ) );
			ms_pShaderClVector->EndPass();
		ms_pShaderClVector->End();
	m_pd3dDevice->SetRenderTarget(0,m_lpBackBuffer);
}

/*******************************************************************************************
   Name:    reduceAdd
   Purpose: compute clfResult=sum(this)
********************************************************************************************/
void clFragmentVector::reduceAdd(clFloat *clfResult) {
	m_ID[0] = ms_memoryMananger->getTextureTarget(m_memDesc,m_pTempTexture[0],m_pTempTextureSurface[0]);
	m_ID[1] = ms_memoryMananger->getTextureTarget(m_memDesc,m_pTempTexture[1],m_pTempTextureSurface[1]);

	ms_pShaderClVector->SetTexture(ms_tLastPass, m_pVectorTexture);
	ms_pShaderClVector->SetTechnique(ms_tReduceAddRest);

	int iDepth = reduceAddInternal();
	// write directly to the readSurface to avoid a flipTexture call
	combineLastPoints(iDepth,clfResult->readSurface());

	ms_memoryMananger->releaseTextureTarget(m_ID[0]);
	ms_memoryMananger->releaseTextureTarget(m_ID[1]);
}

/*******************************************************************************************
   Name:    reduceAdd
   Purpose: compute clfResult=sum(this*clvSecond)
********************************************************************************************/
void clFragmentVector::reduceAdd(clFragmentVector* clvSecond, clFloat *clfResult) {
	m_ID[0] = ms_memoryMananger->getTextureTarget(m_memDesc,m_pTempTexture[0],m_pTempTextureSurface[0]);
	m_ID[1] = ms_memoryMananger->getTextureTarget(m_memDesc,m_pTempTexture[1],m_pTempTextureSurface[1]);

	ms_pShaderClVector->SetTexture(ms_tVector,  m_pVectorTexture);
	ms_pShaderClVector->SetTexture(ms_tVector2, clvSecond->m_pVectorTexture);
	ms_pShaderClVector->SetTechnique(ms_tReduceAddFirst);

	int iDepth = reduceAddInternal();
	// write directly to the readSurface to avoid a flipTexture call
	combineLastPoints(iDepth,clfResult->readSurface());

	ms_memoryMananger->releaseTextureTarget(m_ID[0]);
	ms_memoryMananger->releaseTextureTarget(m_ID[1]);
}

/*******************************************************************************************
   Name:    reduceAdd
   Purpose: return sum(this)
********************************************************************************************/
float clFragmentVector::reduceAdd() {
	LPDIRECT3DSURFACE9 pSurface;
	PDIRECT3DTEXTURE9  pTexture;
	int iMiniTexID = ms_memoryMananger->getTextureTarget(clMemDescr(1,1,m_memDesc.m_d3dFormat,D3DUSAGE_RENDERTARGET),pTexture,pSurface);
	m_ID[0] = ms_memoryMananger->getTextureTarget(m_memDesc,m_pTempTexture[0],m_pTempTextureSurface[0]);
	m_ID[1] = ms_memoryMananger->getTextureTarget(m_memDesc,m_pTempTexture[1],m_pTempTextureSurface[1]);

	ms_pShaderClVector->SetTexture(ms_tLastPass, m_pVectorTexture);
	ms_pShaderClVector->SetTechnique(ms_tReduceAddRest);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -