material and texture classes moved to material.(cc,h)
2D texture mappings from textures.cc polished and moved to material.h
add ColourMap class and subclasses to make textures more flexible
two example textures: CheckersTexture and CloudTexture (using Perlin noise)
/* * cpuflags * * Simple tool which detects CPU capabilities * and outputs appropriate compiler flags. * * Usage: * cpuflags [gcc version] [intelc version] * * Returns: * [arch] * [gcc flags] * [intelc flags] * * The gcc/intelc version must be passed as floating point value, * e.g. 4.23 * * Copyright (C) 2008 Radek Brich <radek@brich.org> * * Based on x86cpucaps * by Osamu Kayasono <jacobi@jcom.home.ne.jp> * http://members.jcom.home.ne.jp/jacobi/linux/softwares.html * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */#include <stdio.h>#include <stdlib.h>#include <string.h>#define LEN_VENDORNAME 13#define VENDOR_INTEL 1#define VENDOR_AMD 2#define VENDOR_CYRIX 3#define VENDOR_CENTAUR 4#define VENDOR_TRANSMETA 5#define VENDOR_OTHERS 0struct simdcaps{ unsigned int has_mmx; unsigned int has_sse; unsigned int has_sse2; unsigned int has_sse3; unsigned int has_ssse3; unsigned int has_sse41; unsigned int has_sse42; unsigned int has_mmxext; unsigned int has_3dnowext; unsigned int has_3dnow;};/* CPU caps */#define FLAG_MMX (1<<23)#define FLAG_SSE (1<<25)#define FLAG_SSE2 (1<<26)/* CPU caps 2 */#define FLAG_SSE3 (1<<0)#define FLAG_SSSE3 (1<<9)#define FLAG_SSE41 (1<<19)#define FLAG_SSE42 (1<<20)/* AMD CPU caps */#define FLAG_MMXEXT (1<<22)#define FLAG_3DNOWEXT (1<<30)#define FLAG_3DNOW (1<<31)/* cpuid, from kernel source ( linux/include/asm-i386/processor.h ) */inline void cpuid(int op, int *eax, int *ebx, int *ecx, int *edx){ __asm__("cpuid" : "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=d" (*edx) : "a" (op));}/* * check SIMD capabilities */int x86cpucaps_simd(struct simdcaps *simd){ int ex[4]; memset(&(*simd),0,sizeof(struct simdcaps)); /* check CPU has CPUID */ cpuid(0,&ex[0],&ex[1],&ex[2],&ex[3]); if ( ex[0] < 1) return 1; cpuid(0x80000001,&ex[0],&ex[1],&ex[2],&ex[3]); if ( (ex[3] & FLAG_MMXEXT ) == FLAG_MMXEXT) simd->has_mmxext = 1; if ( (ex[3] & FLAG_3DNOW ) == FLAG_3DNOW) simd->has_3dnow = 1; if ( (ex[3] & FLAG_3DNOWEXT ) == FLAG_3DNOWEXT) simd->has_3dnowext = 1; cpuid(1,&ex[0],&ex[1],&ex[2],&ex[3]); if ( (ex[3] & FLAG_MMX ) == FLAG_MMX ) simd->has_mmx = 1; if ( (ex[3] & FLAG_SSE ) == FLAG_SSE ) simd->has_sse = 1; if ( (ex[3] & FLAG_SSE2 ) == FLAG_SSE2) simd->has_sse2 = 1; if ( (ex[2] & FLAG_SSE3 ) == FLAG_SSE3 ) simd->has_sse3 = 1; if ( (ex[2] & FLAG_SSSE3 ) == FLAG_SSSE3 ) simd->has_ssse3 = 1; if ( (ex[2] & FLAG_SSE41 ) == FLAG_SSE41 ) simd->has_sse41 = 1; if ( (ex[2] & FLAG_SSE42 ) == FLAG_SSE42 ) simd->has_sse42 = 1; /* SSE CPU supports mmxext too */ if (simd->has_sse == 1) simd->has_mmxext = 1; return 0;}/* * check CPU Family-Model-Stepping */int x86cpucaps_cpumodel(){ int ex[4]; int f = 0; /* check CPU has CPUID */ cpuid(0,&ex[0],&ex[1],&ex[2],&ex[3]); if ( ex[0] < 1) return f; cpuid(1,&ex[0],&ex[1],&ex[2],&ex[3]); f = ex[0] & 0x0fff; return f;}/* * check CPU Vendor */int x86cpucaps_vendor(char *vendorname){ int ex[4]; int f = 0; char vendorstr[LEN_VENDORNAME]; /* check CPU has CPUID */ cpuid(0,&ex[0],&ex[1],&ex[2],&ex[3]); if ( ex[0] < 1) return f; /* read Vendor Strings */ vendorstr[0] = ex[1] & 0xff; vendorstr[1] = (ex[1] >> 8) & 0xff; vendorstr[2] = (ex[1] >> 16) & 0xff; vendorstr[3] = (ex[1] >> 24) & 0xff; vendorstr[4] = ex[3] & 0xff; vendorstr[5] = (ex[3] >> 8) & 0xff; vendorstr[6] = (ex[3] >> 16) & 0xff; vendorstr[7] = (ex[3] >> 24) & 0xff; vendorstr[8] = ex[2] & 0xff; vendorstr[9] = (ex[2] >> 8) & 0xff; vendorstr[10]= (ex[2] >> 16) & 0xff; vendorstr[11]= (ex[2] >> 24) & 0xff; vendorstr[12]= '\0'; if ( strcmp(vendorstr, "GenuineIntel") == 0 ) f = VENDOR_INTEL; else if ( strcmp(vendorstr, "AuthenticAMD") == 0 ) f = VENDOR_AMD; else if ( strcmp(vendorstr, "CyrixInstead") == 0 ) f = VENDOR_CYRIX; else if ( strcmp(vendorstr, "CentaurHauls") == 0 ) f = VENDOR_CENTAUR; else if ( strcmp(vendorstr, "GenuineTMx86") == 0 ) f = VENDOR_TRANSMETA; strncpy(vendorname, vendorstr, LEN_VENDORNAME); return f;}int main(int argc, char **argv){ int family, model, stepping; char *arch, *gccarch, *gccsimd, *iccarch, *icctune, *iccsimd; int cpu_id = x86cpucaps_cpumodel(); char vendorname[LEN_VENDORNAME]; int vendor_id = x86cpucaps_vendor(vendorname); struct simdcaps simd; float gccver = 999.; float iccver = 999.; if (argc > 1) gccver = atof(argv[1]); if (argc > 2) iccver = atof(argv[2]); family = (cpu_id & 0xf00) >> 8; model = (cpu_id & 0x0f0) >> 4; stepping = cpu_id & 0x00f; switch (vendor_id) { case VENDOR_INTEL: if (family == 4) { arch = "i486"; } else if (family == 5) { if (model < 4) arch = "pentium"; else arch = "pentium-mmx"; } else if (family == 6) { if (model <= 1) arch = "pentiumpro"; else if (model < 7) arch = "pentium2"; else if (model < 12) arch = "pentium3"; else if (model < 14) arch = "pentium-m"; else if (model == 14) arch = "prescott"; // core else if (model == 15) arch = "core2"; } else if (family > 6) { /* family == 15 */ arch = "pentium4"; } else { arch = "i386"; } break; case VENDOR_AMD: if (family == 4) { if (model <= 9) arch = "i486"; else arch = "i586"; } else if (family == 5) { if (model <= 3) arch = "i586"; else if (model <= 7) arch = "k6"; else if (model == 8) arch = "k6-2"; else arch = "k6-3"; } else if (family == 6) { if (model <= 3) arch = "athlon"; else if (model == 4) arch = "athlon-tbird"; else arch = "athlon-xp"; } else if (family > 6) { arch = "k8"; } else { arch = "unknown"; } break; case VENDOR_CYRIX: if (family == 4) arch = "i586"; else if (family == 5) arch = "i586"; else if (family == 6) arch = "i686"; else arch = "unknown"; break; case VENDOR_CENTAUR: if (family == 5) arch = "i586"; else arch = "unknown"; break; case VENDOR_TRANSMETA: arch = "i686"; break; default: arch = "unknown"; break; } /* some targets not supported by older gcc */ gccarch = arch; if (gccver < (float)4.3) { if (!strcmp(gccarch, "core2")) gccarch = "pentium-m"; } if (gccver < (float)3.41) { if (!strcmp(gccarch, "prescott")) gccarch = "pentium4"; if (!strcmp(gccarch, "pentium-m")) gccarch = "pentium4"; } if (gccver < (float)3.4) { if (!strcmp(gccarch, "k8")) gccarch = "athlon-xp"; } if (gccver < (float)3.1) { if (strstr(gccarch, "athlon-") != NULL) gccarch = "athlon"; else if (strstr(gccarch, "k6-") != NULL) gccarch = "k6"; else if (!strcmp(gccarch, "pentium-mmx")) gccarch = "pentium"; else if (!strcmp(gccarch, "pentium2") || !strcmp(gccarch, "pentium3") || !strcmp(gccarch, "pentium4")) gccarch = "pentiumpro"; } if (gccver < (float)3.0) { if (!strcmp(gccarch, "athlon")) gccarch = "pentiumpro"; else if (!strcmp(gccarch, "k6")) gccarch = "pentium"; } if (gccver < (float)2.95) { if (!strcmp(gccarch, "pentiumpro")) gccarch = "i686"; else if (!strcmp(gccarch, "pentium")) gccarch = "i586"; } /* SIMD options */ x86cpucaps_simd(&simd); gccsimd = ""; if (gccver >= 3.1) { if ( simd.has_3dnow || simd.has_3dnowext ) gccsimd = "-m3dnow"; else { if (gccver >= 4.3) { if (simd.has_sse41 || simd.has_sse42) gccsimd = "-msse4 -mfpmath=sse"; else if (simd.has_ssse3) gccsimd = "-mssse3 -mfpmath=sse"; } else if ( gccver >= 3.4 && simd.has_sse3 ) gccsimd = "-msse3 -mfpmath=sse"; else if ( simd.has_sse2 ) gccsimd = "-msse2 -mfpmath=sse"; else if ( simd.has_sse ) gccsimd = "-msse"; else if ( simd.has_mmx ) gccsimd = "-mmmx"; } } /* IntelC options */ iccarch = arch; icctune = arch; iccsimd = ""; if (simd.has_sse41 || simd.has_sse42) iccsimd = "-xS"; else if (simd.has_ssse3) iccsimd = "-xT"; else if (simd.has_sse3) iccsimd = "-msse3 -xP"; else if (simd.has_sse2) iccsimd = "-msse2"; printf("%s\n", arch); /* GCC flags */ if (gccver >= 4.2) gccarch = "native";#ifdef __x86_64__ /* do not output i386 flags on x86_64 */ if (strcmp(gccarch, "core2") != 0 && strcmp(gccarch, "native") != 0) printf("%s\n", gccsimd); else#endif printf("-march=%s %s\n", gccarch, gccsimd); /* IntelC flags */ printf("-march=%s -mtune=%s %s\n", iccarch, icctune, iccsimd); return 0;}