PageRenderTime 1377ms CodeModel.GetById 342ms app.highlight 864ms RepoModel.GetById 157ms app.codeStats 1ms

/opengles/src/arm/GenFragment.cpp

http://ftk.googlecode.com/
C++ | 1978 lines | 1288 code | 377 blank | 313 comment | 87 complexity | d22088b30f83520be38c8b2b8402e417 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   1// ==========================================================================
   2//
   3// GenFragment.cpp		JIT Class for 3D Rendering Library
   4//
   5//						This file contains the rasterizer functions that
   6//						implement the runtime code generation support
   7//						for optimized scan line rasterization routines.
   8//
   9// --------------------------------------------------------------------------
  10//
  11// 12-29-2003		Hans-Martin Will	initial version
  12//
  13// --------------------------------------------------------------------------
  14//
  15// Copyright (c) 2004, Hans-Martin Will. All rights reserved.
  16// 
  17// Redistribution and use in source and binary forms, with or without 
  18// modification, are permitted provided that the following conditions are 
  19// met:
  20// 
  21//	 *  Redistributions of source code must retain the above copyright
  22// 		notice, this list of conditions and the following disclaimer. 
  23//   *	Redistributions in binary form must reproduce the above copyright
  24// 		notice, this list of conditions and the following disclaimer in the 
  25// 		documentation and/or other materials provided with the distribution. 
  26// 
  27// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  28// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
  29// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
  30// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 
  31// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 
  32// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
  33// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  34// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
  35// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
  36// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
  37// THE POSSIBILITY OF SUCH DAMAGE.
  38//
  39// ==========================================================================
  40
  41
  42#include "stdafx.h"
  43#include "CodeGenerator.h"
  44#include "Rasterizer.h"
  45#include "FunctionCache.h"
  46#include "Surface.h"
  47#include "Texture.h"
  48#include "codegen.h"
  49#include "instruction.h"
  50#include "emit.h"
  51#include "arm-dis.h"
  52
  53
  54using namespace EGL;
  55
  56
  57namespace {
  58
  59	inline cg_virtual_reg_t * LOAD_DATA(cg_block_t * block, cg_virtual_reg_t * base, I32 constant) {
  60		cg_virtual_reg_t * offset = cg_virtual_reg_create(block->proc, cg_reg_type_general);
  61		cg_virtual_reg_t * addr = cg_virtual_reg_create(block->proc, cg_reg_type_general);
  62		cg_virtual_reg_t * value = cg_virtual_reg_create(block->proc, cg_reg_type_general);
  63
  64		LDI(offset, constant);
  65		ADD(addr, base, offset);
  66		LDW(value, addr);
  67
  68		return value;
  69	}
  70
  71#define ALLOC_REG(reg) reg = cg_virtual_reg_create(procedure, cg_reg_type_general)
  72#define ALLOC_FLAGS(reg) reg = cg_virtual_reg_create(procedure, cg_reg_type_flags)
  73#define DECL_REG(reg) cg_virtual_reg_t * reg = cg_virtual_reg_create(procedure, cg_reg_type_general)
  74#define DECL_FLAGS(reg) cg_virtual_reg_t * reg = cg_virtual_reg_create(procedure, cg_reg_type_flags)
  75#define DECL_CONST_REG(reg, value) cg_virtual_reg_t * reg = cg_virtual_reg_create(procedure, cg_reg_type_general); LDI(reg, value)
  76
  77}
  78
  79
  80void CodeGenerator :: FetchTexColor(cg_proc_t * procedure, cg_block_t * currentBlock,
  81 								    const RasterizerState::TextureState * textureState,
  82								    cg_virtual_reg_t * regTextureData, 
  83								    cg_virtual_reg_t * regTexOffset,
  84								    cg_virtual_reg_t *& regTexColorR,
  85								    cg_virtual_reg_t *& regTexColorG,			
  86								    cg_virtual_reg_t *& regTexColorB,			
  87								    cg_virtual_reg_t *& regTexColorA,
  88								    cg_virtual_reg_t *& regTexColor565) {
  89
  90	cg_block_t * block = currentBlock;
  91
  92	switch (textureState->InternalFormat) {
  93		case RasterizerState::TextureFormatAlpha:				// 8
  94			{
  95			//texColor = Color(0, 0, 0, reinterpret_cast<const U8 *>(data)[texOffset]);
  96			regTexColorR = regTexColorG = regTexColorB = cg_virtual_reg_create(procedure, cg_reg_type_general);
  97			regTexColorA = cg_virtual_reg_create(procedure, cg_reg_type_general);
  98			regTexColor565 = cg_virtual_reg_create(procedure, cg_reg_type_general);
  99
 100			DECL_REG	(regTexAddr);
 101			
 102
 103			ADD		(regTexAddr, regTexOffset, regTextureData);
 104			LDB		(regTexColorA, regTexAddr);
 105			LDI		(regTexColorR, 0);
 106
 107			LDI		(regTexColor565, 0);
 108
 109			}
 110			break;
 111
 112		case RasterizerState::TextureFormatLuminance:			// 8
 113			{
 114			//U8 luminance = reinterpret_cast<const U8 *>(data)[texOffset];
 115			//texColor = Color (luminance, luminance, luminance, 0xff);
 116			regTexColorR = regTexColorB = regTexColorG = cg_virtual_reg_create(procedure, cg_reg_type_general);
 117			regTexColorA = cg_virtual_reg_create(procedure, cg_reg_type_general);
 118
 119			DECL_REG	(regTexAddr);
 120
 121			ADD		(regTexAddr, regTexOffset, regTextureData);
 122			LDB		(regTexColorR, regTexAddr);
 123			LDI		(regTexColorA, 0xff);
 124
 125			regTexColor565 = Color565FromRGB(block, regTexColorR, regTexColorG, regTexColorB);
 126			}
 127			break;
 128
 129		case RasterizerState::TextureFormatLuminanceAlpha:		// 8-8
 130			{
 131			//U8 luminance = reinterpret_cast<const U8 *>(data)[texOffset * 2];
 132			//U8 alpha = reinterpret_cast<const U8 *>(data)[texOffset * 2 + 1];
 133			//texColor = Color (luminance, luminance, luminance, alpha);
 134			regTexColorR = regTexColorB = regTexColorG = cg_virtual_reg_create(procedure, cg_reg_type_general);
 135			regTexColorA = cg_virtual_reg_create(procedure, cg_reg_type_general);
 136
 137			DECL_REG		(regScaledOffset);
 138			DECL_REG		(regTexAddr);
 139			DECL_REG		(regTexAddr1);
 140			DECL_CONST_REG	(regConstantOne, 1);
 141
 142			LSL		(regScaledOffset, regTexOffset, regConstantOne);
 143			ADD		(regTexAddr, regScaledOffset, regTextureData);
 144			LDB		(regTexColorR, regTexAddr);
 145			ADD		(regTexAddr1, regTexAddr, regConstantOne);
 146			LDB		(regTexColorA, regTexAddr1);
 147
 148			regTexColor565 = Color565FromRGB(block, regTexColorR, regTexColorG, regTexColorB);
 149
 150			}
 151			break;
 152
 153		case RasterizerState::TextureFormatRGB565:					// 5-6-5
 154			//texColor = Color::From565(reinterpret_cast<const U16 *>(data)[texOffset]);
 155			{
 156			regTexColorA = cg_virtual_reg_create(procedure, cg_reg_type_general);
 157			regTexColor565 = cg_virtual_reg_create(procedure, cg_reg_type_general);
 158
 159			DECL_REG	(regScaledOffset);
 160			DECL_REG	(regConstantOne);
 161			DECL_REG	(regTexAddr);
 162
 163			LDI		(regConstantOne, 1);
 164			LSL		(regScaledOffset, regTexOffset, regConstantOne);
 165			ADD		(regTexAddr, regScaledOffset, regTextureData);
 166			LDH		(regTexColor565, regTexAddr);
 167			LDI		(regTexColorA, 0xff);
 168
 169			regTexColorR = ExtractBitFieldTo255(block, regTexColor565, 11, 15);
 170			regTexColorG = ExtractBitFieldTo255(block, regTexColor565,  5, 10);
 171			regTexColorB = ExtractBitFieldTo255(block, regTexColor565,  0,  4);
 172			}
 173			break;
 174
 175		case RasterizerState::TextureFormatRGB8:						// 8-8-8
 176			{
 177			regTexColorA = cg_virtual_reg_create(procedure, cg_reg_type_general);
 178			regTexColorR = cg_virtual_reg_create(procedure, cg_reg_type_general);
 179			regTexColorG = cg_virtual_reg_create(procedure, cg_reg_type_general);
 180			regTexColorB = cg_virtual_reg_create(procedure, cg_reg_type_general);
 181
 182			DECL_REG	(regConstant1);
 183			DECL_REG	(regConstant2);
 184			DECL_REG	(regConstant3);
 185			DECL_REG	(regShiftedOffset);
 186			DECL_REG	(regScaledOffset);
 187			DECL_REG	(regTexAddr0);
 188			DECL_REG	(regTexAddr1);
 189			DECL_REG	(regTexAddr2);
 190
 191			LDI			(regTexColorA, 0xff);
 192			LDI			(regConstant1, 1);
 193			LDI			(regConstant2, 2);
 194			LDI			(regConstant3, 3);
 195
 196			LSL		(regShiftedOffset,	regTexOffset, regConstant1);
 197			ADD		(regScaledOffset,	regTexOffset, regShiftedOffset);
 198			ADD		(regTexAddr0,		regTextureData, regScaledOffset);
 199			LDB		(regTexColorR,		regTexAddr0);
 200			ADD		(regTexAddr1,		regTexAddr0, regConstant1);
 201			LDB		(regTexColorG,		regTexAddr1);
 202			ADD		(regTexAddr2,		regTexAddr0, regConstant2);
 203			LDB		(regTexColorB,		regTexAddr2);
 204
 205			regTexColor565 = Color565FromRGB(block, regTexColorR, regTexColorG, regTexColorB);
 206			}
 207
 208			break;
 209
 210		case RasterizerState::TextureFormatRGBA4444:					// 4-4-4-4
 211			{
 212			DECL_REG	(regScaledOffset);
 213			DECL_REG	(regConstantOne);
 214			DECL_REG	(regTexAddr);
 215			DECL_REG	(regTexColor4444);
 216
 217			LDI		(regConstantOne, 1);
 218			LSL		(regScaledOffset, regTexOffset, regConstantOne);
 219			ADD		(regTexAddr, regScaledOffset, regTextureData);
 220			LDH		(regTexColor4444, regTexAddr);
 221
 222			regTexColorR = ExtractBitFieldTo255(block, regTexColor4444, 12, 15);
 223			regTexColorG = ExtractBitFieldTo255(block, regTexColor4444,  8, 11);
 224			regTexColorB = ExtractBitFieldTo255(block, regTexColor4444,  4,  7);
 225			regTexColorA = ExtractBitFieldTo255(block, regTexColor4444,  0,  3);
 226
 227			regTexColor565 = Color565FromRGB(block, regTexColorR, regTexColorG, regTexColorB);
 228			}
 229
 230			break;
 231
 232		case RasterizerState::TextureFormatRGBA8:						// 8-8-8-8
 233			{
 234			regTexColorA = cg_virtual_reg_create(procedure, cg_reg_type_general);
 235			regTexColorR = cg_virtual_reg_create(procedure, cg_reg_type_general);
 236			regTexColorG = cg_virtual_reg_create(procedure, cg_reg_type_general);
 237			regTexColorB = cg_virtual_reg_create(procedure, cg_reg_type_general);
 238
 239			DECL_REG	(regConstant1);
 240			DECL_REG	(regConstant2);
 241			DECL_REG	(regConstant3);
 242			DECL_REG	(regConstant7);
 243			DECL_REG	(regScaledOffset);
 244			DECL_REG	(regTexAddr0);
 245			DECL_REG	(regTexAddr1);
 246			DECL_REG	(regTexAddr2);
 247			DECL_REG	(regTexAddr3);
 248
 249			LDI		(regConstant1, 1);
 250			LDI		(regConstant2, 2);
 251			LDI		(regConstant3, 3);
 252			LDI		(regConstant7, 7);
 253
 254			LSL		(regScaledOffset, regTexOffset, regConstant2);
 255			ADD		(regTexAddr0, regTextureData, regScaledOffset);
 256			LDB		(regTexColorR, regTexAddr0);
 257			ADD		(regTexAddr1, regTexAddr0, regConstant1);
 258			LDB		(regTexColorG, regTexAddr1);
 259			ADD		(regTexAddr2, regTexAddr0, regConstant2);
 260			LDB		(regTexColorB, regTexAddr2);
 261			ADD		(regTexAddr3, regTexAddr0, regConstant3);
 262			LDB		(regTexColorA, regTexAddr3);
 263
 264			regTexColor565 = Color565FromRGB(block, regTexColorR, regTexColorG, regTexColorB);
 265			}
 266
 267			break;
 268
 269		case RasterizerState::TextureFormatRGBA5551:					// 5-5-5-1
 270			//texColor = Color::From5551(reinterpret_cast<const U16 *>(data)[texOffset]);
 271			{
 272			DECL_REG	(regScaledOffset);
 273			DECL_REG	(regConstantOne);
 274			DECL_REG	(regTexAddr);
 275			DECL_REG	(regTexColor5551);
 276
 277			LDI		(regConstantOne, 1);
 278			LSL		(regScaledOffset, regTexOffset, regConstantOne);
 279			ADD		(regTexAddr, regScaledOffset, regTextureData);
 280			LDH		(regTexColor5551, regTexAddr);
 281
 282			regTexColorR = ExtractBitFieldTo255(block, regTexColor5551, 11, 15);
 283			regTexColorG = ExtractBitFieldTo255(block, regTexColor5551,  7, 10);
 284			regTexColorB = ExtractBitFieldTo255(block, regTexColor5551,  1,  5);
 285			regTexColorA = ExtractBitFieldTo255(block, regTexColor5551,  0,  0);
 286
 287			regTexColor565 = Color565FromRGB(block, regTexColorR, regTexColorG, regTexColorB);
 288			}
 289			break;
 290
 291		default:
 292			//texColor = Color(0xff, 0xff, 0xff, 0xff);
 293			{
 294			regTexColorR = regTexColorB = regTexColorG = regTexColorA = cg_virtual_reg_create(procedure, cg_reg_type_general);
 295			regTexColor565 = cg_virtual_reg_create(procedure, cg_reg_type_general);
 296
 297			LDI		(regTexColorR, 0xff);
 298			LDI		(regTexColor565, 0xffff);
 299			}
 300			break;
 301	}
 302}
 303
 304namespace {
 305
 306	void WrapOrClamp(cg_proc_t * procedure, cg_block_t * block, 
 307					 cg_virtual_reg_t * regIn, 
 308					 cg_virtual_reg_t * regOut, 
 309					 cg_virtual_reg_t * regMask,  
 310					 RasterizerState::WrappingMode mode) {
 311
 312		switch (mode) {
 313			case RasterizerState::WrappingModeClampToEdge:
 314				//tu0 = EGL_CLAMP(tu, 0, EGL_ONE);
 315				{
 316					DECL_REG	(regConstantZero);
 317					DECL_REG	(regTemp);
 318
 319					LDI		(regConstantZero, EGL_FixedFromInt(0));
 320					MIN		(regTemp, regIn, regMask);
 321					MAX		(regOut, regTemp, regConstantZero);
 322				}
 323				break;
 324
 325			default:
 326			case RasterizerState::WrappingModeRepeat:
 327				//tu0 = tu & 0xffff;
 328				{
 329					AND		(regOut, regIn, regMask);
 330				}
 331				break;
 332		}
 333	}
 334
 335	cg_virtual_reg_t * BlendComponent(cg_proc_t * procedure, cg_block_t * block, 
 336									  cg_virtual_reg_t *regA, cg_virtual_reg_t *regB, 
 337									  cg_virtual_reg_t * regAlpha) {
 338
 339		DECL_REG	(regDiff);
 340		DECL_REG	(regProduct);
 341		DECL_REG	(regConstant8);
 342		DECL_REG	(regShifted);
 343		DECL_REG	(regResult);
 344
 345		SUB			(regDiff, regB, regA);
 346		MUL			(regProduct, regDiff, regAlpha);
 347		LDI			(regConstant8, 8);
 348		ASR			(regShifted, regProduct, regConstant8);
 349		ADD			(regResult, regA, regShifted);
 350
 351		return regResult;
 352	}
 353}
 354
 355
 356void CodeGenerator :: GenerateFetchTexColor(cg_proc_t * procedure, cg_block_t * currentBlock, 
 357											size_t unit,
 358											FragmentGenerationInfo & fragmentInfo,
 359										    cg_virtual_reg_t *& regTexColorR,
 360										    cg_virtual_reg_t *& regTexColorG,			
 361										    cg_virtual_reg_t *& regTexColorB,			
 362										    cg_virtual_reg_t *& regTexColorA,
 363											cg_virtual_reg_t *& regTexColor565) {
 364
 365	cg_block_t * block = currentBlock;
 366
 367	cg_virtual_reg_t * regU = fragmentInfo.regU[unit];
 368	cg_virtual_reg_t * regV = fragmentInfo.regV[unit];
 369
 370	//EGL_Fixed tu0;
 371	//EGL_Fixed tv0;
 372
 373	if (m_State->GetMinFilterMode(unit) == RasterizerState::FilterModeNearest) {
 374		DECL_REG	(regU0);
 375		DECL_REG	(regV0);
 376
 377		DECL_REG	(regMask);
 378
 379		LDI		(regMask, 0xffff);
 380
 381		WrapOrClamp(procedure, block, regU, regU0, regMask, m_State->m_Texture[unit].WrappingModeS);
 382		WrapOrClamp(procedure, block, regV, regV0, regMask, m_State->m_Texture[unit].WrappingModeT);
 383
 384		// get the pixel color
 385		//Texture * texture = m_Texture->GetTexture(m_MipMapLevel);
 386		//cg_virtual_reg_t * texX = EGL_IntFromFixed(texture->GetWidth() * tu0);
 387		//cg_virtual_reg_t * texY = EGL_IntFromFixed(texture->GetHeight() * tv0);
 388		//cg_virtual_reg_t * texOffset = texX + (texY << texture->GetExponent());
 389		//void * data = texture->GetData();
 390		DECL_REG	(regScaledU);
 391		DECL_REG	(regTexX);
 392		DECL_REG	(regScaledV);
 393		DECL_REG	(regTexY);
 394		DECL_REG	(regScaledTexY);
 395		DECL_REG	(regTexOffset);
 396		DECL_REG	(regConstant16);
 397
 398		cg_virtual_reg_t * regTextureLogWidth =		LOAD_DATA(block, fragmentInfo.regTexture[unit], OFFSET_TEXTURE_LOG_WIDTH);
 399		cg_virtual_reg_t * regTextureLogHeight =	LOAD_DATA(block, fragmentInfo.regTexture[unit], OFFSET_TEXTURE_LOG_HEIGHT);
 400		cg_virtual_reg_t * regTextureData =			LOAD_DATA(block, fragmentInfo.regTexture[unit], OFFSET_TEXTURE_DATA);
 401
 402		LSL		(regScaledU, regU0, regTextureLogWidth);
 403		LSL		(regScaledV, regV0, regTextureLogHeight);
 404		LDI		(regConstant16, 16);
 405		ASR		(regTexX, regScaledU, regConstant16);
 406		ASR		(regTexY, regScaledV, regConstant16);
 407		LSL		(regScaledTexY, regTexY, regTextureLogWidth);
 408		ADD		(regTexOffset, regScaledTexY, regTexX);
 409
 410		FetchTexColor(procedure, block, m_State->m_Texture + unit, regTextureData, regTexOffset,
 411					  regTexColorR, regTexColorG, regTexColorB, regTexColorA, regTexColor565);
 412	} else {
 413		assert(m_State->GetMinFilterMode(unit) == RasterizerState::FilterModeLinear);
 414
 415		cg_virtual_reg_t * regTextureLogWidth =		LOAD_DATA(block, fragmentInfo.regTexture[unit], OFFSET_TEXTURE_LOG_WIDTH);
 416
 417		DECL_REG	(regHalf);
 418		DECL_REG	(regHalfU);
 419		DECL_REG	(regHalfV);
 420
 421		LDI			(regHalf, 0x8000);
 422
 423		cg_virtual_reg_t * regTextureLogHeight =	LOAD_DATA(block, fragmentInfo.regTexture[unit], OFFSET_TEXTURE_LOG_HEIGHT);
 424
 425		ASR			(regHalfU, regHalf, regTextureLogWidth);
 426		ASR			(regHalfV, regHalf, regTextureLogHeight);
 427
 428		DECL_REG	(regRoundedU);
 429		DECL_REG	(regRoundedV);
 430
 431		SUB			(regRoundedU, regU, regHalfU);
 432		SUB			(regRoundedV, regV, regHalfV);
 433
 434		DECL_REG	(regScaledU);
 435		DECL_REG	(regScaledV);
 436		DECL_REG	(regFixedOne);
 437		DECL_REG	(regFracU);
 438		DECL_REG	(regFracV);
 439		DECL_REG	(regMask);
 440
 441		LDI			(regMask, 0xffff);
 442		LSL			(regScaledU, regRoundedU, regTextureLogWidth);
 443		LSL			(regScaledV, regRoundedV, regTextureLogHeight);
 444		AND			(regFracU, regScaledU, regMask);
 445		AND			(regFracV, regScaledV, regMask);
 446
 447		DECL_REG	(regTexX);
 448		DECL_REG	(regTexY);
 449		DECL_REG	(regConstant16);
 450
 451		LDI			(regConstant16, 16);
 452		ASR			(regTexX, regScaledU, regConstant16);
 453		ASR			(regTexY, regScaledV, regConstant16);
 454
 455		DECL_REG	(regConstant1);
 456		DECL_REG	(regIntMaskU0);
 457		DECL_REG	(regIntMaskU);
 458		DECL_REG	(regIntMaskV0);
 459		DECL_REG	(regIntMaskV);
 460
 461		LDI			(regConstant1, 1);
 462		LSL			(regIntMaskU0, regConstant1, regTextureLogWidth);
 463		LSL			(regIntMaskV0, regConstant1, regTextureLogHeight);
 464		SUB			(regIntMaskU, regIntMaskU0, regConstant1);
 465		SUB			(regIntMaskV, regIntMaskV0, regConstant1);
 466
 467		DECL_REG	(regI0);
 468		DECL_REG	(regI1);
 469		DECL_REG	(regJ0);
 470		DECL_REG	(regJ1);
 471
 472		DECL_REG	(regTexX1);
 473		DECL_REG	(regTexY1);
 474
 475		ADD			(regTexX1, regTexX, regConstant1);
 476		ADD			(regTexY1, regTexY, regConstant1);
 477
 478		WrapOrClamp(procedure, block, regTexX, regI0, regIntMaskU, m_State->m_Texture[unit].WrappingModeS);
 479		WrapOrClamp(procedure, block, regTexX1, regI1, regIntMaskU, m_State->m_Texture[unit].WrappingModeS);
 480		WrapOrClamp(procedure, block, regTexY, regJ0, regIntMaskV, m_State->m_Texture[unit].WrappingModeT);
 481		WrapOrClamp(procedure, block, regTexY1, regJ1, regIntMaskV, m_State->m_Texture[unit].WrappingModeT);
 482
 483		DECL_REG	(regScaledJ0);
 484		DECL_REG	(regScaledJ1);
 485
 486		LSL		(regScaledJ0, regJ0, regTextureLogWidth);
 487		LSL		(regScaledJ1, regJ1, regTextureLogWidth);
 488
 489		DECL_REG	(regTexOffset00);
 490		DECL_REG	(regTexOffset01);
 491		DECL_REG	(regTexOffset10);
 492		DECL_REG	(regTexOffset11);
 493
 494		ADD		(regTexOffset00, regI0, regScaledJ0);
 495		ADD		(regTexOffset01, regI1, regScaledJ0);
 496		ADD		(regTexOffset10, regI0, regScaledJ1);
 497		ADD		(regTexOffset11, regI1, regScaledJ1);
 498
 499		cg_virtual_reg_t * regColorR00,	* regColorR01, *regColorR10, * regColorR11;
 500		cg_virtual_reg_t * regColorG00, * regColorG01, *regColorG10, * regColorG11;
 501		cg_virtual_reg_t * regColorB00, * regColorB01, *regColorB10, * regColorB11;
 502		cg_virtual_reg_t * regColorA00, * regColorA01, *regColorA10, * regColorA11;
 503		cg_virtual_reg_t * regColor56500, * regColor56501, *regColor56510, * regColor56511;
 504
 505		cg_virtual_reg_t * regTextureData =			LOAD_DATA(block, fragmentInfo.regTexture[unit], OFFSET_TEXTURE_DATA);
 506
 507		FetchTexColor(procedure, block, m_State->m_Texture + unit, regTextureData, regTexOffset00,
 508					  regColorR00, regColorG00, regColorB00, regColorA00, regColor56500);
 509
 510		FetchTexColor(procedure, block, m_State->m_Texture + unit, regTextureData, regTexOffset01,
 511					  regColorR01, regColorG01, regColorB01, regColorA01, regColor56501);
 512
 513		FetchTexColor(procedure, block, m_State->m_Texture + unit, regTextureData, regTexOffset10,
 514					  regColorR10, regColorG10, regColorB10, regColorA10, regColor56510);
 515
 516		FetchTexColor(procedure, block, m_State->m_Texture + unit, regTextureData, regTexOffset11,
 517					  regColorR11, regColorG11, regColorB11, regColorA11, regColor56511);
 518
 519		cg_virtual_reg_t * regColorR0, * regColorR1;
 520		cg_virtual_reg_t * regColorG0, * regColorG1;
 521		cg_virtual_reg_t * regColorB0, * regColorB1;
 522		cg_virtual_reg_t * regColorA0, * regColorA1;
 523
 524		// blend into 0 and 1 colors
 525		DECL_REG	(regConstant8);
 526		DECL_REG	(regAdjustedFracU);
 527		DECL_REG	(regAdjustedFracV);
 528
 529		LDI			(regConstant8, 8);
 530		ASR			(regAdjustedFracU, regFracU, regConstant8);
 531		ASR			(regAdjustedFracV, regFracV, regConstant8);
 532
 533		regColorR0 = BlendComponent(procedure, block, regColorR00, regColorR01, regAdjustedFracU);
 534		regColorR1 = BlendComponent(procedure, block, regColorR10, regColorR11, regAdjustedFracU);
 535		regTexColorR = BlendComponent(procedure, block, regColorR0, regColorR1, regAdjustedFracV);
 536
 537		regColorG0 = BlendComponent(procedure, block, regColorG00, regColorG01, regAdjustedFracU);
 538		regColorG1 = BlendComponent(procedure, block, regColorG10, regColorG11, regAdjustedFracU);
 539		regTexColorG = BlendComponent(procedure, block, regColorG0, regColorG1, regAdjustedFracV);
 540
 541		regColorB0 = BlendComponent(procedure, block, regColorB00, regColorB01, regAdjustedFracU);
 542		regColorB1 = BlendComponent(procedure, block, regColorB10, regColorB11, regAdjustedFracU);
 543		regTexColorB = BlendComponent(procedure, block, regColorB0, regColorB1, regAdjustedFracV);
 544
 545		regColorA0 = BlendComponent(procedure, block, regColorA00, regColorA01, regAdjustedFracU);
 546		regColorA1 = BlendComponent(procedure, block, regColorA10, regColorA11, regAdjustedFracU);
 547		regTexColorA = BlendComponent(procedure, block, regColorA0, regColorA1, regAdjustedFracV);
 548
 549		// create composite color
 550
 551		regTexColor565 =  Color565FromRGB(block, regTexColorR, regTexColorG, regTexColorB);
 552	}
 553}
 554
 555
 556// Actually, we could extract the scaling of the texture coordinates into the outer driving loop, 
 557// and have the adjusted clipping range for tu and tv be stored in the rasterizer.
 558
 559void CodeGenerator :: GenerateFragment(cg_proc_t * procedure,  cg_block_t * currentBlock,
 560			cg_block_ref_t * continuation, FragmentGenerationInfo & fragmentInfo,
 561			int weight, bool forceScissor) {
 562
 563	cg_block_t * block = currentBlock;
 564
 565	// Signature of generated function is:
 566	// (I32 x, I32 y, EGL_Fixed depth, EGL_Fixed tu, EGL_Fixed tv, EGL_Fixed fogDensity, const Color& baseColor);
 567	
 568	// fragment level clipping (for now)
 569
 570	//if (m_Surface->GetWidth() <= x || x < 0 ||
 571	//	m_Surface->GetHeight() <= y || y < 0) {
 572	//	return;
 573	//}
 574
 575	if (forceScissor || m_State->m_ScissorTest.Enabled) {
 576		DECL_REG	(regConstXStart);
 577		DECL_REG	(regConstXEnd);
 578		DECL_FLAGS	(regXStartTest);
 579		DECL_FLAGS	(regXEndTest);
 580
 581		LDI			(regConstXStart, m_State->m_ScissorTest.X);
 582		LDI			(regConstXEnd, m_State->m_ScissorTest.X + m_State->m_ScissorTest.Width);
 583
 584		CMP			(regXStartTest, fragmentInfo.regX, regConstXStart);
 585		BLT			(regXStartTest, continuation);
 586		CMP			(regXEndTest, fragmentInfo.regX, regConstXEnd);
 587		BGE			(regXEndTest, continuation);
 588
 589		if (fragmentInfo.regY) {
 590			DECL_REG	(regConstYStart);
 591			DECL_REG	(regConstYEnd);
 592			DECL_FLAGS	(regYStartTest);
 593			DECL_FLAGS	(regYEndTest);
 594
 595			LDI			(regConstYStart, m_State->m_ScissorTest.Y);
 596			LDI			(regConstYEnd, m_State->m_ScissorTest.Y + m_State->m_ScissorTest.Height);
 597
 598			CMP			(regYStartTest, fragmentInfo.regY, regConstYStart);
 599			BLT			(regYStartTest, continuation);
 600			CMP			(regYEndTest, fragmentInfo.regY, regConstYEnd);
 601			BGE			(regYEndTest, continuation);
 602		}
 603	}
 604
 605	//bool depthTest;
 606	//U32 offset = x + y * m_Surface->GetWidth();
 607	//I32 zBufferValue = m_Surface->GetDepthBuffer()[offset];
 608	cg_virtual_reg_t * regOffset;
 609	
 610	if (fragmentInfo.regY) {
 611		regOffset = cg_virtual_reg_create(procedure, cg_reg_type_general);
 612
 613		cg_virtual_reg_t * regWidth = LOAD_DATA(block, fragmentInfo.regInfo, OFFSET_SURFACE_WIDTH);
 614
 615		DECL_REG	(regScaledY);
 616
 617		MUL		(regScaledY, fragmentInfo.regY, regWidth);
 618		ADD		(regOffset, regScaledY, fragmentInfo.regX);
 619	} else {
 620		regOffset = fragmentInfo.regX;
 621	}
 622
 623	cg_virtual_reg_t * regDepthBuffer =			LOAD_DATA(block, fragmentInfo.regInfo, OFFSET_SURFACE_DEPTH_BUFFER);
 624
 625	DECL_FLAGS	(regDepthTest);
 626	DECL_REG	(regScaledY);
 627	DECL_REG	(regConstant1);
 628	DECL_REG	(regConstant2);
 629	DECL_REG	(regOffset4);
 630	DECL_REG	(regOffset2);
 631	DECL_REG	(regZBufferAddr);
 632	DECL_REG	(regZBufferValue);
 633
 634	LDI		(regConstant1, 1);
 635	LDI		(regConstant2, 2);
 636	LSL		(regOffset2, regOffset, regConstant1);
 637	LSL		(regOffset4, regOffset, regConstant2);
 638	ADD		(regZBufferAddr, regDepthBuffer, regOffset2);
 639	LDH		(regZBufferValue, regZBufferAddr);
 640
 641	/*
 642	 * Enable this piece if we want to clamp the depth value to 0 .. 0xffff
 643	{
 644		DECL_CONST_REG	(regConstant0, 0);
 645		DECL_CONST_REG	(regConstant1, 0xffff);
 646		DECL_REG		(regNewDepth);
 647		DECL_REG		(regTempDepth);
 648
 649		MIN				(regTempDepth, fragmentInfo.regDepth, regConstant1);
 650		MAX				(regNewDepth, regTempDepth, regConstant0);
 651
 652		fragmentInfo.regDepth = regNewDepth;
 653	}*/
 654
 655	CMP		(regDepthTest, fragmentInfo.regDepth, regZBufferValue);
 656
 657	cg_opcode_t branchOnDepthTestPassed, branchOnDepthTestFailed;
 658
 659	switch (m_State->m_DepthTest.Func) {
 660		default:
 661		case RasterizerState::CompFuncNever:	
 662			//depthTest = false;						
 663			branchOnDepthTestPassed = cg_op_nop;
 664			branchOnDepthTestFailed = cg_op_bra;
 665			break;
 666
 667		case RasterizerState::CompFuncLess:		
 668			//depthTest = depth < zBufferValue;		
 669			branchOnDepthTestPassed = cg_op_blt;
 670			branchOnDepthTestFailed = cg_op_bge;
 671			break;
 672
 673		case RasterizerState::CompFuncEqual:	
 674			//depthTest = depth == zBufferValue;		
 675			branchOnDepthTestPassed = cg_op_beq;
 676			branchOnDepthTestFailed = cg_op_bne;
 677			break;
 678
 679		case RasterizerState::CompFuncLEqual:	
 680			//depthTest = depth <= zBufferValue;		
 681			branchOnDepthTestPassed = cg_op_ble;
 682			branchOnDepthTestFailed = cg_op_bgt;
 683			break;
 684
 685		case RasterizerState::CompFuncGreater:	
 686			//depthTest = depth > zBufferValue;		
 687			branchOnDepthTestPassed = cg_op_bgt;
 688			branchOnDepthTestFailed = cg_op_ble;
 689			break;
 690
 691		case RasterizerState::CompFuncNotEqual:	
 692			//depthTest = depth != zBufferValue;		
 693			branchOnDepthTestPassed = cg_op_bne;
 694			branchOnDepthTestFailed = cg_op_beq;
 695			break;
 696
 697		case RasterizerState::CompFuncGEqual:	
 698			//depthTest = depth >= zBufferValue;		
 699			branchOnDepthTestPassed = cg_op_bge;
 700			branchOnDepthTestFailed = cg_op_blt;
 701			break;
 702
 703		case RasterizerState::CompFuncAlways:	
 704			//depthTest = true;						
 705			branchOnDepthTestPassed = cg_op_bra;
 706			branchOnDepthTestFailed = cg_op_nop;
 707			break;
 708	}
 709
 710	if (!m_State->m_Stencil.Enabled && m_State->m_DepthTest.Enabled) {
 711		//if (!depthTest)
 712		//	return;
 713
 714		if (branchOnDepthTestFailed == cg_op_nop) {
 715			// nothing
 716		} else if (branchOnDepthTestFailed == cg_op_bra) {
 717			BRA		(continuation);
 718		} else {
 719			cg_create_inst_branch_cond(block, branchOnDepthTestFailed, regDepthTest, continuation CG_INST_DEBUG_ARGS);
 720		}
 721	}
 722
 723	//Color color = baseColor;
 724	cg_virtual_reg_t * regColorR = ClampTo255(block, fragmentInfo.regR);
 725	cg_virtual_reg_t * regColorG = ClampTo255(block, fragmentInfo.regG);
 726	cg_virtual_reg_t * regColorB = ClampTo255(block, fragmentInfo.regB);
 727	cg_virtual_reg_t * regColorA = ClampTo255(block, fragmentInfo.regA);
 728	cg_virtual_reg_t * regColor565 = Color565FromRGB(block, regColorR, regColorG, regColorB);
 729
 730	cg_virtual_reg_t * regBaseColorR = regColorR;
 731	cg_virtual_reg_t * regBaseColorG = regColorG;
 732	cg_virtual_reg_t * regBaseColorB = regColorB;
 733	cg_virtual_reg_t * regBaseColorA = regColorA;
 734	cg_virtual_reg_t * regBaseColor565 = regColor565;
 735
 736	for (size_t unit = 0; unit < EGL_NUM_TEXTURE_UNITS; ++unit) {
 737		if (m_State->m_Texture[unit].Enabled) {
 738
 739			//Color texColor; 
 740			cg_virtual_reg_t * regTexColorR;			
 741			cg_virtual_reg_t * regTexColorG;			
 742			cg_virtual_reg_t * regTexColorB;			
 743			cg_virtual_reg_t * regTexColorA;
 744			cg_virtual_reg_t * regTexColor565;
 745
 746			GenerateFetchTexColor(procedure, block, unit, fragmentInfo, 
 747								  regTexColorR, regTexColorG, regTexColorB, regTexColorA, regTexColor565);
 748
 749
 750			if (m_State->m_Texture[unit].Mode == RasterizerState::TextureModeCombine) {
 751
 752				//Color arg[3];
 753				cg_virtual_reg_t * regArgR[3];			
 754				cg_virtual_reg_t * regArgG[3];			
 755				cg_virtual_reg_t * regArgB[3];			
 756				cg_virtual_reg_t * regArgA[3];
 757				cg_virtual_reg_t * regArg565[3];
 758
 759				for (size_t idx = 0; idx < 3; ++idx) {
 760					//Color rgbIn;
 761					cg_virtual_reg_t * regRgbInR;			
 762					cg_virtual_reg_t * regRgbInG;			
 763					cg_virtual_reg_t * regRgbInB;			
 764					cg_virtual_reg_t * regRgbInA;			
 765					cg_virtual_reg_t * regRgbIn565;
 766
 767					//U8 alphaIn;
 768					cg_virtual_reg_t * regAlphaIn;
 769
 770					switch (m_State->m_Texture[unit].CombineSrcRGB[idx]) {
 771					case RasterizerState::TextureCombineSrcTexture:
 772						//rgbIn = texColor;
 773						{
 774							regRgbInR = regTexColorR;
 775							regRgbInG = regTexColorG;
 776							regRgbInB = regTexColorB;
 777							regRgbInA = regTexColorA;
 778							regRgbIn565 = regTexColor565;
 779						}
 780						break;
 781
 782					case RasterizerState::TextureCombineSrcConstant:
 783						//rgbIn = m_State->m_Texture[unit].EnvColor;
 784						{
 785							regRgbInR = cg_virtual_reg_create(procedure, cg_reg_type_general);
 786							regRgbInG = cg_virtual_reg_create(procedure, cg_reg_type_general);
 787							regRgbInB = cg_virtual_reg_create(procedure, cg_reg_type_general);
 788							regRgbInA = cg_virtual_reg_create(procedure, cg_reg_type_general);
 789
 790							LDI		(regRgbInR, m_State->m_Texture[unit].EnvColor.r);
 791							LDI		(regRgbInG, m_State->m_Texture[unit].EnvColor.g);
 792							LDI		(regRgbInB, m_State->m_Texture[unit].EnvColor.b);
 793							LDI		(regRgbInA, m_State->m_Texture[unit].EnvColor.a);
 794
 795							regRgbIn565 = Color565FromRGB(block, regRgbInR, regRgbInG, regRgbInB);
 796						}
 797						break;
 798
 799					case RasterizerState::TextureCombineSrcPrimaryColor:
 800						//rgbIn = baseColor;
 801						{
 802							regRgbInR = regBaseColorR;
 803							regRgbInG = regBaseColorG;
 804							regRgbInB = regBaseColorB;
 805							regRgbInA = regBaseColorA;
 806							regRgbIn565 = regBaseColor565;
 807						}
 808
 809						break;
 810
 811					case RasterizerState::TextureCombineSrcPrevious:
 812						//rgbIn = color;
 813						{
 814							regRgbInR = regColorR;
 815							regRgbInG = regColorG;
 816							regRgbInB = regColorB;
 817							regRgbInA = regColorA;
 818							regRgbIn565 = regColor565;
 819						}
 820						break;
 821					}
 822
 823					switch (m_State->m_Texture[unit].CombineSrcAlpha[idx]) {
 824					case RasterizerState::TextureCombineSrcTexture:
 825						//alphaIn = texColor.a;
 826						regAlphaIn = regTexColorA;
 827						break;
 828
 829					case RasterizerState::TextureCombineSrcConstant:
 830						//alphaIn = m_State->m_Texture[unit].EnvColor.a;
 831						{
 832							regAlphaIn = cg_virtual_reg_create(procedure, cg_reg_type_general);
 833							LDI		(regAlphaIn, m_State->m_Texture[unit].EnvColor.a);
 834						}
 835
 836						break;
 837
 838					case RasterizerState::TextureCombineSrcPrimaryColor:
 839						//alphaIn = baseColor.a;
 840						regAlphaIn = regBaseColorA;
 841						break;
 842
 843					case RasterizerState::TextureCombineSrcPrevious:
 844						//alphaIn = color.a;
 845						regAlphaIn = regColorA;
 846						break;
 847					}
 848
 849					//U8 alphaOut;
 850					cg_virtual_reg_t * regAlphaOut;
 851
 852					if (m_State->m_Texture[unit].CombineOpAlpha[idx] == RasterizerState::TextureCombineOpSrcAlpha) {
 853						//alphaOut = alphaIn;
 854						regAlphaOut = regAlphaIn;
 855					} else {
 856						//alphaOut = 0xFF - alphaIn;
 857						DECL_CONST_REG	(constantMaxColor, 0xff);
 858
 859						regAlphaOut = Sub(block, constantMaxColor, regAlphaIn);
 860					}
 861
 862					switch (m_State->m_Texture[unit].CombineOpRGB[idx]) {
 863					case RasterizerState::TextureCombineOpSrcColor:
 864						//arg[idx] = Color(rgbIn.r, rgbIn.g, rgbIn.b, alphaOut);
 865						{
 866							regArgR[idx] = regRgbInR;
 867							regArgG[idx] = regRgbInG;
 868							regArgB[idx] = regRgbInB;
 869							regArg565[idx] = regRgbIn565;
 870							regArgA[idx] = regAlphaOut;
 871						}
 872						break;
 873
 874					case RasterizerState::TextureCombineOpOneMinusSrcColor:
 875						//arg[idx] = Color(0xFF - rgbIn.r, 0xFF - rgbIn.g, 0xFF - rgbIn.b, alphaOut);
 876						{
 877							DECL_CONST_REG	(constantMaxColor, 0xff);
 878
 879							regArgR[idx] = Sub(block, constantMaxColor, regRgbInR);
 880							regArgG[idx] = Sub(block, constantMaxColor, regRgbInG);
 881							regArgB[idx] = Sub(block, constantMaxColor, regRgbInB);
 882							regArg565[idx] = Color565FromRGB(block, regArgR[idx], regArgG[idx], regArgB[idx]);
 883							regArgA[idx] = regAlphaOut;
 884						}
 885						break;
 886
 887					case RasterizerState::TextureCombineOpSrcAlpha:
 888						//arg[idx] = Color(rgbIn.a, rgbIn.a, rgbIn.a, alphaOut);
 889						{
 890							regArgR[idx] = regArgG[idx] = regArgB[idx] = regRgbInA;
 891							regArg565[idx] = Color565FromRGB(block, regArgR[idx], regArgG[idx], regArgB[idx]);
 892							regArgA[idx] = regAlphaOut;
 893						}
 894
 895						break;
 896
 897					case RasterizerState::TextureCombineOpOneMinusSrcAlpha:
 898						//arg[idx] = Color(0xFF - rgbIn.a, 0xFF - rgbIn.a, 0xFF - rgbIn.a, alphaOut);
 899						{
 900							DECL_CONST_REG	(constantMaxColor, 0xff);
 901
 902							regArgR[idx] = regArgG[idx] = regArgB[idx] = Sub(block, constantMaxColor, regRgbInA);
 903							regArg565[idx] = Color565FromRGB(block, regArgR[idx], regArgG[idx], regArgB[idx]);
 904							regArgA[idx] = regAlphaOut;
 905						}
 906
 907						break;
 908					}
 909				}
 910
 911				//U8 combineAlpha;
 912				cg_virtual_reg_t * regCombineAlpha;
 913
 914				switch (m_State->m_Texture[unit].CombineFuncAlpha) {
 915				case RasterizerState::TextureModeCombineReplace:
 916					{
 917						//combineAlpha = MulU8(arg[0].a, 0xFF, scaleAlpha);
 918						regCombineAlpha = regArgA[0];
 919					}
 920
 921					break;
 922
 923				case RasterizerState::TextureModeCombineModulate:
 924					//combineAlpha = MulU8(arg[0].a, arg[1].a, scaleAlpha);
 925					regCombineAlpha = Mul255(block, regArgA[0], regArgA[1]);
 926					break;
 927
 928				case RasterizerState::TextureModeCombineAdd:
 929					//combineAlpha = AddU8(arg[0].a, arg[1].a, scaleAlpha);
 930					regCombineAlpha = Add(block, regArgA[0], regArgA[1]);
 931					break;
 932
 933				case RasterizerState::TextureModeCombineAddSigned:
 934					//combineAlpha = AddSignedU8(arg[0].a, arg[1].a, scaleAlpha);
 935					regCombineAlpha = AddSigned(block, regArgA[0], regArgA[1]);
 936					break;
 937
 938				case RasterizerState::TextureModeCombineInterpolate:
 939					//combineAlpha = InterpolateU8(arg[0].a, arg[1].a, arg[2].a, scaleAlpha);
 940					//regCombineAlpha = Blend255(block, regArgA[0], regArgA[1], regArgA[2]);
 941					regCombineAlpha = Blend255(block, regArgA[1], regArgA[0], regArgA[2]);
 942					break;
 943
 944				case RasterizerState::TextureModeCombineSubtract:
 945					//combineAlpha = SubU8(arg[0].a, arg[1].a, scaleAlpha);
 946					regCombineAlpha = Sub(block, regArgA[0], regArgA[1]);
 947					break;
 948				}
 949
 950				switch (m_State->m_Texture[unit].CombineFuncRGB) {
 951				case RasterizerState::TextureModeCombineReplace:
 952					//color = Color(
 953					//		MulU8(arg[0].r, 0xFF, scaleRGB), 
 954					//		MulU8(arg[0].g, 0xFF, scaleRGB), 
 955					//		MulU8(arg[0].b, 0xFF, scaleRGB), 
 956					//		combineAlpha); 
 957					regColorR = regArgR[0];
 958					regColorG = regArgG[0];
 959					regColorB = regArgB[0];
 960					regColorA = regCombineAlpha;
 961					break;
 962
 963				case RasterizerState::TextureModeCombineModulate:
 964					//color = 
 965					//	Color(
 966					//		MulU8(arg[0].r, arg[1].r, scaleRGB), 
 967					//		MulU8(arg[0].g, arg[1].g, scaleRGB), 
 968					//		MulU8(arg[0].b, arg[1].b, scaleRGB), 
 969					//		combineAlpha); 
 970					regColorR = Mul255(block, regArgR[0], regArgR[1]);
 971					regColorG = Mul255(block, regArgG[0], regArgG[1]);
 972					regColorB = Mul255(block, regArgB[0], regArgB[1]);
 973					regColorA = regCombineAlpha;
 974					break;
 975
 976				case RasterizerState::TextureModeCombineAdd:
 977					//color = 
 978					//	Color(
 979					//		AddU8(arg[0].r, arg[1].r, scaleRGB), 
 980					//		AddU8(arg[0].g, arg[1].g, scaleRGB), 
 981					//		AddU8(arg[0].b, arg[1].b, scaleRGB), 
 982					//		combineAlpha); 
 983					regColorR = Add(block, regArgR[0], regArgR[1]);
 984					regColorG = Add(block, regArgG[0], regArgG[1]);
 985					regColorB = Add(block, regArgB[0], regArgB[1]);
 986					regColorA = regCombineAlpha;
 987					break;
 988
 989				case RasterizerState::TextureModeCombineAddSigned:
 990					//color = 
 991					//	Color(
 992					//		AddSignedU8(arg[0].r, arg[1].r, scaleRGB), 
 993					//		AddSignedU8(arg[0].g, arg[1].g, scaleRGB), 
 994					//		AddSignedU8(arg[0].b, arg[1].b, scaleRGB), 
 995					//		combineAlpha); 
 996					regColorR = AddSigned(block, regArgR[0], regArgR[1]);
 997					regColorG = AddSigned(block, regArgG[0], regArgG[1]);
 998					regColorB = AddSigned(block, regArgB[0], regArgB[1]);
 999					regColorA = regCombineAlpha;
1000					break;
1001
1002				case RasterizerState::TextureModeCombineInterpolate:
1003					//color =
1004					//	Color(
1005					//		InterpolateU8(arg[0].r, arg[1].r, arg[2].r, scaleRGB),
1006					//		InterpolateU8(arg[0].g, arg[1].g, arg[2].g, scaleRGB),
1007					//		InterpolateU8(arg[0].b, arg[1].b, arg[2].b, scaleRGB),
1008					//		combineAlpha); 
1009					//regColorR = Blend255(block, regArgR[0], regArgR[1], regArgR[2]);
1010					//regColorG = Blend255(block, regArgG[0], regArgG[1], regArgG[2]);
1011					//regColorB = Blend255(block, regArgB[0], regArgB[1], regArgB[2]);
1012					regColorR = Blend255(block, regArgR[1], regArgR[0], regArgR[2]);
1013					regColorG = Blend255(block, regArgG[1], regArgG[0], regArgG[2]);
1014					regColorB = Blend255(block, regArgB[1], regArgB[0], regArgB[2]);
1015					regColorA = regCombineAlpha;
1016					break;
1017
1018				case RasterizerState::TextureModeCombineSubtract:
1019					//color = 
1020					//	Color(
1021					//		SubU8(arg[0].r, arg[1].r, scaleRGB), 
1022					//		SubU8(arg[0].g, arg[1].g, scaleRGB), 
1023					//		SubU8(arg[0].b, arg[1].b, scaleRGB), 
1024					//		combineAlpha); 
1025					regColorR = Sub(block, regArgR[0], regArgR[1]);
1026					regColorG = Sub(block, regArgG[0], regArgG[1]);
1027					regColorB = Sub(block, regArgB[0], regArgB[1]);
1028					regColorA = regCombineAlpha;
1029					break;
1030
1031				case RasterizerState::TextureModeCombineDot3RGB:
1032				case RasterizerState::TextureModeCombineDot3RGBA:
1033
1034					//{
1035					//	U8 dotRGB = Dot3U8(arg[0], arg[1], scaleRGB);
1036					//	color = Color(dotRGB, dotRGB, dotRGB, combineAlpha);
1037					//}
1038					//{
1039					//	U8 dotRGB = Dot3U8(arg[0], arg[1], scaleRGB);
1040					//	U8 dotAlpha = Dot3U8(arg[0], arg[1], scaleAlpha);
1041					//	color = Color(dotRGB, dotRGB, dotRGB, dotAlpha);
1042					//}
1043
1044					regColorR = Dot3(block, regArgR, regArgG, regArgB); 
1045					regColorG = regColorB = regColorR;
1046
1047					if (m_State->m_Texture[unit].CombineFuncRGB == RasterizerState::TextureModeCombineDot3RGBA)
1048						regColorA = regColorR;
1049					else 
1050						regColorA = regCombineAlpha;
1051
1052					break;
1053				}
1054
1055				EGL_Fixed scaleAlpha = m_State->m_Texture[unit].ScaleAlpha;
1056
1057				if (scaleAlpha != EGL_ONE) {
1058					DECL_REG		(regResultA);
1059					DECL_CONST_REG	(regScaleAlpha, scaleAlpha);
1060
1061					FMUL			(regResultA, regColorA, regScaleAlpha);
1062
1063					regColorA = regResultA;
1064				}
1065
1066				// Clamp to 0 .. 0xff
1067				{
1068					DECL_REG		(regClampLow);
1069					DECL_REG		(regClampHigh);
1070					DECL_CONST_REG	(constantMaxColor, 0xff);
1071					DECL_CONST_REG	(constant0, 0);
1072
1073					MAX		(regClampLow, regColorA, constant0);
1074					MIN		(regClampHigh, regClampLow, constantMaxColor);
1075
1076					regColorA = regClampHigh;
1077				}
1078
1079				EGL_Fixed scaleRGB = m_State->m_Texture[unit].ScaleRGB;
1080	
1081				if (scaleRGB != EGL_ONE) {
1082					DECL_REG		(regResultR);
1083					DECL_REG		(regResultG);
1084					DECL_REG		(regResultB);
1085					DECL_CONST_REG	(regScaleRGB, scaleRGB);
1086
1087					FMUL			(regResultR, regColorR, regScaleRGB);
1088					FMUL			(regResultG, regColorG, regScaleRGB);
1089					FMUL			(regResultB, regColorB, regScaleRGB);
1090
1091					regColorR = regResultR;
1092					regColorG = regResultG;
1093					regColorB = regResultB;
1094					regColor565 = Color565FromRGB(block, regColorR, regColorG, regColorB);
1095				}
1096
1097				// Clamp to 0 .. 0xff
1098
1099				{
1100					DECL_REG		(regClampLowR);
1101					DECL_REG		(regClampHighR);
1102					DECL_REG		(regClampLowG);
1103					DECL_REG		(regClampHighG);
1104					DECL_REG		(regClampLowB);
1105					DECL_REG		(regClampHighB);
1106					DECL_CONST_REG	(constantMaxColor, 0xff);
1107					DECL_CONST_REG	(constant0, 0);
1108
1109					MAX		(regClampLowR, regColorR, constant0);
1110					MIN		(regClampHighR, regClampLowR, constantMaxColor);
1111					MAX		(regClampLowG, regColorG, constant0);
1112					MIN		(regClampHighG, regClampLowG, constantMaxColor);
1113					MAX		(regClampLowB, regColorB, constant0);
1114					MIN		(regClampHighB, regClampLowB, constantMaxColor);
1115
1116					regColorR = regClampHighR;
1117					regColorG = regClampHighG;
1118					regColorB = regClampHighB;
1119					regColor565 = Color565FromRGB(block, regColorR, regColorG, regColorB);
1120				}
1121
1122			} else {
1123				switch (m_State->m_Texture[unit].InternalFormat) {
1124					default:
1125					case RasterizerState::TextureFormatAlpha:
1126						switch (m_State->m_Texture[unit].Mode) {
1127							case RasterizerState::TextureModeReplace:
1128								{
1129								//color = Color(color.r, color.g, color.b, texColor.a);
1130								regColorA = regTexColorA;
1131								}
1132
1133								break;
1134
1135							case RasterizerState::TextureModeModulate:
1136							case RasterizerState::TextureModeBlend:
1137							case RasterizerState::TextureModeAdd:
1138								{
1139								//color = Color(color.r, color.g, color.b, MulU8(color.a, texColor.a));
1140								regColorA = Mul255(block, regColorA, regTexColorA);
1141								}
1142
1143								break;
1144						}
1145						break;
1146
1147					case RasterizerState::TextureFormatLuminance:
1148					case RasterizerState::TextureFormatRGB565:
1149					case RasterizerState::TextureFormatRGB8:
1150						switch (m_State->m_Texture[unit].Mode) {
1151							case RasterizerState::TextureModeDecal:
1152							case RasterizerState::TextureModeReplace:
1153								{
1154								//color = Color(texColor.r, texColor.g, texColor.b, color.a);
1155								regColorR = regTexColorR;
1156								regColorG = regTexColorG;
1157								regColorB = regTexColorB;
1158								regColor565 = regTexColor565;
1159								}
1160
1161								break;
1162
1163							case RasterizerState::TextureModeModulate:
1164								{
1165								//color = Color(MulU8(color.r, texColor.r), 
1166								//	MulU8(color.g, texColor.g), MulU8(color.b, texColor.b), color.a);
1167								regColorR = Mul255(block, regColorR, regTexColorR);
1168								regColorG = Mul255(block, regColorG, regTexColorG);
1169								regColorB = Mul255(block, regColorB, regTexColorB);
1170								regColor565 = Color565FromRGB(block, regColorR, regColorG, regColorB);
1171								}
1172
1173								break;
1174
1175							case RasterizerState::TextureModeBlend:
1176								{
1177								//color = 
1178								//	Color(
1179								//		MulU8(color.r, 0xff - texColor.r) + MulU8(m_State->m_TexEnvColor.r, texColor.r),
1180								//		MulU8(color.g, 0xff - texColor.g) + MulU8(m_State->m_TexEnvColor.g, texColor.g),
1181								//		MulU8(color.b, 0xff - texColor.b) + MulU8(m_State->m_TexEnvColor.b, texColor.b),
1182								//		color.a);
1183
1184								regColorR   = Blend255(block, m_State->m_Texture[unit].EnvColor.r, regColorR, regTexColorR);
1185								regColorG   = Blend255(block, m_State->m_Texture[unit].EnvColor.g, regColorG, regTexColorG);
1186								regColorB   = Blend255(block, m_State->m_Texture[unit].EnvColor.b, regColorB, regTexColorB);
1187								regColor565 = Color565FromRGB(block, regColorR, regColorG, regColorB);
1188								}
1189
1190								break;
1191
1192							case RasterizerState::TextureModeAdd:
1193								{
1194								//color =
1195								//	Color(
1196								//		ClampU8(color.r + texColor.r),
1197								//		ClampU8(color.g + texColor.g),
1198								//		ClampU8(color.b + texColor.b),
1199								//		color.a);
1200
1201								regColorR	= AddSaturate255(block, regColorR, regTexColorR);
1202								regColorG	= AddSaturate255(block, regColorG, regTexColorG);
1203								regColorB	= AddSaturate255(block, regColorB, regTexColorB);
1204								regColor565 = Color565FromRGB(block, regColorR, regColorG, regColorB);
1205								}
1206
1207								break;
1208						}
1209						break;
1210
1211					case RasterizerState::TextureFormatLuminanceAlpha:
1212					case RasterizerState::TextureFormatRGBA5551:
1213					case RasterizerState::TextureFormatRGBA4444:
1214					case RasterizerState::TextureFormatRGBA8:
1215						switch (m_State->m_Texture[unit].Mode) {
1216							case RasterizerState::TextureModeReplace:
1217								{
1218								//color = texColor;
1219								regColorR = regTexColorR;
1220								regColorG = regTexColorG;
1221								regColorB = regTexColorB;
1222								regColorA = regTexColorA;
1223								regColor565 = regTexColor565;
1224								}
1225
1226								break;
1227
1228							case RasterizerState::TextureModeModulate:
1229								{
1230								//color = color * texColor;
1231								regColorR = Mul255(block, regColorR, regTexColorR);
1232								regColorG = Mul255(block, regColorG, regTexColorG);
1233								regColorB = Mul255(block, regColorB, regTexColorB);
1234								regColorA = Mul255(block, regColorA, regTexColorA);
1235								regColor565 = Color565FromRGB(block, regColorR, regColorG, regColorB);
1236								}
1237
1238								break;
1239
1240							case RasterizerState::TextureModeDecal:
1241								{
1242								//color = 
1243								//	Color(
1244								//		MulU8(color.r, 0xff - texColor.a) + MulU8(texColor.r, texColor.a),
1245								//		MulU8(color.g, 0xff - texColor.a) + MulU8(texColor.g, texColor.a),
1246								//		MulU8(color.b, 0xff - texColor.a) + MulU8(texColor.b, texColor.a),
1247								//		color.a);
1248
1249								regColorR   = Blend255(block, regColorR, regTexColorR, regTexColorA);
1250								regColorG   = Blend255(block, regColorG, regTexColorG, regTexColorA);
1251								regColorB   = Blend255(block, regColorB, regTexColorB, regTexColorA);
1252								regColor565 = Color565FromRGB(block, regColorR, regColorG, regColorB);
1253								}
1254
1255								break;
1256
1257							case RasterizerState::TextureModeBlend:
1258								{
1259								//color = 
1260								//	Color(
1261								//		MulU8(color.r, 0xff - texColor.r) + MulU8(m_State->m_TexEnvColor.r, texColor.r),
1262								//		MulU8(color.g, 0xff - texColor.g) + MulU8(m_State->m_TexEnvColor.g, texColor.g),
1263								//		MulU8(color.b, 0xff - texColor.b) + MulU8(m_State->m_TexEnvColor.b, texColor.b),
1264								//		MulU8(color.a, texColor.a));
1265								regColorR   = Blend255(block, m_State->m_Texture[unit].EnvColor.r, regColorR, regTexColorR);
1266								regColorG   = Blend255(block, m_State->m_Texture[unit].EnvColor.g, regColorG, regTexColorG);
1267								regColorB   = Blend255(block, m_State->m_Texture[unit].EnvColor.b, regColorB, regTexColorB);
1268								regColorA	= Mul255(block, regColorA, regTexColorA);
1269								regColor565 = Color565FromRGB(block, regColorR, regColorG, regColorB);
1270								}
1271
1272								break;
1273
1274							case RasterizerState::TextureModeAdd:
1275								{
1276								//color =
1277								//	Color(
1278								//		ClampU8(color.r + texColor.r),
1279								//		ClampU8(color.g + texColor.g),
1280								//		ClampU8(color.b + texColor.b),
1281								//		MulU8(color.a, texColor.a));
1282								regColorR	= AddSaturate255(block, regColorR, regTexColorR);
1283								regColorG	= AddSaturate255(block, regColorG, regTexColorG);
1284								regColorB	= AddSaturate255(block, regColorB, regTexColorB);
1285								regColorA	= Mul255(block, regColorA, regTexColorA);
1286								regColor565 = Color565FromRGB(block, regColorR, regColorG, regColorB);
1287								}
1288
1289								break;
1290						}
1291						break;
1292				}
1293			}
1294		}
1295	}
1296
1297	// fog
1298	if (m_State->m_Fog.Enabled) {
1299		//color = Color::Blend(color, m_State->m_FogColor, fogDensity);
1300		DECL_REG	(regFogColorR);
1301		DECL_REG	(regFogColorG);
1302		DECL_REG	(regFogColorB);
1303
1304		LDI		(regFogColorR, m_State->m_Fog.Color.r);
1305		LDI		(regFogColorG, m_State->m_Fog.Color.g);
1306		LDI		(regFogColorB, m_State->m_Fog.Color.b);
1307
1308		cg_virtual_reg_t * regFog = ClampTo255(block, fragmentInfo.regFog);
1309
1310		regColorR = Blend255(block, regFogColorR, regColorR, regFog);
1311		regColorG = Blend255(block, regFogColorG, regColorG, regFog);
1312		regColorB = Blend255(block, regFogColorB, regColorB, regFog);
1313
1314		// create RGB 565 representation
1315		regColor565 = Color565FromRGB(block, regColorR,	regColorG, regColorB);
1316	}
1317
1318	if (m_State->m_Alpha.Enabled) {
1319		//bool alphaTest;
1320		//U8 alpha = color.A();
1321		//U8 alphaRef = EGL_IntFromFixed(m_State->m_AlphaReference * 255);
1322		DECL_REG	(regAlphaRef);
1323		DECL_FLAGS	(regAlphaTest);
1324
1325		LDI		(regAlphaRef, EGL_IntFromFixed(m_State->m_Alpha.Reference * 255));
1326		CMP		(regAlphaTest, regColorA, regAlphaRef);
1327
1328		cg_opcode_t failedTest;
1329		
1330		switch (m_State->m_Alpha.Func) {
1331			default:
1332			case RasterizerState::CompFuncNever:	
1333				//alphaTest = false;					
1334				failedTest = cg_op_bra;
1335				break;
1336
1337			case RasterizerState::CompFuncLess:		
1338				//alphaTest = alpha < alphaRef;		
1339				failedTest = cg_op_bge;
1340				break;
1341
1342			case RasterizerState::CompFuncEqual:	
1343				//alphaTest = alpha == alphaRef;		
1344				failedTest = cg_op_bne;
1345				break;
1346
1347			case RasterizerState::CompFuncLEqual:	
1348				//alphaTest = alpha <= alphaRef;		
1349				failedTest = cg_op_bgt;
1350				break;
1351
1352			case RasterizerState::CompFuncGreater:	
1353				//alphaTest = alpha > alphaRef;		
1354				failedTest = cg_op_ble;
1355				break;
1356
1357			case RasterizerState::CompFuncNotEqual:	
1358				//alphaTest = alpha != alphaRef;		
1359				failedTest = cg_op_beq;
1360				break;
1361
1362			case RasterizerState::CompFuncGEqual:	
1363				//alphaTest = alpha >= alphaRef;		
1364				failedTest = cg_op_blt;
1365				break;
1366
1367			case RasterizerState::CompFuncAlways:	
1368				//alphaTest = true;					
1369				failedTest = cg_op_nop;
1370				break;
1371		}
1372
1373		//if (!alphaTest) {
1374		//	return;
1375		//}
1376		if (failedTest != cg_op_nop) {
1377			if (failedTest == cg_op_bra) {
1378				BRA		(continuation);
1379			} else {
1380				cg_create_inst_branch_cond(block, failedTest, regAlphaTest, continuation CG_INST_DEBUG_ARGS);
1381			}
1382		}
1383	}
1384
1385	if (m_State->m_Stencil.Enabled) {
1386
1387		//bool stencilTest;
1388		//U32 stencilRef = m_State->m_Stencil.Reference & m_State->ComparisonMask;
1389		//U32 stencilValue = m_Surface->GetStencilBuffer()[offset];
1390		//U32 stencil = stencilValue & m_State->m_Stencil.ComparisonMask;
1391		DECL_REG	(regStencilRef);
1392		DECL_REG	(regStencilMask);
1393		DECL_REG	(regStencilAddr);
1394		DECL_REG	(regStencilValue);
1395		DECL_REG	(regStencil);
1396		DECL_FLAGS	(regStencilTest);
1397
1398		cg_virtual_reg_t * regStencilBuffer =		LOAD_DATA(block, fragmentInfo.regInfo, OFFSET_SURFACE_STENCIL_BUFFER);
1399
1400		LDI		(regStencilRef, m_State->m_Stencil.Reference & m_State->m_Stencil.ComparisonMask);
1401		LDI		(regStencilMask, m_State->m_Stencil.ComparisonMask);
1402		ADD		(regStencilAddr, regStencilBuffer, regOffset4);
1403		LDW		(regStencilValue, regStencilAddr);
1404		AND		(regStencil, regStencilValue, regStencilMask);
1405		CMP		(regStencilTest, regStencil, regStencilRef);
1406
1407		cg_opcode_t passedTest;
1408
1409		switch (m_State->m_Stencil.Func) {
1410			default:
1411			case RasterizerState::CompFuncNever:	
1412				//stencilTest = false;				
1413				passedTest = cg_op_nop;
1414				break;
1415
1416			case RasterizerState::CompFuncLess:		
1417				//stencilTest = stencilRef < stencil;	
1418				passedTest = cg_op_bgt;
1419				break;
1420
1421			case RasterizerState::CompFuncEqual:	
1422				//stencilTest = stencilRef == stencil;
1423				passedTest = cg_op_beq;
1424				break;
1425
1426			case RasterizerState::CompFuncLEqual:	
1427				//stencilTest = stencilRef <= stencil;
1428				passedTest = cg_op_bge;
1429				break;
1430
1431			case RasterizerState::CompFuncGreater:	
1432				//stencilTest = stencilRef > stencil;	
1433				passedTest = cg_op_blt;
1434				break;
1435
1436			case RasterizerState::CompFuncNotEqual:	
1437				//stencilTest = stencilRef != stencil;
1438				passedTest = cg_op_bne;
1439				break;
1440
1441			case RasterizerState::CompFuncGEqual:	
1442				//stencilTest = stencilRef >= stencil;
1443				passedTest = cg_op_ble;
1444				break;
1445
1446			case RasterizerState::CompFuncAlways:	
1447				//stencilTest = true;					
1448				passedTest = cg_op_bra;
1449				break;
1450		}
1451
1452		// branch on stencil test
1453		cg_block_ref_t * labelStencilPassed = cg_block_ref_create(procedure);
1454		cg_block_ref_t * labelStencilBypassed = cg_block_ref_create(procedure);
1455
1456		if (passedTest != cg_op_nop) {
1457			cg_create_inst_branch_cond(block, passedTest,	regStencilTest, labelStencilPassed CG_INST_DEBUG_ARGS);
1458		}
1459
1460		//if (!stencilTest) {
1461		{
1462			cg_virtual_reg_t * regNewStencilValue;
1463
1464			switch (m_State->m_Stencil.Fail) {
1465				default:
1466				case RasterizerState::StencilOpKeep: 
1467					goto no_write;
1468
1469				case RasterizerState::StencilOpZero: 
1470					//stencilValue = 0; 
1471					regNewStencilValue = cg_virtual_reg_create(procedure, cg_reg_type_general);
1472
1473					LDI		(regNewStencilValue, 0);
1474					break;
1475
1476				case RasterizerState::StencilOpReplace: 
1477					//stencilValue = m_State->m_StencilReference; 
1478					regNewStencilValue = regStencilRef;
1479					break;
1480
1481				case RasterizerState::StencilOpIncr: 
1482					//if (stencilValue !=…

Large files files are truncated, but you can click here to view the full file