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

📄 clfragmentvector.cpp

📁 在GPU上实现数值模拟技术(线性方程组)的通用架构
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	int iDepth = reduceAddInternal();
	combineLastPointsGeneral(iDepth,pSurface,0);

	float result = evalLastPoint(pSurface);
	ms_memoryMananger->releaseTextureTarget(m_ID[0]);
	ms_memoryMananger->releaseTextureTarget(m_ID[1]);
	ms_memoryMananger->releaseTextureTarget(iMiniTexID);
	return result;
}

/*******************************************************************************************
   Name:    reduceAdd
   Purpose: return sum(this*clvSecond)
********************************************************************************************/
float clFragmentVector::reduceAdd(clFragmentVector* clvSecond) {
	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_tVector,  m_pVectorTexture);
	ms_pShaderClVector->SetTexture(ms_tVector2, clvSecond->m_pVectorTexture);
	ms_pShaderClVector->SetTechnique(ms_tReduceAddFirst);

	int iDepth = reduceAddInternal();
	combineLastPointsGeneral(iDepth,pSurface,0);

	float result = evalLastPoint(pSurface);
	ms_memoryMananger->releaseTextureTarget(m_ID[0]);
	ms_memoryMananger->releaseTextureTarget(m_ID[1]);
	ms_memoryMananger->releaseTextureTarget(iMiniTexID);
	return result;
}

/*******************************************************************************************
   Name:    splitQuadX
   Purpose: reduce a quad to half of it's size in x-dimension
********************************************************************************************/
void clFragmentVector::splitQuadX(CL_TEX2D_VERTEX *hQuad) {
	hQuad[1].x = (hQuad[1].x+1.0f)/2.0f-1.0f;
	hQuad[3].x = (hQuad[3].x+1.0f)/2.0f-1.0f;

	hQuad[1].tu /= 2.0;
	hQuad[3].tu /= 2.0;
}

/*******************************************************************************************
   Name:    splitQuadY
   Purpose: reduce a quad to half of it's size in y-dimension
********************************************************************************************/
void clFragmentVector::splitQuadY(CL_TEX2D_VERTEX *hQuad) {
	hQuad[2].y = (hQuad[2].y-1.0f)/2.0f+1.0f;
	hQuad[3].y = (hQuad[3].y-1.0f)/2.0f+1.0f;

	hQuad[2].tv /= 2.0;
	hQuad[3].tv /= 2.0;
}

/*******************************************************************************************
   Name:    splitQuad
   Purpose: reduce a quad to half of it's size in both dimensions
********************************************************************************************/
void clFragmentVector::splitQuad(CL_TEX2D_VERTEX *hQuad) {
	splitQuadX(hQuad);
	splitQuadY(hQuad);
}


/*******************************************************************************************
   Name:    reduceAddInternal
   Purpose: called by the reduceAdd methods
********************************************************************************************/
int clFragmentVector::reduceAddInternal() {
	int iDepth = 1;

	// a quad covering the entire viewport
	CL_TEX2D_VERTEX hQuad[4];	memcpy(hQuad,ms_hCoverQuad,sizeof(CL_TEX2D_VERTEX)*4);

	m_pd3dDevice->SetFVF( CL_TEX2D_VERTEX_FVF );

	while (iDepth*2 < m_memDesc.m_iWidth && iDepth*2 < m_memDesc.m_iHeight) {
		splitQuad(hQuad);
		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

		if (iDepth == 2) ms_pShaderClVector->SetTechnique(ms_tReduceAddRest);
	}
	
	// further reduce non-quadratic vectors
	if (m_memDesc.m_iWidth != m_memDesc.m_iHeight) {
		reduceInXDirection(iDepth,hQuad);	// try to reduce in x-direction
		reduceInYDirection(iDepth,hQuad);	// try to reduce in y-direction
	}

	m_pd3dDevice->SetRenderTarget(0,m_lpBackBuffer);

	return iDepth;
}


/*******************************************************************************************
   Name:    multiplyScalar
   Purpose: multiply this vector with a scalar (this = this*fScalar)
********************************************************************************************/
void clFragmentVector::multiplyScalar(float fScalar){
	BeginScene();
		ms_pShaderClVector->SetFloat(ms_fMultiply,fScalar);
		ms_pShaderClVector->SetTexture(ms_tVector, m_pVectorTexture);
		ms_pShaderClVector->SetTechnique(ms_tMultiplyScal);

		RenderViewPortCover(ms_pShaderClVector);
	EndScene();
}

LPDIRECT3DSURFACE9 clFragmentVector::getWriteSurface() {
	m_ID[0] = ms_memoryMananger->getTextureTarget(m_memDesc,m_pTempTexture[0],m_pTempTextureSurface[0]);
	return m_pTempTextureSurface[0];
}

LPDIRECT3DSURFACE9 clFragmentVector::getReadSurface() {
	return m_pVectorTextureSurface;
}

void clFragmentVector::swapSurfaces() {
	// swap temp and vector surface and texture
	PDIRECT3DTEXTURE9	swapTex		= m_pVectorTexture;
	LPDIRECT3DSURFACE9	swapSurface = m_pVectorTextureSurface;
	m_pVectorTexture				= m_pTempTexture[0];
	m_pVectorTextureSurface			= m_pTempTextureSurface[0];
	ms_memoryMananger->releaseTextureTarget(m_ID[0],swapTex,swapSurface);
	m_ID[0] = -1;
}

/*******************************************************************************************
   Name:    addVector
   Purpose: adds this vector to another vector storing the result in target 
            vTarget = (this*fScal1)+(vSource*fScal2)
********************************************************************************************/
void clFragmentVector::addVector(clFragmentVector* vSource, clFragmentVector* vTarget, float fScal1, float fScal2) {
	vTarget->BeginScene();
		ms_pShaderClVector->SetTechnique(ms_tVectorAdd);
		ms_pShaderClVector->SetFloat(ms_fMultiply,fScal1);
		ms_pShaderClVector->SetFloat(ms_fMultiply2,fScal2);
		ms_pShaderClVector->SetTexture(ms_tVector,   this->m_pVectorTexture);
		ms_pShaderClVector->SetTexture(ms_tLastPass, vSource->m_pVectorTexture);

		RenderViewPortCover(ms_pShaderClVector);
	vTarget->EndScene();
}

/*******************************************************************************************
   Name:    vectorOp
   Purpose: executes different vector-vector ops depending on eOpType
********************************************************************************************/
void clFragmentVector::vectorOp(CL_enum eOpType, clFragmentVector *clvSource, clFragmentVector *clvTarget, float fScal1, float fScal2) {
	switch (eOpType) {
		case CL_ADD: addVector(clvSource, clvTarget, fScal1, fScal2);
			break;
		case CL_SUB: addVector(clvSource, clvTarget, fScal1, -fScal2);
			break;
	}
}

void clFragmentVector::addVector(clFragmentVector* vSource, clFragmentVector* vTarget, float fScal, clFloat *clfScal) {
	vTarget->BeginScene();
		ms_pShaderClVector->SetTechnique(ms_tVectorAdd);

		ms_pShaderClVector->SetFloat(ms_fMultiply,fScal);
		ms_pShaderClVector->SetTexture(ms_tMultiply, clfScal->readTexture());
		ms_pShaderClVector->SetTexture(ms_tVector,   this->m_pVectorTexture);
		ms_pShaderClVector->SetTexture(ms_tLastPass, vSource->m_pVectorTexture);

		RenderViewPortCover(ms_pShaderClVector,1);
	vTarget->EndScene();
}

void clFragmentVector::subtractVector(clFragmentVector* vSource, clFragmentVector* vTarget, float fScal, clFloat *clfScal) {
	vTarget->BeginScene();
		ms_pShaderClVector->SetTechnique(ms_tVectorAdd);

		ms_pShaderClVector->SetFloat(ms_fMultiply,fScal);
		ms_pShaderClVector->SetTexture(ms_tMultiply, clfScal->readTexture());
		ms_pShaderClVector->SetTexture(ms_tVector,   this->m_pVectorTexture);
		ms_pShaderClVector->SetTexture(ms_tLastPass, vSource->m_pVectorTexture);

		RenderViewPortCover(ms_pShaderClVector,2);
	vTarget->EndScene();
}


/*******************************************************************************************
   Name:    copyVector
   Purpose: dublicate a vector (this.data = clvSource.data)
********************************************************************************************/
void clFragmentVector::copyVector(clFragmentVector *clvSource) {
	BeginScene();
		ms_pShaderClVector->SetFloat(ms_fMultiply,1);
		ms_pShaderClVector->SetTexture(ms_tVector, clvSource->m_pVectorTexture);
		ms_pShaderClVector->SetTechnique(ms_tMultiplyScal);

		RenderViewPortCover(ms_pShaderClVector);
	EndScene();
}

/*******************************************************************************************
   Name:    setData
   Purpose: copy vector to a texture on the GPU
********************************************************************************************/
void clFragmentVector::setData(float* fVectorData) {
	D3DLOCKED_RECT rfTextureLock;
	LPDIRECT3DSURFACE9 pSurf;
	PDIRECT3DTEXTURE9  pTex;
	int id = ms_memoryMananger->getSysmemTexture(m_memDesc,pTex,pSurf);

	pTex->LockRect(0, &rfTextureLock, NULL, 0);					// lock whole region in the vector texture
		#ifdef use16BitPrecOnly
			D3DXFLOAT16* temp = new D3DXFLOAT16[getSize()]; // convert float32 to float16
			for (int i=0;i<getSize();i++) temp[i] = fVectorData[i];
			D3DXFLOAT16* pfTexture = (D3DXFLOAT16*)rfTextureLock.pBits;
			memcpy(pfTexture,temp,getSize()*sizeof(D3DXFLOAT16));
			delete [] temp;
		#else
			float* pfTexture = (float*)rfTextureLock.pBits;
			memcpy(pfTexture,fVectorData,getSize()*sizeof(float));
		#endif
	pTex->UnlockRect(0);
	setData(pSurf);

	ms_memoryMananger->releaseSysmemTexture(id);
}

/*******************************************************************************************
   Name:    getData
   Purpose: read vector data back into main mem
********************************************************************************************/
void clFragmentVector::getData(float* fVectorData) {
	D3DLOCKED_RECT rfTextureLock;
	LPDIRECT3DSURFACE9 pSurf;
	PDIRECT3DTEXTURE9  pTex;
	int id = ms_memoryMananger->getSysmemTexture(m_memDesc,pTex,pSurf);

	// transfer data from GPU to CPU
	getData(pSurf);

	// copy data into user pointer
	pTex->LockRect(0, &rfTextureLock, NULL, D3DLOCK_READONLY);	// lock whole region in the vector texture
		#ifdef use16BitPrecOnly
			D3DXFLOAT16* temp = new D3DXFLOAT16[getSize()]; // convert float32 to float16
			D3DXFLOAT16* pfTexture = (D3DXFLOAT16*)rfTextureLock.pBits;
 			memcpy(temp,pfTexture,getSize()*sizeof(D3DXFLOAT16));
			for (int i=0;i<getSize();i++) fVectorData[i] = temp[i];
			delete [] temp;
		#else
			float* pfTexture = (float*)rfTextureLock.pBits;
 			memcpy(fVectorData,pfTexture,getSize()*sizeof(float));
		#endif
	pTex->UnlockRect(0);

	ms_memoryMananger->releaseSysmemTexture(id);
}

HRESULT clFragmentVector::setData(LPDIRECT3DSURFACE9 m_pSurfSystem) {
	HRESULT hr;
	CHECK_HR(m_pd3dDevice->UpdateSurface(m_pSurfSystem, NULL, m_pVectorTextureSurface, NULL));
	return S_OK;
}

HRESULT clFragmentVector::getData(LPDIRECT3DSURFACE9 m_pSurfSystem) {
	HRESULT hr;
	CHECK_HR(m_pd3dDevice->GetRenderTargetData(m_pVectorTextureSurface, m_pSurfSystem));
	return S_OK;
}

/*******************************************************************************************
   Name:    toString
   Purpose: convert the vector to a string, outputting only the first iOutputCount values
            iOutputCount==0 (default) outputs all values
********************************************************************************************/
TCHAR* clFragmentVector::toString(int iOutputCount) {
	TCHAR* cpResult = new TCHAR[20*getSize()]; // TODO: check if 20 makes sense here
	TCHAR* cpTemp   = new TCHAR[20];
	float* pfData  = new float[getSize()];
	
	getData(pfData);

	cpResult[0] = 0;
	for (int i = 0;i<getSize();i++) {
		if (iOutputCount > 0 && iOutputCount <= i) return cpResult;

		if ((i+1)%m_memDesc.m_iWidth)
			_stprintf(cpTemp,_T("%7.5f\t "),pfData[i]);
		else
			_stprintf(cpTemp,_T("%7.5f\n"),pfData[i]);
		_tcscat(cpResult,cpTemp);
	}

	return cpResult;
}

/*******************************************************************************************
   Name:    toShortString
   Purpose: convert the vector to a string, but display only non zero entries
********************************************************************************************/
TCHAR* clFragmentVector::toShortString(int iOutputCount) {
	TCHAR* cpResult = new TCHAR[20*getSize()]; // TODO: check if 20 makes sense here
	TCHAR* cpTemp   = new TCHAR[20];
	float* pfData  = new float[getSize()];
	int iOutCounter = 0;
	
	getData(pfData);

	cpResult[0] = 0;
	for (int i = 0;i<getSize();i++) {
		if (fabs(pfData[i]) > 0.00001)	{
			_stprintf(cpTemp,_T("%i:%7.5f\t "),i, pfData[i]);
			_tcscat(cpResult,cpTemp);

			iOutCounter++;
			if (iOutputCount > 0 && iOutputCount < iOutCounter) return cpResult;
		}
	}

	return cpResult;
}

⌨️ 快捷键说明

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