📄 tessellate.br
字号:
#include <stdio.h>
#include "timing.h"
#include "graphics.h"
extern int isdebug;
kernel void curve (float2 inp<>, out float height<>) {
float2 input={512.0,512.0};
input+=inp;
height = input.x*input.x+input.y*input.y*input.y*input.y*input.x;
}
kernel void curve2 (float4 input<>, out float2 height<>) {
float h1,h2;
curve(input.xy,h1);curve(input.zw,h2);
height.x=h1;height.y=h2;
}
void __print_cpu_inner (float a, float b, float c ,float d) {
printf("%f %f -> %f %f\n",a,b,c,d);
}
kernel void evaluateError(float input<>, float actual <>, out float error<>) {
error=abs((input-actual)/(actual+1));
}
kernel
void shouldTessellate (float4 input <>, float toler, out float output<>) {
float2 height;
curve2 (input,height);
{
float3 bottomleft= {input.z,input.w,height.y};
float3 topright = {input.x,input.y,height.x};
float3 center = .5*topright+.5*bottomleft;//lerp (topright,
// bottomleft,
// float3(.5,.5,.5));
float fheight,error;
curve(center.xy,fheight);
evaluateError(center.z,fheight,error);
output= error>=toler;
//printf(center.z,fheight,error,toler);
}
}
kernel void shouldTessellateCheat(float4 input<>, float numerator,float denom, out float output<>) {
float tmp = fmod((indexof output).x,denom);
float infrez =isinf(input).x?0.0:1.0;
if (tmp+.25>denom) tmp=0;
output=(tmp+.25<numerator)?infrez:0.0;
}
kernel void TessellateCheat4(float4 inputA<>, float4 inputB<>, float4 inputC<>, float4 inputD<>,
float toler,
out float4 outputA<>, out float4 outputB<>, out float4 outputC<>, out float4 outputD<>) {
float4 output;
float shouldDivide;
float4 input = inputA+inputB+inputC+inputD;
float2 topleft = input.xy;
float2 topright = input.zw;
float2 center = .5*topleft+.5*topright;//lerp (topleft,topright,float2(.5,.5));
shouldTessellate (input, toler, shouldDivide);
if (shouldDivide) {
output.xy = input.xy;
output.zw = center;
}else {
output=input;
}
outputA=output;
if (shouldDivide) {
output.zw = center;
output.xy = input.zw;
outputB=output;
output.xy = input.xw;
outputC=output;
output.xy = input.zy;
outputD=output;
}
}
kernel void TessellateCheat(float4 input<>,
float toler,
out float4 output<>) {
float shouldDivide;
float2 topleft = input.xy;
float2 topright = input.zw;
float2 center = .5*topleft+.5*topright;//lerp (topleft,topright,float2(.5,.5));
shouldTessellate (input, toler, shouldDivide);
if (shouldDivide) {
output.xy = input.xy;
output.zw = center;
}else {
output=input;
}
output=output;
if (shouldDivide) {
output.zw = center;
output.xy = input.zw;
output=output;
output.xy = input.xw;
output=output;
output.xy = input.zy;
output=output;
}
}
kernel void Tessellate(float4 input<>, float shouldDivide<>, vout[4] float4 output<>) {
float2 topleft = input.xy;
float2 topright = input.zw;
float2 center = .5*topleft+.5*topright;//lerp (topleft,topright,float2(.5,.5));
if (shouldDivide) {
output.xy = input.xy;
output.zw = center;
}else {
output=input;
}
push(output);
if (shouldDivide) {
output.zw = center;
output.xy = input.zw;
push(output);
output.xy = input.xw;
push(output);
output.xy = input.zy;
push(output);
}
}
char * charmalloc (unsigned int s) {
return (char*)malloc(s);
}
float4 * float4malloc(float f) {
return (float4 *)malloc((unsigned int)f);
}
float tof (int i) {
return (float)i;
}
float tofd (double i) {
return (float)i;
}
unsigned int schedulesizes [6][19]={{1,1,1,1,2,8,32,128,512,0,0,0,0,0,0,0,0,0},
{1,1,1,1,2,8,32,128,512,2048,0,0,0,0,0,0,0,0,0},
{1,1,1,1,2,8,32,128,512,0,0,0,0,0,0,0,0,0},
{1,1,1,1,1,2,5,13,39,116,346,1038,0,0,0,0,0,0,0},
{1,1,1,1,1,1,1,1,1,2,4,8,16,32,64,128,256,512,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
unsigned int schedulesizesY [6][19]={{32,128,512,2048,2048,2048,2048,2048,2048,0,0,0,0,0,0,0,0,0},
{32,128,512,2048,2048,2048,2048,2048,2048,2048,0,0,0,0,0,0,0,0,0},
{32,128,512,2048,2048,2048,2048,2048,2048,0,0,0,0,0,0,0,0,0},
{24,48,192,768,2048,2048,2048,2048,2048,2048,2048,2048,0,0,0,0,0,0,0},
{8,16,32,64,128,256,512,1024,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
kernel void filter(float4 a<>,vout [] float4 output<>) {
if (round(fmod((indexof a).x,2.0f))==1.0f) {
output=2.0f;
push(output);
}else {
output=1.0f;
push(output);
}
push(output);
}
#define NUMTESTS 4096
int haupto (int argc,char ** argv) {
int i,length = argc>1?atoi(argv[1]):2048;
float4 tests <length>;
float4 o <1>;
float4 *array;
array = (float4*)malloc(4*sizeof(float4)*length);
start = GetTimeMillis();
for (i=0;i<NUMTESTS;++i) {
filter (tests,o);
}
streamWrite(o,array);
stop=GetTimeMillis();
printf("Total Time %f\n",(stop-start)/(NUMTESTS*1000.));
return 0;
}
#define STRIDE 2048
#define SIZE 2048
int main (int argc, char ** argv) {
char usecpu=0;
char novout=0;
int i;
SetupMillisTimer();
for (i=0;i<argc;++i) {
char match=0;
int j;
if (strcmp(argv[i],"-cpu")==0) {
match=1;
usecpu=1;
}
if (strcmp(argv[i],"-novout")==0) {
match=1;
novout=1;
}
if (match) {
for (j=i+1;j<argc;++j) argv[j-1]=argv[j];
argc--;
i--;
}
}
{
float toler = argc>1?tofd(atof(argv[1])):tofd(.1);
int limit = argc>2?atoi(argv[2]):32;
int cheatdenom=argc>3?atoi(argv[3]):0;
int cheatnumerator=argc>4?atoi(argv[4]):1;
float4 * finaldata=float4malloc(4096*4096*sizeof(float4));
float4 input[4096]={float4(0,0,SIZE/2,SIZE/2),float4(0,SIZE/2,SIZE/2,SIZE),float4(SIZE/2,0,SIZE,SIZE/2),float4(SIZE/2,SIZE/2,SIZE,SIZE)};
float sizes[4096]={0};
float lastsize;
float4 polys<1,STRIDE>;
int ite;
if (usecpu) return haupt(argc,argv);
for (ite=4;ite<4096;++ite) input[ite]=float4((float)1.0/floor(.5),(float)1.0/floor(.5),(float)1.0/floor(.5),(float)1.0/floor(.5));
streamRead(polys,input);
if (cheatdenom) printf ("Warning: Cheating to get lower even results\n");
start = GetTimeMillis();
ite=0;
if (novout&&0) {
int i=0,j=0;
float4 last<1,16>;
for (i=0;schedulesizes[i][0];++i) {
start = GetTimeMillis();
for (j=0;schedulesizes[i][j];++j) {
unsigned int siz = (schedulesizes[i][j]);
unsigned int sizy = schedulesizesY[i][j];
float4 cur<siz,sizy>;
TessellateCheat(last,
toler,
cur);
streamSwap(last,cur);
}
streamWrite(last,finaldata);
stop = GetTimeMillis();
printf ("time for %d: %f\n",i,(float)(stop-start));
}
}else if (novout&&1) {
int i=0,j=0;
float4 lastA<1,4>;
float4 lastB<1,4>;
float4 lastC<1,4>;
float4 lastD<1,4>;
for (i=0;schedulesizes[i][0];++i) {
start = GetTimeMillis();
for (j=0;schedulesizes[i][j];++j) {
unsigned int siz = (schedulesizes[i][j]+3)/4;
unsigned int sizy = schedulesizesY[i][j];
float4 curA<siz,sizy>;
float4 curB<siz,sizy>;
float4 curC<siz,sizy>;
float4 curD<siz,sizy>;
TessellateCheat4(lastA, lastB, lastC, lastD,
toler,
curA, curB, curC, curD);
streamSwap(lastA,curA);
streamSwap(lastB,curB);
streamSwap(lastC,curC);
streamSwap(lastD,curD);
}
streamWrite(lastA,finaldata);
streamWrite(lastB,finaldata);
streamWrite(lastC,finaldata);
streamWrite(lastD,finaldata);
stop = GetTimeMillis();
printf ("time for %d: %f\n",i,(float)(stop-start));
}
}else
do {
int lastsizeint;ite++;
lastsize=streamSize(polys).y;
lastsizeint=(int)lastsize;
{
float doTessellate<lastsizeint,STRIDE>;
float4 nextPolys<1,STRIDE>;
cheatdenom?
shouldTessellateCheat(polys,
(float)cheatnumerator,
(float)cheatdenom,
doTessellate):
shouldTessellate(polys,toler,doTessellate);
Tessellate(polys,doTessellate,nextPolys);
streamSwap(polys,nextPolys);
}
if (ite<4096) sizes[ite-1]=streamSize(polys).y;
}while ((ite<STRIDE&&streamSize(polys).y==1)||(streamSize(polys).y<limit&&streamSize(polys).y!=lastsize));
{
float4 size = streamSize(polys);
streamWrite(polys,finaldata);
stop = GetTimeMillis();
{
char * data=charmalloc((SIZE+1)*(SIZE+1)*sizeof(char));
memset(data,0,sizeof(char)*(1+SIZE)*(1+SIZE));
for (ite=0;ite<4096&&sizes[ite];++ite) {
printf ("Size %f\n",sizes[ite]);
}
printf ("time %f\n",(float)(stop-start));
Draw(finaldata,size,data,SIZE+1);
writePng("polys.ppm",data,SIZE+1,SIZE+1);
free (data);
}
}
if (isdebug==2)
streamPrint(polys);
return 0;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -