Skip to content

Instantly share code, notes, and snippets.

@jbush001
Created January 11, 2015 16:23
Show Gist options
  • Save jbush001/dad09925e33afaee24ae to your computer and use it in GitHub Desktop.
Save jbush001/dad09925e33afaee24ae to your computer and use it in GitHub Desktop.
viewobj-da6881.cpp
# 1 "<built-in>"
# 1 "viewobj.cpp"
//
// Copyright (C) 2011-2015 Jeff Bush
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library 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
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the
// Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
// Boston, MA 02110-1301, USA.
//
#if 0 /* expanded by -frewrite-includes */
#include <stdio.h>
#endif /* expanded by -frewrite-includes */
# 20 "viewobj.cpp"
# 1 "../..//software/libc/include/stdio.h" 1
//
// Copyright (C) 2014 Jeff Bush
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library 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
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the
// Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
// Boston, MA 02110-1301, USA.
//
#ifndef __STDIO_H
#define __STDIO_H
#if 0 /* expanded by -frewrite-includes */
#include <stdarg.h>
#endif /* expanded by -frewrite-includes */
# 23 "../..//software/libc/include/stdio.h"
# 1 "../..//software/libc/include/stdarg.h" 1
//
// Copyright (C) 2014 Jeff Bush
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library 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
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the
// Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
// Boston, MA 02110-1301, USA.
//
#ifndef __STDARG_H
#define __STDARG_H
#define va_start(AP, LASTARG) __builtin_va_start(AP, LASTARG);
#define va_arg(AP, TYPE) __builtin_va_arg(AP, TYPE)
#define va_end(AP) __builtin_va_end(AP)
#define va_list __builtin_va_list
#endif
# 29 "../..//software/libc/include/stdarg.h"
# 24 "../..//software/libc/include/stdio.h" 2
#if 0 /* expanded by -frewrite-includes */
#include <stddef.h>
#endif /* expanded by -frewrite-includes */
# 24 "../..//software/libc/include/stdio.h"
# 1 "../..//software/libc/include/stddef.h" 1
//
// Copyright (C) 2014 Jeff Bush
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library 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
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the
// Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
// Boston, MA 02110-1301, USA.
//
#ifndef __STDDEF_H
#define __STDDEF_H
#define NULL 0
typedef unsigned int size_t;
typedef int ptrdiff_t;
#define offsetof(__type__, __member__) ((size_t) (&((__type__*) 0)->__member__))
#endif
# 31 "../..//software/libc/include/stddef.h"
# 25 "../..//software/libc/include/stdio.h" 2
#define EOF -1
typedef struct __file FILE;
extern FILE *stdout;
extern FILE *stdin;
extern FILE *stderr;
#ifdef __cplusplus
extern "C" {
#endif
# 37 "../..//software/libc/include/stdio.h"
void puts(const char *s);
void putchar(int ch);
int vfprintf(FILE *file, const char *format, va_list args);
int printf(const char *fmt, ...);
int sprintf(char *buf, const char *fmt, ...);
int snprintf(char *buf, size_t size, const char *fmt, ...);
void fputc(int ch, FILE *file);
void fputs(const char *s, FILE *file);
int fflush(FILE *file);
FILE *fopen(const char *filename, const char *mode);
size_t fread(void *ptr, size_t size, size_t nelem, FILE *stream);
size_t fwrite(const void *ptr, size_t size, size_t nelem, FILE *stream);
int fclose(FILE *stream);
#ifdef __cplusplus
}
#endif
# 55 "../..//software/libc/include/stdio.h"
#endif
# 57 "../..//software/libc/include/stdio.h"
# 21 "viewobj.cpp" 2
#if 0 /* expanded by -frewrite-includes */
#include <RenderContext.h>
#endif /* expanded by -frewrite-includes */
# 21 "viewobj.cpp"
# 1 "../..//software/librender/RenderContext.h" 1
//
// Copyright (C) 2011-2014 Jeff Bush
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library 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
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the
// Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
// Boston, MA 02110-1301, USA.
//
#ifndef __RENDER_CONTEXT_H
#define __RENDER_CONTEXT_H
#if 0 /* expanded by -frewrite-includes */
#include "RenderTarget.h"
#endif /* expanded by -frewrite-includes */
# 23 "../..//software/librender/RenderContext.h"
# 1 "../..//software/librender/RenderTarget.h" 1
//
// Copyright (C) 2011-2014 Jeff Bush
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library 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
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the
// Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
// Boston, MA 02110-1301, USA.
//
#ifndef __RENDER_TARGET_H
#define __RENDER_TARGET_H
#if 0 /* expanded by -frewrite-includes */
#include "RenderUtils.h"
#endif /* expanded by -frewrite-includes */
# 24 "../..//software/librender/RenderTarget.h"
# 1 "../..//software/librender/RenderUtils.h" 1
//
// Copyright (C) 2011-2014 Jeff Bush
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library 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
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the
// Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
// Boston, MA 02110-1301, USA.
//
#ifndef __RENDER_UTILS_H
#define __RENDER_UTILS_H
#if 0 /* expanded by -frewrite-includes */
#include <stdint.h>
#endif /* expanded by -frewrite-includes */
# 23 "../..//software/librender/RenderUtils.h"
# 1 "../..//software/libc/include/stdint.h" 1
//
// Copyright (C) 2014 Jeff Bush
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library 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
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the
// Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
// Boston, MA 02110-1301, USA.
//
#ifndef __STDINT_H
#define __STDINT_H
typedef int veci16_t __attribute__((__vector_size__(16 * sizeof(int))));
typedef unsigned int vecu16_t __attribute__((__vector_size__(16 * sizeof(int))));
typedef float vecf16_t __attribute__((__vector_size__(16 * sizeof(float))));
typedef char int8_t;
typedef unsigned char uint8_t;
typedef short int16_t;
typedef unsigned short uint16_t;
typedef int int32_t;
typedef unsigned int uint32_t;
typedef long long int int64_t;
typedef unsigned long long int uint64_t;
typedef unsigned int intptr_t;
#endif
# 38 "../..//software/libc/include/stdint.h"
# 24 "../..//software/librender/RenderUtils.h" 2
namespace librender
{
const int kCacheLineSize = 64;
template <typename T>
inline T min(const T &a, const T &b)
{
if (a < b)
return a;
else
return b;
}
template <typename T>
inline T max(const T &a, const T &b)
{
if (a > b)
return a;
else
return b;
}
// Flush a data cache line from both L1 and L2.
inline void dflush(unsigned int address)
{
asm("dflush %0" : : "s" (address));
}
inline vecf16_t splatf(float f)
{
return __builtin_nyuzi_makevectorf(f);
}
inline veci16_t splati(unsigned int i)
{
return __builtin_nyuzi_makevectori(i);
}
// Ensure all values in this vector are between 0.0 and 1.0
inline vecf16_t clampfv(vecf16_t in)
{
const vecf16_t zero = splatf(0.0f);
const vecf16_t one = splatf(1.0f);
vecf16_t a = __builtin_nyuzi_vector_mixf(__builtin_nyuzi_mask_cmpf_lt(in, zero), zero, in);
return __builtin_nyuzi_vector_mixf(__builtin_nyuzi_mask_cmpf_gt(a, one), one, a);
}
template<int MAX>
inline veci16_t saturateiv(veci16_t in)
{
return __builtin_nyuzi_vector_mixi(__builtin_nyuzi_mask_cmpi_ugt(in, splati(MAX)), splati(MAX), in);
}
// Return fractional part of value
inline vecf16_t fracv(vecf16_t in)
{
return in - __builtin_nyuzi_vitof(__builtin_nyuzi_vftoi(in));
}
inline vecf16_t absfv(vecf16_t in)
{
// Note that the cast will not perform a conversion.
return veci16_t(in) & splati(0x7fffffff);
}
inline float fabs_f(float val)
{
return val < 0.0 ? -val : val;
}
// Newton's method vector square root.
inline vecf16_t sqrtfv(vecf16_t value)
{
vecf16_t guess = value;
for (int iteration = 0; iteration < 6; iteration++)
guess = ((value / guess) + guess) / splatf(2.0f);
return guess;
}
// "Quake" fast inverse square root
// Note that the integer casts here do not perform float/int conversions
// but just interpret the numbers directly as the opposite type.
inline vecf16_t isqrtfv(vecf16_t number)
{
vecf16_t x2 = number * splatf(0.5f);
vecf16_t y = vecf16_t(splati(0x5f3759df) - (veci16_t(x2) >> splati(1)));
y = y * (splatf(1.5f) - (x2 * y * y));
return y;
}
}
#endif
# 120 "../..//software/librender/RenderUtils.h"
# 25 "../..//software/librender/RenderTarget.h" 2
#if 0 /* expanded by -frewrite-includes */
#include "Surface.h"
#endif /* expanded by -frewrite-includes */
# 25 "../..//software/librender/RenderTarget.h"
# 1 "../..//software/librender/Surface.h" 1
//
// Copyright (C) 2011-2014 Jeff Bush
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library 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
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the
// Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
// Boston, MA 02110-1301, USA.
//
#ifndef __SURFACE_H
#define __SURFACE_H
#if 0 /* expanded by -frewrite-includes */
#include <stdio.h>
#endif /* expanded by -frewrite-includes */
# 24 "../..//software/librender/Surface.h"
# 25 "../..//software/librender/Surface.h"
#if 0 /* expanded by -frewrite-includes */
#include <stdint.h>
#endif /* expanded by -frewrite-includes */
# 25 "../..//software/librender/Surface.h"
# 26 "../..//software/librender/Surface.h"
#if 0 /* expanded by -frewrite-includes */
#include <stdlib.h>
#endif /* expanded by -frewrite-includes */
# 26 "../..//software/librender/Surface.h"
# 1 "../..//software/libc/include/stdlib.h" 1
//
// Copyright (C) 2014 Jeff Bush
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library 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
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the
// Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
// Boston, MA 02110-1301, USA.
//
#ifndef __STDLIB_H
#define __STDLIB_H
#if 0 /* expanded by -frewrite-includes */
#include <stddef.h>
#endif /* expanded by -frewrite-includes */
# 23 "../..//software/libc/include/stdlib.h"
# 24 "../..//software/libc/include/stdlib.h"
typedef int (*cmpfun)(const void *, const void *);
#ifdef __cplusplus
extern "C" {
#endif
# 30 "../..//software/libc/include/stdlib.h"
void *calloc(size_t size, size_t numElements);
void *malloc(size_t size);
void *memalign(size_t size, size_t align);
void *realloc(void* oldmem, size_t bytes);
void free(void*);
void abort(void) __attribute__((noreturn));
void exit(int status) __attribute__((noreturn));
void qsort(void *base, size_t nel, size_t width, cmpfun cmp);
int atoi(const char *num);
int abs(int value);
#ifdef __cplusplus
}
#endif
# 46 "../..//software/libc/include/stdlib.h"
#endif
# 48 "../..//software/libc/include/stdlib.h"
# 27 "../..//software/librender/Surface.h" 2
#if 0 /* expanded by -frewrite-includes */
#include "RenderUtils.h"
#endif /* expanded by -frewrite-includes */
# 27 "../..//software/librender/Surface.h"
# 28 "../..//software/librender/Surface.h"
extern "C" void fast_clear64x64(unsigned int ptr, unsigned int stride, unsigned int color);
namespace librender
{
const int kBytesPerPixel = 4;
const int kTileSize = 64;
static_assert(__builtin_clz(kTileSize) & 1, "Tile size must be power of four");
//
// Surface is a chunk of 2D bitmap memory.
// Because this contains vector elements, this structure must be allocated on a cache boundary
// If this is to be used as a destination, the width and height must be a multiple of
// 64 bytes.
//
class Surface
{
public:
// This will allocate surface memory and free it automatically.
Surface(int fbWidth, int fbHeight);
// This will use the passed pointer as surface memory and will
// not attempt to free it.
Surface(int fbWidth, int fbHeight, void *fbBase);
~Surface();
// Write values to a 4x4 block, with lanes arranged as follows:
// 0 1 2 3
// 4 5 6 7
// 8 9 10 11
// 12 13 14 15
void writeBlockMasked(int left, int top, int mask, veci16_t values)
{
veci16_t ptrs = f4x4AtOrigin + splati(left * 4 + top * fStride);
__builtin_nyuzi_scatter_storei_masked(ptrs, values, mask);
}
// Read values from a 4x4 block, in same order as writeBlockMasked
veci16_t readBlock(int left, int top) const
{
veci16_t ptrs = f4x4AtOrigin + splati(left * 4 + top * fStride);
return __builtin_nyuzi_gather_loadi(ptrs);
}
// Set all 32-bit values in a tile to a predefined value.
void clearTile(int left, int top, unsigned int value)
{
if (kTileSize == 64 && fWidth - left >= 64 && fHeight - top >= 64)
{
fast_clear64x64(fBaseAddress + (left + top * fWidth) * kBytesPerPixel, fWidth * kBytesPerPixel,
value);
}
else
clearTileSlow(left, top, value);
}
// Push a tile from the L2 cache back to system memory
void flushTile(int left, int top);
veci16_t readPixels(veci16_t tx, veci16_t ty, unsigned short mask) const
{
veci16_t pointers = (ty * splati(fStride) + tx * splati(kBytesPerPixel))
+ splati(fBaseAddress);
return __builtin_nyuzi_gather_loadi_masked(pointers, mask);
}
inline int getWidth() const
{
return fWidth;
}
inline int getHeight() const
{
return fHeight;
}
inline int getStride() const
{
return fStride;
}
void *bits()
{
return (void*) fBaseAddress;
}
void *operator new(size_t size)
{
// Because this structure has vector members, it must be vector width aligned
return memalign(kCacheLineSize, size);
}
private:
void initializePointerVec();
void clearTileSlow(int left, int top, unsigned int value);
vecu16_t f4x4AtOrigin;
int fWidth;
int fHeight;
int fStride;
unsigned int fBaseAddress;
bool fOwnedPointer;
};
}
#endif
# 139 "../..//software/librender/Surface.h"
# 26 "../..//software/librender/RenderTarget.h" 2
namespace librender
{
//
// A set of surfaces to render to.
//
class RenderTarget
{
public:
void setColorBuffer(Surface *buffer)
{
fColorBuffer = buffer;
}
void setZBuffer(Surface *buffer)
{
fZBuffer = buffer;
}
Surface *getColorBuffer()
{
return fColorBuffer;
}
Surface *getZBuffer()
{
return fZBuffer;
}
private:
Surface *fColorBuffer = nullptr;
Surface *fZBuffer = nullptr;
};
}
#endif
# 64 "../..//software/librender/RenderTarget.h"
# 24 "../..//software/librender/RenderContext.h" 2
#if 0 /* expanded by -frewrite-includes */
#include "VertexShader.h"
#endif /* expanded by -frewrite-includes */
# 24 "../..//software/librender/RenderContext.h"
# 1 "../..//software/librender/VertexShader.h" 1
//
// Copyright (C) 2011-2014 Jeff Bush
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library 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
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the
// Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
// Boston, MA 02110-1301, USA.
//
#ifndef __VERTEX_SHADER_H
#define __VERTEX_SHADER_H
#if 0 /* expanded by -frewrite-includes */
#include <stdlib.h>
#endif /* expanded by -frewrite-includes */
# 24 "../..//software/librender/VertexShader.h"
# 25 "../..//software/librender/VertexShader.h"
#if 0 /* expanded by -frewrite-includes */
#include "RenderUtils.h"
#endif /* expanded by -frewrite-includes */
# 25 "../..//software/librender/VertexShader.h"
# 26 "../..//software/librender/VertexShader.h"
namespace librender
{
enum VertexParam
{
kParamX,
kParamY,
kParamZ,
kParamW
};
// This is subclassed by client programs to compute vertex parameters.
// Because this contains vector elements, it must be allocated on a cache boundary
class VertexShader
{
public:
// Vertex attributes go in, vertex parameters come out.
// Attributes are expected to be interleaved: v0a0 v0a1 v1a0 v1a1...
// This will process up to 16 vertices at a time.
void processVertices(float *outParams, const float *attribs, const void *inUniforms,
int numVertices) const;
int getNumParams() const
{
return fParamsPerVertex;
}
int getNumAttribs() const
{
return fAttribsPerVertex;
}
void *operator new(size_t size)
{
// Because this has vector members, it must be vector width aligned
return memalign(kCacheLineSize, size);
}
protected:
VertexShader(int attribsPerVertex, int paramsPerVertex);
virtual void shadeVertices(vecf16_t *outParams, const vecf16_t *inAttribs,
const void *inUniforms, int mask) const = 0;
private:
veci16_t fParamStepVector;
veci16_t fAttribStepVector;
int fParamsPerVertex;
int fAttribsPerVertex;
};
}
#endif
# 80 "../..//software/librender/VertexShader.h"
# 25 "../..//software/librender/RenderContext.h" 2
#if 0 /* expanded by -frewrite-includes */
#include "PixelShader.h"
#endif /* expanded by -frewrite-includes */
# 25 "../..//software/librender/RenderContext.h"
# 1 "../..//software/librender/PixelShader.h" 1
//
// Copyright (C) 2011-2014 Jeff Bush
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library 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
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the
// Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
// Boston, MA 02110-1301, USA.
//
#ifndef __PIXEL_SHADER_H
#define __PIXEL_SHADER_H
#if 0 /* expanded by -frewrite-includes */
#include <stdint.h>
#endif /* expanded by -frewrite-includes */
# 24 "../..//software/librender/PixelShader.h"
# 25 "../..//software/librender/PixelShader.h"
#if 0 /* expanded by -frewrite-includes */
#include "ParameterInterpolator.h"
#endif /* expanded by -frewrite-includes */
# 25 "../..//software/librender/PixelShader.h"
# 1 "../..//software/librender/ParameterInterpolator.h" 1
//
// Copyright (C) 2011-2014 Jeff Bush
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library 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
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the
// Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
// Boston, MA 02110-1301, USA.
//
#ifndef __PARAMETER_INTERPOLATOR_H
#define __PARAMETER_INTERPOLATOR_H
#if 0 /* expanded by -frewrite-includes */
#include <stdint.h>
#endif /* expanded by -frewrite-includes */
# 24 "../..//software/librender/ParameterInterpolator.h"
# 25 "../..//software/librender/ParameterInterpolator.h"
#if 0 /* expanded by -frewrite-includes */
#include "LinearInterpolator.h"
#endif /* expanded by -frewrite-includes */
# 25 "../..//software/librender/ParameterInterpolator.h"
# 1 "../..//software/librender/LinearInterpolator.h" 1
//
// Copyright (C) 2011-2014 Jeff Bush
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library 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
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the
// Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
// Boston, MA 02110-1301, USA.
//
#ifndef __LINEAR_INTERPOLATOR_H
#define __LINEAR_INTERPOLATOR_H
#if 0 /* expanded by -frewrite-includes */
#include "RenderUtils.h"
#endif /* expanded by -frewrite-includes */
# 23 "../..//software/librender/LinearInterpolator.h"
# 24 "../..//software/librender/LinearInterpolator.h"
namespace librender
{
//
// 2D linear interpolator. Given the value of a parameter at 3 points in a plane,
// determine the value at any other arbitrary point.
//
class LinearInterpolator
{
public:
void init(float x0, float y0, float c0, float x1,
float y1, float c1, float x2, float y2, float c2);
// Return values of this parameter at 16 locations given by the vectors
// x and y.
inline vecf16_t getValuesAt(vecf16_t x, vecf16_t y) const
{
return x * splatf(fGx) + y * splatf(fGy) + splatf(fC00);
}
private:
float fGx; // @C/@X
float fGy; // @C/@Y
float fC00; // Value of C at 0, 0
};
}
#endif
# 54 "../..//software/librender/LinearInterpolator.h"
# 26 "../..//software/librender/ParameterInterpolator.h" 2
namespace librender
{
const int kMaxParams = 16;
//
// Perform perspective correct interpolation of parameters across a triangle.
// The triangle parameters are set up in world coordinate space, but the interpolant
// values will be requested in screen space. This maps those values properly.
// The basic approach is described in the paper "Perspective-Correct Interpolation"
// by Kok-Lim Low.
//
// "the attribute value at point c in the image plane can be correctly derived by
// just linearly interpolating between I1/Z1 and I2/Z2, and then divide the
// interpolated result by 1/Zt, which itself can be derived by linear interpolation"
//
//
class ParameterInterpolator
{
public:
// Coordinates are in screen space (-1.0 -> 1.0)
void setUpTriangle(float x1, float y1, float z1,
float x2, float y2, float z2,
float x3, float y3, float z3);
// c1, c2, and c2 represent the value of the parameter at the three
// triangle points specified in setUpTriangle.
void setUpParam(int paramIndex, float c1, float c2, float c3);
// Compute 16 parameter values
// Note that this computes the value for *all* parameters associated with this
// triangle and stores them in the params array. The number of output params
// is determined by the maximum index passed to setUpParam.
void computeParams(vecf16_t x, vecf16_t y, vecf16_t params[], vecf16_t &outZValues) const;
private:
LinearInterpolator fOneOverZInterpolator;
LinearInterpolator fParamOverZInterpolator[kMaxParams];
int fNumParams = 0;
float fX0;
float fY0;
float fZ0;
float fX1;
float fY1;
float fZ1;
float fX2;
float fY2;
float fZ2;
};
}
#endif
# 81 "../..//software/librender/ParameterInterpolator.h"
# 26 "../..//software/librender/PixelShader.h" 2
#if 0 /* expanded by -frewrite-includes */
#include "RenderTarget.h"
#endif /* expanded by -frewrite-includes */
# 26 "../..//software/librender/PixelShader.h"
# 27 "../..//software/librender/PixelShader.h"
#if 0 /* expanded by -frewrite-includes */
#include "VertexShader.h"
#endif /* expanded by -frewrite-includes */
# 27 "../..//software/librender/PixelShader.h"
# 28 "../..//software/librender/PixelShader.h"
#if 0 /* expanded by -frewrite-includes */
#include "Texture.h"
#endif /* expanded by -frewrite-includes */
# 28 "../..//software/librender/PixelShader.h"
# 1 "../..//software/librender/Texture.h" 1
//
// Copyright (C) 2011-2014 Jeff Bush
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library 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
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the
// Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
// Boston, MA 02110-1301, USA.
//
#ifndef __TEXTURE_SAMPLER_H
#define __TEXTURE_SAMPLER_H
#if 0 /* expanded by -frewrite-includes */
#include <stdint.h>
#endif /* expanded by -frewrite-includes */
# 24 "../..//software/librender/Texture.h"
# 25 "../..//software/librender/Texture.h"
#if 0 /* expanded by -frewrite-includes */
#include "Surface.h"
#endif /* expanded by -frewrite-includes */
# 25 "../..//software/librender/Texture.h"
# 26 "../..//software/librender/Texture.h"
namespace librender
{
const int kMaxMipLevels = 8;
class Texture
{
public:
Texture();
void setMipSurface(int mipLevel, const Surface *surface);
void readPixels(vecf16_t u, vecf16_t v, unsigned short mask, vecf16_t outChannels[4]) const;
void enableBilinearFiltering(bool enable)
{
fEnableBilinearFiltering = enable;
}
private:
const Surface *fMipSurfaces[kMaxMipLevels];
bool fEnableBilinearFiltering = false;
int fBaseMipBits;
int fMaxMipLevel = 0;
};
}
#endif
# 53 "../..//software/librender/Texture.h"
# 29 "../..//software/librender/PixelShader.h" 2
#if 0 /* expanded by -frewrite-includes */
#include "DrawState.h"
#endif /* expanded by -frewrite-includes */
# 29 "../..//software/librender/PixelShader.h"
# 1 "../..//software/librender/DrawState.h" 1
//
// Copyright (C) 2011-2015 Jeff Bush
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library 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
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the
// Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
// Boston, MA 02110-1301, USA.
//
#ifndef __DRAW_STATE_H
#define __DRAW_STATE_H
#if 0 /* expanded by -frewrite-includes */
#include "Texture.h"
#endif /* expanded by -frewrite-includes */
# 23 "../..//software/librender/DrawState.h"
# 24 "../..//software/librender/DrawState.h"
namespace librender
{
const int kMaxTextures = 4;
enum CullMode
{
kCullCw,
kCullCcw,
kCullNone
};
struct DrawState
{
bool fEnableZBuffer = false;
bool fEnableBlend = false;
const float *fVertexAttributes = nullptr;
int fNumVertices = 0;
const int *fIndices = nullptr;
int fNumIndices = 0;
const void *fUniforms = nullptr;
int fParamsPerVertex = 0;
float *fVertexParams = nullptr;
CullMode cullMode = kCullCw;
const class VertexShader *fVertexShader = nullptr;
const class PixelShader *fPixelShader = nullptr;
const Texture *fTextures[kMaxTextures];
};
}
#endif
# 57 "../..//software/librender/DrawState.h"
# 30 "../..//software/librender/PixelShader.h" 2
namespace librender
{
enum ColorChannel
{
kColorR,
kColorG,
kColorB,
kColorA
};
//
// This is overriden by the application to perform pixel shading.
//
class PixelShader
{
public:
virtual void shadePixels(const vecf16_t inParams[], vecf16_t outColor[4],
const void *uniforms, const Texture * const sampler[kMaxTextures],
unsigned short mask) const = 0;
};
}
#endif
# 57 "../..//software/librender/PixelShader.h"
# 26 "../..//software/librender/RenderContext.h" 2
#if 0 /* expanded by -frewrite-includes */
#include "SliceAllocator.h"
#endif /* expanded by -frewrite-includes */
# 26 "../..//software/librender/RenderContext.h"
# 1 "../..//software/librender/SliceAllocator.h" 1
//
// Copyright (C) 2011-2014 Jeff Bush
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library 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
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the
// Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
// Boston, MA 02110-1301, USA.
//
#ifndef __SLICE_ALLOCATOR_H
#define __SLICE_ALLOCATOR_H
#if 0 /* expanded by -frewrite-includes */
#include <assert.h>
#endif /* expanded by -frewrite-includes */
# 23 "../..//software/librender/SliceAllocator.h"
# 1 "../..//software/libc/include/assert.h" 1
//
// Copyright (C) 2014 Jeff Bush
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library 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
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the
// Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
// Boston, MA 02110-1301, USA.
//
#ifndef __ASSERT_H
#define __ASSERT_H
#if 0 /* expanded by -frewrite-includes */
#include <stdlib.h>
#endif /* expanded by -frewrite-includes */
# 23 "../..//software/libc/include/assert.h"
# 24 "../..//software/libc/include/assert.h"
#ifdef NDEBUG
#define assert(ignore) ((void) 0)
#else
# 28 "../..//software/libc/include/assert.h"
#define assert(cond) if (!(cond)) { printf("ASSERT FAILED: %s:%d: %s\n", __FILE__, __LINE__, \
#cond); abort(); }
#endif
# 31 "../..//software/libc/include/assert.h"
#endif
# 33 "../..//software/libc/include/assert.h"
# 24 "../..//software/librender/SliceAllocator.h" 2
#if 0 /* expanded by -frewrite-includes */
#include <stddef.h>
#endif /* expanded by -frewrite-includes */
# 24 "../..//software/librender/SliceAllocator.h"
# 25 "../..//software/librender/SliceAllocator.h"
namespace librender
{
//
// This very quickly allocates short-lived objects by slicing them off the end
// of a larger chunk. It can only free all objects at once.
//
class SliceAllocator
{
public:
SliceAllocator(int arenaSize)
: fArenaBase((char*) malloc(arenaSize)),
fTotalSize(arenaSize),
fNextAlloc((char*) fArenaBase)
{
}
SliceAllocator(const SliceAllocator&) = delete;
SliceAllocator& operator=(const SliceAllocator&) = delete;
~SliceAllocator()
{
free(fArenaBase);
}
// This is thread safe and lock-free. Alignment must be a power of 2
void *alloc(size_t size, size_t alignment = 4)
{
char *nextAlloc;
char *alignedAlloc;
do
{
nextAlloc = fNextAlloc;
alignedAlloc = reinterpret_cast<char*>((reinterpret_cast<unsigned int>(nextAlloc)
+ alignment - 1) & ~(alignment - 1));
assert(alignedAlloc + size < fArenaBase + fTotalSize);
}
while (!__sync_bool_compare_and_swap(&fNextAlloc, nextAlloc, alignedAlloc + size));
return alignedAlloc;
}
// This is not thread safe. Caller must guarantee no other threads
// are calling other methods on the allocator when this is called
void reset()
{
fNextAlloc = fArenaBase;
}
size_t bytesUsed() const
{
return fNextAlloc - fArenaBase;
}
private:
char *fArenaBase;
unsigned int fTotalSize;
char * volatile fNextAlloc;
};
}
inline void *operator new(size_t size, librender::SliceAllocator *allocator)
{
return allocator->alloc(size);
}
inline void *operator new(size_t size, librender::SliceAllocator &allocator)
{
return allocator.alloc(size);
}
inline void *operator new[] (size_t size, librender::SliceAllocator *allocator)
{
return allocator->alloc(size);
}
inline void *operator new[] (size_t size, librender::SliceAllocator &allocator)
{
return allocator.alloc(size);
}
#endif
# 111 "../..//software/librender/SliceAllocator.h"
# 27 "../..//software/librender/RenderContext.h" 2
#if 0 /* expanded by -frewrite-includes */
#include "SliceArray.h"
#endif /* expanded by -frewrite-includes */
# 27 "../..//software/librender/RenderContext.h"
# 1 "../..//software/librender/SliceArray.h" 1
//
// Copyright (C) 2011-2014 Jeff Bush
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library 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
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the
// Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
// Boston, MA 02110-1301, USA.
//
#ifndef __SLICE_ARRAY_H
#define __SLICE_ARRAY_H
#if 0 /* expanded by -frewrite-includes */
#include "SliceAllocator.h"
#endif /* expanded by -frewrite-includes */
# 23 "../..//software/librender/SliceArray.h"
# 24 "../..//software/librender/SliceArray.h"
namespace librender
{
//
// Variable sized array that uses SliceAllocator. reset() must be called
// on this object before using it again after reset() is called on the
// allocator. This uses a fast, lock-free append.
// BUCKET size should be large enough to avoid needing multiple allocations,
// but small enough that it doesn't waste memory.
//
template <typename T, int BUCKET_SIZE>
class SliceArray
{
private:
struct Bucket;
public:
SliceArray() {}
SliceArray(const SliceArray&) = delete;
SliceArray& operator=(const SliceArray&) = delete;
void setAllocator(SliceAllocator *allocator)
{
fAllocator = allocator;
}
void sort()
{
if (!fFirstBucket)
return; // Empty
// Insertion sort
for (iterator i = begin().next(), e = end(); i != e; ++i)
{
iterator j = i;
while (j != begin() && *j.prev() > *j)
{
// swap
T temp = *j;
*j = *j.prev();
*j.prev() = temp;
--j;
}
}
}
void append(const T &copyFrom)
{
int index;
Bucket *bucket;
while (true)
{
// index and bucket must be read in this order to avoid a race
// condition. Because these are volatile, the compiler won't
// reorder them.
index = fNextBucketIndex;
bucket = fLastBucket;
if (index == BUCKET_SIZE || bucket == nullptr)
{
allocateBucket();
continue;
}
if (__sync_bool_compare_and_swap(&fNextBucketIndex, index, index + 1))
break;
}
bucket->items[index] = copyFrom;
}
void reset()
{
// Manually invoke destructor on items.
for (Bucket *bucket = fFirstBucket; bucket; bucket = bucket->next)
bucket->~Bucket();
fFirstBucket = nullptr;
fLastBucket = nullptr;
fNextBucketIndex = 0;
}
class iterator
{
public:
bool operator!=(const iterator &iter)
{
return fBucket != iter.fBucket || fIndex != iter.fIndex;
}
bool operator==(const iterator &iter)
{
return fBucket == iter.fBucket && fIndex == iter.fIndex;
}
const iterator &operator++()
{
// subtle: don't advance to next bucket if it is
// null, otherwise next() will not iterate to end()
// when it is on last item.
if (++fIndex == BUCKET_SIZE && fBucket->next)
{
fBucket = fBucket->next;
fIndex = 0;
}
return *this;
}
const iterator &operator--()
{
if (--fIndex < 0)
{
fBucket = fBucket->prev;
fIndex = BUCKET_SIZE - 1;
}
return *this;
}
T& operator*() const
{
return fBucket->items[fIndex];
}
iterator next() const
{
iterator tmp = *this;
++tmp;
return tmp;
}
iterator prev() const
{
iterator tmp = *this;
--tmp;
return tmp;
}
private:
friend class SliceArray;
iterator(Bucket *bucket, int index)
: fBucket(bucket),
fIndex(index)
{}
Bucket *fBucket;
int fIndex; // Index in current bucket
};
iterator begin() const
{
return iterator(fFirstBucket, 0);
}
iterator end() const
{
return iterator(fLastBucket, fNextBucketIndex);
}
private:
struct Bucket
{
Bucket *next = nullptr;
Bucket *prev = nullptr;
T items[BUCKET_SIZE];
};
void allocateBucket()
{
// Lock
do
{
while (fLock)
;
}
while (!__sync_bool_compare_and_swap(&fLock, 0, 1));
// Check first that someone didn't beat us to allocating
if (fNextBucketIndex == BUCKET_SIZE || fLastBucket == nullptr)
{
if (fLastBucket)
{
// Append to end of chain
Bucket *newBucket = new (fAllocator) Bucket;
newBucket->prev = fLastBucket;
fLastBucket->next = newBucket;
fLastBucket = newBucket;
}
else
{
// Allocate initial bucket
fFirstBucket = new (fAllocator) Bucket;
fLastBucket = fFirstBucket;
}
// We must update fNextBucketIndex after fLastBucket to avoid a race
// condition. Because they are volatile, the compiler shouldn't reorder them.
fNextBucketIndex = 0;
}
fLock = 0;
__sync_synchronize();
}
static int compareElements(const void *t1, const void *t2)
{
return *reinterpret_cast<const T*>(t1) > *reinterpret_cast<const T*>(t2) ? 1 : -1;
}
Bucket *fFirstBucket = nullptr;
Bucket * volatile fLastBucket = nullptr;
volatile int fNextBucketIndex = 0; // When the bucket is full, this will equal BUCKET_SIZE
SliceAllocator *fAllocator = nullptr;
volatile int fLock = 0;
};
}
#endif
# 247 "../..//software/librender/SliceArray.h"
# 28 "../..//software/librender/RenderContext.h" 2
#if 0 /* expanded by -frewrite-includes */
#include "DrawState.h"
#endif /* expanded by -frewrite-includes */
# 28 "../..//software/librender/RenderContext.h"
# 29 "../..//software/librender/RenderContext.h"
namespace librender
{
//
// Main interface for client applications to enqueue rendering commands.
//
class RenderContext
{
public:
RenderContext(unsigned int workingMemSize = 0x400000);
RenderContext(const RenderContext&) = delete;
RenderContext& operator=(const RenderContext&) = delete;
void setClearColor(float r, float g, float b);
void bindTarget(RenderTarget *target);
void bindShader(VertexShader *vertexShader, PixelShader *pixelShader);
void bindGeometry(const float *vertices, int numVertices, const int *indices, int numIndices);
void bindTexture(int textureIndex, Texture *texture)
{
fCurrentState.fTextures[textureIndex] = texture;
}
// XXX Unlike other state changes, this will be invalidated when finish() is called.
void bindUniforms(const void *uniforms, size_t size);
void enableZBuffer(bool enabled)
{
fCurrentState.fEnableZBuffer = enabled;
}
void enableBlend(bool enabled)
{
fCurrentState.fEnableBlend = enabled;
}
void submitDrawCommand();
void finish();
void enableWireframeMode(bool enable)
{
fWireframeMode = enable;
}
void setCullingMode(CullMode mode)
{
fCurrentState.cullMode = mode;
}
private:
struct Triangle
{
int sequenceNumber;
const DrawState *state;
float x0, y0, z0, x1, y1, z1, x2, y2, z2;
int x0Rast, y0Rast, x1Rast, y1Rast, x2Rast, y2Rast;
float *params;
bool woundCcw;
bool operator>(const Triangle &tri) const
{
return sequenceNumber > tri.sequenceNumber;
}
};
void shadeVertices(int index);
void setUpTriangle(int triangleIndex);
void fillTile(int x, int y);
void wireframeTile(int x, int y);
static void _shadeVertices(void *_castToContext, int x, int y, int z);
static void _setUpTriangle(void *_castToContext, int x, int y, int z);
static void _fillTile(void *_castToContext, int x, int y, int z);
static void _wireframeTile(void *_castToContext, int x, int y, int z);
void clipOne(int sequence, const DrawState &command, const float *params0, const float *params1,
const float *params2);
void clipTwo(int sequence, const DrawState &command, const float *params0, const float *params1,
const float *params2);
void enqueueTriangle(int sequence, const DrawState &command, const float *params0,
const float *params1, const float *params2);
typedef SliceArray<Triangle, 64> TriangleArray;
typedef SliceArray<DrawState, 32> DrawQueue;
RenderTarget *fRenderTarget = nullptr;
TriangleArray *fTiles = nullptr;
int fFbWidth = 0;
int fFbHeight = 0;
int fTileColumns = 0;
int fTileRows = 0;
SliceAllocator fAllocator;
DrawState fCurrentState;
DrawQueue fDrawQueue;
DrawQueue::iterator fRenderCommandIterator = fDrawQueue.end();
int fBaseSequenceNumber = 0;
unsigned int fClearColor = 0xff000000;
bool fWireframeMode = false;
};
}
#endif
# 129 "../..//software/librender/RenderContext.h"
# 22 "viewobj.cpp" 2
#if 0 /* expanded by -frewrite-includes */
#include <Surface.h>
#endif /* expanded by -frewrite-includes */
# 22 "viewobj.cpp"
# 23 "viewobj.cpp"
#if 0 /* expanded by -frewrite-includes */
#include "TextureShader.h"
#endif /* expanded by -frewrite-includes */
# 23 "viewobj.cpp"
# 1 "./TextureShader.h" 1
//
// Copyright (C) 2011-2014 Jeff Bush
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library 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
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the
// Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
// Boston, MA 02110-1301, USA.
//
#ifndef __TEXTURE_SHADER_H
#define __TEXTURE_SHADER_H
#if 0 /* expanded by -frewrite-includes */
#include <Matrix.h>
#endif /* expanded by -frewrite-includes */
# 24 "./TextureShader.h"
# 1 "../..//software/librender/Matrix.h" 1
//
// Copyright (C) 2011-2014 Jeff Bush
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library 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
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the
// Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
// Boston, MA 02110-1301, USA.
//
#ifndef __MATRIX_H
#define __MATRIX_H
#if 0 /* expanded by -frewrite-includes */
#include <stdio.h>
#endif /* expanded by -frewrite-includes */
# 23 "../..//software/librender/Matrix.h"
# 24 "../..//software/librender/Matrix.h"
#if 0 /* expanded by -frewrite-includes */
#include <string.h>
#endif /* expanded by -frewrite-includes */
# 24 "../..//software/librender/Matrix.h"
# 1 "../..//software/libc/include/string.h" 1
//
// Copyright (C) 2014 Jeff Bush
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library 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
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the
// Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
// Boston, MA 02110-1301, USA.
//
#ifndef __STRING_H
#define __STRING_H
#if 0 /* expanded by -frewrite-includes */
#include <stddef.h>
#endif /* expanded by -frewrite-includes */
# 23 "../..//software/libc/include/string.h"
# 24 "../..//software/libc/include/string.h"
#ifdef __cplusplus
extern "C" {
#endif
# 28 "../..//software/libc/include/string.h"
void *memcpy(void *dest, const void *src, size_t length);
void *memset(void *dest, int value, size_t length);
int strcmp(const char *str1, const char *str2);
int strcasecmp(const char *str1, const char *str2);
int strncasecmp(const char *str1, const char *str2, size_t length);
size_t strlen(const char *str);
char* strcpy(char *dest, const char *src);
char* strncpy(char *dest, const char *src, size_t length);
char *strchr(const char *string, int c);
char *strcat(char *c, const char *s);
#ifdef __cplusplus
}
#endif
# 43 "../..//software/libc/include/string.h"
#endif
# 45 "../..//software/libc/include/string.h"
# 25 "../..//software/librender/Matrix.h" 2
#if 0 /* expanded by -frewrite-includes */
#include <math.h>
#endif /* expanded by -frewrite-includes */
# 25 "../..//software/librender/Matrix.h"
# 1 "../..//software/libc/include/math.h" 1
//
// Copyright (C) 2014 Jeff Bush
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library 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
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the
// Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
// Boston, MA 02110-1301, USA.
//
#ifndef __MATH_H
#define __MATH_H
#define M_PI 3.1415
#ifdef __cplusplus
extern "C" {
#endif
# 28 "../..//software/libc/include/math.h"
double fmod(double val1, double val2);
double sin(double angle);
double cos(double angle);
double sqrt(double value);
#ifdef __cplusplus
}
#endif
# 37 "../..//software/libc/include/math.h"
#endif
# 39 "../..//software/libc/include/math.h"
# 26 "../..//software/librender/Matrix.h" 2
#if 0 /* expanded by -frewrite-includes */
#include "Vec3.h"
#endif /* expanded by -frewrite-includes */
# 26 "../..//software/librender/Matrix.h"
# 1 "../..//software/librender/Vec3.h" 1
//
// Copyright (C) 2011-2015 Jeff Bush
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library 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
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the
// Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
// Boston, MA 02110-1301, USA.
//
#ifndef __Vec3_H
#define __Vec3_H
#if 0 /* expanded by -frewrite-includes */
#include <math.h>
#endif /* expanded by -frewrite-includes */
# 23 "../..//software/librender/Vec3.h"
# 24 "../..//software/librender/Vec3.h"
namespace librender
{
class Vec3
{
public:
Vec3()
{
fValues[0] = 0.0f;
fValues[1] = 0.0f;
fValues[2] = 0.0f;
}
Vec3(float a, float b, float c)
{
fValues[0] = a;
fValues[1] = b;
fValues[2] = c;
}
Vec3 operator+(const Vec3 &other) const
{
Vec3 newVal;
for (int i = 0; i < 3; i++)
newVal.fValues[i] = fValues[i] + other.fValues[i];
return newVal;
}
Vec3 operator-(const Vec3 &other) const
{
Vec3 newVal;
for (int i = 0; i < 3; i++)
newVal.fValues[i] = fValues[i] - other.fValues[i];
return newVal;
}
Vec3 operator*(float other) const
{
Vec3 newVal;
for (int i = 0; i < 3; i++)
newVal.fValues[i] = fValues[i] * other;
return newVal;
}
Vec3 operator/(float other) const
{
Vec3 newVal;
float denom = 1.0 / other;
for (int i = 0; i < 3; i++)
newVal.fValues[i] = fValues[i] * denom;
return newVal;
}
float magnitude() const
{
float magSquared = 0.0;
for (int i = 0; i < 3; i++)
magSquared += fValues[i] * fValues[i];
return sqrt(magSquared);
}
Vec3 normalized() const
{
return *this / magnitude();
}
float &operator[](int index)
{
return fValues[index];
}
float operator[](int index) const
{
return fValues[index];
}
Vec3 crossProduct(const Vec3 &other) const
{
Vec3 result;
result.fValues[0] = fValues[1] * other.fValues[2] - fValues[2] * other.fValues[1];
result.fValues[1] = fValues[2] * other.fValues[0] - fValues[0] * other.fValues[2];
result.fValues[2] = fValues[0] * other.fValues[1] - fValues[1] * other.fValues[0];
return result;
}
void print() const
{
printf("%f %f %f\n", fValues[0], fValues[1], fValues[2]);
}
private:
float fValues[3];
};
}
#endif
# 127 "../..//software/librender/Vec3.h"
# 27 "../..//software/librender/Matrix.h" 2
#if 0 /* expanded by -frewrite-includes */
#include "RenderUtils.h"
#endif /* expanded by -frewrite-includes */
# 27 "../..//software/librender/Matrix.h"
# 28 "../..//software/librender/Matrix.h"
namespace librender
{
class Matrix
{
public:
Matrix()
{
memset(fValues, 0, sizeof(float) * 16);
fValues[0][0] = 1.0f;
fValues[1][1] = 1.0f;
fValues[2][2] = 1.0f;
fValues[3][3] = 1.0f;
}
Matrix(const float values[4][4])
{
for (int row = 0; row < 4; row++)
{
for (int col = 0; col < 4; col++)
fValues[row][col] = values[row][col];
}
}
Matrix(const Matrix &rhs)
{
memcpy((void*) fValues, rhs.fValues, sizeof(float) * 16);
}
Matrix &operator=(const Matrix &rhs)
{
memcpy((void*) fValues, rhs.fValues, sizeof(float) * 16);
return *this;
}
Matrix operator*(const Matrix &rhs) const
{
Matrix newMat;
for (int col = 0; col < 4; col++)
{
for (int row = 0; row < 4; row++)
{
float sum = 0.0f;
for (int i = 0; i < 4; i++)
sum += fValues[row][i] * rhs.fValues[i][col];
newMat.fValues[row][col] = sum;
}
}
return newMat;
}
Matrix &operator*=(const Matrix &rhs)
{
*this = *this * rhs;
return *this;
}
// Multiply 16 Vec3s by this matrix.
void mulVec(vecf16_t outVec[4], const vecf16_t inVec[4]) const
{
for (int row = 0; row < 4; row++)
{
vecf16_t sum = splatf(0.0f);
for (int col = 0; col < 4; col++)
sum += splatf(fValues[row][col]) * inVec[col];
outVec[row] = sum;
}
}
Matrix upper3x3() const
{
Matrix newMat = *this;
newMat.fValues[0][3] = 0.0f;
newMat.fValues[1][3] = 0.0f;
newMat.fValues[2][3] = 0.0f;
newMat.fValues[3][0] = 0.0f;
newMat.fValues[3][1] = 0.0f;
newMat.fValues[3][2] = 0.0f;
return newMat;
}
Matrix inverse() const
{
float newVals[4][4];
float s0 = fValues[0][0] * fValues[1][1] - fValues[1][0] * fValues[0][1];
float s1 = fValues[0][0] * fValues[1][2] - fValues[1][0] * fValues[0][2];
float s2 = fValues[0][0] * fValues[1][3] - fValues[1][0] * fValues[0][3];
float s3 = fValues[0][1] * fValues[1][2] - fValues[1][1] * fValues[0][2];
float s4 = fValues[0][1] * fValues[1][3] - fValues[1][1] * fValues[0][3];
float s5 = fValues[0][2] * fValues[1][3] - fValues[1][2] * fValues[0][3];
float c5 = fValues[2][2] * fValues[3][3] - fValues[3][2] * fValues[2][3];
float c4 = fValues[2][1] * fValues[3][3] - fValues[3][1] * fValues[2][3];
float c3 = fValues[2][1] * fValues[3][2] - fValues[3][1] * fValues[2][2];
float c2 = fValues[2][0] * fValues[3][3] - fValues[3][0] * fValues[2][3];
float c1 = fValues[2][0] * fValues[3][2] - fValues[3][0] * fValues[2][2];
float c0 = fValues[2][0] * fValues[3][1] - fValues[3][0] * fValues[2][1];
float invdet = 1.0f / (s0 * c5 - s1 * c4 + s2 * c3 + s3 * c2 - s4 * c1 + s5 * c0);
newVals[0][0] = (fValues[1][1] * c5 - fValues[1][2] * c4 + fValues[1][3] * c3) * invdet;
newVals[0][1] = (-fValues[0][1] * c5 + fValues[0][2] * c4 - fValues[0][3] * c3) * invdet;
newVals[0][2] = (fValues[3][1] * s5 - fValues[3][2] * s4 + fValues[3][3] * s3) * invdet;
newVals[0][3] = (-fValues[2][1] * s5 + fValues[2][2] * s4 - fValues[2][3] * s3) * invdet;
newVals[1][0] = (-fValues[1][0] * c5 + fValues[1][2] * c2 - fValues[1][3] * c1) * invdet;
newVals[1][1] = (fValues[0][0] * c5 - fValues[0][2] * c2 + fValues[0][3] * c1) * invdet;
newVals[1][2] = (-fValues[3][0] * s5 + fValues[3][2] * s2 - fValues[3][3] * s1) * invdet;
newVals[1][3] = (fValues[2][0] * s5 - fValues[2][2] * s2 + fValues[2][3] * s1) * invdet;
newVals[2][0] = (fValues[1][0] * c4 - fValues[1][1] * c2 + fValues[1][3] * c0) * invdet;
newVals[2][1] = (-fValues[0][0] * c4 + fValues[0][1] * c2 - fValues[0][3] * c0) * invdet;
newVals[2][2] = (fValues[3][0] * s4 - fValues[3][1] * s2 + fValues[3][3] * s0) * invdet;
newVals[2][3] = (-fValues[2][0] * s4 + fValues[2][1] * s2 - fValues[2][3] * s0) * invdet;
newVals[3][0] = (-fValues[1][0] * c3 + fValues[1][1] * c1 - fValues[1][2] * c0) * invdet;
newVals[3][1] = (fValues[0][0] * c3 - fValues[0][1] * c1 + fValues[0][2] * c0) * invdet;
newVals[3][2] = (-fValues[3][0] * s3 + fValues[3][1] * s1 - fValues[3][2] * s0) * invdet;
newVals[3][3] = (fValues[2][0] * s3 - fValues[2][1] * s1 + fValues[2][2] * s0) * invdet;
return Matrix(newVals);
}
Matrix transpose() const
{
float newVals[4][4];
for (int row = 0; row < 4; row++)
{
for (int col = 0; col < 4; col++)
newVals[row][col] = fValues[col][row];
}
return Matrix(newVals);
}
void print() const
{
for (int row = 0; row < 4; row++)
{
for (int col = 0; col < 4; col++)
printf("%g ", fValues[row][col]);
printf("\n");
}
}
// Rotate about an axis (which is expected to be unit length)
static Matrix getRotationMatrix(float angle, float x, float y, float z)
{
float s = sin(angle);
float c = cos(angle);
float t = 1.0f - c;
const float kMat1[4][4] = {
{ (t * x * x + c), (t * x * y - s * z), (t * x * y + s * y), 0.0f },
{ (t * x * y + s * z), (t * y * y + c), (t * x * z - s * x), 0.0f },
{ (t * x * y - s * y), (t * y * z + s * x), (t * z * z + c), 0.0f },
{ 0.0f, 0.0f, 0.0f, 1.0f }
};
return Matrix(kMat1);
}
static Matrix getTranslationMatrix(float x, float y, float z)
{
const float kValues[4][4] = {
{ 1.0f, 0.0f, 0.0f, x },
{ 0.0f, 1.0f, 0.0f, y },
{ 0.0f, 0.0f, 1.0f, z },
{ 0.0f, 0.0f, 0.0f, 1.0f },
};
return Matrix(kValues);
}
static Matrix getProjectionMatrix(float viewPortWidth, float viewPortHeight)
{
const float kAspectRatio = viewPortWidth / viewPortHeight;
const float kProjCoeff[4][4] = {
{ 1.0f / kAspectRatio, 0.0, 0.0, 0.0 },
{ 0.0, 1.0, 0.0, 0.0 },
{ 0.0, 0.0, 1.0, 0.0 },
{ 0.0, 0.0, 1.0, 0.0 },
};
return Matrix(kProjCoeff);
}
static Matrix getScaleMatrix(float scale)
{
const float kValues[4][4] = {
{ scale, 0.0f, 0.0f, 0.0f },
{ 0.0f, scale, 0.0f, 0.0f },
{ 0.0f, 0.0f, scale, 0.0f },
{ 0.0f, 0.0f, 0.0f, 1.0f },
};
return Matrix(kValues);
}
static Matrix lookAt(const Vec3 &location, const Vec3 &lookAt, const Vec3 &up)
{
Vec3 z = (lookAt - location).normalized();
Vec3 x = z.crossProduct(up).normalized();
Vec3 y = x.crossProduct(z).normalized();
const float cameraValues[4][4] = {
{ x[0], x[1], x[2], 0 },
{ y[0], y[1], y[2], 0 },
{ -z[0], -z[1], -z[2], 0 },
{ 0, 0, 0, 1 }
};
return Matrix(cameraValues) * getTranslationMatrix(-location[0], -location[1], -location[2]);
}
private:
float fValues[4][4];
};
}
#endif
# 258 "../..//software/librender/Matrix.h"
# 25 "./TextureShader.h" 2
#if 0 /* expanded by -frewrite-includes */
#include <VertexShader.h>
#endif /* expanded by -frewrite-includes */
# 25 "./TextureShader.h"
# 26 "./TextureShader.h"
#if 0 /* expanded by -frewrite-includes */
#include <PixelShader.h>
#endif /* expanded by -frewrite-includes */
# 26 "./TextureShader.h"
# 27 "./TextureShader.h"
#if 0 /* expanded by -frewrite-includes */
#include <RenderUtils.h>
#endif /* expanded by -frewrite-includes */
# 27 "./TextureShader.h"
# 28 "./TextureShader.h"
#if 0 /* expanded by -frewrite-includes */
#include <Texture.h>
#endif /* expanded by -frewrite-includes */
# 28 "./TextureShader.h"
# 29 "./TextureShader.h"
using namespace librender;
struct TextureUniforms
{
Matrix fMVPMatrix;
Matrix fNormalMatrix;
bool fHasTexture;
Vec3 fLightDirection;
float fAmbient;
float fDirectional;
};
class TextureVertexShader : public VertexShader
{
public:
TextureVertexShader()
: VertexShader(8, 9)
{
}
void shadeVertices(vecf16_t *outParams, const vecf16_t *inAttribs, const void *_uniforms,
int) const override
{
const TextureUniforms *uniforms = static_cast<const TextureUniforms*>(_uniforms);
// Multiply vertex position by mvp matrix
vecf16_t coord[4];
for (int i = 0; i < 3; i++)
coord[i] = inAttribs[i];
coord[3] = splatf(1.0f);
uniforms->fMVPMatrix.mulVec(outParams, coord);
// Copy texture coordinate
outParams[4] = inAttribs[3];
outParams[5] = inAttribs[4];
// Multiply normal
for (int i = 0; i < 3; i++)
coord[i] = inAttribs[i + 5];
coord[3] = splatf(1.0f);
uniforms->fNormalMatrix.mulVec(outParams + 6, coord);
}
};
class TexturePixelShader : public librender::PixelShader
{
public:
void shadePixels(const vecf16_t inParams[16], vecf16_t outColor[4],
const void *_castToUniforms, const Texture * const sampler[kMaxTextures],
unsigned short mask) const override
{
const TextureUniforms *uniforms = static_cast<const TextureUniforms*>(_castToUniforms);
// Determine lambertian illumination
vecf16_t dot = -inParams[2] * splatf(uniforms->fLightDirection[0])
+ -inParams[3] * splatf(uniforms->fLightDirection[1])
+ -inParams[4] * splatf(uniforms->fLightDirection[2]);
dot *= splatf(uniforms->fDirectional);
vecf16_t illumination = librender::clampfv(dot) + splatf(uniforms->fAmbient);
if (uniforms->fHasTexture)
{
sampler[0]->readPixels(inParams[0], inParams[1], mask, outColor);
outColor[kColorR] *= illumination;
outColor[kColorG] *= illumination;
outColor[kColorB] *= illumination;
}
else
{
outColor[kColorR] = illumination;
outColor[kColorB] = illumination;
outColor[kColorG] = illumination;
outColor[kColorA] = splatf(1.0);
}
}
};
#endif
# 110 "./TextureShader.h"
# 24 "viewobj.cpp" 2
struct FileHeader
{
unsigned int fileSize;
unsigned int numTextures;
unsigned int numMeshes;
};
struct TextureEntry
{
unsigned int offset;
unsigned int mipLevels;
short width;
short height;
};
struct MeshEntry
{
unsigned int offset;
unsigned int textureId;
unsigned int numVertices;
unsigned int numIndices;
};
const int kAttrsPerVertex = 8;
const int kBlockSize = 512;
static volatile unsigned int * const REGISTERS = (volatile unsigned int*) 0xffff0000;
void readBlock(unsigned int blockAddress, void *out)
{
int i;
unsigned int *ptr = (unsigned int*) out;
REGISTERS[0x30 / 4] = blockAddress;
for (i = 0; i < kBlockSize / 4; i++)
*ptr++ = REGISTERS[0x34 / 4];
}
char *readResourceFile()
{
char tmp[kBlockSize];
unsigned int fileSize;
char *resourceData;
// Read the first block to determine how large the rest of the file is.
readBlock(0, tmp);
fileSize = ((FileHeader*) tmp)->fileSize;
printf("reading resource file, %d bytes\n", fileSize);
resourceData = (char*) malloc(fileSize + kBlockSize);
memcpy(resourceData, tmp, kBlockSize);
for (int i = 1, len=(fileSize + kBlockSize - 1) / kBlockSize; i < len; i++)
readBlock(i * kBlockSize, resourceData + i * kBlockSize);
return resourceData;
}
int main()
{
// Set up resource data
char *resourceData = readResourceFile();
const FileHeader *resourceHeader = (FileHeader*) resourceData;
const TextureEntry *texHeader = (TextureEntry*)(resourceData + sizeof(FileHeader));
const MeshEntry *meshHeader = (MeshEntry*)(resourceData + sizeof(FileHeader) + resourceHeader->numTextures
* sizeof(TextureEntry));
Texture **textures = new Texture*[resourceHeader->numTextures];
printf("%d textures %d meshes\n", resourceHeader->numTextures, resourceHeader->numMeshes);
// Create texture objects
for (unsigned int textureIndex = 0; textureIndex < resourceHeader->numTextures; textureIndex++)
{
textures[textureIndex] = new Texture();
textures[textureIndex]->enableBilinearFiltering(true);
int offset = texHeader[textureIndex].offset;
for (unsigned int mipLevel = 0; mipLevel < texHeader[textureIndex].mipLevels; mipLevel++)
{
int width = texHeader[textureIndex].width >> mipLevel;
int height = texHeader[textureIndex].height >> mipLevel;
Surface *surface = new Surface(width, height, resourceData + offset);
textures[textureIndex]->setMipSurface(mipLevel, surface);
offset += width * height * 4;
}
}
// Set up render state
RenderContext *context = new RenderContext(0x1000000);
RenderTarget *renderTarget = new RenderTarget();
Surface *colorBuffer = new Surface(FB_WIDTH, FB_HEIGHT, (void*) 0x200000);
Surface *zBuffer = new Surface(FB_WIDTH, FB_HEIGHT);
renderTarget->setColorBuffer(colorBuffer);
renderTarget->setZBuffer(zBuffer);
context->bindTarget(renderTarget);
context->enableZBuffer(true);
context->bindShader(new TextureVertexShader(), new TexturePixelShader());
context->setClearColor(0.52, 0.80, 0.98);
Matrix projectionMatrix = Matrix::getProjectionMatrix(FB_WIDTH, FB_HEIGHT);
TextureUniforms uniforms;
uniforms.fLightDirection = Vec3(-1, -0.5, 1).normalized();
uniforms.fDirectional = 0.3f;
uniforms.fAmbient = 0.7f;
float theta = 0.0;
for (int frame = 0; ; frame++)
{
Matrix modelViewMatrix = Matrix::lookAt(Vec3(0, 3, 0), Vec3(cos(theta), 3, sin(theta)), Vec3(0, 1, 0));
theta = theta + M_PI / 8;
if (theta > M_PI * 2)
theta -= M_PI * 2;
uniforms.fMVPMatrix = projectionMatrix * modelViewMatrix;
uniforms.fNormalMatrix = modelViewMatrix.upper3x3();
for (unsigned int i = 0; i < resourceHeader->numMeshes; i++)
{
const MeshEntry &entry = meshHeader[i];
if (entry.textureId != 0xffffffff)
{
assert(entry.textureId < resourceHeader->numTextures);
context->bindTexture(0, textures[entry.textureId]);
uniforms.fHasTexture = true;
}
else
uniforms.fHasTexture = false;
context->bindUniforms(&uniforms, sizeof(uniforms));
context->bindGeometry((const float*) (resourceData + entry.offset), entry.numVertices,
(const int*)(resourceData + entry.offset + (entry.numVertices * kAttrsPerVertex
* sizeof(float))), entry.numIndices);
context->submitDrawCommand();
}
int startInstructions = __builtin_nyuzi_read_control_reg(6);
context->finish();
printf("rendered frame in %d instructions\n", __builtin_nyuzi_read_control_reg(6)
- startInstructions);
while (true)
;
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment