ComplexValueTy CodeGenFunction::EmitComplexDivSmiths(ComplexValueTy LHS, ComplexValueTy RHS) { auto ElemTy = RHS.Re->getType(); // if(abs(d) <= abs(c)) then auto FabsIntrinsic = GetIntrinsicFunction(llvm::Intrinsic::fabs, ElemTy); auto Predicate = Builder.CreateFCmpOLE(Builder.CreateCall(FabsIntrinsic, RHS.Im), Builder.CreateCall(FabsIntrinsic, RHS.Re)); auto ThenBlock = createBasicBlock("compdiv-then"); auto ElseBlock = createBasicBlock("compdiv-else"); auto MergeBlock = createBasicBlock("compdiv-done"); Builder.CreateCondBr(Predicate, ThenBlock, ElseBlock); llvm::Value *R, *Den, *E, *F; auto ResultRe = llvm::PHINode::Create(ElemTy, 2, "compdiv-re"); auto ResultIm = llvm::PHINode::Create(ElemTy, 2, "compdiv-im"); // r = d / c // den = c + d * r // e = (a + b * r) / den // f = (b - a * r) / den EmitBlock(ThenBlock); R = Builder.CreateFDiv(RHS.Im, RHS.Re); Den = Builder.CreateFAdd(RHS.Re, Builder.CreateFMul(RHS.Im, R)); E = Builder.CreateFDiv(Builder.CreateFAdd(LHS.Re, Builder.CreateFMul(LHS.Im, R)), Den); F = Builder.CreateFDiv(Builder.CreateFSub(LHS.Im, Builder.CreateFMul(LHS.Re, R)), Den); ResultRe->addIncoming(E, ThenBlock); ResultIm->addIncoming(F, ThenBlock); EmitBranch(MergeBlock); // r = c / d // den = c * r + d // e = (a * r + b) / den // f = (b * r - a) / den EmitBlock(ElseBlock); R = Builder.CreateFDiv(RHS.Re, RHS.Im); Den = Builder.CreateFAdd(Builder.CreateFMul(RHS.Re, R), RHS.Im); E = Builder.CreateFDiv(Builder.CreateFAdd( Builder.CreateFMul(LHS.Re, R), LHS.Im), Den); F = Builder.CreateFDiv(Builder.CreateFSub( Builder.CreateFMul(LHS.Im, R), LHS.Re), Den); ResultRe->addIncoming(E, ElseBlock); ResultIm->addIncoming(F, ElseBlock); EmitBranch(MergeBlock); EmitBlock(MergeBlock); Builder.Insert(ResultRe); Builder.Insert(ResultIm); return ComplexValueTy(ResultRe, ResultIm); }
/* ======================== idDxtDecoder::DecompressNormalMapDXT1Renormalize ======================== */ void idDxtDecoder::DecompressNormalMapDXT1Renormalize( const byte* inBuf, byte* outBuf, int width, int height ) { byte block[64]; this->width = width; this->height = height; this->inData = inBuf; for( int j = 0; j < height; j += 4 ) { for( int i = 0; i < width; i += 4 ) { DecodeColorValues( block, false, true ); for( int k = 0; k < 16; k++ ) { float normal[3]; normal[0] = block[k * 4 + 0] / 255.0f * 2.0f - 1.0f; normal[1] = block[k * 4 + 1] / 255.0f * 2.0f - 1.0f; normal[2] = block[k * 4 + 2] / 255.0f * 2.0f - 1.0f; float rsq = idMath::InvSqrt( normal[0] * normal[0] + normal[1] * normal[1] + normal[2] * normal[2] ); normal[0] *= rsq; normal[1] *= rsq; normal[2] *= rsq; block[k * 4 + 0] = idMath::Ftob( ( normal[0] + 1.0f ) / 2.0f * 255.0f + 0.5f ); block[k * 4 + 1] = idMath::Ftob( ( normal[1] + 1.0f ) / 2.0f * 255.0f + 0.5f ); block[k * 4 + 2] = idMath::Ftob( ( normal[2] + 1.0f ) / 2.0f * 255.0f + 0.5f ); } EmitBlock( outBuf, i, j, block ); } } }
/* ======================== idDxtDecoder::DecompressImageDXT1 ======================== */ void idDxtDecoder::DecompressImageDXT1( const byte* inBuf, byte* outBuf, int width, int height ) { byte block[64]; this->width = width; this->height = height; this->inData = inBuf; for( int j = 0; j < height; j += 4 ) { for( int i = 0; i < width; i += 4 ) { DecodeColorValues( block, false, true ); EmitBlock( outBuf, i, j, block ); } } }
/* ======================== idDxtDecoder::DecompressYCoCgCTX1DXT5A ======================== */ void idDxtDecoder::DecompressYCoCgCTX1DXT5A( const byte* inBuf, byte* outBuf, int width, int height ) { byte block[64]; this->width = width; this->height = height; this->inData = inBuf; for( int j = 0; j < height; j += 4 ) { for( int i = 0; i < width; i += 4 ) { DecodeAlphaValues( block, 3 ); DecodeCTX1Values( block ); EmitBlock( outBuf, i, j, block ); } } }
/* ======================== idDxtDecoder::DecompressNormalMapDXT1 ======================== */ void idDxtDecoder::DecompressNormalMapDXT1( const byte* inBuf, byte* outBuf, int width, int height ) { byte block[64]; this->width = width; this->height = height; this->inData = inBuf; for( int j = 0; j < height; j += 4 ) { for( int i = 0; i < width; i += 4 ) { DecodeColorValues( block, false, true ); #if 1 float normals[16 * 4]; /* for ( int k = 0; k < 16; k++ ) { normals[k*4+0] = block[k*4+0] / 255.0f * 2.0f - 1.0f; normals[k*4+1] = block[k*4+1] / 255.0f * 2.0f - 1.0f; } */ UnRotateNormals( block, normals, block[0 * 4 + 2], 0 ); for( int k = 0; k < 16; k++ ) { float x = normals[k * 4 + 0]; float y = normals[k * 4 + 1]; float z = 1.0f - x * x - y * y; if( z < 0.0f ) z = 0.0f; normals[k * 4 + 2] = sqrt( z ); } for( int k = 0; k < 16; k++ ) { block[k * 4 + 0] = idMath::Ftob( ( normals[k * 4 + 0] + 1.0f ) / 2.0f * 255.0f ); block[k * 4 + 1] = idMath::Ftob( ( normals[k * 4 + 1] + 1.0f ) / 2.0f * 255.0f ); block[k * 4 + 2] = idMath::Ftob( ( normals[k * 4 + 2] + 1.0f ) / 2.0f * 255.0f ); } #else DeriveNormalZValues( block ); #endif EmitBlock( outBuf, i, j, block ); } } }
/* ======================== idDxtDecoder::DecompressNormalMapDXT5 ======================== */ void idDxtDecoder::DecompressNormalMapDXT5( const byte* inBuf, byte* outBuf, int width, int height ) { byte block[64]; byte c0, c1; this->width = width; this->height = height; this->inData = inBuf; for( int j = 0; j < height; j += 4 ) { for( int i = 0; i < width; i += 4 ) { DecodeAlphaValues( block, 0 ); DecodeNormalYValues( block, 1, c0, c1 ); #if 1 float normals[16 * 4]; //BiasScaleNormals( block, normals, c0, c1 ); UnRotateNormals( block, normals, c0, c1 ); for( int k = 0; k < 16; k++ ) { float x = normals[k * 4 + 0]; float y = normals[k * 4 + 1]; float z = 1.0f - x * x - y * y; if( z < 0.0f ) z = 0.0f; normals[k * 4 + 2] = sqrt( z ); } for( int k = 0; k < 16; k++ ) { block[k * 4 + 0] = idMath::Ftob( ( normals[k * 4 + 0] + 1.0f ) / 2.0f * 255.0f ); block[k * 4 + 1] = idMath::Ftob( ( normals[k * 4 + 1] + 1.0f ) / 2.0f * 255.0f ); block[k * 4 + 2] = idMath::Ftob( ( normals[k * 4 + 2] + 1.0f ) / 2.0f * 255.0f ); } #else BiasScaleNormalY( block, 1, c0, c1 ); DeriveNormalZValues( block ); #endif EmitBlock( outBuf, i, j, block ); } } }