From b691c43c44ff180d10e7d4a9afc83b98551ff586 Mon Sep 17 00:00:00 2001 From: daoge_cmd <3523206925@qq.com> Date: Sun, 1 Mar 2026 12:16:08 +0800 Subject: Initial commit --- .../Windows64/Iggy/gdraw/gdraw_d3d.cpp | 2228 +++++++++++++ Minecraft.Client/Windows64/Iggy/gdraw/gdraw_d3d.h | 107 + .../Windows64/Iggy/gdraw/gdraw_d3d10.cpp | 138 + .../Windows64/Iggy/gdraw/gdraw_d3d10.h | 132 + .../Windows64/Iggy/gdraw/gdraw_d3d10_shaders.inl | 3427 ++++++++++++++++++++ .../Windows64/Iggy/gdraw/gdraw_d3d11.cpp | 147 + .../Windows64/Iggy/gdraw/gdraw_d3d11.h | 139 + .../Windows64/Iggy/gdraw/gdraw_d3d1x_shared.inl | 2491 ++++++++++++++ .../Windows64/Iggy/gdraw/gdraw_d3d9_shaders.inl | 1075 ++++++ .../Windows64/Iggy/gdraw/gdraw_gl_shaders.inl | 1084 +++++++ .../Windows64/Iggy/gdraw/gdraw_gl_shared.inl | 2428 ++++++++++++++ .../Windows64/Iggy/gdraw/gdraw_shared.inl | 2595 +++++++++++++++ Minecraft.Client/Windows64/Iggy/gdraw/gdraw_wgl.c | 202 ++ Minecraft.Client/Windows64/Iggy/gdraw/gdraw_wgl.h | 38 + Minecraft.Client/Windows64/Iggy/include/gdraw.h | 726 +++++ Minecraft.Client/Windows64/Iggy/include/iggy.h | 1295 ++++++++ .../Windows64/Iggy/include/iggyexpruntime.h | 49 + .../Windows64/Iggy/include/iggyperfmon.h | 89 + Minecraft.Client/Windows64/Iggy/include/rrCore.h | 2322 +++++++++++++ Minecraft.Client/Windows64/Iggy/lib/iggy_w32.lib | Bin 0 -> 49766 bytes Minecraft.Client/Windows64/Iggy/lib/iggy_w64.lib | Bin 0 -> 51572 bytes .../Windows64/Iggy/lib/iggyexpruntime_w32.lib | Bin 0 -> 2430 bytes .../Windows64/Iggy/lib/iggyexpruntime_w64.lib | Bin 0 -> 2386 bytes .../Windows64/Iggy/lib/iggyperfmon_w32.lib | Bin 0 -> 2436 bytes .../Windows64/Iggy/lib/iggyperfmon_w64.lib | Bin 0 -> 2390 bytes .../Windows64/Iggy/lib/redist64/iggy_w64.dll | Bin 0 -> 1063424 bytes 26 files changed, 20712 insertions(+) create mode 100644 Minecraft.Client/Windows64/Iggy/gdraw/gdraw_d3d.cpp create mode 100644 Minecraft.Client/Windows64/Iggy/gdraw/gdraw_d3d.h create mode 100644 Minecraft.Client/Windows64/Iggy/gdraw/gdraw_d3d10.cpp create mode 100644 Minecraft.Client/Windows64/Iggy/gdraw/gdraw_d3d10.h create mode 100644 Minecraft.Client/Windows64/Iggy/gdraw/gdraw_d3d10_shaders.inl create mode 100644 Minecraft.Client/Windows64/Iggy/gdraw/gdraw_d3d11.cpp create mode 100644 Minecraft.Client/Windows64/Iggy/gdraw/gdraw_d3d11.h create mode 100644 Minecraft.Client/Windows64/Iggy/gdraw/gdraw_d3d1x_shared.inl create mode 100644 Minecraft.Client/Windows64/Iggy/gdraw/gdraw_d3d9_shaders.inl create mode 100644 Minecraft.Client/Windows64/Iggy/gdraw/gdraw_gl_shaders.inl create mode 100644 Minecraft.Client/Windows64/Iggy/gdraw/gdraw_gl_shared.inl create mode 100644 Minecraft.Client/Windows64/Iggy/gdraw/gdraw_shared.inl create mode 100644 Minecraft.Client/Windows64/Iggy/gdraw/gdraw_wgl.c create mode 100644 Minecraft.Client/Windows64/Iggy/gdraw/gdraw_wgl.h create mode 100644 Minecraft.Client/Windows64/Iggy/include/gdraw.h create mode 100644 Minecraft.Client/Windows64/Iggy/include/iggy.h create mode 100644 Minecraft.Client/Windows64/Iggy/include/iggyexpruntime.h create mode 100644 Minecraft.Client/Windows64/Iggy/include/iggyperfmon.h create mode 100644 Minecraft.Client/Windows64/Iggy/include/rrCore.h create mode 100644 Minecraft.Client/Windows64/Iggy/lib/iggy_w32.lib create mode 100644 Minecraft.Client/Windows64/Iggy/lib/iggy_w64.lib create mode 100644 Minecraft.Client/Windows64/Iggy/lib/iggyexpruntime_w32.lib create mode 100644 Minecraft.Client/Windows64/Iggy/lib/iggyexpruntime_w64.lib create mode 100644 Minecraft.Client/Windows64/Iggy/lib/iggyperfmon_w32.lib create mode 100644 Minecraft.Client/Windows64/Iggy/lib/iggyperfmon_w64.lib create mode 100644 Minecraft.Client/Windows64/Iggy/lib/redist64/iggy_w64.dll (limited to 'Minecraft.Client/Windows64/Iggy') diff --git a/Minecraft.Client/Windows64/Iggy/gdraw/gdraw_d3d.cpp b/Minecraft.Client/Windows64/Iggy/gdraw/gdraw_d3d.cpp new file mode 100644 index 00000000..50dabfc3 --- /dev/null +++ b/Minecraft.Client/Windows64/Iggy/gdraw/gdraw_d3d.cpp @@ -0,0 +1,2228 @@ +// gdraw_d3d.cpp - author: Sean Barrett - copyright 2009-2011 RAD Game Tools +// +// This implements the Iggy graphics driver layer for Direct3D 9. + +// GDraw consists of several components that interact fairly loosely with each other; +// e.g. the resource management, drawing and filtering parts are all fairly independent +// of each other. If you want to modify some aspect of GDraw - say the texture allocation +// logic - your best bet is usually to just look for one of the related entry points, +// e.g. MakeTextureBegin, and take it from there. There's a bunch of code in this file, +// but none of it is really complicated. +// +// The one bit you might want to change that's not that localized is to integrate +// GDraw with an existing state caching system. The following bits all modify D3D state +// in some way: +// - The rendering helpers (set_viewport_raw, set_projection_raw, set_*_renderstate) +// - RenderTile*/TextureDrawBuffer* may change the active rendertarget and depth/stencil surface, +// as do D3D_NoMoreGDrawThisFrame and set_render_target +// - set_texture +// - set_renderstate and set_renderstate_full. These are the main places where render state changes occur; +// you should probably start here. +// - DrawIndexedTriangles sets the active vertex/index buffers and vertex declaration +// - Most of the functions in the "filter effects" section modify D3D state, mostly +// pixel shader constants and textures + +#define WIN32_LEAN_AND_MEAN +#include +#include +#include +#include + +// We temporarily disable this warning for the shared interface portions +#pragma warning (push) +#pragma warning (disable: 4201) // nonstandard extension used : nameless struct/union + +#include "gdraw.h" +#include "iggy.h" +#include "gdraw_d3d.h" + +// The native handle type holds resource handles and a coarse description. +typedef union { + // handle that is a texture + struct { + IDirect3DTexture9 *d3d; + IDirect3DTexture9 *d3d_msaa; + U32 w, h; + } tex; + + // handle that is a vertex buffer + struct { + IDirect3DVertexBuffer9 *base; + IDirect3DIndexBuffer9 *indices; + } vbuf; +} GDrawNativeHandle; + +#define GDRAW_D3D // this controls the next include so the cache gets declared with the correct types, which makes it typesafe +#include "gdraw_shared.inl" + +#pragma warning (pop) + +// max rendertarget stack depth. this depends on the extent to which you +// use filters and non-standard blend modes, and how nested they are. +#define MAX_RENDER_STACK_DEPTH 8 // Iggy is hardcoded to a limit of 16... probably 1-3 is realistic +#define AATEX_SAMPLER 7 // sampler that aa_tex gets set in +#define QUAD_IB_COUNT 2048 // quad index buffer has indices for this many quads + +#define ASSERT_COUNT(a,b) ((a) == (b) ? (b) : -1) + +static GDrawFunctions gdraw_funcs; + +// render target state +typedef struct +{ + GDrawHandle *color_buffer; + S32 base_x, base_y, width, height; + U32 flags; + rrbool cached; +} GDrawFramebufferState; + +struct ProgramWithCachedVariableLocations +{ + DWORD *bytecode; + union { + IDirect3DPixelShader9 *pshader; + IDirect3DVertexShader9 *vshader; + }; + int vars[MAX_VARS]; // it's unsigned in d3d, but we want an 'undefined' value +}; + +/////////////////////////////////////////////////////////////////////////////// +// +// GDraw data structure +// +// +// This is the primary rendering abstraction, which hides all +// the platform-specific rendering behavior from Iggy. It is +// full of platform-specific graphics state, and also general +// graphics state so that it doesn't have to callback into Iggy +// to get at that graphics state. + +typedef struct +{ + IDirect3DDevice9 *d3d_device; + + // fragment shaders + ProgramWithCachedVariableLocations fprog[GDRAW_TEXTURE__count][3]; + ProgramWithCachedVariableLocations exceptional_blend[GDRAW_BLENDSPECIAL__count]; + ProgramWithCachedVariableLocations filter_prog[2][16]; + ProgramWithCachedVariableLocations blur_prog[MAX_TAPS+1]; + ProgramWithCachedVariableLocations colormatrix; + ProgramWithCachedVariableLocations manual_clear; + + // vertex declarations + IDirect3DVertexDeclaration9 *vdec[GDRAW_vformat__count]; + + // vertex shaders + ProgramWithCachedVariableLocations vert[GDRAW_vformat__count]; // [format] + + // render targets + GDrawHandleCache rendertargets; + GDrawHandle rendertarget_handles[MAX_RENDER_STACK_DEPTH]; // not -1, because we use +1 to initialize + + gswf_recti rt_valid[MAX_RENDER_STACK_DEPTH+1]; // valid rect for texture clamping + + // size of our render targets + S32 frametex_width, frametex_height; + + // viewport setting (in pixels) for current frame + S32 vx,vy; + S32 fw,fh; // full width/height of virtual display + S32 tw,th; // actual width/height of current tile + S32 tpw,tph; // width/height of padded version of tile + + S32 tx0,ty0; + S32 tx0p,ty0p; + rrbool in_blur; + + F32 projection[4]; // scalex,scaley,transx,transy + rrbool use_3d; + F32 xform_3d[3][4]; + + IDirect3DSurface9 *main_framebuffer; + IDirect3DSurface9 *main_depthbuffer; + IDirect3DSurface9 *rt_depthbuffer; // non-multisampled rendertarget depth buffer. only used when MSAA is on! + rrbool main_msaa; // does main framebuffer have MSAA enabled? + + IDirect3DTexture9 *aa_tex; + + // scale factors converting worldspace to viewspace <0,0>.. + F32 world_to_pixel[2]; + + // cached state + U32 scissor_state; // ~0 if unknown, otherwise 0 or 1 + int blend_mode; // -1 if unknown, otherwise GDRAW_BLEND_* + U32 stencil_key; // field built from stencil test flags. 0=no stencil, ~0 is used for "unknown state" + U32 z_key; // same for z-writes/z-test + rrbool last_was_3d; + + // render-state stack described above for 'temporary' rendering + GDrawFramebufferState frame[MAX_RENDER_STACK_DEPTH]; + GDrawFramebufferState *cur; + + // texture and vertex buffer pools + GDrawHandleCache *texturecache; + GDrawHandleCache *vbufcache; + + // mipmapping + GDrawMipmapContext mipmap; + rrbool conditional_nonpow2; + + // stat tracking + rrbool frame_done; + U64 frame_counter; + + // error reporting + void (__cdecl *error_handler)(HRESULT hr); +} GDraw; + +static GDraw *gdraw; + +// not a real index buffer because we only get quads via user pointer +static U16 quad_ib[QUAD_IB_COUNT*6]; + + +//////////////////////////////////////////////////////////////////////// +// +// Error handling +// + +static void report_d3d_error(HRESULT hr, char *call, char *context) +{ + if (hr == E_OUTOFMEMORY) + IggyGDrawSendWarning(NULL, "GDraw D3D out of memory in %s%s", call, context); + else + IggyGDrawSendWarning(NULL, "GDraw D3D error in %s%s: 0x%08x", call, context, hr); +} + + +//////////////////////////////////////////////////////////////////////// +// +// General resource management for both textures and vertex buffers +// + +template +static void safe_release(T *&p) +{ + if (p) { + p->Release(); + p = NULL; + } +} + +static void unbind_resources(void) +{ + IDirect3DDevice9 *d3d = gdraw->d3d_device; + S32 i; + + // unset active textures and vertex/index buffers, + // to make sure there are no dangling refs + for (i=0; i < 3; ++i) + d3d->SetTexture(i, NULL); + + d3d->SetStreamSource(0, NULL, 0, 0); + d3d->SetIndices(NULL); +} + +static void api_free_resource(GDrawHandle *r) +{ + unbind_resources(); + if (r->state != GDRAW_HANDLE_STATE_user_owned) { + if (!r->cache->is_vertex) { + safe_release(r->handle.tex.d3d); + } else { + safe_release(r->handle.vbuf.base); + safe_release(r->handle.vbuf.indices); + } + } +} + +static void RADLINK gdraw_UnlockHandles(GDrawStats * /*stats*/) +{ + gdraw_HandleCacheUnlockAll(gdraw->texturecache); + gdraw_HandleCacheUnlockAll(gdraw->vbufcache); +} + +//////////////////////////////////////////////////////////////////////// +// +// Texture creation/updating/deletion +// + +extern GDrawTexture *gdraw_D3D_WrappedTextureCreate(IDirect3DTexture9 *texhandle) +{ + GDrawStats stats={0}; + GDrawHandle *p = gdraw_res_alloc_begin(gdraw->texturecache, 0, &stats); // it may need to free one item to give us a handle + p->handle.tex.d3d = texhandle; + p->handle.tex.w = 1; + p->handle.tex.h = 1; + gdraw_HandleCacheAllocateEnd(p, 0, NULL, GDRAW_HANDLE_STATE_user_owned); + return (GDrawTexture *) p; +} + +extern void gdraw_D3D_WrappedTextureChange(GDrawTexture *tex, IDirect3DTexture9 *texhandle) +{ + GDrawHandle *p = (GDrawHandle *) tex; + p->handle.tex.d3d = texhandle; +} + +extern void gdraw_D3D_WrappedTextureDestroy(GDrawTexture *tex) +{ + GDrawStats stats={0}; + gdraw_res_free((GDrawHandle *) tex, &stats); +} + +static void RADLINK gdraw_SetTextureUniqueID(GDrawTexture *tex, void *old_id, void *new_id) +{ + GDrawHandle *p = (GDrawHandle *) tex; + // if this is still the handle it's thought to be, change the owner; + // if the owner *doesn't* match, then they're changing a stale handle, so ignore + if (p->owner == old_id) + p->owner = new_id; +} + + +static rrbool RADLINK gdraw_MakeTextureBegin(void *owner, S32 width, S32 height, gdraw_texture_format format, U32 flags, GDraw_MakeTexture_ProcessingInfo *p, GDrawStats *stats) +{ + GDrawHandle *t = NULL; + D3DFORMAT d3dfmt; + S32 bpp; + + if (format == GDRAW_TEXTURE_FORMAT_rgba32) { + d3dfmt = D3DFMT_A8R8G8B8; + bpp = 4; + } else { + d3dfmt = D3DFMT_A8; + bpp = 1; + } + + // compute estimated size of texture in video memory + S32 size = width*height*bpp; + if (flags & GDRAW_MAKETEXTURE_FLAGS_mipmap) + size = size*4/3; // not correct for non-square + + // allocate a handle and make room in the cache for this much data + t = gdraw_res_alloc_begin(gdraw->texturecache, size, stats); + if (!t) + return NULL; + + HRESULT hr = gdraw->d3d_device->CreateTexture(width, height, (flags & GDRAW_MAKETEXTURE_FLAGS_mipmap) ? 0 : 1, + 0, d3dfmt, D3DPOOL_MANAGED, &t->handle.tex.d3d, NULL); + + if (FAILED(hr)) { + gdraw_HandleCacheAllocateFail(t); + IggyGDrawSendWarning(NULL, "GDraw CreateTexture() call failed with error code 0x%08x", hr); + return false; + } + + t->handle.tex.w = width; + t->handle.tex.h = height; + + gdraw_HandleCacheAllocateEnd(t, size, owner, (flags & GDRAW_MAKETEXTURE_FLAGS_never_flush) ? GDRAW_HANDLE_STATE_pinned : GDRAW_HANDLE_STATE_locked); + stats->nonzero_flags |= GDRAW_STATS_alloc_tex; + stats->alloc_tex += 1; + stats->alloc_tex_bytes += size; + + p->texture_type = GDRAW_TEXTURE_TYPE_bgra; + p->p0 = t; + + if (flags & GDRAW_MAKETEXTURE_FLAGS_mipmap) { + rrbool ok; + assert(p->temp_buffer != NULL); + ok = gdraw_MipmapBegin(&gdraw->mipmap, width, height, t->handle.tex.d3d->GetLevelCount(), bpp, p->temp_buffer, p->temp_buffer_bytes); + assert(ok); // this should never trigger unless the temp_buffer is way too small + + p->p1 = &gdraw->mipmap; + p->texture_data = gdraw->mipmap.pixels[0]; + p->num_rows = gdraw->mipmap.bheight; + p->stride_in_bytes = gdraw->mipmap.pitch[0]; + p->i0 = 0; // current output y + p->i1 = bpp; + } else { + D3DLOCKED_RECT z; + hr = t->handle.tex.d3d->LockRect(0, &z, NULL, 0); + if (FAILED(hr)) { + t->handle.tex.d3d->Release(); + gdraw_HandleCacheAllocateFail(t); + + if (hr == E_OUTOFMEMORY) { + IggyGDrawSendWarning(NULL, "GDraw out of texture memory allocating %dx%d (%dbpp) texture", width, height, 8*bpp); + return false; + } else { + IggyGDrawSendWarning(NULL, "GDraw LockRect for texture allocation failed, D3D error 0x%08x\n", hr); + return false; + } + } + + p->p1 = NULL; + p->texture_data = (U8 *) z.pBits; + p->num_rows = height; + p->stride_in_bytes = z.Pitch; + } + + return true; +} + +static rrbool RADLINK gdraw_MakeTextureMore(GDraw_MakeTexture_ProcessingInfo *p) +{ + GDrawHandle *t = (GDrawHandle *) p->p0; + + if (p->p1) { + GDrawMipmapContext *c = (GDrawMipmapContext *) p->p1; + U32 outy = p->i0; + U32 bpp = p->i1; + U32 width = c->width; + U32 height = c->height; + U32 bheight = c->bheight; + U32 level = 0; + + if (outy >= c->height) + return false; + + do { + // upload data for this miplevel + D3DLOCKED_RECT z; + HRESULT hr = t->handle.tex.d3d->LockRect(level, &z, NULL, 0); + if (FAILED(hr)) + return false; + + for (U32 y=0; y < bheight; ++y) + memcpy((U8 *) z.pBits + ((outy >> level) + y) * z.Pitch, c->pixels[level] + y * c->pitch[level], width * bpp); + t->handle.tex.d3d->UnlockRect(level); + + // prepare next miplevel + width = RR_MAX(width >> 1, 1); + height = RR_MAX(height >> 1, 1); + bheight = RR_MAX(bheight >> 1, 1); + } while (gdraw_MipmapAddLines(c, ++level)); + + // prepare next chunk + p->i0 += p->num_rows; + p->texture_data = c->pixels[0]; + p->num_rows = c->bheight = RR_MIN(c->bheight, c->height - p->i0); + return true; + } else + return false; +} + +static GDrawTexture * RADLINK gdraw_MakeTextureEnd(GDraw_MakeTexture_ProcessingInfo *p, GDrawStats * /*stats*/) +{ + GDrawHandle *t = (GDrawHandle *) p->p0; + if (p->p1) + gdraw_MakeTextureMore(p); // use more to upload the last batch of data + else + t->handle.tex.d3d->UnlockRect(0); + + return (GDrawTexture *) t; +} + + +static rrbool RADLINK gdraw_UpdateTextureBegin(GDrawTexture *t, void *unique_id, GDrawStats * /*stats*/) +{ + return gdraw_HandleCacheLock((GDrawHandle *) t, unique_id); +} + +static void RADLINK gdraw_UpdateTextureRect(GDrawTexture *t, void * /*unique_id*/, S32 x, S32 y, S32 stride, S32 w, S32 h, U8 *samples, gdraw_texture_format format) +{ + GDrawHandle *s = (GDrawHandle *) t; + RECT rdest = { x, y, x+w, y+h }; + S32 i, bpl = (format == GDRAW_TEXTURE_FORMAT_font ? 1 : 4) * w; + D3DLOCKED_RECT lr; + + HRESULT hr = s->handle.tex.d3d->LockRect(0, &lr, &rdest, 0); + if (FAILED(hr)) { + IggyGDrawSendWarning(0, "GDraw LockRect() for texture update failed; D3D error 0x%08x", hr); + return; + } + + for (i=0; i < h; i++) + memcpy((U8 *) lr.pBits + i * lr.Pitch, samples + i*stride, bpl); + + s->handle.tex.d3d->UnlockRect(0); +} + +static void RADLINK gdraw_UpdateTextureEnd(GDrawTexture *t, void * /*unique_id*/, GDrawStats * /*stats*/) +{ + gdraw_HandleCacheUnlock((GDrawHandle *) t); +} + +static void RADLINK gdraw_FreeTexture(GDrawTexture *tt, void *unique_id, GDrawStats *stats) +{ + GDrawHandle *t = (GDrawHandle *) tt; + assert(t != NULL); // @GDRAW_ASSERT + if (t->owner == unique_id || unique_id == NULL) { + if (t->cache == &gdraw->rendertargets) { + gdraw_HandleCacheUnlock(t); + // cache it by simply not freeing it + return; + } + + gdraw_res_free(t, stats); + } +} + +static rrbool RADLINK gdraw_TryToLockTexture(GDrawTexture *t, void *unique_id, GDrawStats * /*stats*/) +{ + return gdraw_HandleCacheLock((GDrawHandle *) t, unique_id); +} + +static void RADLINK gdraw_DescribeTexture(GDrawTexture *tex, GDraw_Texture_Description *desc) +{ + GDrawHandle *p = (GDrawHandle *) tex; + desc->width = p->handle.tex.w; + desc->height = p->handle.tex.h; + desc->size_in_bytes = p->bytes; +} + +static void RADLINK gdraw_SetAntialiasTexture(S32 width, U8 *rgba) +{ + HRESULT hr; + D3DLOCKED_RECT lr; + S32 i; + U8 *d; + + safe_release(gdraw->aa_tex); // release the old texture, if any. + + hr = gdraw->d3d_device->CreateTexture(width, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &gdraw->aa_tex, NULL); + if (FAILED(hr)) { + IggyGDrawSendWarning(0, "GDraw D3D error in CreateTexture 0x%08x", hr); + return; + } + + hr = gdraw->aa_tex->LockRect(0, &lr, NULL, 0); + if (!FAILED(hr)) { + d = (U8 *) lr.pBits; + for (i=0; i < width; i++) { + d[i*4+0] = rgba[i*4+2]; + d[i*4+1] = rgba[i*4+1]; + d[i*4+2] = rgba[i*4+0]; + d[i*4+3] = rgba[i*4+3]; + } + + gdraw->aa_tex->UnlockRect(0); + } else + IggyGDrawSendWarning(0, "GDraw D3D error in LockRect for texture creation: 0x%08x", hr); +} + +//////////////////////////////////////////////////////////////////////// +// +// Vertex buffer creation/deletion +// + +static rrbool RADLINK gdraw_MakeVertexBufferBegin(void *unique_id, gdraw_vformat /*vformat*/, S32 vbuf_size, S32 ibuf_size, GDraw_MakeVertexBuffer_ProcessingInfo *p, GDrawStats *stats) +{ + char *failed_call; + GDrawHandle *vb = gdraw_res_alloc_begin(gdraw->vbufcache, vbuf_size + ibuf_size, stats); + if (!vb) + return false; + + vb->handle.vbuf.base = NULL; + vb->handle.vbuf.indices = NULL; + + HRESULT hr; + hr = gdraw->d3d_device->CreateVertexBuffer(vbuf_size, D3DUSAGE_WRITEONLY, 0, D3DPOOL_MANAGED, &vb->handle.vbuf.base, NULL); + failed_call = "CreateVertexBuffer"; + if (!FAILED(hr)) { + hr = gdraw->d3d_device->CreateIndexBuffer(ibuf_size, D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_MANAGED, &vb->handle.vbuf.indices, NULL); + failed_call = "CreateIndexBuffer"; + } + if (!FAILED(hr)) { + hr = vb->handle.vbuf.base->Lock(0, vbuf_size, (void **) &p->vertex_data, 0); + failed_call = "Lock"; + } + if (!FAILED(hr)) + hr = vb->handle.vbuf.indices->Lock(0, ibuf_size, (void **) &p->index_data, 0); + + if (FAILED(hr)) { + if (vb->handle.vbuf.base) + vb->handle.vbuf.base->Unlock(); // does nothing if we didn't actually lock + + safe_release(vb->handle.vbuf.base); + safe_release(vb->handle.vbuf.indices); + + gdraw_HandleCacheAllocateFail(vb); + + report_d3d_error(hr, failed_call, " creating vertex buffer"); + return false; + } + + p->vertex_data_length = vbuf_size; + p->index_data_length = ibuf_size; + p->p0 = vb; + + gdraw_HandleCacheAllocateEnd(vb, vbuf_size + ibuf_size, unique_id, GDRAW_HANDLE_STATE_locked); + return true; +} + +static rrbool RADLINK gdraw_MakeVertexBufferMore(GDraw_MakeVertexBuffer_ProcessingInfo * /*p*/) +{ + assert(0); + return false; +} + +static GDrawVertexBuffer * RADLINK gdraw_MakeVertexBufferEnd(GDraw_MakeVertexBuffer_ProcessingInfo *p, GDrawStats * /*stats*/) +{ + GDrawHandle *vb = (GDrawHandle *) p->p0; + vb->handle.vbuf.base->Unlock(); + vb->handle.vbuf.indices->Unlock(); + return (GDrawVertexBuffer *) vb; +} + +static rrbool RADLINK gdraw_TryLockVertexBuffer(GDrawVertexBuffer *vb, void *unique_id, GDrawStats * /*stats*/) +{ + return gdraw_HandleCacheLock((GDrawHandle *) vb, unique_id); +} + +static void RADLINK gdraw_FreeVertexBuffer(GDrawVertexBuffer *vb, void *unique_id, GDrawStats *stats) +{ + GDrawHandle *h = (GDrawHandle *) vb; + assert(h != NULL); // @GDRAW_ASSERT + if (h->owner == unique_id) + gdraw_res_free(h, stats); +} + +static void RADLINK gdraw_DescribeVertexBuffer(GDrawVertexBuffer *vbuf, GDraw_VertexBuffer_Description *desc) +{ + GDrawHandle *p = (GDrawHandle *) vbuf; + desc->size_in_bytes = p->bytes; +} + +//////////////////////////////////////////////////////////////////////// +// +// Create/free (or cache) render targets +// + +static GDrawHandle *get_color_rendertarget(GDrawStats *stats) +{ + // try to recycle LRU rendertarget + GDrawHandle *t = gdraw_HandleCacheGetLRU(&gdraw->rendertargets); + if (t) { + gdraw_HandleCacheLock(t, (void *) 1); + return t; + } + + // ran out of RTs, allocate a new one + S32 size = gdraw->frametex_width * gdraw->frametex_height * 4; + if (gdraw->rendertargets.bytes_free < size) { + IggyGDrawSendWarning(NULL, "GDraw rendertarget allocation failed: hit size limit of %d bytes", gdraw->rendertargets.total_bytes); + return NULL; + } + + t = gdraw_HandleCacheAllocateBegin(&gdraw->rendertargets); + if (!t) { + IggyGDrawSendWarning(NULL, "GDraw rendertarget allocation failed: hit handle limit"); + return t; + } + + HRESULT hr = gdraw->d3d_device->CreateTexture(gdraw->frametex_width, gdraw->frametex_height, 1, D3DUSAGE_RENDERTARGET, + D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &t->handle.tex.d3d, NULL); + if (FAILED(hr)) { + report_d3d_error(hr, "CreateTexture", " creating rendertarget"); + gdraw_HandleCacheAllocateFail(t); + return NULL; + } + + gdraw_HandleCacheAllocateEnd(t, size, (void *) 1, GDRAW_HANDLE_STATE_locked); + stats->nonzero_flags |= GDRAW_STATS_alloc_tex; + stats->alloc_tex += 1; + stats->alloc_tex_bytes += size; + + return t; +} + +static IDirect3DSurface9 *get_rendertarget_depthbuffer(GDrawStats *stats) +{ + if (!gdraw->rt_depthbuffer) { + HRESULT hr = gdraw->d3d_device->CreateDepthStencilSurface(gdraw->frametex_width, gdraw->frametex_height, D3DFMT_D24S8, D3DMULTISAMPLE_NONE, 0, TRUE, &gdraw->rt_depthbuffer, NULL); + if (FAILED(hr)) + IggyGDrawSendWarning(NULL, "GDraw D3D error in CreateDepthStencilSurface: 0x%08x", hr); + else { + stats->nonzero_flags |= GDRAW_STATS_alloc_tex; + stats->alloc_tex += 1; + stats->alloc_tex_bytes += gdraw->frametex_width * gdraw->frametex_height * 4; + } + } + + return gdraw->rt_depthbuffer; +} + +static void flush_rendertargets(GDrawStats *stats) +{ + gdraw_res_flush(&gdraw->rendertargets, stats); + safe_release(gdraw->rt_depthbuffer); +} + +//////////////////////////////////////////////////////////////////////// +// +// Vertex shader constants +// + +#define VVAR_world0 0 +#define VVAR_world1 1 +#define VVAR_count_worldonly 2 // number of constants to send if you only changed world matrix + +#define VVAR_x_off 2 +#define VVAR_count_world_xoff 3 // number of constants to send if you changed world+x_off + +#define VVAR_texgen_s 3 +#define VVAR_texgen_t 4 +#define VVAR_count 5 // number of constants to send if you changed all per-batch state + +#define VVAR_x3d 5 +#define VVAR_y3d 6 +#define VVAR_z3d 7 +#define VVAR_count3d 8 + +// Fixed-location pixel shader constants +#define PVAR_cmul 0 +#define PVAR_cadd 1 +#define PVAR_focal 2 +#define PVAR_rescale1 3 + +struct VertexVars +{ + F32 world[2][4]; + F32 x_off[4]; + F32 texgen_s[4]; + F32 texgen_t[4]; + F32 viewproj[3][4]; +}; + +//////////////////////////////////////////////////////////////////////// +// +// Rendering helpers +// + +static void set_d3d_texture(U32 sampler, IDirect3DTexture9 *tex, U32 wrap, U32 nearest) +{ + static const int addrmodes[ASSERT_COUNT(GDRAW_WRAP__count, 4)] = { + D3DTADDRESS_CLAMP, // GDRAW_WRAP_clamp + D3DTADDRESS_WRAP, // GDRAW_WRAP_repeat + D3DTADDRESS_MIRROR, // GDRAW_WRAP_mirror + D3DTADDRESS_CLAMP, // GDRAW_WRAP_clamp_to_border (never used by client code!) + }; + + static const int filtermodes[2] = { + D3DTEXF_LINEAR, // !nearest + D3DTEXF_POINT, // nearest + }; + + assert(wrap < sizeof(addrmodes) / sizeof(addrmodes[0])); + assert(nearest < sizeof(filtermodes) / sizeof(filtermodes[0])); + IDirect3DDevice9 *d3d = gdraw->d3d_device; + + d3d->SetTexture(sampler, tex); + d3d->SetSamplerState(sampler, D3DSAMP_MAGFILTER, filtermodes[nearest]); + d3d->SetSamplerState(sampler, D3DSAMP_ADDRESSU, addrmodes[wrap]); + d3d->SetSamplerState(sampler, D3DSAMP_ADDRESSV, addrmodes[wrap]); +} + +static void set_viewport_raw(S32 x, S32 y, S32 w, S32 h) +{ + D3DVIEWPORT9 vp = { x, y, w, h, 0.0f, 1.0f }; + gdraw->d3d_device->SetViewport(&vp); +} + +static void set_projection_base(void) +{ + F32 m[3][4] = { 0 }; + + // x3d = < viewproj.x, 0, 0, 0 > + // y3d = < 0, viewproj.y, 0, 0 > + // w3d = < viewproj.z, viewproj.w, 1.0, 1.0 > + + m[0][0] = gdraw->projection[0]; + m[1][1] = gdraw->projection[1]; + m[2][0] = gdraw->projection[2]; + m[2][1] = gdraw->projection[3]; + + m[2][2] = 1.0; + m[2][3] = 1.0; + + gdraw->d3d_device->SetVertexShaderConstantF(VVAR_x3d, m[0], 3); +} + +static void set_projection_raw(S32 x0, S32 x1, S32 y0, S32 y1) +{ + gdraw->projection[0] = 2.0f / (x1-x0); + gdraw->projection[1] = 2.0f / (y1-y0); + gdraw->projection[2] = (x1+x0)/(F32)(x0-x1) - 0.5f * gdraw->projection[0]; // -0.5f: convert from D3D9 to GL/D3D10 pixel coordinates + gdraw->projection[3] = (y1+y0)/(F32)(y0-y1) - 0.5f * gdraw->projection[1]; + + set_projection_base(); +} + +static void set_viewport(void) +{ + if (gdraw->in_blur) { + set_viewport_raw(0, 0, gdraw->tpw, gdraw->tph); + return; + } + + if (gdraw->cur == gdraw->frame) // if the rendering stack is empty + // render a tile-sized region to the user-request tile location + set_viewport_raw(gdraw->vx, gdraw->vy, gdraw->tw, gdraw->th); + else if (gdraw->cur->cached) + set_viewport_raw(0, 0, gdraw->cur->width, gdraw->cur->height); + else + // if on the render stack, draw a padded-tile-sized region at the origin + set_viewport_raw(0, 0, gdraw->tpw, gdraw->tph); +} + +static void set_projection(void) +{ + if (gdraw->in_blur) return; + if (gdraw->cur == gdraw->frame) // if the render stack is empty + set_projection_raw(gdraw->tx0, gdraw->tx0+gdraw->tw, gdraw->ty0+gdraw->th, gdraw->ty0); + else if (gdraw->cur->cached) + set_projection_raw(gdraw->cur->base_x, gdraw->cur->base_x+gdraw->cur->width, gdraw->cur->base_y, gdraw->cur->base_y+gdraw->cur->height); + else + set_projection_raw(gdraw->tx0p, gdraw->tx0p+gdraw->tpw, gdraw->ty0p+gdraw->tph, gdraw->ty0p); +} + +static void set_common_renderstate() +{ + IDirect3DDevice9 *d3d = gdraw->d3d_device; + S32 i; + + // all the render states we never change while drawing + d3d->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); + d3d->SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP); + d3d->SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP); + d3d->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE); + d3d->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_EQUAL); + d3d->SetRenderState(D3DRS_STENCILREF, 255); + d3d->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE); + d3d->SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, 0 ); + d3d->SetRenderState(D3DRS_DEPTHBIAS, 0 ); + d3d->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD); + d3d->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, FALSE); + + for (i=0; i < 3; i++) { + d3d->SetTextureStageState(i, D3DTSS_TEXCOORDINDEX, i); + d3d->SetTextureStageState(i, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE); + d3d->SetSamplerState(i, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR); + d3d->SetSamplerState(i, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); + d3d->SetSamplerState(i, D3DSAMP_MIPMAPLODBIAS, 0); + d3d->SetSamplerState(i, D3DSAMP_MAXMIPLEVEL, 0); + } + + d3d->SetTextureStageState(AATEX_SAMPLER, D3DTSS_TEXCOORDINDEX, AATEX_SAMPLER); + + d3d->SetTexture(AATEX_SAMPLER, gdraw->aa_tex); + d3d->SetSamplerState(AATEX_SAMPLER, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP); + d3d->SetSamplerState(AATEX_SAMPLER, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP); + d3d->SetSamplerState(AATEX_SAMPLER, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); + d3d->SetSamplerState(AATEX_SAMPLER, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); + d3d->SetSamplerState(AATEX_SAMPLER, D3DSAMP_MIPMAPLODBIAS, 0); + d3d->SetSamplerState(AATEX_SAMPLER, D3DSAMP_MAXMIPLEVEL, 0); + + // reset our state caching + gdraw->scissor_state = ~0u; + gdraw->blend_mode = -1; + gdraw->stencil_key = ~0u; + gdraw->z_key = ~0u; + + VertexVars vvars = { 0 }; + d3d->SetVertexShaderConstantF(0, vvars.world[0], VVAR_count); +} + +static void clear_renderstate(void) +{ + IDirect3DDevice9 *d3d = gdraw->d3d_device; + + d3d->SetTexture(0, NULL); + d3d->SetTexture(1, NULL); + d3d->SetTexture(2, NULL); + d3d->SetTexture(AATEX_SAMPLER, NULL); + d3d->SetStreamSource(0, NULL, 0, 0); + d3d->SetIndices(NULL); + + d3d->SetRenderState(D3DRS_ZWRITEENABLE, FALSE); + d3d->SetRenderState(D3DRS_ZFUNC, D3DCMP_ALWAYS); + d3d->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE); + d3d->SetRenderState(D3DRS_COLORWRITEENABLE, 0xf); + d3d->SetRenderState(D3DRS_STENCILENABLE, FALSE); + d3d->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE); + + d3d->SetVertexShader(0); + d3d->SetPixelShader(0); + d3d->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); + d3d->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); +} + +static void clear_zbuffer(IDirect3DSurface9 *surf, U32 flags) +{ + IDirect3DDevice9 *d3d = gdraw->d3d_device; + IDirect3DSurface9 *target; + D3DSURFACE_DESC desc; + surf->GetDesc(&desc); + + // here's where it gets stupid: we need a rendertarget that's + // big enough so we can actually clear the full z-buffer. + // we don't actually render to it or anything, we just need to + // set it... + target = gdraw->main_framebuffer; + if (surf != gdraw->main_depthbuffer) { + // tile surface could, in theory, be larger than main framebuffer, so + // check if we have at least one rendertarget matching the rt depth + // buffer created and use that while clearing if possible + S32 i; + for (i=0; i < MAX_RENDER_STACK_DEPTH; ++i) + if (gdraw->rendertargets.handle[i].handle.tex.d3d) { + gdraw->rendertargets.handle[i].handle.tex.d3d->GetSurfaceLevel(0, &target); + break; + } + } + + D3DVIEWPORT9 vp = { 0, 0, desc.Width, desc.Height, 0.0f, 1.0f }; + d3d->SetRenderTarget(0, target); + d3d->SetDepthStencilSurface(surf); + d3d->SetViewport(&vp); + d3d->Clear(0, NULL, flags, 0, 1.0f, 0); + + if (target != gdraw->main_framebuffer) + target->Release(); +} + +//////////////////////////////////////////////////////////////////////// +// +// Begin/end rendering of a tile and per-frame processing +// + +void gdraw_D3D_SetTileOrigin(IDirect3DSurface9 *rt, IDirect3DSurface9 *depth, S32 x, S32 y) +{ + D3DSURFACE_DESC desc; + + if (gdraw->frame_done) { + ++gdraw->frame_counter; + gdraw->frame_done = false; + } + + rt->GetDesc(&desc); + + gdraw->main_framebuffer = rt; + gdraw->main_depthbuffer = depth; + gdraw->main_msaa = (desc.MultiSampleType != D3DMULTISAMPLE_NONE); + gdraw->vx = x; + gdraw->vy = y; +} + +static void RADLINK gdraw_SetViewSizeAndWorldScale(S32 w, S32 h, F32 scale_x, F32 scale_y) +{ + memset(gdraw->frame, 0, sizeof(gdraw->frame)); + gdraw->cur = gdraw->frame; + gdraw->fw = w; + gdraw->fh = h; + gdraw->tw = w; + gdraw->th = h; + gdraw->world_to_pixel[0] = scale_x; + gdraw->world_to_pixel[1] = scale_y; + + set_viewport(); +} + +static void RADLINK gdraw_Set3DTransform(F32 *mat) +{ + if (mat == NULL) + gdraw->use_3d = 0; + else { + gdraw->use_3d = 1; + memcpy(gdraw->xform_3d, mat, sizeof(gdraw->xform_3d)); + } +} + + +// must include anything necessary for texture creation/update +static void RADLINK gdraw_RenderingBegin(void) +{ +} +static void RADLINK gdraw_RenderingEnd(void) +{ +} + +static void RADLINK gdraw_RenderTileBegin(S32 x0, S32 y0, S32 x1, S32 y1, S32 pad, GDrawStats *stats) +{ + if (x0 == 0 && y0 == 0 && x1 == gdraw->fw && y1 == gdraw->fh) + pad = 0; + + gdraw->tx0 = x0; + gdraw->ty0 = y0; + gdraw->tw = x1-x0; + gdraw->th = y1-y0; + + // padded region + gdraw->tx0p = RR_MAX(x0 - pad, 0); + gdraw->ty0p = RR_MAX(y0 - pad, 0); + gdraw->tpw = RR_MIN(x1 + pad, gdraw->fw) - gdraw->tx0p; + gdraw->tph = RR_MIN(y1 + pad, gdraw->fh) - gdraw->ty0p; + + // just record the max, but then when we texture from, we have to use + // sub-regions -- alternatively, each gdraw gets its own rendertargets + if (gdraw->tpw > gdraw->frametex_width || gdraw->tph > gdraw->frametex_height) { + gdraw->frametex_width = RR_MAX(gdraw->tpw, gdraw->frametex_width); + gdraw->frametex_height = RR_MAX(gdraw->tph, gdraw->frametex_height); + + flush_rendertargets(stats); + } + + // clear our depth buffers + clear_zbuffer(gdraw->main_depthbuffer, D3DCLEAR_STENCIL | D3DCLEAR_ZBUFFER); + if (gdraw->rt_depthbuffer) + clear_zbuffer(gdraw->rt_depthbuffer, D3DCLEAR_STENCIL | D3DCLEAR_ZBUFFER); + + // set our rendertarget + gdraw->d3d_device->SetRenderTarget(0, gdraw->main_framebuffer); + gdraw->d3d_device->SetDepthStencilSurface(gdraw->main_depthbuffer); + set_viewport(); + set_projection(); + set_common_renderstate(); +} + +static void RADLINK gdraw_RenderTileEnd(GDrawStats * /*stats*/) +{ +} + +void gdraw_D3D_SetRendertargetSize(S32 w, S32 h) +{ + if (gdraw && (w != gdraw->frametex_width || h != gdraw->frametex_height)) { + GDrawStats stats = { 0 }; + gdraw->frametex_width = w; + gdraw->frametex_height = h; + flush_rendertargets(&stats); + } +} + +void gdraw_D3D_NoMoreGDrawThisFrame(void) +{ + clear_renderstate(); + if (gdraw->main_framebuffer) + gdraw->d3d_device->SetRenderTarget(0, gdraw->main_framebuffer); + if (gdraw->main_depthbuffer) + gdraw->d3d_device->SetDepthStencilSurface(gdraw->main_depthbuffer); + gdraw->frame_done = true; + + GDrawFence now = { gdraw->frame_counter }; + gdraw_HandleCacheTick(gdraw->texturecache, now); + gdraw_HandleCacheTick(gdraw->vbufcache, now); +} + +#define MAX_DEPTH_VALUE (1 << 13) + +static void RADLINK gdraw_GetInfo(GDrawInfo *d) +{ + D3DCAPS9 caps; + gdraw->d3d_device->GetDeviceCaps(&caps); + + d->num_stencil_bits = 8; + d->max_id = MAX_DEPTH_VALUE-2; + // for floating point depth, just use mantissa, e.g. 16-20 bits + d->max_texture_size = RR_MIN(caps.MaxTextureWidth, caps.MaxTextureHeight); + d->buffer_format = GDRAW_BFORMAT_vbib; + d->shared_depth_stencil = 1; + d->always_mipmap = 1; + d->conditional_nonpow2 = (caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) != 0; +} + +//////////////////////////////////////////////////////////////////////// +// +// Enable/disable rendertargets in stack fashion +// + +static void set_render_target(GDrawStats *stats) +{ + IDirect3DSurface9 *target = NULL, *depth = NULL; + + if (gdraw->cur->color_buffer) { + S32 need_depth; + need_depth = (gdraw->cur->flags & (GDRAW_TEXTUREDRAWBUFFER_FLAGS_needs_id | GDRAW_TEXTUREDRAWBUFFER_FLAGS_needs_stencil)); + + unbind_resources(); // to make sure this RT isn't accidentally set as a texture (avoid D3D warnings) + gdraw->cur->color_buffer->handle.tex.d3d->GetSurfaceLevel(0, &target); // if this fails, there's nothing to be done + if (need_depth) { + if (gdraw->main_msaa) + depth = get_rendertarget_depthbuffer(stats); // @TODO: is this right? get_rt_depthbuffer doesn't seem to do MSAA + else { + // if tile is smaller than frametex, then trying to use the tile's zbuffer may not work + if (gdraw->tw < gdraw->frametex_width || gdraw->th < gdraw->frametex_height) + depth = get_rendertarget_depthbuffer(stats); + else + depth = gdraw->main_depthbuffer; + } + } + } else { + target = gdraw->main_framebuffer; + depth = gdraw->main_depthbuffer; + } + + gdraw->d3d_device->SetRenderTarget(0, target); + gdraw->d3d_device->SetDepthStencilSurface(depth); + if (target != gdraw->main_framebuffer) + target->Release(); + + stats->nonzero_flags |= GDRAW_STATS_rendtarg; + stats->rendertarget_changes += 1; +} + +static rrbool RADLINK gdraw_TextureDrawBufferBegin(gswf_recti *region, gdraw_texture_format /*format*/, U32 flags, void *owner, GDrawStats *stats) +{ + GDrawFramebufferState *n = gdraw->cur+1; + GDrawHandle *t; + if (gdraw->tw == 0 || gdraw->th == 0) + return false; + + if (n >= &gdraw->frame[MAX_RENDER_STACK_DEPTH]) { + IggyGDrawSendWarning(NULL, "GDraw rendertarget nesting exceeds MAX_RENDER_STACK_DEPTH"); + return false; + } + + if (owner) { + S32 w = region->x1 - region->x0; + S32 h = region->y1 - region->y0; + + // allocate a texture handle and free enough texture space + t = gdraw_res_alloc_begin(gdraw->texturecache, w*h*4, stats); + if (!t) + return false; + else { + IDirect3DTexture9 * tex; + HRESULT hr = gdraw->d3d_device->CreateTexture(w,h,1, + D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, + D3DPOOL_DEFAULT, &tex, NULL); + + if (FAILED(hr)) { + if (t) + gdraw_HandleCacheAllocateFail(t); + IggyGDrawSendWarning(NULL, "GDraw D3D error for CreateTexture for cacheAsBitmap rendertarget: 0x%08x", hr); + return false; + } + + stats->nonzero_flags |= GDRAW_STATS_alloc_tex; + stats->alloc_tex += 1; + stats->alloc_tex_bytes += w*h*4; + + gdraw_HandleCacheAllocateEnd(t, w*h*4, (void *) 1, GDRAW_HANDLE_STATE_locked); + } + } else { + t = get_color_rendertarget(stats); + if (!t) + return false; + } + + n->flags = flags; + n->color_buffer = t; + assert(n->color_buffer != NULL); // @GDRAW_ASSERT + + ++gdraw->cur; + gdraw->cur->cached = owner != NULL; + if (owner) { + gdraw->cur->base_x = region->x0; + gdraw->cur->base_y = region->y0; + gdraw->cur->width = region->x1 - region->x0; + gdraw->cur->height = region->y1 - region->y0; + } + + set_render_target(stats); + assert(gdraw->frametex_width >= gdraw->tw && gdraw->frametex_height >= gdraw->th); // @GDRAW_ASSERT + set_viewport(); + set_projection(); + + int k = (int) (t - gdraw->rendertargets.handle); + + if (region) { + D3DRECT r; + S32 ox, oy, pad = 2; // 2 pixels of border on all sides + // 1 pixel turns out to be not quite enough with the interpolator precision we get. + + if (gdraw->in_blur) + ox = oy = 0; + else + ox = gdraw->tx0p, oy = gdraw->ty0p; + + // clamp region to tile + S32 xt0 = RR_MAX(region->x0 - ox, 0); + S32 yt0 = RR_MAX(region->y0 - oy, 0); + S32 xt1 = RR_MIN(region->x1 - ox, gdraw->tpw); + S32 yt1 = RR_MIN(region->y1 - oy, gdraw->tph); + + // but the padding needs to clamp to render target bounds + r.x1 = RR_MAX(xt0 - pad, 0); + r.y1 = RR_MAX(yt0 - pad, 0); + r.x2 = RR_MIN(xt1 + pad, gdraw->frametex_width); + r.y2 = RR_MIN(yt1 + pad, gdraw->frametex_height); + + if (r.x2 <= r.x1 || r.y2 <= r.y1) { // region doesn't intersect with current tile + --gdraw->cur; + gdraw_FreeTexture((GDrawTexture *) t, 0, stats); + // note: don't send a warning since this will happen during regular tiled rendering + return false; + } + + gdraw->d3d_device->Clear(1, &r, D3DCLEAR_TARGET, 0, 1, 0); + gdraw->rt_valid[k].x0 = xt0; + gdraw->rt_valid[k].y0 = yt0; + gdraw->rt_valid[k].x1 = xt1; + gdraw->rt_valid[k].y1 = yt1; + } else { + gdraw->d3d_device->Clear(0, NULL, D3DCLEAR_TARGET, 0, 1, 0); + gdraw->rt_valid[k].x0 = 0; + gdraw->rt_valid[k].y0 = 0; + gdraw->rt_valid[k].x1 = gdraw->frametex_width; + gdraw->rt_valid[k].y1 = gdraw->frametex_height; + } + + return true; +} + +static GDrawTexture *RADLINK gdraw_TextureDrawBufferEnd(GDrawStats *stats) +{ + GDrawFramebufferState *n = gdraw->cur; + GDrawFramebufferState *m = --gdraw->cur; + + if (gdraw->tw == 0 || gdraw->th == 0) return 0; + + if (n >= &gdraw->frame[MAX_RENDER_STACK_DEPTH]) + return 0; // already returned a warning in Begin + + assert(m >= gdraw->frame); // bug in Iggy -- unbalanced + + if (m != gdraw->frame) { + assert(m->color_buffer != NULL); // @GDRAW_ASSERT + } + assert(n->color_buffer != NULL); // @GDRAW_ASSERT + + // switch back to old render target + set_render_target(stats); + + // if we're at the root, set the viewport back + set_viewport(); + set_projection(); + + return (GDrawTexture *) n->color_buffer; +} + + +//////////////////////////////////////////////////////////////////////// +// +// Clear stencil/depth buffers +// +// Open question whether we'd be better off finding bounding boxes +// and only clearing those; it depends exactly how fast clearing works. +// + +static void clear_renderstate_acceleration_cache(void) +{ + gdraw->last_was_3d = false; + gdraw->scissor_state = ~0u; + gdraw->stencil_key = 0; + gdraw->blend_mode = ~0u; +} + +static void do_screen_quad(gswf_recti *s, F32 *tc, GDrawStats *stats); + +static void RADLINK gdraw_ClearStencilBits(U32 bits) +{ + IDirect3DDevice9 *d3d = gdraw->d3d_device; + F32 texcoord[8] = { 0 }; + GDrawStats stats = { 0 }; + gswf_recti region; + + region.x0 = 0; + region.y0 = 0; + region.x1 = gdraw->frametex_width; + region.y1 = gdraw->frametex_height; + + d3d->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); + d3d->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE); + d3d->SetRenderState(D3DRS_STENCILWRITEMASK, bits); + d3d->SetRenderState(D3DRS_STENCILENABLE, TRUE); + // fewest states to force it to always write: make the stencil test always fail + d3d->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_NEVER); + d3d->SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_REPLACE); + d3d->SetRenderState(D3DRS_STENCILREF, 0); + d3d->SetRenderState(D3DRS_COLORWRITEENABLE, FALSE); + d3d->SetRenderState(D3DRS_ZENABLE, FALSE); + d3d->SetRenderState(D3DRS_ZFUNC, FALSE); + d3d->SetRenderState(D3DRS_ZWRITEENABLE, FALSE); + + d3d->SetPixelShader(gdraw->manual_clear.pshader); + do_screen_quad(®ion, texcoord, &stats); + + // restore state from set_common_renderstate + d3d->SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP); + d3d->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_EQUAL); + d3d->SetRenderState(D3DRS_STENCILREF, 255); + + // make next renderstate reset other state + clear_renderstate_acceleration_cache(); + + // reset matrices et al + set_render_target(&stats); + set_viewport(); + set_projection(); +} + +// this only happens rarely (hopefully never) if we use the depth buffer, +// so we can just clear the whole thing +static void RADLINK gdraw_ClearID(void) +{ + GDrawStats stats = { 0 }; + + clear_zbuffer(gdraw->main_depthbuffer, D3DCLEAR_ZBUFFER); + set_render_target(&stats); + set_viewport(); + set_projection(); +} + +//////////////////////////////////////////////////////////////////////// +// +// Set all the render state from GDrawRenderState +// +// This also is responsible for getting the framebuffer into a texture +// if the read-modify-write blend operation can't be expressed with +// the native blend operators. (E.g. "screen") +// + +// convert an ID request to a value suitable for the depth buffer, +// assuming the depth buffer has been mappped to 0..1 +static F32 depth_from_id(S32 id) +{ + return 1.0f - ((F32) id + 1.0f) / MAX_DEPTH_VALUE; +} + +static void set_texture(S32 texunit, GDrawTexture *tex) +{ + if (texunit >= 0) + set_d3d_texture(texunit, ((GDrawHandle *) tex)->handle.tex.d3d, GDRAW_WRAP_clamp, 0); +} + +static int set_renderstate_full(S32 vertex_format, GDrawRenderState *r, GDrawStats * /*stats*/) +{ + IDirect3DDevice9 *d3d = gdraw->d3d_device; + U32 stencil_key, z_key; + F32 depth = depth_from_id(r->id); + VertexVars vvars; + int vvarcount = VVAR_count_world_xoff; + + // set vertex shader + d3d->SetVertexShader(gdraw->vert[vertex_format].vshader); + + // set vertex shader constants + if (!r->use_world_space) + gdraw_ObjectSpace(vvars.world[0], r->o2w, depth, 0.0f); + else + gdraw_WorldSpace(vvars.world[0], gdraw->world_to_pixel, depth, 0.0f); + + memcpy(&vvars.x_off, r->edge_matrix, 4*sizeof(F32)); + + if (r->texgen0_enabled) { + memcpy(&vvars.texgen_s, r->s0_texgen, 4*sizeof(F32)); + memcpy(&vvars.texgen_t, r->t0_texgen, 4*sizeof(F32)); + vvarcount = VVAR_count; + } + + if (gdraw->use_3d || gdraw->last_was_3d) { + if (gdraw->use_3d) { + vvarcount = VVAR_count3d; + memcpy(&vvars.viewproj, gdraw->xform_3d, 12*sizeof(F32)); + } else + set_projection_base(); + gdraw->last_was_3d = gdraw->use_3d; + } + + d3d->SetVertexShaderConstantF(0, vvars.world[0], vvarcount); + + // set the blend mode + int blend_mode = r->blend_mode; + int tex0mode = r->tex0_mode; + + static struct gdraw_d3d_blendspec { + BOOL enable; + D3DBLEND src; + D3DBLEND dest; + } blends[ASSERT_COUNT(GDRAW_BLEND__count, 6)] = { + FALSE, D3DBLEND_ONE, D3DBLEND_ZERO, // GDRAW_BLEND_none + TRUE, D3DBLEND_ONE, D3DBLEND_INVSRCALPHA, // GDRAW_BLEND_alpha + TRUE, D3DBLEND_DESTCOLOR, D3DBLEND_INVSRCALPHA, // GDRAW_BLEND_multiply + TRUE, D3DBLEND_ONE, D3DBLEND_ONE, // GDRAW_BLEND_add + + FALSE, D3DBLEND_ONE, D3DBLEND_ZERO, // GDRAW_BLEND_filter + FALSE, D3DBLEND_ONE, D3DBLEND_ZERO, // GDRAW_BLEND_special + }; + assert(blend_mode >= 0 && blend_mode < sizeof(blends)/sizeof(*blends)); + + if (blend_mode != gdraw->blend_mode) { + gdraw->blend_mode = blend_mode; + if (blends[blend_mode].enable) { + d3d->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + d3d->SetRenderState(D3DRS_SRCBLEND, blends[blend_mode].src); + d3d->SetRenderState(D3DRS_DESTBLEND, blends[blend_mode].dest); + } else + d3d->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); + } + + // set the pixel shader + IDirect3DPixelShader9 *pshader; + if (blend_mode != GDRAW_BLEND_special) { + assert(tex0mode >= 0 && tex0mode < sizeof(gdraw->fprog) / sizeof(*gdraw->fprog)); + + int additive = 0; + if (r->cxf_add) { + additive = 1; + if (r->cxf_add[3]) additive = 2; + } + + pshader = gdraw->fprog[tex0mode][additive].pshader; + } else + pshader = gdraw->exceptional_blend[r->special_blend].pshader; + + d3d->SetPixelShader(pshader); + + // set textures + if (tex0mode != GDRAW_TEXTURE_none) { + if (!r->tex[0]) return 0; + set_d3d_texture(0, ((GDrawHandle *) r->tex[0])->handle.tex.d3d, r->wrap0, r->nearest0); + } + + // set pixel shader constants + d3d->SetPixelShaderConstantF(PVAR_cmul, r->color, 1); + + if (r->cxf_add) { + F32 temp[4] = { r->cxf_add[0]/255.0f, r->cxf_add[1]/255.0f, r->cxf_add[2]/255.0f, r->cxf_add[3]/255.0f }; + d3d->SetPixelShaderConstantF(PVAR_cadd, temp, 1); + } + + if (tex0mode == GDRAW_TEXTURE_focal_gradient) + d3d->SetPixelShaderConstantF(PVAR_focal, r->focal_point, 1); + + // Set pixel operation states + gdraw->scissor_state = ~0u; + if (r->scissor) { + RECT s; + gdraw->scissor_state = r->scissor; + if (gdraw->cur == gdraw->frame) { + s.left = r->scissor_rect.x0 + gdraw->vx - gdraw->tx0; + s.top = r->scissor_rect.y0 + gdraw->vy - gdraw->ty0; + s.right = r->scissor_rect.x1 + gdraw->vx - gdraw->tx0; + s.bottom = r->scissor_rect.y1 + gdraw->vy - gdraw->ty0; + } else { + s.left = r->scissor_rect.x0 - gdraw->tx0p; + s.top = r->scissor_rect.y0 - gdraw->ty0p; + s.right = r->scissor_rect.x1 - gdraw->tx0p; + s.bottom = r->scissor_rect.y1 - gdraw->ty0p; + } + d3d->SetScissorRect(&s); + d3d->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE); + } else { + if (r->scissor != gdraw->scissor_state) { + gdraw->scissor_state = r->scissor; + d3d->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE); + } + } + + // stencil changed? + stencil_key = r->stencil_test | (r->stencil_set << 8); + if (stencil_key != gdraw->stencil_key) { + gdraw->stencil_key = stencil_key; + + d3d->SetRenderState(D3DRS_STENCILMASK, r->stencil_test); + d3d->SetRenderState(D3DRS_STENCILWRITEMASK, r->stencil_set); + d3d->SetRenderState(D3DRS_STENCILENABLE, (r->stencil_set | r->stencil_test) != 0); + d3d->SetRenderState(D3DRS_COLORWRITEENABLE, r->stencil_set ? 0x0 : 0xf); + } + + // z key + z_key = r->set_id | (r->test_id << 1); + if (z_key != gdraw->z_key) { + gdraw->z_key = z_key; + d3d->SetRenderState(D3DRS_ZENABLE, (r->test_id | r->set_id) ? D3DZB_TRUE : D3DZB_FALSE); + d3d->SetRenderState(D3DRS_ZFUNC, r->test_id ? D3DCMP_LESS : D3DCMP_ALWAYS); + d3d->SetRenderState(D3DRS_ZWRITEENABLE, r->set_id); + } + + return 1; +} + +static RADINLINE int set_renderstate(S32 vertex_format, GDrawRenderState *r, GDrawStats *stats) +{ + if (r->identical_state) { + // fast path: only need to change vertex shader, other state is the same + gdraw->d3d_device->SetVertexShader(gdraw->vert[vertex_format].vshader); + return 1; + } else + return set_renderstate_full(vertex_format, r, stats); +} + +//////////////////////////////////////////////////////////////////////// +// +// Vertex formats +// + +static D3DVERTEXELEMENT9 vformat_v2[] = +{ + { 0,0, D3DDECLTYPE_FLOAT2, 0, D3DDECLUSAGE_POSITION, 0 }, + D3DDECL_END() +}; + +static D3DVERTEXELEMENT9 vformat_v2aa[] = +{ + { 0,0, D3DDECLTYPE_FLOAT2, 0, D3DDECLUSAGE_POSITION, 0 }, + { 0,8, D3DDECLTYPE_SHORT4, 0, D3DDECLUSAGE_TEXCOORD, 0 }, + D3DDECL_END() +}; + +static D3DVERTEXELEMENT9 vformat_v2tc2[] = +{ + { 0,0, D3DDECLTYPE_FLOAT2, 0, D3DDECLUSAGE_POSITION, 0 }, + { 0,8, D3DDECLTYPE_FLOAT2, 0, D3DDECLUSAGE_TEXCOORD, 0 }, + D3DDECL_END() +}; + +static D3DVERTEXELEMENT9 *vformats[ASSERT_COUNT(GDRAW_vformat__count, 3)] = { + vformat_v2, // GDRAW_vformat_v2 + vformat_v2aa, // GDRAW_vformat_v2aa + vformat_v2tc2, // GDRAW_vformat_v2tc2 +}; + +static int vertsize[ASSERT_COUNT(GDRAW_vformat__count, 3)] = { + 8, // GDRAW_vformat_v2 + 16, // GDRAW_vformat_v2aa + 16, // GDRAW_vformat_v2tc2 +}; + +//////////////////////////////////////////////////////////////////////// +// +// Draw triangles with a given renderstate +// + +static void tag_resources(void *r1, void *r2=NULL, void *r3=NULL, void *r4=NULL) +{ + U64 now = gdraw->frame_counter; + if (r1) ((GDrawHandle *) r1)->fence.value = now; + if (r2) ((GDrawHandle *) r2)->fence.value = now; + if (r3) ((GDrawHandle *) r3)->fence.value = now; + if (r4) ((GDrawHandle *) r4)->fence.value = now; +} + +static void RADLINK gdraw_DrawIndexedTriangles(GDrawRenderState *r, GDrawPrimitive *p, GDrawVertexBuffer *buf, GDrawStats *stats) +{ + GDrawHandle *vb = (GDrawHandle *) buf; + int vfmt = p->vertex_format; + assert(vfmt >= 0 && vfmt < GDRAW_vformat__count); + + if (!set_renderstate(vfmt, r, stats)) + return; + + + gdraw->d3d_device->SetVertexDeclaration(gdraw->vdec[vfmt]); + + if (vb) { + gdraw->d3d_device->SetIndices(vb->handle.vbuf.indices); + gdraw->d3d_device->SetStreamSource(0, vb->handle.vbuf.base, (U32) (UINTa) p->vertices, vertsize[vfmt]); + + gdraw->d3d_device->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, p->num_vertices, (U32) ((UINTa) p->indices) >> 1, p->num_indices/3); + + gdraw->d3d_device->SetStreamSource(0,0,0,0); + gdraw->d3d_device->SetIndices(0); + } else if (p->indices) { + gdraw->d3d_device->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0, p->num_vertices, p->num_indices/3, p->indices, D3DFMT_INDEX16, p->vertices, vertsize[vfmt]); + } else { // dynamic quads + assert(p->num_vertices % 4 == 0); + UINT stride = vertsize[vfmt]; + S32 pos = 0; + while (pos < p->num_vertices) { + S32 vert_count = RR_MIN(p->num_vertices - pos, QUAD_IB_COUNT * 4); + gdraw->d3d_device->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0, vert_count, (vert_count/4)*2, quad_ib, D3DFMT_INDEX16, (U8 *)p->vertices + pos * stride, stride); + pos += vert_count; + } + } + + tag_resources(vb, r->tex[0], r->tex[1]); + + stats->nonzero_flags |= GDRAW_STATS_batches; + stats->num_batches += 1; + stats->drawn_indices += p->num_indices; + stats->drawn_vertices += p->num_vertices; +} + +/////////////////////////////////////////////////////////////////////// +// +// Flash 8 filter effects +// + +static void set_pixel_constant(S32 constant, F32 x, F32 y, F32 z, F32 w) +{ + if (constant >= 0) { + F32 value[4] = { x,y,z,w }; + gdraw->d3d_device->SetPixelShaderConstantF(constant, value, 1); + } +} + +// caller sets up texture coordinates +static void do_screen_quad(gswf_recti *s, F32 *tc, GDrawStats *stats) +{ + F32 px0 = (F32) s->x0, py0 = (F32) s->y0, px1 = (F32) s->x1, py1 = (F32) s->y1; + gswf_vertex_xyst vert[4]; + VertexVars vvars; + + // interleave the data so we can use UP + vert[0].x = px0; vert[0].y = py0; vert[0].s = tc[0]; vert[0].t = tc[1]; + vert[1].x = px1; vert[1].y = py0; vert[1].s = tc[2]; vert[1].t = tc[1]; + vert[2].x = px1; vert[2].y = py1; vert[2].s = tc[2]; vert[2].t = tc[3]; + vert[3].x = px0; vert[3].y = py1; vert[3].s = tc[0]; vert[3].t = tc[3]; + + gdraw_PixelSpace(vvars.world[0]); + + gdraw->d3d_device->SetVertexDeclaration(gdraw->vdec[GDRAW_vformat_v2tc2]); + gdraw->d3d_device->SetVertexShader(gdraw->vert[GDRAW_vformat_v2tc2].vshader); + gdraw->d3d_device->SetVertexShaderConstantF(0, vvars.world[0], VVAR_count_worldonly); + gdraw->d3d_device->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, vert, 16); + + stats->nonzero_flags |= GDRAW_STATS_batches; + stats->num_batches += 1; + stats->drawn_indices += 6; + stats->drawn_vertices += 4; +} + +static void gdraw_DriverBlurPass(GDrawRenderState *r, int taps, float *data, gswf_recti *s, float *tc, float /*height_max*/, float *clamp, GDrawStats *gstats) +{ + ProgramWithCachedVariableLocations *prg = &gdraw->blur_prog[taps]; + gdraw->d3d_device->SetPixelShader(prg->pshader); + set_texture(prg->vars[VAR_blur_tex0], r->tex[0]); + + assert(prg->vars[VAR_blur_tap] >= 0); + gdraw->d3d_device->SetPixelShaderConstantF(prg->vars[VAR_blur_tap], data, taps); + gdraw->d3d_device->SetPixelShaderConstantF(prg->vars[VAR_blur_clampv], clamp, 1); + + do_screen_quad(s, tc, gstats); + tag_resources(r->tex[0]); +} + +static void gdraw_Colormatrix(GDrawRenderState *r, gswf_recti *s, float *tc, GDrawStats *stats) +{ + if (!gdraw_TextureDrawBufferBegin(s, GDRAW_TEXTURE_FORMAT_rgba32, GDRAW_TEXTUREDRAWBUFFER_FLAGS_needs_color | GDRAW_TEXTUREDRAWBUFFER_FLAGS_needs_alpha, 0, stats)) + return; + + gdraw->d3d_device->SetPixelShader(gdraw->colormatrix.pshader); + set_texture(gdraw->colormatrix.vars[VAR_colormatrix_tex0], r->tex[0]); + gdraw->d3d_device->SetPixelShaderConstantF(gdraw->colormatrix.vars[VAR_colormatrix_data], r->shader_data, 5); + do_screen_quad(s, tc, stats); + tag_resources(r->tex[0]); + r->tex[0] = gdraw_TextureDrawBufferEnd(stats); +} + +static gswf_recti *get_valid_rect(GDrawTexture *tex) +{ + GDrawHandle *h = (GDrawHandle *) tex; + S32 n = (S32) (h - gdraw->rendertargets.handle); + assert(n >= 0 && n <= MAX_RENDER_STACK_DEPTH+1); + return &gdraw->rt_valid[n]; +} + +static void set_clamp_constant(int constant, GDrawTexture *tex) +{ + gswf_recti *s = get_valid_rect(tex); + // when we make the valid data, we make sure there is an extra empty pixel at the border + set_pixel_constant(constant, + (s->x0-0.5f) / gdraw->frametex_width, + (s->y0-0.5f) / gdraw->frametex_height, + (s->x1+0.5f) / gdraw->frametex_width, + (s->y1+0.5f) / gdraw->frametex_height); +} + +static void gdraw_Filter(GDrawRenderState *r, gswf_recti *s, float *tc, int isbevel, GDrawStats *stats) +{ + ProgramWithCachedVariableLocations *prg = &gdraw->filter_prog[isbevel][r->filter_mode]; + + if (!gdraw_TextureDrawBufferBegin(s, GDRAW_TEXTURE_FORMAT_rgba32, GDRAW_TEXTUREDRAWBUFFER_FLAGS_needs_color | GDRAW_TEXTUREDRAWBUFFER_FLAGS_needs_alpha, NULL, stats)) + return; + + gdraw->d3d_device->SetPixelShader(prg->pshader); + set_texture(prg->vars[VAR_filter_tex0], r->tex[0]); + set_texture(prg->vars[VAR_filter_tex1], r->tex[1]); + set_texture(prg->vars[VAR_filter_tex2], r->tex[2]); + + set_pixel_constant(prg->vars[VAR_filter_color], r->shader_data[0], r->shader_data[1], r->shader_data[2], r->shader_data[3]); + set_pixel_constant(prg->vars[VAR_filter_tc_off], -r->shader_data[4] / (F32)gdraw->frametex_width, -r->shader_data[5] / (F32)gdraw->frametex_height, r->shader_data[6], 0); + set_pixel_constant(prg->vars[VAR_filter_color2], r->shader_data[8], r->shader_data[9], r->shader_data[10], r->shader_data[11]); + set_clamp_constant(prg->vars[VAR_filter_clamp0], r->tex[0]); + set_clamp_constant(prg->vars[VAR_filter_clamp1], r->tex[1]); + + do_screen_quad(s, tc, stats); + tag_resources(r->tex[0], r->tex[1], r->tex[2]); + r->tex[0] = gdraw_TextureDrawBufferEnd(stats); +} + +static void RADLINK gdraw_FilterQuad(GDrawRenderState *r, S32 x0, S32 y0, S32 x1, S32 y1, GDrawStats *stats) +{ + IDirect3DDevice9 *d3d = gdraw->d3d_device; + F32 tc[4]; + gswf_recti s; + + // clip to tile boundaries + s.x0 = RR_MAX(x0, gdraw->tx0p); + s.y0 = RR_MAX(y0, gdraw->ty0p); + s.x1 = RR_MIN(x1, gdraw->tx0p + gdraw->tpw); + s.y1 = RR_MIN(y1, gdraw->ty0p + gdraw->tph); + if (s.x1 < s.x0 || s.y1 < s.y0) + return; + + tc[0] = (s.x0 - gdraw->tx0p) / (F32) gdraw->frametex_width; + tc[1] = (s.y0 - gdraw->ty0p) / (F32) gdraw->frametex_height; + tc[2] = (s.x1 - gdraw->tx0p) / (F32) gdraw->frametex_width; + tc[3] = (s.y1 - gdraw->ty0p) / (F32) gdraw->frametex_height; + + // clear to known render state + d3d->SetRenderState(D3DRS_STENCILENABLE, FALSE); + d3d->SetRenderState(D3DRS_COLORWRITEENABLE, 0xf); + + d3d->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE); + d3d->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESS); + d3d->SetRenderState(D3DRS_ZWRITEENABLE, FALSE); + + d3d->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE); + d3d->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); + + gdraw->scissor_state = 0; + gdraw->blend_mode = GDRAW_BLEND_none; + gdraw->stencil_key = 0; + gdraw->z_key = 0; + + if (r->blend_mode == GDRAW_BLEND_filter) { + switch (r->filter) { + case GDRAW_FILTER_blur: { + GDrawBlurInfo b; + gswf_recti bounds = *get_valid_rect(r->tex[0]); + gdraw_ShiftRect(&s, &s, -gdraw->tx0p, -gdraw->ty0p); // blur uses physical rendertarget coordinates + + b.BlurPass = gdraw_DriverBlurPass; + b.w = gdraw->tpw; + b.h = gdraw->tph; + b.frametex_width = gdraw->frametex_width; + b.frametex_height = gdraw->frametex_height; + + // blur needs to draw with multiple passes, so set up special state + gdraw->in_blur = true; + set_viewport_raw(0, 0, gdraw->tpw, gdraw->tph); + set_projection_raw(0, gdraw->tpw, gdraw->tph, 0); + + // do the blur + gdraw_Blur(&gdraw_funcs, &b,r, &s, &bounds, stats); + + // restore the normal state + gdraw->in_blur = false; + set_viewport(); + set_projection(); + break; + } + + case GDRAW_FILTER_colormatrix: + gdraw_Colormatrix(r, &s, tc, stats); + break; + + case GDRAW_FILTER_dropshadow: + gdraw_Filter(r, &s, tc, 0, stats); + break; + + case GDRAW_FILTER_bevel: + gdraw_Filter(r, &s, tc, 1, stats); + break; + + default: + assert(0); + } + } else { + GDrawHandle *blend_tex = NULL; + static S16 zero[4] = { 0, 0, 0, 0 }; + + // for crazy blend modes, we need to read back from the framebuffer + // and do the blending in the pixel shader. we do this with StretchRect + // rather than trying to render-to-texture-all-along, because we want + // to be able to render over the user's existing framebuffer, which might + // not be a texture. note that this causes MSAA issues! + if (r->blend_mode == GDRAW_BLEND_special && + (blend_tex = get_color_rendertarget(stats)) != NULL) { + + IDirect3DSurface9 *src; + HRESULT hr = d3d->GetRenderTarget(0, &src); + if (!FAILED(hr)) { + IDirect3DSurface9 *dest; + hr = blend_tex->handle.tex.d3d->GetSurfaceLevel(0, &dest); + if (!FAILED(hr)) { + RECT drect = { 0, 0, gdraw->tpw, gdraw->tph }; + RECT srect; + + if (gdraw->cur != gdraw->frame) + srect = drect; + else { + srect.left = gdraw->vx; + srect.top = gdraw->vy; + srect.right = gdraw->vx + gdraw->tw; + srect.bottom = gdraw->vy + gdraw->th; + drect.left = gdraw->tx0 - gdraw->tx0p; + drect.top = gdraw->ty0 - gdraw->ty0p; + drect.right = drect.left + gdraw->tw; + drect.bottom = drect.top + gdraw->th; + } + + d3d->StretchRect(src, &srect, dest, &drect, D3DTEXF_POINT); + dest->Release(); + + stats->nonzero_flags |= GDRAW_STATS_blits; + stats->num_blits += 1; + stats->num_blit_pixels += (srect.right - srect.left) * (srect.bottom - srect.top); + } + + src->Release(); + } + + set_texture(1, (GDrawTexture *) blend_tex); + // make sure we set color_add, because the shader reads it + if (!r->cxf_add) + r->cxf_add = zero; + } + + if (!set_renderstate(GDRAW_vformat_v2tc2, r, stats)) + return; + + do_screen_quad(&s, tc, stats); + tag_resources(r->tex[0], r->tex[1]); + if (blend_tex) + gdraw_FreeTexture((GDrawTexture *) blend_tex, 0, stats); + } +} + +/////////////////////////////////////////////////////////////////////// +// +// Shaders +// + +#include "gdraw_d3d9_shaders.inl" + +static void create_pixel_shader(ProgramWithCachedVariableLocations *p, ProgramWithCachedVariableLocations *src) +{ + *p = *src; + if(p->bytecode) { + HRESULT hr = gdraw->d3d_device->CreatePixelShader(p->bytecode, &p->pshader); + if (FAILED(hr)) { + IggyGDrawSendWarning(NULL, "GDraw D3D error creating pixel shader: 0x%08x", hr); + p->pshader = NULL; + } + } +} + +static void create_vertex_shader(ProgramWithCachedVariableLocations *p, ProgramWithCachedVariableLocations *src) +{ + *p = *src; + if(p->bytecode) { + HRESULT hr = gdraw->d3d_device->CreateVertexShader(p->bytecode, &p->vshader); + if (FAILED(hr)) { + IggyGDrawSendWarning(NULL, "GDraw D3D error creating vertex shader: 0x%08x", hr); + p->vshader = NULL; + } + } +} + +static void destroy_shader(ProgramWithCachedVariableLocations *p) +{ + safe_release(p->pshader); +} + +static void create_all_shaders(void) +{ + S32 i; + + for (i=0; i < GDRAW_TEXTURE__count*3; ++i) create_pixel_shader(&gdraw->fprog[0][i], pshader_basic_arr + i); + for (i=0; i < GDRAW_BLENDSPECIAL__count; ++i) create_pixel_shader(&gdraw->exceptional_blend[i], pshader_exceptional_blend_arr + i); + for (i=0; i < 32; ++i) create_pixel_shader(&gdraw->filter_prog[0][i], pshader_filter_arr + i); + for (i=0; i < MAX_TAPS+1; ++i) create_pixel_shader(&gdraw->blur_prog[i], pshader_blur_arr + i); + create_pixel_shader(&gdraw->colormatrix, pshader_color_matrix_arr); + create_pixel_shader(&gdraw->manual_clear, pshader_manual_clear_arr); + + for (i=0; i < GDRAW_vformat__count; i++) { + HRESULT hr = gdraw->d3d_device->CreateVertexDeclaration(vformats[i], &gdraw->vdec[i]); + if (FAILED(hr)) + IggyGDrawSendWarning(NULL, "GDraw D3D error in CreateVertexDeclaration: 0x%08x", hr); + + create_vertex_shader(&gdraw->vert[i], vshader_vsd3d9_arr + i); + } +} + +static void destroy_all_shaders() +{ + S32 i; + + for (i=0; i < GDRAW_TEXTURE__count*3; ++i) destroy_shader(&gdraw->fprog[0][i]); + for (i=0; i < GDRAW_BLENDSPECIAL__count; ++i) destroy_shader(&gdraw->exceptional_blend[i]); + for (i=0; i < 32; ++i) destroy_shader(&gdraw->filter_prog[0][i]); + for (i=0; i < MAX_TAPS+1; ++i) destroy_shader(&gdraw->blur_prog[i]); + destroy_shader(&gdraw->colormatrix); + + for (i=0; i < GDRAW_vformat__count; i++) { + if (gdraw->vdec[i]) { gdraw->vdec[i]->Release(); gdraw->vdec[i] = 0; } + destroy_shader(&gdraw->vert[i]); + } +} + +//////////////////////////////////////////////////////////////////////// +// +// Create and tear-down the state +// + +typedef struct +{ + S32 num_handles; + S32 num_bytes; +} GDrawResourceLimit; + +// These are the defaults limits used by GDraw unless the user specifies something else. +static GDrawResourceLimit gdraw_limits[ASSERT_COUNT(GDRAW_D3D_RESOURCE__count, 3)] = { + MAX_RENDER_STACK_DEPTH + 1, 16*1024*1024, // GDRAW_D3D_RESOURCE_rendertarget + 500, 16*1024*1024, // GDRAW_D3D_RESOURCE_texture + 1000, 2*1024*1024, // GDRAW_D3D_RESOURCE_vertexbuffer +}; + +static GDrawHandleCache *make_handle_cache(gdraw_d3d_resourcetype type) +{ + S32 num_handles = gdraw_limits[type].num_handles; + S32 num_bytes = gdraw_limits[type].num_bytes; + GDrawHandleCache *cache = (GDrawHandleCache *) IggyGDrawMalloc(sizeof(GDrawHandleCache) + (num_handles - 1) * sizeof(GDrawHandle)); + if (cache) { + gdraw_HandleCacheInit(cache, num_handles, num_bytes); + cache->is_vertex = (type == GDRAW_D3D_RESOURCE_vertexbuffer); + } + + return cache; +} + +static void free_gdraw() +{ + if (!gdraw) return; + if (gdraw->texturecache) IggyGDrawFree(gdraw->texturecache); + if (gdraw->vbufcache) IggyGDrawFree(gdraw->vbufcache); + IggyGDrawFree(gdraw); + gdraw = NULL; +} + +int gdraw_D3D_SetResourceLimits(gdraw_d3d_resourcetype type, S32 num_handles, S32 num_bytes) +{ + GDrawStats stats={0}; + + if (type == GDRAW_D3D_RESOURCE_rendertarget) // RT count is small and space is preallocated + num_handles = MAX_RENDER_STACK_DEPTH + 1; + + assert(type >= GDRAW_D3D_RESOURCE_rendertarget && type < GDRAW_D3D_RESOURCE__count); + assert(num_handles >= 0); + assert(num_bytes >= 0); + + // nothing to do if the values are unchanged + if (gdraw_limits[type].num_handles == num_handles && + gdraw_limits[type].num_bytes == num_bytes) + return 1; + + gdraw_limits[type].num_handles = num_handles; + gdraw_limits[type].num_bytes = num_bytes; + + // if no gdraw context created, there's nothing to worry about + if (!gdraw) + return 1; + + // resize the appropriate pool + switch (type) { + case GDRAW_D3D_RESOURCE_rendertarget: + flush_rendertargets(&stats); + gdraw_HandleCacheInit(&gdraw->rendertargets, num_handles, num_bytes); + return 1; + + case GDRAW_D3D_RESOURCE_texture: + if (gdraw->texturecache) { + gdraw_res_flush(gdraw->texturecache, &stats); + IggyGDrawFree(gdraw->texturecache); + } + gdraw->texturecache = make_handle_cache(GDRAW_D3D_RESOURCE_texture); + return gdraw->texturecache != NULL; + + case GDRAW_D3D_RESOURCE_vertexbuffer: + if (gdraw->vbufcache) { + gdraw_res_flush(gdraw->vbufcache, &stats); + IggyGDrawFree(gdraw->vbufcache); + } + gdraw->vbufcache = make_handle_cache(GDRAW_D3D_RESOURCE_vertexbuffer); + return gdraw->vbufcache != NULL; + + default: + return 0; + } +} + +GDrawFunctions *gdraw_D3D_CreateContext(IDirect3DDevice9 *dev, S32 w, S32 h) +{ + gdraw = (GDraw *) IggyGDrawMalloc(sizeof(*gdraw)); + if (!gdraw) return NULL; + + memset(gdraw, 0, sizeof(*gdraw)); + + gdraw->frametex_width = w; + gdraw->frametex_height = h; + + gdraw->texturecache = make_handle_cache(GDRAW_D3D_RESOURCE_texture); + gdraw->vbufcache = make_handle_cache(GDRAW_D3D_RESOURCE_vertexbuffer); + gdraw_HandleCacheInit(&gdraw->rendertargets, gdraw_limits[GDRAW_D3D_RESOURCE_rendertarget].num_handles, gdraw_limits[GDRAW_D3D_RESOURCE_rendertarget].num_bytes); + + if (!gdraw->texturecache || !gdraw->vbufcache) { + free_gdraw(); + return NULL; + } + + if (!quad_ib[1]) { + // initialize quad index buffer + for (U16 i=0; i < QUAD_IB_COUNT; i++) { + quad_ib[i*6 + 0] = i*4 + 0; + quad_ib[i*6 + 1] = i*4 + 1; + quad_ib[i*6 + 2] = i*4 + 2; + quad_ib[i*6 + 3] = i*4 + 0; + quad_ib[i*6 + 4] = i*4 + 2; + quad_ib[i*6 + 5] = i*4 + 3; + } + } + + #if 1 + D3DCAPS9 caps; + dev->GetDeviceCaps(&caps); + gdraw->conditional_nonpow2 = ((caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) != 0); + #endif + + gdraw->d3d_device = dev; + create_all_shaders(); + + gdraw_funcs.SetViewSizeAndWorldScale = gdraw_SetViewSizeAndWorldScale; + gdraw_funcs.GetInfo = gdraw_GetInfo; + + gdraw_funcs.DescribeTexture = gdraw_DescribeTexture; + gdraw_funcs.DescribeVertexBuffer = gdraw_DescribeVertexBuffer; + + gdraw_funcs.RenderingBegin = gdraw_RenderingBegin; + gdraw_funcs.RenderingEnd = gdraw_RenderingEnd; + gdraw_funcs.RenderTileBegin = gdraw_RenderTileBegin; + gdraw_funcs.RenderTileEnd = gdraw_RenderTileEnd; + + gdraw_funcs.TextureDrawBufferBegin = gdraw_TextureDrawBufferBegin; + gdraw_funcs.TextureDrawBufferEnd = gdraw_TextureDrawBufferEnd; + + gdraw_funcs.DrawIndexedTriangles = gdraw_DrawIndexedTriangles; + gdraw_funcs.FilterQuad = gdraw_FilterQuad; + + gdraw_funcs.SetAntialiasTexture = gdraw_SetAntialiasTexture; + + gdraw_funcs.ClearStencilBits = gdraw_ClearStencilBits; + gdraw_funcs.ClearID = gdraw_ClearID; + + gdraw_funcs.MakeTextureBegin = gdraw_MakeTextureBegin; + gdraw_funcs.MakeTextureMore = gdraw_MakeTextureMore; + gdraw_funcs.MakeTextureEnd = gdraw_MakeTextureEnd; + + gdraw_funcs.UpdateTextureBegin = gdraw_UpdateTextureBegin; + gdraw_funcs.UpdateTextureRect = gdraw_UpdateTextureRect; + gdraw_funcs.UpdateTextureEnd = gdraw_UpdateTextureEnd; + + gdraw_funcs.FreeTexture = gdraw_FreeTexture; + gdraw_funcs.TryToLockTexture = gdraw_TryToLockTexture; + + gdraw_funcs.MakeTextureFromResource = (gdraw_make_texture_from_resource *) gdraw_D3D_MakeTextureFromResource; + gdraw_funcs.FreeTextureFromResource = gdraw_D3D_DestroyTextureFromResource; + + gdraw_funcs.MakeVertexBufferBegin = gdraw_MakeVertexBufferBegin; + gdraw_funcs.MakeVertexBufferMore = gdraw_MakeVertexBufferMore; + gdraw_funcs.MakeVertexBufferEnd = gdraw_MakeVertexBufferEnd; + gdraw_funcs.TryToLockVertexBuffer = gdraw_TryLockVertexBuffer; + gdraw_funcs.FreeVertexBuffer = gdraw_FreeVertexBuffer; + + gdraw_funcs.UnlockHandles = gdraw_UnlockHandles; + gdraw_funcs.SetTextureUniqueID = gdraw_SetTextureUniqueID; + gdraw_funcs.Set3DTransform = gdraw_Set3DTransform; + + return &gdraw_funcs; +} + +void gdraw_D3D_DestroyContext(void) +{ + if (gdraw && gdraw->d3d_device) { + GDrawStats stats={0}; + destroy_all_shaders(); + gdraw_res_flush(gdraw->texturecache, &stats); + gdraw_res_flush(gdraw->vbufcache, &stats); + flush_rendertargets(&stats); + + safe_release(gdraw->aa_tex); + gdraw->d3d_device = NULL; + } + + free_gdraw(); +} + +void gdraw_D3D_SetErrorHandler(void (__cdecl *error_handler)(HRESULT hr)) +{ + if (gdraw) + gdraw->error_handler = error_handler; +} + +void gdraw_D3D_PreReset(void) +{ + if (!gdraw) return; + + GDrawStats stats={0}; + flush_rendertargets(&stats); + + // we may end up resizing the frame buffer + gdraw->frametex_width = 0; + gdraw->frametex_height = 0; +} + +void gdraw_D3D_PostReset(void) +{ + // maybe re-create rendertargets right now? +} + +void RADLINK gdraw_D3D_BeginCustomDraw(IggyCustomDrawCallbackRegion *region, D3DMATRIX *mat) +{ + clear_renderstate(); + gdraw_GetObjectSpaceMatrix(mat->m[0], region->o2w, gdraw->projection, 0, 0); +} + +void RADLINK gdraw_D3D_EndCustomDraw(IggyCustomDrawCallbackRegion * /*region*/) +{ + set_common_renderstate(); + set_projection(); +} + +void RADLINK gdraw_D3D_GetResourceUsageStats(gdraw_d3d_resourcetype type, S32 *handles_used, S32 *bytes_used) +{ + GDrawHandleCache *cache; + + switch (type) { + case GDRAW_D3D_RESOURCE_rendertarget: cache = &gdraw->rendertargets; break; + case GDRAW_D3D_RESOURCE_texture: cache = gdraw->texturecache; break; + case GDRAW_D3D_RESOURCE_vertexbuffer: cache = gdraw->vbufcache; break; + default: cache = NULL; break; + } + + *handles_used = *bytes_used = 0; + + if (cache) { + S32 i; + U64 frame = gdraw->frame_counter; + + for (i=0; i < cache->max_handles; ++i) + if (cache->handle[i].bytes && cache->handle[i].owner && cache->handle[i].fence.value == frame) { + *handles_used += 1; + *bytes_used += cache->handle[i].bytes; + } + } +} + +GDrawTexture * RADLINK gdraw_D3D_MakeTextureFromResource(U8 *resource_file, S32 /*len*/, IggyFileTextureRaw *texture) +{ + GDrawTexture *h; + S32 width, height, mipmaps, size; + IDirect3DTexture9 *tex; + D3DFORMAT d3dfmt; + width = texture->w; + height = texture->h; + mipmaps = texture->mipmaps; + + // discard mipmaps on non-pow-of-2 if the hardware doesn't support + if (gdraw->conditional_nonpow2) { + if ((width & (width-1)) || (height & (height-1))) + mipmaps = 1; + } + + switch (texture->format) { + case IFT_FORMAT_rgba_8888 : size= 4; d3dfmt = D3DFMT_A8R8G8B8; break; + case IFT_FORMAT_rgba_4444_LE: size= 2; d3dfmt = D3DFMT_A4R4G4B4; break; + case IFT_FORMAT_rgba_5551_LE: size= 2; d3dfmt = D3DFMT_A1R5G5B5; break; + case IFT_FORMAT_la_88 : size= 2; d3dfmt = D3DFMT_A8L8; break; + case IFT_FORMAT_la_44 : size= 1; d3dfmt = D3DFMT_A4L4; break; + case IFT_FORMAT_i_8 : + case IFT_FORMAT_i_4 : size= 2; d3dfmt = D3DFMT_A8L8; break; + case IFT_FORMAT_l_8 : size= 1; + case IFT_FORMAT_l_4 : size= 1; d3dfmt = D3DFMT_L8; break; + case IFT_FORMAT_DXT1 : size= 8; d3dfmt = D3DFMT_DXT1; break; + case IFT_FORMAT_DXT3 : size=16; d3dfmt = D3DFMT_DXT3; break; + case IFT_FORMAT_DXT5 : size=16; d3dfmt = D3DFMT_DXT5; break; + default: size=0; d3dfmt=D3DFMT_UNKNOWN; break; + } + + HRESULT hr = gdraw->d3d_device->CreateTexture(width, height, mipmaps, + 0, d3dfmt, D3DPOOL_MANAGED, &tex, NULL); + if (FAILED(hr)) { + if (size >= 8 && ((width & 3) || (height & 3))) + IggyGDrawSendWarning(NULL, "GDraw D3D error, dxtc texture dimensions must be multiples of 4"); + else + report_d3d_error(hr, "CreateTexture", ""); + return NULL; + } + + U8 *data = resource_file + texture->file_offset; + + for (int level=0; level < mipmaps; ++level) { + S32 dxt_width = (width+3)/4; + S32 effective_height; + if (size >= 8) + effective_height = (height+3)/4; + else + effective_height = height; + + D3DLOCKED_RECT z; + hr = tex->LockRect(level, &z, NULL, 0); + if (FAILED(hr)) { + report_d3d_error(hr, "LockRect", " while creating texture"); + tex->Release(); + return NULL; + } + U8 *pixels = (U8*) z.pBits; + for (S32 j=0; j < effective_height; ++j) { + switch (texture->format) { + default: + memcpy(pixels + z.Pitch*j, data + j*width*size, width*size); + break; + case IFT_FORMAT_rgba_8888: { + for (S32 i=0; i < width; ++i) { + pixels[z.Pitch*j + i*4 + 0] = data[j*width*4 + i*4 + 2]; + pixels[z.Pitch*j + i*4 + 1] = data[j*width*4 + i*4 + 1]; + pixels[z.Pitch*j + i*4 + 2] = data[j*width*4 + i*4 + 0]; + pixels[z.Pitch*j + i*4 + 3] = data[j*width*4 + i*4 + 3]; + } + break; + } + case IFT_FORMAT_DXT1: + case IFT_FORMAT_DXT3: + case IFT_FORMAT_DXT5: + memcpy(pixels + z.Pitch*j, data + j*dxt_width*size, dxt_width*size); + break; + case IFT_FORMAT_i_8: + case IFT_FORMAT_i_4: { + // convert from intensity to luminance-alpha by replicating all the pixels + for (S32 i=0; i < width; ++i) + pixels[z.Pitch*j + i*2 + 0] = + pixels[z.Pitch*j + i*2 + 1] = data[j*width + i]; + break; + } + } + } + tex->UnlockRect(level); + + data += (size<8) ? width*height*size : ((width+3)/4)*((height+3)/4)*size; + width = width >>1; width += !width ; + height = height>>1; height += !height; + } + + h = gdraw_D3D_WrappedTextureCreate(tex); + if (!h) tex->Release(); + return h; +} + +void RADLINK gdraw_D3D_DestroyTextureFromResource(GDrawTexture *tex) +{ + GDrawHandle *h = (GDrawHandle *) tex; + h->handle.tex.d3d->Release(); + gdraw_D3D_WrappedTextureDestroy(tex); +} + diff --git a/Minecraft.Client/Windows64/Iggy/gdraw/gdraw_d3d.h b/Minecraft.Client/Windows64/Iggy/gdraw/gdraw_d3d.h new file mode 100644 index 00000000..927688e4 --- /dev/null +++ b/Minecraft.Client/Windows64/Iggy/gdraw/gdraw_d3d.h @@ -0,0 +1,107 @@ +// gdraw_d3d.h - author: Sean Barrett - copyright 2009-2011 RAD Game Tools +// +// Interface for creating a D3D GDraw driver. + +#include "gdraw.h" + +#define IDOC +//idoc(parent,GDraw_d3d9) + +typedef enum gdraw_d3d_resourcetype +{ + GDRAW_D3D_RESOURCE_rendertarget, + GDRAW_D3D_RESOURCE_texture, + GDRAW_D3D_RESOURCE_vertexbuffer, + + GDRAW_D3D_RESOURCE__count, +} gdraw_d3d_resourcetype; + +IDOC extern int gdraw_D3D_SetResourceLimits(gdraw_d3d_resourcetype type, S32 num_handles, S32 num_bytes); +/* This sets how large the memory pool for a given resource types is, and how many handles + GDraw should allocate for it. GDraw keeps track of allocations in each pool, and will free + old resources in a LRU manner to make space if one of the limits is about to be exceeded. + + Returns 1 if value successfully changed, 0 on error. + You need to call IggyPlayerFlushAll on all active Iggys before you do this to make + them flush their resources since changing the resource limits invalidates all handles. + You also need to call IggyFlushInstalledFonts if you have any installed fonts. +*/ + +IDOC extern GDrawFunctions * gdraw_D3D_CreateContext(IDirect3DDevice9 *dev, S32 w, S32 h); +/* Creates a GDraw context for rendering using D3D. You need to pass in the D3D device + and the width/height of the content you're displaying. + + The width/height is used solely for sizing internal rendertargets. They will be + allocated to the larger of this size and the size of any rendered tiles (with padding). + In other words, you can pass in (0,0) and the rendertargets will be allocated to the + right size. However, if you draw multiple Iggy files or tiles of different sizes, + they might first be allocated too small; it's best to pass in the correct size initially + to avoid unnecessary allocation/deallocation of too-small rendertargets. + + There can only be one D3D GDraw context active at any one time. + + If initialization fails for some reason (the main reason would be an out of memory condition), + NULL is returned. Otherwise, you can pass the return value to IggySetGDraw. */ + +IDOC extern void gdraw_D3D_SetRendertargetSize(S32 w, S32 h); +/* Reset the size used for internal rendertargets defined by CreateContext. Flushes + all existing rendertargets if the size changes. */ + +IDOC extern void gdraw_D3D_DestroyContext(void); +/* Destroys the current GDraw context, if any. */ + +IDOC extern void gdraw_D3D_SetTileOrigin(IDirect3DSurface9 *rt, IDirect3DSurface9 *depth, S32 x, S32 y); +/* This sets the main rendertarget that GDraw should render to, the corresponding + depth/stencil surface, and the x/y position where to draw the top-left of the current tile (to be used for tiled + rendering). You need to call this before Iggy calls any rendering functions. */ + +IDOC extern void gdraw_D3D_NoMoreGDrawThisFrame(void); +/* Tells GDraw that no more rendering operations will occur this frame. This triggers + some end-of-frame processing; most importantly, GDraw uses this call as a marker to + detect thrashing (and react accordingly), so please do not forget to call this + every frame! (As long as Iggy does any rendering, that is) */ + +IDOC extern void gdraw_D3D_PreReset(void); +/* Call this before D3D device Reset(); it will free all default pool resources allocated + by GDraw. */ + +IDOC extern void gdraw_D3D_PostReset(void); +/* Call after D3D device Reset(). */ + +IDOC extern void RADLINK gdraw_D3D_BeginCustomDraw(IggyCustomDrawCallbackRegion *Region, D3DMATRIX *mat); +/* Call at the beginning of Iggy custom draw callback to clear any odd render states GDraw has + set on the D3D device, and to get the current 2D object-to-world transformation. */ + +IDOC extern void RADLINK gdraw_D3D_EndCustomDraw(IggyCustomDrawCallbackRegion *Region); +/* Call at the end of Iggy custom draw callback so GDraw can restore its render states. */ + +IDOC extern void RADLINK gdraw_D3D_GetResourceUsageStats(gdraw_d3d_resourcetype type, S32 *handles_used, S32 *bytes_used); +/* D3D only: Get resource usage stats for last frame. + This can be used to get an estimate of how much graphics memory got used by GDraw + during the last frame. + Caveat: This counts the number of bytes that GDraw knows about. 3D hardware usually + has its own management overhead, alignment requirements, allocation granularity + and so on. In short, this is not an accurate estimate of how much memory is actually + used by the GPU - it is a lower bound, though, and makes for a useful ballpark estimate. */ + +IDOC extern GDrawTexture *gdraw_D3D_WrappedTextureCreate(IDirect3DTexture9 *tex_handle); +/* Create a wrapped texture from a D3D texture. + A wrapped texture can be used to let Iggy draw using the contents of a texture + you create and manage on your own. For example, you might render to this texture, + or stream video into it. Wrapped textures take up a handle. They will never be + freed or otherwise modified by GDraw; nor will GDraw change any reference counts. + All this is up to the application. */ + +IDOC extern void gdraw_D3D_WrappedTextureChange(GDrawTexture *tex, IDirect3DTexture9 *tex_handle); +/* Switch an existing GDrawTexture * that represents a wrapped texture to use + a new underlying D3D texture. For example, you might internally double-buffer + a dynamically updated texture. As above, GDraw will leave this texture alone + and not touch any reference counts. */ + +IDOC extern void gdraw_D3D_WrappedTextureDestroy(GDrawTexture *tex); +/* Destroys the GDraw wrapper for a wrapped texture object. This will free up + a GDraw texture handle but not release the associated D3D texture; that is + up to you. */ + +extern GDrawTexture * RADLINK gdraw_D3D_MakeTextureFromResource(U8 *resource_file, S32 length, IggyFileTextureRaw *texture); +extern void RADLINK gdraw_D3D_DestroyTextureFromResource(GDrawTexture *tex); diff --git a/Minecraft.Client/Windows64/Iggy/gdraw/gdraw_d3d10.cpp b/Minecraft.Client/Windows64/Iggy/gdraw/gdraw_d3d10.cpp new file mode 100644 index 00000000..225f2581 --- /dev/null +++ b/Minecraft.Client/Windows64/Iggy/gdraw/gdraw_d3d10.cpp @@ -0,0 +1,138 @@ +// gdraw_d3d10.cpp - author: Fabian Giesen - copyright 2011 RAD Game Tools +// +// This implements the Iggy graphics driver layer for D3D 10. + +// GDraw consists of several components that interact fairly loosely with each other; +// e.g. the resource management, drawing and filtering parts are all fairly independent +// of each other. If you want to modify some aspect of GDraw - say the texture allocation +// logic - your best bet is usually to just look for one of the related entry points, +// e.g. MakeTextureBegin, and take it from there. There's a bunch of code in this file, +// but none of it is really complicated. +// +// The one bit you might want to change that's not that localized is to integrate +// GDraw with an existing state caching system. The following bits all modify D3D state +// in some way: +// - The rendering helpers (set_viewport_raw, set_projection_raw, set_*_renderstate) +// - RenderTile*/TextureDrawBuffer* may change the active rendertarget and depth/stencil surface, +// as do D3D1X_(NoMoreGDrawThisFrame) and set_render_target +// - set_texture +// - set_renderstate and set_renderstate_full. These are the main places where render state changes occur; +// you should probably start here. +// - DrawIndexedTriangles sets the active vertex/index buffers and vertex declaration +// - Most of the functions in the "filter effects" section modify D3D state, mostly +// pixel shader constants and textures + +#define GDRAW_ASSERTS + +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif + +// We temporarily disable this warning for the shared interface portions +#pragma warning (push) +#pragma warning (disable: 4201) // nonstandard extension used : nameless struct/union + +#include +#include +#include "gdraw.h" +#include "iggy.h" +#include +#include + +#include "gdraw_d3d10.h" + +#pragma warning (pop) + +// Some macros to allow as much sharing between D3D10 and D3D11 code as possible. +#define D3D1X_(id) D3D10_##id +#define ID3D1X(id) ID3D10##id +#define gdraw_D3D1X_(id) gdraw_D3D10_##id +#define GDRAW_D3D1X_(id) GDRAW_D3D10_##id + +typedef ID3D10Device ID3D1XDevice; +typedef ID3D10Device ID3D1XContext; +typedef S32 ViewCoord; +typedef gdraw_d3d10_resourcetype gdraw_resourcetype; + +static void report_d3d_error(HRESULT hr, char *call, char *context); + +static void *map_buffer(ID3D1XContext *, ID3D10Buffer *buf, bool discard) +{ + void *ptr; + if (FAILED(buf->Map(discard ? D3D10_MAP_WRITE_DISCARD : D3D10_MAP_WRITE_NO_OVERWRITE, 0, &ptr))) + return NULL; + else + return ptr; +} + +static void unmap_buffer(ID3D1XContext *, ID3D10Buffer *buf) +{ + buf->Unmap(); +} + +static RADINLINE void set_pixel_shader(ID3D10Device *ctx, ID3D10PixelShader *shader) +{ + ctx->PSSetShader(shader); +} + +static RADINLINE void set_vertex_shader(ID3D10Device *ctx, ID3D10VertexShader *shader) +{ + ctx->VSSetShader(shader); +} + +static ID3D10BlendState *create_blend_state(ID3D10Device *dev, BOOL blend, D3D10_BLEND src, D3D10_BLEND dst) +{ + D3D10_BLEND_DESC desc = {}; + desc.BlendEnable[0] = blend; + desc.SrcBlend = src; + desc.DestBlend = dst; + desc.BlendOp = D3D10_BLEND_OP_ADD; + desc.SrcBlendAlpha = (src == D3D10_BLEND_DEST_COLOR ) ? D3D10_BLEND_DEST_ALPHA : src; + desc.DestBlendAlpha = dst; + desc.BlendOpAlpha = D3D10_BLEND_OP_ADD; + desc.RenderTargetWriteMask[0] = D3D10_COLOR_WRITE_ENABLE_ALL; + + ID3D10BlendState *res; + HRESULT hr = dev->CreateBlendState(&desc, &res); + if (FAILED(hr)) { + report_d3d_error(hr, "CreateBlendState", ""); + res = NULL; + } + + return res; +} + +#define GDRAW_SHADER_FILE "gdraw_d3d10_shaders.inl" +#include "gdraw_d3d1x_shared.inl" + +static void create_pixel_shader(ProgramWithCachedVariableLocations *p, ProgramWithCachedVariableLocations *src) +{ + *p = *src; + if(p->bytecode) { + HRESULT hr = gdraw->d3d_device->CreatePixelShader(p->bytecode, p->size, &p->pshader); + if (FAILED(hr)) { + report_d3d_error(hr, "CreatePixelShader", ""); + p->pshader = NULL; + return; + } + } +} + +static void create_vertex_shader(ProgramWithCachedVariableLocations *p, ProgramWithCachedVariableLocations *src) +{ + *p = *src; + if(p->bytecode) { + HRESULT hr = gdraw->d3d_device->CreateVertexShader(p->bytecode, p->size, &p->vshader); + if (FAILED(hr)) { + report_d3d_error(hr, "CreateVertexShader", ""); + p->vshader = NULL; + return; + } + } +} + +GDrawFunctions *gdraw_D3D10_CreateContext(ID3D10Device *dev, S32 w, S32 h) +{ + return create_context(dev, dev, w, h); +} + diff --git a/Minecraft.Client/Windows64/Iggy/gdraw/gdraw_d3d10.h b/Minecraft.Client/Windows64/Iggy/gdraw/gdraw_d3d10.h new file mode 100644 index 00000000..929146b2 --- /dev/null +++ b/Minecraft.Client/Windows64/Iggy/gdraw/gdraw_d3d10.h @@ -0,0 +1,132 @@ +// gdraw_d3d10.h - author: Fabian Giesen - copyright 2011 RAD Game Tools +// +// Interface for creating a D3D10 GDraw driver. + +#define IDOC +//idoc(parent,GDraw_d3d10) + +typedef enum gdraw_d3d10_resourcetype +{ + GDRAW_D3D10_RESOURCE_rendertarget, + GDRAW_D3D10_RESOURCE_texture, + GDRAW_D3D10_RESOURCE_vertexbuffer, + GDRAW_D3D10_RESOURCE_dynbuffer, // Streaming buffer for dynamic vertex/index data (handle count ignored) + + GDRAW_D3D10_RESOURCE__count, +} gdraw_d3d10_resourcetype; + +IDOC extern int gdraw_D3D10_SetResourceLimits(gdraw_d3d10_resourcetype type, S32 num_handles, S32 num_bytes); +/* This sets how large the memory pool for a given resource types is, and how many handles + GDraw should allocate for it. GDraw keeps track of allocations in each pool, and will free + old resources in a LRU manner to make space if one of the limits is about to be exceeded. + + Returns 1 if value successfully changed, 0 on error. + You need to call IggyPlayerFlushAll on all active Iggys before you do this to make + them flush their resources since changing the resource limits invalidates all handles. + You also need to call IggyFlushInstalledFonts if you have any installed fonts. +*/ + +IDOC extern GDrawFunctions * gdraw_D3D10_CreateContext(ID3D10Device *dev, S32 w, S32 h); +/* Creates a GDraw context for rendering using D3D. You need to pass in the D3D device + and the width/height of render target textures. + + The width/height is used solely for sizing internal rendertargets. They will be + allocated to the larger of this size and the size of any rendered tiles (with padding). + In other words, you can pass in (0,0) and the rendertargets will be allocated to the + right size. However, if you draw multiple Iggy files or tiles of different sizes, + they might first be allocated too small; it's best to pass in the correct size initially + to avoid unnecessary allocation/deallocation of too-small rendertargets. + + There can only be one D3D GDraw context active at any one time. + + If initialization fails for some reason (the main reason would be an out of memory condition), + NULL is returned. Otherwise, you can pass the return value to IggySetGDraw. */ + +IDOC extern void gdraw_D3D10_DestroyContext(void); +/* Destroys the current GDraw context, if any. */ + +IDOC extern void gdraw_D3D10_SetErrorHandler(void (__cdecl *error_handler)(HRESULT hr)); +/* Sets the GDraw D3D error handler. + + This will get called with the respective D3D error code if GDraw encounters an error + that it can't handle by itself (e.g. running out of state objects). */ + +IDOC extern void gdraw_D3D10_SetRendertargetSize(S32 w, S32 h); +/* Changes the current render target size (and recreates all rendertargets if necessary). + This allows you to shrink the rendertargets if the new needed size is smaller + than it was previously. As with $gdraw_D3D10_CreateContext, the width and + height specified here are only minimums; GDraw will reallocate larger rendertargets + as needed. */ + +IDOC extern void gdraw_D3D10_SetTileOrigin(ID3D10RenderTargetView *main_rt, ID3D10DepthStencilView *main_ds, + ID3D10ShaderResourceView *non_msaa_rt, S32 x, S32 y); +/* This sets the main rendertarget and matching depth/stencil buffer that GDraw + should render to and the x/y position of the output location of the top-left + of the current tile (allowing you to finely-position content, or to do tiled + rendering). + + If your rendertarget uses multisampling, you also need to specify a shader + resource view for a non-MSAA rendertarget texture (identically sized to main_rt) + in non_msaa_rt. This is only used if the Flash content includes non-standard + blend modes which have to use a special blend shader, so you can leave it NULL + if you forbid such content. + + You need to call this before Iggy calls any rendering functions. */ + +IDOC extern void gdraw_D3D10_NoMoreGDrawThisFrame(void); +/* Tells GDraw that no more rendering operations will occur this frame. This triggers + some end-of-frame processing; most importantly, GDraw uses this call as a marker to + detect thrashing (and react accordingly), so please do not forget to call this + every frame! (As long as Iggy does any rendering, that is) */ + +IDOC extern void gdraw_D3D10_PreReset(void); +/* Call this before D3D device Reset(); it will free all default pool resources allocated + by GDraw. */ + +IDOC extern void gdraw_D3D10_PostReset(void); +/* Call after D3D device Reset(). */ + +IDOC extern void RADLINK gdraw_D3D10_BeginCustomDraw(IggyCustomDrawCallbackRegion *Region, F32 mat[4][4]); +/* Call at the beginning of Iggy custom draw callback to clear any odd render states GDraw has + set on the D3D device, and to get the current 2D object-to-world transformation. */ + +IDOC extern void RADLINK gdraw_D3D10_EndCustomDraw(IggyCustomDrawCallbackRegion *Region); +/* Call at the end of Iggy custom draw callback so GDraw can restore its render states. */ + +IDOC extern void RADLINK gdraw_D3D10_GetResourceUsageStats(gdraw_d3d10_resourcetype type, S32 *handles_used, S32 *bytes_used); +/* D3D only: Get resource usage stats for last frame. + This can be used to get an estimate of how much graphics memory got used by GDraw + during the last frame. + + For the dynbuffer, this always returns 0 in handles_used and the *size of the largest + single allocation* in bytes_used. It needs to be sized so that this allocation fits; + make it smaller and it won't work, but if you make it much larger (say more than 2x + as big), it's just a waste of memory. That said, we still recommend to make it no + smaller than 64k, and the default is 256k. + + Caveat: This counts the number of bytes that GDraw knows about. 3D hardware usually + has its own management overhead, alignment requirements, allocation granularity + and so on. In short, this is not an accurate estimate of how much memory is actually + used by the GPU - it is a lower bound, though, and makes for a useful ballpark estimate. */ + +IDOC extern GDrawTexture *gdraw_D3D10_WrappedTextureCreate(ID3D10ShaderResourceView *tex_view); +/* Create a wrapped texture from a shader resource view. + A wrapped texture can be used to let Iggy draw using the contents of a texture + you create and manage on your own. For example, you might render to this texture, + or stream video into it. Wrapped textures take up a handle. They will never be + freed or otherwise modified by GDraw; nor will GDraw change any reference counts. + All this is up to the application. */ + +IDOC extern void gdraw_D3D10_WrappedTextureChange(GDrawTexture *tex, ID3D10ShaderResourceView *tex_view); +/* Switch an existing GDrawTexture * that represents a wrapped texture to use + a new underlying D3D view. For example, you might internally double-buffer + a dynamically updated texture. As above, GDraw will leave this texture alone + and not touch any reference counts. */ + +IDOC extern void gdraw_D3D10_WrappedTextureDestroy(GDrawTexture *tex); +/* Destroys the GDraw wrapper for a wrapped texture object. This will free up + a GDraw texture handle but not release the associated D3D texture; that is + up to you. */ + +extern GDrawTexture * RADLINK gdraw_D3D10_MakeTextureFromResource(U8 *resource_file, S32 length, IggyFileTextureRaw *texture); +extern void RADLINK gdraw_D3D10_DestroyTextureFromResource(GDrawTexture *tex); diff --git a/Minecraft.Client/Windows64/Iggy/gdraw/gdraw_d3d10_shaders.inl b/Minecraft.Client/Windows64/Iggy/gdraw/gdraw_d3d10_shaders.inl new file mode 100644 index 00000000..d4d2bb22 --- /dev/null +++ b/Minecraft.Client/Windows64/Iggy/gdraw/gdraw_d3d10_shaders.inl @@ -0,0 +1,3427 @@ +// This file was automatically generated by shadergen. Do not edit by hand! + +static DWORD pshader_basic_0[239] = { + 0x43425844, 0x424a7ef2, 0x6c708f66, 0xff55849a, 0xbcc512aa, 0x00000001, 0x000003bc, 0x00000005, + 0x00000034, 0x000001a8, 0x00000200, 0x00000234, 0x00000340, 0x46454452, 0x0000016c, 0x00000001, + 0x0000008c, 0x00000003, 0x0000001c, 0xffff0400, 0x00008100, 0x00000139, 0x0000007c, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000007, 0x00000001, 0x00000001, 0x00000083, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000007, 0x00000001, 0x0000000d, 0x00000088, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x65745f73, 0x74003178, + 0x00317865, 0x00635350, 0x00000088, 0x00000004, 0x000000a4, 0x00000040, 0x00000000, 0x00000000, + 0x00000104, 0x00000000, 0x00000010, 0x00000002, 0x00000110, 0x00000000, 0x00000120, 0x00000010, + 0x00000010, 0x00000000, 0x00000110, 0x00000000, 0x0000012a, 0x00000020, 0x00000010, 0x00000000, + 0x00000110, 0x00000000, 0x00000130, 0x00000030, 0x00000010, 0x00000000, 0x00000110, 0x00000000, + 0x6f6c6f63, 0x756d5f72, 0xabab006c, 0x00030001, 0x00040001, 0x00000000, 0x00000000, 0x6f6c6f63, + 0x64615f72, 0x6f660064, 0x006c6163, 0x63736572, 0x31656c61, 0x63694d00, 0x6f736f72, 0x28207466, + 0x48202952, 0x204c534c, 0x64616853, 0x43207265, 0x69706d6f, 0x2072656c, 0x39322e39, 0x3235392e, + 0x3131332e, 0xabab0031, 0x4e475349, 0x00000050, 0x00000002, 0x00000008, 0x00000038, 0x00000000, + 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x00000044, 0x00000000, 0x00000000, 0x00000003, + 0x00000001, 0x00000c0f, 0x505f5653, 0x7469736f, 0x006e6f69, 0x43584554, 0x44524f4f, 0xababab00, + 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, + 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x52444853, 0x00000104, 0x00000040, + 0x00000041, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x0300005a, 0x00106000, 0x00000007, + 0x04001858, 0x00107000, 0x00000007, 0x00005555, 0x03001062, 0x001010c2, 0x00000001, 0x03000065, + 0x001020f2, 0x00000000, 0x02000068, 0x00000002, 0x0700000e, 0x00100012, 0x00000000, 0x0010102a, + 0x00000001, 0x0010103a, 0x00000001, 0x05000036, 0x00100022, 0x00000000, 0x0010103a, 0x00000001, + 0x09000045, 0x001000f2, 0x00000000, 0x00100046, 0x00000000, 0x00107e46, 0x00000007, 0x00106000, + 0x00000007, 0x09000038, 0x00100072, 0x00000001, 0x00208ff6, 0x00000000, 0x00000000, 0x00208246, + 0x00000000, 0x00000000, 0x06000036, 0x00100082, 0x00000001, 0x0020803a, 0x00000000, 0x00000000, + 0x07000038, 0x001020f2, 0x00000000, 0x00100e46, 0x00000000, 0x00100e46, 0x00000001, 0x0100003e, + 0x54415453, 0x00000074, 0x00000007, 0x00000002, 0x00000000, 0x00000002, 0x00000003, 0x00000000, + 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +}; + +static DWORD pshader_basic_1[261] = { + 0x43425844, 0x90372132, 0x718f790d, 0x41ee8636, 0x62f4522d, 0x00000001, 0x00000414, 0x00000005, + 0x00000034, 0x000001a8, 0x00000200, 0x00000234, 0x00000398, 0x46454452, 0x0000016c, 0x00000001, + 0x0000008c, 0x00000003, 0x0000001c, 0xffff0400, 0x00008100, 0x00000139, 0x0000007c, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000007, 0x00000001, 0x00000001, 0x00000083, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000007, 0x00000001, 0x0000000d, 0x00000088, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x65745f73, 0x74003178, + 0x00317865, 0x00635350, 0x00000088, 0x00000004, 0x000000a4, 0x00000040, 0x00000000, 0x00000000, + 0x00000104, 0x00000000, 0x00000010, 0x00000002, 0x00000110, 0x00000000, 0x00000120, 0x00000010, + 0x00000010, 0x00000002, 0x00000110, 0x00000000, 0x0000012a, 0x00000020, 0x00000010, 0x00000000, + 0x00000110, 0x00000000, 0x00000130, 0x00000030, 0x00000010, 0x00000000, 0x00000110, 0x00000000, + 0x6f6c6f63, 0x756d5f72, 0xabab006c, 0x00030001, 0x00040001, 0x00000000, 0x00000000, 0x6f6c6f63, + 0x64615f72, 0x6f660064, 0x006c6163, 0x63736572, 0x31656c61, 0x63694d00, 0x6f736f72, 0x28207466, + 0x48202952, 0x204c534c, 0x64616853, 0x43207265, 0x69706d6f, 0x2072656c, 0x39322e39, 0x3235392e, + 0x3131332e, 0xabab0031, 0x4e475349, 0x00000050, 0x00000002, 0x00000008, 0x00000038, 0x00000000, + 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x00000044, 0x00000000, 0x00000000, 0x00000003, + 0x00000001, 0x00000c0f, 0x505f5653, 0x7469736f, 0x006e6f69, 0x43584554, 0x44524f4f, 0xababab00, + 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, + 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x52444853, 0x0000015c, 0x00000040, + 0x00000057, 0x04000059, 0x00208e46, 0x00000000, 0x00000002, 0x0300005a, 0x00106000, 0x00000007, + 0x04001858, 0x00107000, 0x00000007, 0x00005555, 0x03001062, 0x001010c2, 0x00000001, 0x03000065, + 0x001020f2, 0x00000000, 0x02000068, 0x00000002, 0x0700000e, 0x00100012, 0x00000000, 0x0010102a, + 0x00000001, 0x0010103a, 0x00000001, 0x05000036, 0x00100022, 0x00000000, 0x0010103a, 0x00000001, + 0x09000045, 0x001000f2, 0x00000000, 0x00100046, 0x00000000, 0x00107e46, 0x00000007, 0x00106000, + 0x00000007, 0x09000038, 0x00100072, 0x00000001, 0x00208ff6, 0x00000000, 0x00000000, 0x00208246, + 0x00000000, 0x00000000, 0x06000036, 0x00100082, 0x00000001, 0x0020803a, 0x00000000, 0x00000000, + 0x07000038, 0x001000f2, 0x00000000, 0x00100e46, 0x00000000, 0x00100e46, 0x00000001, 0x0a000032, + 0x00100072, 0x00000000, 0x00208246, 0x00000000, 0x00000001, 0x00100ff6, 0x00000000, 0x00100246, + 0x00000000, 0x07000033, 0x00102072, 0x00000000, 0x00100ff6, 0x00000000, 0x00100246, 0x00000000, + 0x05000036, 0x00102082, 0x00000000, 0x0010003a, 0x00000000, 0x0100003e, 0x54415453, 0x00000074, + 0x0000000a, 0x00000002, 0x00000000, 0x00000002, 0x00000004, 0x00000000, 0x00000000, 0x00000001, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +}; + +static DWORD pshader_basic_2[249] = { + 0x43425844, 0xf18db76f, 0x60007209, 0xb95de8b5, 0x04b32ff3, 0x00000001, 0x000003e4, 0x00000005, + 0x00000034, 0x000001a8, 0x00000200, 0x00000234, 0x00000368, 0x46454452, 0x0000016c, 0x00000001, + 0x0000008c, 0x00000003, 0x0000001c, 0xffff0400, 0x00008100, 0x00000139, 0x0000007c, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000007, 0x00000001, 0x00000001, 0x00000083, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000007, 0x00000001, 0x0000000d, 0x00000088, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x65745f73, 0x74003178, + 0x00317865, 0x00635350, 0x00000088, 0x00000004, 0x000000a4, 0x00000040, 0x00000000, 0x00000000, + 0x00000104, 0x00000000, 0x00000010, 0x00000002, 0x00000110, 0x00000000, 0x00000120, 0x00000010, + 0x00000010, 0x00000002, 0x00000110, 0x00000000, 0x0000012a, 0x00000020, 0x00000010, 0x00000000, + 0x00000110, 0x00000000, 0x00000130, 0x00000030, 0x00000010, 0x00000000, 0x00000110, 0x00000000, + 0x6f6c6f63, 0x756d5f72, 0xabab006c, 0x00030001, 0x00040001, 0x00000000, 0x00000000, 0x6f6c6f63, + 0x64615f72, 0x6f660064, 0x006c6163, 0x63736572, 0x31656c61, 0x63694d00, 0x6f736f72, 0x28207466, + 0x48202952, 0x204c534c, 0x64616853, 0x43207265, 0x69706d6f, 0x2072656c, 0x39322e39, 0x3235392e, + 0x3131332e, 0xabab0031, 0x4e475349, 0x00000050, 0x00000002, 0x00000008, 0x00000038, 0x00000000, + 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x00000044, 0x00000000, 0x00000000, 0x00000003, + 0x00000001, 0x00000c0f, 0x505f5653, 0x7469736f, 0x006e6f69, 0x43584554, 0x44524f4f, 0xababab00, + 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, + 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x52444853, 0x0000012c, 0x00000040, + 0x0000004b, 0x04000059, 0x00208e46, 0x00000000, 0x00000002, 0x0300005a, 0x00106000, 0x00000007, + 0x04001858, 0x00107000, 0x00000007, 0x00005555, 0x03001062, 0x001010c2, 0x00000001, 0x03000065, + 0x001020f2, 0x00000000, 0x02000068, 0x00000001, 0x0700000e, 0x00100012, 0x00000000, 0x0010102a, + 0x00000001, 0x0010103a, 0x00000001, 0x05000036, 0x00100022, 0x00000000, 0x0010103a, 0x00000001, + 0x09000045, 0x001000f2, 0x00000000, 0x00100046, 0x00000000, 0x00107e46, 0x00000007, 0x00106000, + 0x00000007, 0x0b000032, 0x00100012, 0x00000000, 0x0020803a, 0x00000000, 0x00000000, 0x0010003a, + 0x00000000, 0x0020803a, 0x00000000, 0x00000001, 0x09000000, 0x001000e2, 0x00000000, 0x00208906, + 0x00000000, 0x00000000, 0x00208906, 0x00000000, 0x00000001, 0x07000038, 0x00102072, 0x00000000, + 0x00100006, 0x00000000, 0x00100796, 0x00000000, 0x05000036, 0x00102082, 0x00000000, 0x0010000a, + 0x00000000, 0x0100003e, 0x54415453, 0x00000074, 0x00000008, 0x00000001, 0x00000000, 0x00000002, + 0x00000003, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, +}; + +static DWORD pshader_basic_3[298] = { + 0x43425844, 0x8666f1ab, 0x6789c83a, 0x84ddee9b, 0x99672a63, 0x00000001, 0x000004a8, 0x00000005, + 0x00000034, 0x000001f4, 0x0000024c, 0x00000280, 0x0000042c, 0x46454452, 0x000001b8, 0x00000001, + 0x000000d8, 0x00000005, 0x0000001c, 0xffff0400, 0x00008100, 0x00000185, 0x000000bc, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000000c3, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000007, 0x00000001, 0x00000001, 0x000000ca, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000000, 0x00000001, 0x0000000d, 0x000000cf, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000007, 0x00000001, 0x0000000d, 0x000000d4, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x65745f73, 0x73003078, + 0x7865745f, 0x65740031, 0x74003078, 0x00317865, 0x00635350, 0x000000d4, 0x00000004, 0x000000f0, + 0x00000040, 0x00000000, 0x00000000, 0x00000150, 0x00000000, 0x00000010, 0x00000002, 0x0000015c, + 0x00000000, 0x0000016c, 0x00000010, 0x00000010, 0x00000000, 0x0000015c, 0x00000000, 0x00000176, + 0x00000020, 0x00000010, 0x00000000, 0x0000015c, 0x00000000, 0x0000017c, 0x00000030, 0x00000010, + 0x00000000, 0x0000015c, 0x00000000, 0x6f6c6f63, 0x756d5f72, 0xabab006c, 0x00030001, 0x00040001, + 0x00000000, 0x00000000, 0x6f6c6f63, 0x64615f72, 0x6f660064, 0x006c6163, 0x63736572, 0x31656c61, + 0x63694d00, 0x6f736f72, 0x28207466, 0x48202952, 0x204c534c, 0x64616853, 0x43207265, 0x69706d6f, + 0x2072656c, 0x39322e39, 0x3235392e, 0x3131332e, 0xabab0031, 0x4e475349, 0x00000050, 0x00000002, + 0x00000008, 0x00000038, 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x00000044, + 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x00000f0f, 0x505f5653, 0x7469736f, 0x006e6f69, + 0x43584554, 0x44524f4f, 0xababab00, 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, + 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, + 0x52444853, 0x000001a4, 0x00000040, 0x00000069, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, + 0x0300005a, 0x00106000, 0x00000000, 0x0300005a, 0x00106000, 0x00000007, 0x04001858, 0x00107000, + 0x00000000, 0x00005555, 0x04001858, 0x00107000, 0x00000007, 0x00005555, 0x03001062, 0x001010f2, + 0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x00000002, 0x0a00000e, 0x00100012, + 0x00000000, 0x00004002, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, 0x0010103a, 0x00000001, + 0x07000038, 0x00100032, 0x00000000, 0x00100006, 0x00000000, 0x00101046, 0x00000001, 0x09000045, + 0x001000f2, 0x00000000, 0x00100046, 0x00000000, 0x00107e46, 0x00000000, 0x00106000, 0x00000000, + 0x09000038, 0x00100072, 0x00000001, 0x00208ff6, 0x00000000, 0x00000000, 0x00208246, 0x00000000, + 0x00000000, 0x06000036, 0x00100082, 0x00000001, 0x0020803a, 0x00000000, 0x00000000, 0x07000038, + 0x001000f2, 0x00000000, 0x00100e46, 0x00000000, 0x00100e46, 0x00000001, 0x0700000e, 0x00100012, + 0x00000001, 0x0010102a, 0x00000001, 0x0010103a, 0x00000001, 0x05000036, 0x00100022, 0x00000001, + 0x0010103a, 0x00000001, 0x09000045, 0x001000f2, 0x00000001, 0x00100046, 0x00000001, 0x00107e46, + 0x00000007, 0x00106000, 0x00000007, 0x07000038, 0x001020f2, 0x00000000, 0x00100e46, 0x00000000, + 0x00100e46, 0x00000001, 0x0100003e, 0x54415453, 0x00000074, 0x0000000b, 0x00000002, 0x00000000, + 0x00000002, 0x00000006, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, +}; + +static DWORD pshader_basic_4[320] = { + 0x43425844, 0xc29dc729, 0xa89895e0, 0x45d2e5a7, 0x85a6e3df, 0x00000001, 0x00000500, 0x00000005, + 0x00000034, 0x000001f4, 0x0000024c, 0x00000280, 0x00000484, 0x46454452, 0x000001b8, 0x00000001, + 0x000000d8, 0x00000005, 0x0000001c, 0xffff0400, 0x00008100, 0x00000185, 0x000000bc, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000000c3, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000007, 0x00000001, 0x00000001, 0x000000ca, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000000, 0x00000001, 0x0000000d, 0x000000cf, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000007, 0x00000001, 0x0000000d, 0x000000d4, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x65745f73, 0x73003078, + 0x7865745f, 0x65740031, 0x74003078, 0x00317865, 0x00635350, 0x000000d4, 0x00000004, 0x000000f0, + 0x00000040, 0x00000000, 0x00000000, 0x00000150, 0x00000000, 0x00000010, 0x00000002, 0x0000015c, + 0x00000000, 0x0000016c, 0x00000010, 0x00000010, 0x00000002, 0x0000015c, 0x00000000, 0x00000176, + 0x00000020, 0x00000010, 0x00000000, 0x0000015c, 0x00000000, 0x0000017c, 0x00000030, 0x00000010, + 0x00000000, 0x0000015c, 0x00000000, 0x6f6c6f63, 0x756d5f72, 0xabab006c, 0x00030001, 0x00040001, + 0x00000000, 0x00000000, 0x6f6c6f63, 0x64615f72, 0x6f660064, 0x006c6163, 0x63736572, 0x31656c61, + 0x63694d00, 0x6f736f72, 0x28207466, 0x48202952, 0x204c534c, 0x64616853, 0x43207265, 0x69706d6f, + 0x2072656c, 0x39322e39, 0x3235392e, 0x3131332e, 0xabab0031, 0x4e475349, 0x00000050, 0x00000002, + 0x00000008, 0x00000038, 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x00000044, + 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x00000f0f, 0x505f5653, 0x7469736f, 0x006e6f69, + 0x43584554, 0x44524f4f, 0xababab00, 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, + 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, + 0x52444853, 0x000001fc, 0x00000040, 0x0000007f, 0x04000059, 0x00208e46, 0x00000000, 0x00000002, + 0x0300005a, 0x00106000, 0x00000000, 0x0300005a, 0x00106000, 0x00000007, 0x04001858, 0x00107000, + 0x00000000, 0x00005555, 0x04001858, 0x00107000, 0x00000007, 0x00005555, 0x03001062, 0x001010f2, + 0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x00000002, 0x0a00000e, 0x00100012, + 0x00000000, 0x00004002, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, 0x0010103a, 0x00000001, + 0x07000038, 0x00100032, 0x00000000, 0x00100006, 0x00000000, 0x00101046, 0x00000001, 0x09000045, + 0x001000f2, 0x00000000, 0x00100046, 0x00000000, 0x00107e46, 0x00000000, 0x00106000, 0x00000000, + 0x09000038, 0x00100072, 0x00000001, 0x00208ff6, 0x00000000, 0x00000000, 0x00208246, 0x00000000, + 0x00000000, 0x06000036, 0x00100082, 0x00000001, 0x0020803a, 0x00000000, 0x00000000, 0x07000038, + 0x001000f2, 0x00000000, 0x00100e46, 0x00000000, 0x00100e46, 0x00000001, 0x0700000e, 0x00100012, + 0x00000001, 0x0010102a, 0x00000001, 0x0010103a, 0x00000001, 0x05000036, 0x00100022, 0x00000001, + 0x0010103a, 0x00000001, 0x09000045, 0x001000f2, 0x00000001, 0x00100046, 0x00000001, 0x00107e46, + 0x00000007, 0x00106000, 0x00000007, 0x07000038, 0x001000f2, 0x00000000, 0x00100e46, 0x00000000, + 0x00100e46, 0x00000001, 0x0a000032, 0x00100072, 0x00000000, 0x00208246, 0x00000000, 0x00000001, + 0x00100ff6, 0x00000000, 0x00100246, 0x00000000, 0x07000033, 0x00102072, 0x00000000, 0x00100ff6, + 0x00000000, 0x00100246, 0x00000000, 0x05000036, 0x00102082, 0x00000000, 0x0010003a, 0x00000000, + 0x0100003e, 0x54415453, 0x00000074, 0x0000000e, 0x00000002, 0x00000000, 0x00000002, 0x00000007, + 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +}; + +static DWORD pshader_basic_5[337] = { + 0x43425844, 0xf38a8aa1, 0x76e83e07, 0xe035a58b, 0x8d62e8be, 0x00000001, 0x00000544, 0x00000005, + 0x00000034, 0x000001f4, 0x0000024c, 0x00000280, 0x000004c8, 0x46454452, 0x000001b8, 0x00000001, + 0x000000d8, 0x00000005, 0x0000001c, 0xffff0400, 0x00008100, 0x00000185, 0x000000bc, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000000c3, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000007, 0x00000001, 0x00000001, 0x000000ca, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000000, 0x00000001, 0x0000000d, 0x000000cf, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000007, 0x00000001, 0x0000000d, 0x000000d4, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x65745f73, 0x73003078, + 0x7865745f, 0x65740031, 0x74003078, 0x00317865, 0x00635350, 0x000000d4, 0x00000004, 0x000000f0, + 0x00000040, 0x00000000, 0x00000000, 0x00000150, 0x00000000, 0x00000010, 0x00000002, 0x0000015c, + 0x00000000, 0x0000016c, 0x00000010, 0x00000010, 0x00000002, 0x0000015c, 0x00000000, 0x00000176, + 0x00000020, 0x00000010, 0x00000000, 0x0000015c, 0x00000000, 0x0000017c, 0x00000030, 0x00000010, + 0x00000000, 0x0000015c, 0x00000000, 0x6f6c6f63, 0x756d5f72, 0xabab006c, 0x00030001, 0x00040001, + 0x00000000, 0x00000000, 0x6f6c6f63, 0x64615f72, 0x6f660064, 0x006c6163, 0x63736572, 0x31656c61, + 0x63694d00, 0x6f736f72, 0x28207466, 0x48202952, 0x204c534c, 0x64616853, 0x43207265, 0x69706d6f, + 0x2072656c, 0x39322e39, 0x3235392e, 0x3131332e, 0xabab0031, 0x4e475349, 0x00000050, 0x00000002, + 0x00000008, 0x00000038, 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x00000044, + 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x00000f0f, 0x505f5653, 0x7469736f, 0x006e6f69, + 0x43584554, 0x44524f4f, 0xababab00, 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, + 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, + 0x52444853, 0x00000240, 0x00000040, 0x00000090, 0x04000059, 0x00208e46, 0x00000000, 0x00000002, + 0x0300005a, 0x00106000, 0x00000000, 0x0300005a, 0x00106000, 0x00000007, 0x04001858, 0x00107000, + 0x00000000, 0x00005555, 0x04001858, 0x00107000, 0x00000007, 0x00005555, 0x03001062, 0x001010f2, + 0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x00000002, 0x0a00000e, 0x00100012, + 0x00000000, 0x00004002, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, 0x0010103a, 0x00000001, + 0x07000038, 0x00100032, 0x00000000, 0x00100006, 0x00000000, 0x00101046, 0x00000001, 0x09000045, + 0x001000f2, 0x00000000, 0x00100046, 0x00000000, 0x00107e46, 0x00000000, 0x00106000, 0x00000000, + 0x0a00000e, 0x00100012, 0x00000001, 0x00004002, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, + 0x0010003a, 0x00000000, 0x07000038, 0x00100072, 0x00000001, 0x00100246, 0x00000000, 0x00100006, + 0x00000001, 0x07000039, 0x00100082, 0x00000001, 0x0010003a, 0x00000000, 0x00004001, 0x00000000, + 0x09000037, 0x00100072, 0x00000000, 0x00100ff6, 0x00000001, 0x00100246, 0x00000001, 0x00100246, + 0x00000000, 0x08000038, 0x001000f2, 0x00000000, 0x00100e46, 0x00000000, 0x00208e46, 0x00000000, + 0x00000000, 0x0700000e, 0x00100012, 0x00000001, 0x0010102a, 0x00000001, 0x0010103a, 0x00000001, + 0x05000036, 0x00100022, 0x00000001, 0x0010103a, 0x00000001, 0x09000045, 0x001000f2, 0x00000001, + 0x00100046, 0x00000001, 0x00107e46, 0x00000007, 0x00106000, 0x00000007, 0x07000038, 0x00100082, + 0x00000000, 0x0010003a, 0x00000000, 0x0010003a, 0x00000001, 0x08000000, 0x001000f2, 0x00000000, + 0x00100e46, 0x00000000, 0x00208e46, 0x00000000, 0x00000001, 0x07000038, 0x00102072, 0x00000000, + 0x00100ff6, 0x00000000, 0x00100246, 0x00000000, 0x05000036, 0x00102082, 0x00000000, 0x0010003a, + 0x00000000, 0x0100003e, 0x54415453, 0x00000074, 0x00000010, 0x00000002, 0x00000000, 0x00000002, + 0x0000000a, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000004, + 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, +}; + +static DWORD pshader_basic_6[298] = { + 0x43425844, 0xf4bd11d7, 0x2d1585d4, 0xa2bece1a, 0x528591b0, 0x00000001, 0x000004a8, 0x00000005, + 0x00000034, 0x000001f4, 0x0000024c, 0x00000280, 0x0000042c, 0x46454452, 0x000001b8, 0x00000001, + 0x000000d8, 0x00000005, 0x0000001c, 0xffff0400, 0x00008100, 0x00000185, 0x000000bc, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000000c3, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000007, 0x00000001, 0x00000001, 0x000000ca, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000000, 0x00000001, 0x0000000d, 0x000000cf, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000007, 0x00000001, 0x0000000d, 0x000000d4, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x65745f73, 0x73003078, + 0x7865745f, 0x65740031, 0x74003078, 0x00317865, 0x00635350, 0x000000d4, 0x00000004, 0x000000f0, + 0x00000040, 0x00000000, 0x00000000, 0x00000150, 0x00000000, 0x00000010, 0x00000002, 0x0000015c, + 0x00000000, 0x0000016c, 0x00000010, 0x00000010, 0x00000000, 0x0000015c, 0x00000000, 0x00000176, + 0x00000020, 0x00000010, 0x00000000, 0x0000015c, 0x00000000, 0x0000017c, 0x00000030, 0x00000010, + 0x00000000, 0x0000015c, 0x00000000, 0x6f6c6f63, 0x756d5f72, 0xabab006c, 0x00030001, 0x00040001, + 0x00000000, 0x00000000, 0x6f6c6f63, 0x64615f72, 0x6f660064, 0x006c6163, 0x63736572, 0x31656c61, + 0x63694d00, 0x6f736f72, 0x28207466, 0x48202952, 0x204c534c, 0x64616853, 0x43207265, 0x69706d6f, + 0x2072656c, 0x39322e39, 0x3235392e, 0x3131332e, 0xabab0031, 0x4e475349, 0x00000050, 0x00000002, + 0x00000008, 0x00000038, 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x00000044, + 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x00000f0f, 0x505f5653, 0x7469736f, 0x006e6f69, + 0x43584554, 0x44524f4f, 0xababab00, 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, + 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, + 0x52444853, 0x000001a4, 0x00000040, 0x00000069, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, + 0x0300005a, 0x00106000, 0x00000000, 0x0300005a, 0x00106000, 0x00000007, 0x04001858, 0x00107000, + 0x00000000, 0x00005555, 0x04001858, 0x00107000, 0x00000007, 0x00005555, 0x03001062, 0x001010f2, + 0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x00000002, 0x0a00000e, 0x00100012, + 0x00000000, 0x00004002, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, 0x0010103a, 0x00000001, + 0x07000038, 0x00100032, 0x00000000, 0x00100006, 0x00000000, 0x00101046, 0x00000001, 0x09000045, + 0x001000f2, 0x00000000, 0x00100046, 0x00000000, 0x00107e46, 0x00000000, 0x00106000, 0x00000000, + 0x09000038, 0x00100072, 0x00000001, 0x00208ff6, 0x00000000, 0x00000000, 0x00208246, 0x00000000, + 0x00000000, 0x06000036, 0x00100082, 0x00000001, 0x0020803a, 0x00000000, 0x00000000, 0x07000038, + 0x001000f2, 0x00000000, 0x00100006, 0x00000000, 0x00100e46, 0x00000001, 0x0700000e, 0x00100012, + 0x00000001, 0x0010102a, 0x00000001, 0x0010103a, 0x00000001, 0x05000036, 0x00100022, 0x00000001, + 0x0010103a, 0x00000001, 0x09000045, 0x001000f2, 0x00000001, 0x00100046, 0x00000001, 0x00107e46, + 0x00000007, 0x00106000, 0x00000007, 0x07000038, 0x001020f2, 0x00000000, 0x00100e46, 0x00000000, + 0x00100e46, 0x00000001, 0x0100003e, 0x54415453, 0x00000074, 0x0000000b, 0x00000002, 0x00000000, + 0x00000002, 0x00000006, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, +}; + +static DWORD pshader_basic_7[320] = { + 0x43425844, 0xf035ea5f, 0x7228ce0c, 0x7acda6b1, 0x84f793b7, 0x00000001, 0x00000500, 0x00000005, + 0x00000034, 0x000001f4, 0x0000024c, 0x00000280, 0x00000484, 0x46454452, 0x000001b8, 0x00000001, + 0x000000d8, 0x00000005, 0x0000001c, 0xffff0400, 0x00008100, 0x00000185, 0x000000bc, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000000c3, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000007, 0x00000001, 0x00000001, 0x000000ca, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000000, 0x00000001, 0x0000000d, 0x000000cf, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000007, 0x00000001, 0x0000000d, 0x000000d4, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x65745f73, 0x73003078, + 0x7865745f, 0x65740031, 0x74003078, 0x00317865, 0x00635350, 0x000000d4, 0x00000004, 0x000000f0, + 0x00000040, 0x00000000, 0x00000000, 0x00000150, 0x00000000, 0x00000010, 0x00000002, 0x0000015c, + 0x00000000, 0x0000016c, 0x00000010, 0x00000010, 0x00000002, 0x0000015c, 0x00000000, 0x00000176, + 0x00000020, 0x00000010, 0x00000000, 0x0000015c, 0x00000000, 0x0000017c, 0x00000030, 0x00000010, + 0x00000000, 0x0000015c, 0x00000000, 0x6f6c6f63, 0x756d5f72, 0xabab006c, 0x00030001, 0x00040001, + 0x00000000, 0x00000000, 0x6f6c6f63, 0x64615f72, 0x6f660064, 0x006c6163, 0x63736572, 0x31656c61, + 0x63694d00, 0x6f736f72, 0x28207466, 0x48202952, 0x204c534c, 0x64616853, 0x43207265, 0x69706d6f, + 0x2072656c, 0x39322e39, 0x3235392e, 0x3131332e, 0xabab0031, 0x4e475349, 0x00000050, 0x00000002, + 0x00000008, 0x00000038, 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x00000044, + 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x00000f0f, 0x505f5653, 0x7469736f, 0x006e6f69, + 0x43584554, 0x44524f4f, 0xababab00, 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, + 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, + 0x52444853, 0x000001fc, 0x00000040, 0x0000007f, 0x04000059, 0x00208e46, 0x00000000, 0x00000002, + 0x0300005a, 0x00106000, 0x00000000, 0x0300005a, 0x00106000, 0x00000007, 0x04001858, 0x00107000, + 0x00000000, 0x00005555, 0x04001858, 0x00107000, 0x00000007, 0x00005555, 0x03001062, 0x001010f2, + 0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x00000002, 0x0a00000e, 0x00100012, + 0x00000000, 0x00004002, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, 0x0010103a, 0x00000001, + 0x07000038, 0x00100032, 0x00000000, 0x00100006, 0x00000000, 0x00101046, 0x00000001, 0x09000045, + 0x001000f2, 0x00000000, 0x00100046, 0x00000000, 0x00107e46, 0x00000000, 0x00106000, 0x00000000, + 0x09000038, 0x00100072, 0x00000001, 0x00208ff6, 0x00000000, 0x00000000, 0x00208246, 0x00000000, + 0x00000000, 0x06000036, 0x00100082, 0x00000001, 0x0020803a, 0x00000000, 0x00000000, 0x07000038, + 0x001000f2, 0x00000000, 0x00100006, 0x00000000, 0x00100e46, 0x00000001, 0x0700000e, 0x00100012, + 0x00000001, 0x0010102a, 0x00000001, 0x0010103a, 0x00000001, 0x05000036, 0x00100022, 0x00000001, + 0x0010103a, 0x00000001, 0x09000045, 0x001000f2, 0x00000001, 0x00100046, 0x00000001, 0x00107e46, + 0x00000007, 0x00106000, 0x00000007, 0x07000038, 0x001000f2, 0x00000000, 0x00100e46, 0x00000000, + 0x00100e46, 0x00000001, 0x0a000032, 0x00100072, 0x00000000, 0x00208246, 0x00000000, 0x00000001, + 0x00100ff6, 0x00000000, 0x00100246, 0x00000000, 0x07000033, 0x00102072, 0x00000000, 0x00100ff6, + 0x00000000, 0x00100246, 0x00000000, 0x05000036, 0x00102082, 0x00000000, 0x0010003a, 0x00000000, + 0x0100003e, 0x54415453, 0x00000074, 0x0000000e, 0x00000002, 0x00000000, 0x00000002, 0x00000007, + 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +}; + +static DWORD pshader_basic_8[308] = { + 0x43425844, 0x8de8fdf8, 0x79362b3c, 0xd3e53d96, 0x9a753d05, 0x00000001, 0x000004d0, 0x00000005, + 0x00000034, 0x000001f4, 0x0000024c, 0x00000280, 0x00000454, 0x46454452, 0x000001b8, 0x00000001, + 0x000000d8, 0x00000005, 0x0000001c, 0xffff0400, 0x00008100, 0x00000185, 0x000000bc, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000000c3, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000007, 0x00000001, 0x00000001, 0x000000ca, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000000, 0x00000001, 0x0000000d, 0x000000cf, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000007, 0x00000001, 0x0000000d, 0x000000d4, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x65745f73, 0x73003078, + 0x7865745f, 0x65740031, 0x74003078, 0x00317865, 0x00635350, 0x000000d4, 0x00000004, 0x000000f0, + 0x00000040, 0x00000000, 0x00000000, 0x00000150, 0x00000000, 0x00000010, 0x00000002, 0x0000015c, + 0x00000000, 0x0000016c, 0x00000010, 0x00000010, 0x00000002, 0x0000015c, 0x00000000, 0x00000176, + 0x00000020, 0x00000010, 0x00000000, 0x0000015c, 0x00000000, 0x0000017c, 0x00000030, 0x00000010, + 0x00000000, 0x0000015c, 0x00000000, 0x6f6c6f63, 0x756d5f72, 0xabab006c, 0x00030001, 0x00040001, + 0x00000000, 0x00000000, 0x6f6c6f63, 0x64615f72, 0x6f660064, 0x006c6163, 0x63736572, 0x31656c61, + 0x63694d00, 0x6f736f72, 0x28207466, 0x48202952, 0x204c534c, 0x64616853, 0x43207265, 0x69706d6f, + 0x2072656c, 0x39322e39, 0x3235392e, 0x3131332e, 0xabab0031, 0x4e475349, 0x00000050, 0x00000002, + 0x00000008, 0x00000038, 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x00000044, + 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x00000f0f, 0x505f5653, 0x7469736f, 0x006e6f69, + 0x43584554, 0x44524f4f, 0xababab00, 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, + 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, + 0x52444853, 0x000001cc, 0x00000040, 0x00000073, 0x04000059, 0x00208e46, 0x00000000, 0x00000002, + 0x0300005a, 0x00106000, 0x00000000, 0x0300005a, 0x00106000, 0x00000007, 0x04001858, 0x00107000, + 0x00000000, 0x00005555, 0x04001858, 0x00107000, 0x00000007, 0x00005555, 0x03001062, 0x001010f2, + 0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x00000002, 0x0a00000e, 0x00100012, + 0x00000000, 0x00004002, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, 0x0010103a, 0x00000001, + 0x07000038, 0x00100032, 0x00000000, 0x00100006, 0x00000000, 0x00101046, 0x00000001, 0x09000045, + 0x001000f2, 0x00000000, 0x00100046, 0x00000000, 0x00107e46, 0x00000000, 0x00106000, 0x00000000, + 0x08000038, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0020803a, 0x00000000, 0x00000000, + 0x0700000e, 0x00100012, 0x00000001, 0x0010102a, 0x00000001, 0x0010103a, 0x00000001, 0x05000036, + 0x00100022, 0x00000001, 0x0010103a, 0x00000001, 0x09000045, 0x001000f2, 0x00000001, 0x00100046, + 0x00000001, 0x00107e46, 0x00000007, 0x00106000, 0x00000007, 0x0a000032, 0x00100012, 0x00000000, + 0x0010000a, 0x00000000, 0x0010003a, 0x00000001, 0x0020803a, 0x00000000, 0x00000001, 0x09000000, + 0x001000e2, 0x00000000, 0x00208906, 0x00000000, 0x00000000, 0x00208906, 0x00000000, 0x00000001, + 0x07000038, 0x00102072, 0x00000000, 0x00100006, 0x00000000, 0x00100796, 0x00000000, 0x05000036, + 0x00102082, 0x00000000, 0x0010000a, 0x00000000, 0x0100003e, 0x54415453, 0x00000074, 0x0000000c, + 0x00000002, 0x00000000, 0x00000002, 0x00000006, 0x00000000, 0x00000000, 0x00000001, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, +}; + +static DWORD pshader_basic_9[310] = { + 0x43425844, 0xf476d124, 0xc7f0f06d, 0x96327107, 0x57955bd0, 0x00000001, 0x000004d8, 0x00000005, + 0x00000034, 0x000001f4, 0x0000024c, 0x00000280, 0x0000045c, 0x46454452, 0x000001b8, 0x00000001, + 0x000000d8, 0x00000005, 0x0000001c, 0xffff0400, 0x00008100, 0x00000185, 0x000000bc, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000000c3, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000007, 0x00000001, 0x00000001, 0x000000ca, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000000, 0x00000001, 0x0000000d, 0x000000cf, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000007, 0x00000001, 0x0000000d, 0x000000d4, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x65745f73, 0x73003078, + 0x7865745f, 0x65740031, 0x74003078, 0x00317865, 0x00635350, 0x000000d4, 0x00000004, 0x000000f0, + 0x00000040, 0x00000000, 0x00000000, 0x00000150, 0x00000000, 0x00000010, 0x00000002, 0x0000015c, + 0x00000000, 0x0000016c, 0x00000010, 0x00000010, 0x00000000, 0x0000015c, 0x00000000, 0x00000176, + 0x00000020, 0x00000010, 0x00000000, 0x0000015c, 0x00000000, 0x0000017c, 0x00000030, 0x00000010, + 0x00000000, 0x0000015c, 0x00000000, 0x6f6c6f63, 0x756d5f72, 0xabab006c, 0x00030001, 0x00040001, + 0x00000000, 0x00000000, 0x6f6c6f63, 0x64615f72, 0x6f660064, 0x006c6163, 0x63736572, 0x31656c61, + 0x63694d00, 0x6f736f72, 0x28207466, 0x48202952, 0x204c534c, 0x64616853, 0x43207265, 0x69706d6f, + 0x2072656c, 0x39322e39, 0x3235392e, 0x3131332e, 0xabab0031, 0x4e475349, 0x00000050, 0x00000002, + 0x00000008, 0x00000038, 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x00000044, + 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x00000f0f, 0x505f5653, 0x7469736f, 0x006e6f69, + 0x43584554, 0x44524f4f, 0xababab00, 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, + 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, + 0x52444853, 0x000001d4, 0x00000040, 0x00000075, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, + 0x0300005a, 0x00106000, 0x00000000, 0x0300005a, 0x00106000, 0x00000007, 0x04001858, 0x00107000, + 0x00000000, 0x00005555, 0x04001858, 0x00107000, 0x00000007, 0x00005555, 0x03001062, 0x001010f2, + 0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x00000002, 0x0a00000e, 0x00100012, + 0x00000000, 0x00004002, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, 0x0010103a, 0x00000001, + 0x07000038, 0x00100032, 0x00000000, 0x00100006, 0x00000000, 0x00101046, 0x00000001, 0x0700000f, + 0x00100012, 0x00000000, 0x00100046, 0x00000000, 0x00100046, 0x00000000, 0x0500004b, 0x00100012, + 0x00000000, 0x0010000a, 0x00000000, 0x09000045, 0x001000f2, 0x00000000, 0x00100006, 0x00000000, + 0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x09000038, 0x00100072, 0x00000001, 0x00208ff6, + 0x00000000, 0x00000000, 0x00208246, 0x00000000, 0x00000000, 0x06000036, 0x00100082, 0x00000001, + 0x0020803a, 0x00000000, 0x00000000, 0x07000038, 0x001000f2, 0x00000000, 0x00100e46, 0x00000000, + 0x00100e46, 0x00000001, 0x0700000e, 0x00100012, 0x00000001, 0x0010102a, 0x00000001, 0x0010103a, + 0x00000001, 0x05000036, 0x00100022, 0x00000001, 0x0010103a, 0x00000001, 0x09000045, 0x001000f2, + 0x00000001, 0x00100046, 0x00000001, 0x00107e46, 0x00000007, 0x00106000, 0x00000007, 0x07000038, + 0x001020f2, 0x00000000, 0x00100e46, 0x00000000, 0x00100e46, 0x00000001, 0x0100003e, 0x54415453, + 0x00000074, 0x0000000d, 0x00000002, 0x00000000, 0x00000002, 0x00000008, 0x00000000, 0x00000000, + 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +}; + +static DWORD pshader_basic_10[332] = { + 0x43425844, 0x08449793, 0x6e27fb50, 0xe33f149a, 0x0f517c0c, 0x00000001, 0x00000530, 0x00000005, + 0x00000034, 0x000001f4, 0x0000024c, 0x00000280, 0x000004b4, 0x46454452, 0x000001b8, 0x00000001, + 0x000000d8, 0x00000005, 0x0000001c, 0xffff0400, 0x00008100, 0x00000185, 0x000000bc, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000000c3, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000007, 0x00000001, 0x00000001, 0x000000ca, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000000, 0x00000001, 0x0000000d, 0x000000cf, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000007, 0x00000001, 0x0000000d, 0x000000d4, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x65745f73, 0x73003078, + 0x7865745f, 0x65740031, 0x74003078, 0x00317865, 0x00635350, 0x000000d4, 0x00000004, 0x000000f0, + 0x00000040, 0x00000000, 0x00000000, 0x00000150, 0x00000000, 0x00000010, 0x00000002, 0x0000015c, + 0x00000000, 0x0000016c, 0x00000010, 0x00000010, 0x00000002, 0x0000015c, 0x00000000, 0x00000176, + 0x00000020, 0x00000010, 0x00000000, 0x0000015c, 0x00000000, 0x0000017c, 0x00000030, 0x00000010, + 0x00000000, 0x0000015c, 0x00000000, 0x6f6c6f63, 0x756d5f72, 0xabab006c, 0x00030001, 0x00040001, + 0x00000000, 0x00000000, 0x6f6c6f63, 0x64615f72, 0x6f660064, 0x006c6163, 0x63736572, 0x31656c61, + 0x63694d00, 0x6f736f72, 0x28207466, 0x48202952, 0x204c534c, 0x64616853, 0x43207265, 0x69706d6f, + 0x2072656c, 0x39322e39, 0x3235392e, 0x3131332e, 0xabab0031, 0x4e475349, 0x00000050, 0x00000002, + 0x00000008, 0x00000038, 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x00000044, + 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x00000f0f, 0x505f5653, 0x7469736f, 0x006e6f69, + 0x43584554, 0x44524f4f, 0xababab00, 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, + 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, + 0x52444853, 0x0000022c, 0x00000040, 0x0000008b, 0x04000059, 0x00208e46, 0x00000000, 0x00000002, + 0x0300005a, 0x00106000, 0x00000000, 0x0300005a, 0x00106000, 0x00000007, 0x04001858, 0x00107000, + 0x00000000, 0x00005555, 0x04001858, 0x00107000, 0x00000007, 0x00005555, 0x03001062, 0x001010f2, + 0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x00000002, 0x0a00000e, 0x00100012, + 0x00000000, 0x00004002, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, 0x0010103a, 0x00000001, + 0x07000038, 0x00100032, 0x00000000, 0x00100006, 0x00000000, 0x00101046, 0x00000001, 0x0700000f, + 0x00100012, 0x00000000, 0x00100046, 0x00000000, 0x00100046, 0x00000000, 0x0500004b, 0x00100012, + 0x00000000, 0x0010000a, 0x00000000, 0x09000045, 0x001000f2, 0x00000000, 0x00100006, 0x00000000, + 0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x09000038, 0x00100072, 0x00000001, 0x00208ff6, + 0x00000000, 0x00000000, 0x00208246, 0x00000000, 0x00000000, 0x06000036, 0x00100082, 0x00000001, + 0x0020803a, 0x00000000, 0x00000000, 0x07000038, 0x001000f2, 0x00000000, 0x00100e46, 0x00000000, + 0x00100e46, 0x00000001, 0x0700000e, 0x00100012, 0x00000001, 0x0010102a, 0x00000001, 0x0010103a, + 0x00000001, 0x05000036, 0x00100022, 0x00000001, 0x0010103a, 0x00000001, 0x09000045, 0x001000f2, + 0x00000001, 0x00100046, 0x00000001, 0x00107e46, 0x00000007, 0x00106000, 0x00000007, 0x07000038, + 0x001000f2, 0x00000000, 0x00100e46, 0x00000000, 0x00100e46, 0x00000001, 0x0a000032, 0x00100072, + 0x00000000, 0x00208246, 0x00000000, 0x00000001, 0x00100ff6, 0x00000000, 0x00100246, 0x00000000, + 0x07000033, 0x00102072, 0x00000000, 0x00100ff6, 0x00000000, 0x00100246, 0x00000000, 0x05000036, + 0x00102082, 0x00000000, 0x0010003a, 0x00000000, 0x0100003e, 0x54415453, 0x00000074, 0x00000010, + 0x00000002, 0x00000000, 0x00000002, 0x00000009, 0x00000000, 0x00000000, 0x00000001, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, +}; + +static DWORD pshader_basic_11[349] = { + 0x43425844, 0x10a3f918, 0xf7959328, 0x525b10eb, 0x0f678477, 0x00000001, 0x00000574, 0x00000005, + 0x00000034, 0x000001f4, 0x0000024c, 0x00000280, 0x000004f8, 0x46454452, 0x000001b8, 0x00000001, + 0x000000d8, 0x00000005, 0x0000001c, 0xffff0400, 0x00008100, 0x00000185, 0x000000bc, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000000c3, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000007, 0x00000001, 0x00000001, 0x000000ca, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000000, 0x00000001, 0x0000000d, 0x000000cf, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000007, 0x00000001, 0x0000000d, 0x000000d4, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x65745f73, 0x73003078, + 0x7865745f, 0x65740031, 0x74003078, 0x00317865, 0x00635350, 0x000000d4, 0x00000004, 0x000000f0, + 0x00000040, 0x00000000, 0x00000000, 0x00000150, 0x00000000, 0x00000010, 0x00000002, 0x0000015c, + 0x00000000, 0x0000016c, 0x00000010, 0x00000010, 0x00000002, 0x0000015c, 0x00000000, 0x00000176, + 0x00000020, 0x00000010, 0x00000000, 0x0000015c, 0x00000000, 0x0000017c, 0x00000030, 0x00000010, + 0x00000000, 0x0000015c, 0x00000000, 0x6f6c6f63, 0x756d5f72, 0xabab006c, 0x00030001, 0x00040001, + 0x00000000, 0x00000000, 0x6f6c6f63, 0x64615f72, 0x6f660064, 0x006c6163, 0x63736572, 0x31656c61, + 0x63694d00, 0x6f736f72, 0x28207466, 0x48202952, 0x204c534c, 0x64616853, 0x43207265, 0x69706d6f, + 0x2072656c, 0x39322e39, 0x3235392e, 0x3131332e, 0xabab0031, 0x4e475349, 0x00000050, 0x00000002, + 0x00000008, 0x00000038, 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x00000044, + 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x00000f0f, 0x505f5653, 0x7469736f, 0x006e6f69, + 0x43584554, 0x44524f4f, 0xababab00, 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, + 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, + 0x52444853, 0x00000270, 0x00000040, 0x0000009c, 0x04000059, 0x00208e46, 0x00000000, 0x00000002, + 0x0300005a, 0x00106000, 0x00000000, 0x0300005a, 0x00106000, 0x00000007, 0x04001858, 0x00107000, + 0x00000000, 0x00005555, 0x04001858, 0x00107000, 0x00000007, 0x00005555, 0x03001062, 0x001010f2, + 0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x00000002, 0x0a00000e, 0x00100012, + 0x00000000, 0x00004002, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, 0x0010103a, 0x00000001, + 0x07000038, 0x00100032, 0x00000000, 0x00100006, 0x00000000, 0x00101046, 0x00000001, 0x0700000f, + 0x00100012, 0x00000000, 0x00100046, 0x00000000, 0x00100046, 0x00000000, 0x0500004b, 0x00100012, + 0x00000000, 0x0010000a, 0x00000000, 0x09000045, 0x001000f2, 0x00000000, 0x00100006, 0x00000000, + 0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x0a00000e, 0x00100012, 0x00000001, 0x00004002, + 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, 0x0010003a, 0x00000000, 0x07000038, 0x00100072, + 0x00000001, 0x00100246, 0x00000000, 0x00100006, 0x00000001, 0x07000039, 0x00100082, 0x00000001, + 0x0010003a, 0x00000000, 0x00004001, 0x00000000, 0x09000037, 0x00100072, 0x00000000, 0x00100ff6, + 0x00000001, 0x00100246, 0x00000001, 0x00100246, 0x00000000, 0x08000038, 0x001000f2, 0x00000000, + 0x00100e46, 0x00000000, 0x00208e46, 0x00000000, 0x00000000, 0x0700000e, 0x00100012, 0x00000001, + 0x0010102a, 0x00000001, 0x0010103a, 0x00000001, 0x05000036, 0x00100022, 0x00000001, 0x0010103a, + 0x00000001, 0x09000045, 0x001000f2, 0x00000001, 0x00100046, 0x00000001, 0x00107e46, 0x00000007, + 0x00106000, 0x00000007, 0x07000038, 0x00100082, 0x00000000, 0x0010003a, 0x00000000, 0x0010003a, + 0x00000001, 0x08000000, 0x001000f2, 0x00000000, 0x00100e46, 0x00000000, 0x00208e46, 0x00000000, + 0x00000001, 0x07000038, 0x00102072, 0x00000000, 0x00100ff6, 0x00000000, 0x00100246, 0x00000000, + 0x05000036, 0x00102082, 0x00000000, 0x0010003a, 0x00000000, 0x0100003e, 0x54415453, 0x00000074, + 0x00000012, 0x00000002, 0x00000000, 0x00000002, 0x0000000c, 0x00000000, 0x00000000, 0x00000001, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000004, 0x00000001, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +}; + +static DWORD pshader_basic_12[365] = { + 0x43425844, 0x50cde65f, 0xba0450c9, 0xc66a01ba, 0xf364c937, 0x00000001, 0x000005b4, 0x00000005, + 0x00000034, 0x000001f4, 0x0000024c, 0x00000280, 0x00000538, 0x46454452, 0x000001b8, 0x00000001, + 0x000000d8, 0x00000005, 0x0000001c, 0xffff0400, 0x00008100, 0x00000185, 0x000000bc, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000000c3, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000007, 0x00000001, 0x00000001, 0x000000ca, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000000, 0x00000001, 0x0000000d, 0x000000cf, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000007, 0x00000001, 0x0000000d, 0x000000d4, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x65745f73, 0x73003078, + 0x7865745f, 0x65740031, 0x74003078, 0x00317865, 0x00635350, 0x000000d4, 0x00000004, 0x000000f0, + 0x00000040, 0x00000000, 0x00000000, 0x00000150, 0x00000000, 0x00000010, 0x00000002, 0x0000015c, + 0x00000000, 0x0000016c, 0x00000010, 0x00000010, 0x00000000, 0x0000015c, 0x00000000, 0x00000176, + 0x00000020, 0x00000010, 0x00000002, 0x0000015c, 0x00000000, 0x0000017c, 0x00000030, 0x00000010, + 0x00000000, 0x0000015c, 0x00000000, 0x6f6c6f63, 0x756d5f72, 0xabab006c, 0x00030001, 0x00040001, + 0x00000000, 0x00000000, 0x6f6c6f63, 0x64615f72, 0x6f660064, 0x006c6163, 0x63736572, 0x31656c61, + 0x63694d00, 0x6f736f72, 0x28207466, 0x48202952, 0x204c534c, 0x64616853, 0x43207265, 0x69706d6f, + 0x2072656c, 0x39322e39, 0x3235392e, 0x3131332e, 0xabab0031, 0x4e475349, 0x00000050, 0x00000002, + 0x00000008, 0x00000038, 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x00000044, + 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x00000f0f, 0x505f5653, 0x7469736f, 0x006e6f69, + 0x43584554, 0x44524f4f, 0xababab00, 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, + 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, + 0x52444853, 0x000002b0, 0x00000040, 0x000000ac, 0x04000059, 0x00208e46, 0x00000000, 0x00000003, + 0x0300005a, 0x00106000, 0x00000000, 0x0300005a, 0x00106000, 0x00000007, 0x04001858, 0x00107000, + 0x00000000, 0x00005555, 0x04001858, 0x00107000, 0x00000007, 0x00005555, 0x03001062, 0x001010f2, + 0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x00000002, 0x0a00000e, 0x00100012, + 0x00000000, 0x00004002, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, 0x0010103a, 0x00000001, + 0x07000038, 0x00100022, 0x00000000, 0x0010000a, 0x00000000, 0x0010101a, 0x00000001, 0x0a000032, + 0x00100012, 0x00000000, 0x0010100a, 0x00000001, 0x0010000a, 0x00000000, 0x0020800a, 0x00000000, + 0x00000002, 0x07000038, 0x00100022, 0x00000000, 0x0010001a, 0x00000000, 0x0010001a, 0x00000000, + 0x09000032, 0x00100022, 0x00000000, 0x0010000a, 0x00000000, 0x0010000a, 0x00000000, 0x0010001a, + 0x00000000, 0x08000038, 0x00100042, 0x00000000, 0x0010000a, 0x00000000, 0x0020801a, 0x00000000, + 0x00000002, 0x07000038, 0x00100042, 0x00000000, 0x0010002a, 0x00000000, 0x0010002a, 0x00000000, + 0x0a000032, 0x00100022, 0x00000000, 0x0010001a, 0x00000000, 0x0020802a, 0x00000000, 0x00000002, + 0x0010002a, 0x00000000, 0x0500004b, 0x00100022, 0x00000000, 0x0010001a, 0x00000000, 0x0b000032, + 0x00100012, 0x00000000, 0x8010000a, 0x00000041, 0x00000000, 0x0020801a, 0x00000000, 0x00000002, + 0x0010001a, 0x00000000, 0x09000045, 0x001000f2, 0x00000000, 0x00100006, 0x00000000, 0x00107e46, + 0x00000000, 0x00106000, 0x00000000, 0x09000038, 0x00100072, 0x00000001, 0x00208ff6, 0x00000000, + 0x00000000, 0x00208246, 0x00000000, 0x00000000, 0x06000036, 0x00100082, 0x00000001, 0x0020803a, + 0x00000000, 0x00000000, 0x07000038, 0x001000f2, 0x00000000, 0x00100e46, 0x00000000, 0x00100e46, + 0x00000001, 0x0700000e, 0x00100012, 0x00000001, 0x0010102a, 0x00000001, 0x0010103a, 0x00000001, + 0x05000036, 0x00100022, 0x00000001, 0x0010103a, 0x00000001, 0x09000045, 0x001000f2, 0x00000001, + 0x00100046, 0x00000001, 0x00107e46, 0x00000007, 0x00106000, 0x00000007, 0x07000038, 0x001020f2, + 0x00000000, 0x00100e46, 0x00000000, 0x00100e46, 0x00000001, 0x0100003e, 0x54415453, 0x00000074, + 0x00000013, 0x00000002, 0x00000000, 0x00000002, 0x0000000a, 0x00000000, 0x00000000, 0x00000001, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +}; + +static DWORD pshader_basic_13[387] = { + 0x43425844, 0x80d41dbd, 0x58a18bbb, 0x9707037c, 0x21268324, 0x00000001, 0x0000060c, 0x00000005, + 0x00000034, 0x000001f4, 0x0000024c, 0x00000280, 0x00000590, 0x46454452, 0x000001b8, 0x00000001, + 0x000000d8, 0x00000005, 0x0000001c, 0xffff0400, 0x00008100, 0x00000185, 0x000000bc, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000000c3, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000007, 0x00000001, 0x00000001, 0x000000ca, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000000, 0x00000001, 0x0000000d, 0x000000cf, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000007, 0x00000001, 0x0000000d, 0x000000d4, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x65745f73, 0x73003078, + 0x7865745f, 0x65740031, 0x74003078, 0x00317865, 0x00635350, 0x000000d4, 0x00000004, 0x000000f0, + 0x00000040, 0x00000000, 0x00000000, 0x00000150, 0x00000000, 0x00000010, 0x00000002, 0x0000015c, + 0x00000000, 0x0000016c, 0x00000010, 0x00000010, 0x00000002, 0x0000015c, 0x00000000, 0x00000176, + 0x00000020, 0x00000010, 0x00000002, 0x0000015c, 0x00000000, 0x0000017c, 0x00000030, 0x00000010, + 0x00000000, 0x0000015c, 0x00000000, 0x6f6c6f63, 0x756d5f72, 0xabab006c, 0x00030001, 0x00040001, + 0x00000000, 0x00000000, 0x6f6c6f63, 0x64615f72, 0x6f660064, 0x006c6163, 0x63736572, 0x31656c61, + 0x63694d00, 0x6f736f72, 0x28207466, 0x48202952, 0x204c534c, 0x64616853, 0x43207265, 0x69706d6f, + 0x2072656c, 0x39322e39, 0x3235392e, 0x3131332e, 0xabab0031, 0x4e475349, 0x00000050, 0x00000002, + 0x00000008, 0x00000038, 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x00000044, + 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x00000f0f, 0x505f5653, 0x7469736f, 0x006e6f69, + 0x43584554, 0x44524f4f, 0xababab00, 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, + 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, + 0x52444853, 0x00000308, 0x00000040, 0x000000c2, 0x04000059, 0x00208e46, 0x00000000, 0x00000003, + 0x0300005a, 0x00106000, 0x00000000, 0x0300005a, 0x00106000, 0x00000007, 0x04001858, 0x00107000, + 0x00000000, 0x00005555, 0x04001858, 0x00107000, 0x00000007, 0x00005555, 0x03001062, 0x001010f2, + 0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x00000002, 0x0a00000e, 0x00100012, + 0x00000000, 0x00004002, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, 0x0010103a, 0x00000001, + 0x07000038, 0x00100022, 0x00000000, 0x0010000a, 0x00000000, 0x0010101a, 0x00000001, 0x0a000032, + 0x00100012, 0x00000000, 0x0010100a, 0x00000001, 0x0010000a, 0x00000000, 0x0020800a, 0x00000000, + 0x00000002, 0x07000038, 0x00100022, 0x00000000, 0x0010001a, 0x00000000, 0x0010001a, 0x00000000, + 0x09000032, 0x00100022, 0x00000000, 0x0010000a, 0x00000000, 0x0010000a, 0x00000000, 0x0010001a, + 0x00000000, 0x08000038, 0x00100042, 0x00000000, 0x0010000a, 0x00000000, 0x0020801a, 0x00000000, + 0x00000002, 0x07000038, 0x00100042, 0x00000000, 0x0010002a, 0x00000000, 0x0010002a, 0x00000000, + 0x0a000032, 0x00100022, 0x00000000, 0x0010001a, 0x00000000, 0x0020802a, 0x00000000, 0x00000002, + 0x0010002a, 0x00000000, 0x0500004b, 0x00100022, 0x00000000, 0x0010001a, 0x00000000, 0x0b000032, + 0x00100012, 0x00000000, 0x8010000a, 0x00000041, 0x00000000, 0x0020801a, 0x00000000, 0x00000002, + 0x0010001a, 0x00000000, 0x09000045, 0x001000f2, 0x00000000, 0x00100006, 0x00000000, 0x00107e46, + 0x00000000, 0x00106000, 0x00000000, 0x09000038, 0x00100072, 0x00000001, 0x00208ff6, 0x00000000, + 0x00000000, 0x00208246, 0x00000000, 0x00000000, 0x06000036, 0x00100082, 0x00000001, 0x0020803a, + 0x00000000, 0x00000000, 0x07000038, 0x001000f2, 0x00000000, 0x00100e46, 0x00000000, 0x00100e46, + 0x00000001, 0x0700000e, 0x00100012, 0x00000001, 0x0010102a, 0x00000001, 0x0010103a, 0x00000001, + 0x05000036, 0x00100022, 0x00000001, 0x0010103a, 0x00000001, 0x09000045, 0x001000f2, 0x00000001, + 0x00100046, 0x00000001, 0x00107e46, 0x00000007, 0x00106000, 0x00000007, 0x07000038, 0x001000f2, + 0x00000000, 0x00100e46, 0x00000000, 0x00100e46, 0x00000001, 0x0a000032, 0x00100072, 0x00000000, + 0x00208246, 0x00000000, 0x00000001, 0x00100ff6, 0x00000000, 0x00100246, 0x00000000, 0x07000033, + 0x00102072, 0x00000000, 0x00100ff6, 0x00000000, 0x00100246, 0x00000000, 0x05000036, 0x00102082, + 0x00000000, 0x0010003a, 0x00000000, 0x0100003e, 0x54415453, 0x00000074, 0x00000016, 0x00000002, + 0x00000000, 0x00000002, 0x0000000b, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000003, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, +}; + +static DWORD pshader_basic_14[404] = { + 0x43425844, 0xb2a25f21, 0x5a5542ec, 0xc550e23f, 0x5a891887, 0x00000001, 0x00000650, 0x00000005, + 0x00000034, 0x000001f4, 0x0000024c, 0x00000280, 0x000005d4, 0x46454452, 0x000001b8, 0x00000001, + 0x000000d8, 0x00000005, 0x0000001c, 0xffff0400, 0x00008100, 0x00000185, 0x000000bc, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000000c3, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000007, 0x00000001, 0x00000001, 0x000000ca, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000000, 0x00000001, 0x0000000d, 0x000000cf, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000007, 0x00000001, 0x0000000d, 0x000000d4, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x65745f73, 0x73003078, + 0x7865745f, 0x65740031, 0x74003078, 0x00317865, 0x00635350, 0x000000d4, 0x00000004, 0x000000f0, + 0x00000040, 0x00000000, 0x00000000, 0x00000150, 0x00000000, 0x00000010, 0x00000002, 0x0000015c, + 0x00000000, 0x0000016c, 0x00000010, 0x00000010, 0x00000002, 0x0000015c, 0x00000000, 0x00000176, + 0x00000020, 0x00000010, 0x00000002, 0x0000015c, 0x00000000, 0x0000017c, 0x00000030, 0x00000010, + 0x00000000, 0x0000015c, 0x00000000, 0x6f6c6f63, 0x756d5f72, 0xabab006c, 0x00030001, 0x00040001, + 0x00000000, 0x00000000, 0x6f6c6f63, 0x64615f72, 0x6f660064, 0x006c6163, 0x63736572, 0x31656c61, + 0x63694d00, 0x6f736f72, 0x28207466, 0x48202952, 0x204c534c, 0x64616853, 0x43207265, 0x69706d6f, + 0x2072656c, 0x39322e39, 0x3235392e, 0x3131332e, 0xabab0031, 0x4e475349, 0x00000050, 0x00000002, + 0x00000008, 0x00000038, 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x00000044, + 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x00000f0f, 0x505f5653, 0x7469736f, 0x006e6f69, + 0x43584554, 0x44524f4f, 0xababab00, 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, + 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, + 0x52444853, 0x0000034c, 0x00000040, 0x000000d3, 0x04000059, 0x00208e46, 0x00000000, 0x00000003, + 0x0300005a, 0x00106000, 0x00000000, 0x0300005a, 0x00106000, 0x00000007, 0x04001858, 0x00107000, + 0x00000000, 0x00005555, 0x04001858, 0x00107000, 0x00000007, 0x00005555, 0x03001062, 0x001010f2, + 0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x00000002, 0x0a00000e, 0x00100012, + 0x00000000, 0x00004002, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, 0x0010103a, 0x00000001, + 0x07000038, 0x00100022, 0x00000000, 0x0010000a, 0x00000000, 0x0010101a, 0x00000001, 0x0a000032, + 0x00100012, 0x00000000, 0x0010100a, 0x00000001, 0x0010000a, 0x00000000, 0x0020800a, 0x00000000, + 0x00000002, 0x07000038, 0x00100022, 0x00000000, 0x0010001a, 0x00000000, 0x0010001a, 0x00000000, + 0x09000032, 0x00100022, 0x00000000, 0x0010000a, 0x00000000, 0x0010000a, 0x00000000, 0x0010001a, + 0x00000000, 0x08000038, 0x00100042, 0x00000000, 0x0010000a, 0x00000000, 0x0020801a, 0x00000000, + 0x00000002, 0x07000038, 0x00100042, 0x00000000, 0x0010002a, 0x00000000, 0x0010002a, 0x00000000, + 0x0a000032, 0x00100022, 0x00000000, 0x0010001a, 0x00000000, 0x0020802a, 0x00000000, 0x00000002, + 0x0010002a, 0x00000000, 0x0500004b, 0x00100022, 0x00000000, 0x0010001a, 0x00000000, 0x0b000032, + 0x00100012, 0x00000000, 0x8010000a, 0x00000041, 0x00000000, 0x0020801a, 0x00000000, 0x00000002, + 0x0010001a, 0x00000000, 0x09000045, 0x001000f2, 0x00000000, 0x00100006, 0x00000000, 0x00107e46, + 0x00000000, 0x00106000, 0x00000000, 0x0a00000e, 0x00100012, 0x00000001, 0x00004002, 0x3f800000, + 0x3f800000, 0x3f800000, 0x3f800000, 0x0010003a, 0x00000000, 0x07000038, 0x00100072, 0x00000001, + 0x00100246, 0x00000000, 0x00100006, 0x00000001, 0x07000039, 0x00100082, 0x00000001, 0x0010003a, + 0x00000000, 0x00004001, 0x00000000, 0x09000037, 0x00100072, 0x00000000, 0x00100ff6, 0x00000001, + 0x00100246, 0x00000001, 0x00100246, 0x00000000, 0x08000038, 0x001000f2, 0x00000000, 0x00100e46, + 0x00000000, 0x00208e46, 0x00000000, 0x00000000, 0x0700000e, 0x00100012, 0x00000001, 0x0010102a, + 0x00000001, 0x0010103a, 0x00000001, 0x05000036, 0x00100022, 0x00000001, 0x0010103a, 0x00000001, + 0x09000045, 0x001000f2, 0x00000001, 0x00100046, 0x00000001, 0x00107e46, 0x00000007, 0x00106000, + 0x00000007, 0x07000038, 0x00100082, 0x00000000, 0x0010003a, 0x00000000, 0x0010003a, 0x00000001, + 0x08000000, 0x001000f2, 0x00000000, 0x00100e46, 0x00000000, 0x00208e46, 0x00000000, 0x00000001, + 0x07000038, 0x00102072, 0x00000000, 0x00100ff6, 0x00000000, 0x00100246, 0x00000000, 0x05000036, + 0x00102082, 0x00000000, 0x0010003a, 0x00000000, 0x0100003e, 0x54415453, 0x00000074, 0x00000018, + 0x00000002, 0x00000000, 0x00000002, 0x0000000e, 0x00000000, 0x00000000, 0x00000001, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000004, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, +}; + +static DWORD pshader_basic_15[322] = { + 0x43425844, 0xe9ac3a59, 0xb10c74ae, 0x7d8ea66b, 0x7f38f805, 0x00000001, 0x00000508, 0x00000005, + 0x00000034, 0x000001f4, 0x0000024c, 0x00000280, 0x0000048c, 0x46454452, 0x000001b8, 0x00000001, + 0x000000d8, 0x00000005, 0x0000001c, 0xffff0400, 0x00008100, 0x00000185, 0x000000bc, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000000c3, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000007, 0x00000001, 0x00000001, 0x000000ca, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000000, 0x00000001, 0x0000000d, 0x000000cf, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000007, 0x00000001, 0x0000000d, 0x000000d4, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x65745f73, 0x73003078, + 0x7865745f, 0x65740031, 0x74003078, 0x00317865, 0x00635350, 0x000000d4, 0x00000004, 0x000000f0, + 0x00000040, 0x00000000, 0x00000000, 0x00000150, 0x00000000, 0x00000010, 0x00000002, 0x0000015c, + 0x00000000, 0x0000016c, 0x00000010, 0x00000010, 0x00000000, 0x0000015c, 0x00000000, 0x00000176, + 0x00000020, 0x00000010, 0x00000000, 0x0000015c, 0x00000000, 0x0000017c, 0x00000030, 0x00000010, + 0x00000000, 0x0000015c, 0x00000000, 0x6f6c6f63, 0x756d5f72, 0xabab006c, 0x00030001, 0x00040001, + 0x00000000, 0x00000000, 0x6f6c6f63, 0x64615f72, 0x6f660064, 0x006c6163, 0x63736572, 0x31656c61, + 0x63694d00, 0x6f736f72, 0x28207466, 0x48202952, 0x204c534c, 0x64616853, 0x43207265, 0x69706d6f, + 0x2072656c, 0x39322e39, 0x3235392e, 0x3131332e, 0xabab0031, 0x4e475349, 0x00000050, 0x00000002, + 0x00000008, 0x00000038, 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x00000044, + 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x00000f0f, 0x505f5653, 0x7469736f, 0x006e6f69, + 0x43584554, 0x44524f4f, 0xababab00, 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, + 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, + 0x52444853, 0x00000204, 0x00000040, 0x00000081, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, + 0x0300005a, 0x00106000, 0x00000000, 0x0300005a, 0x00106000, 0x00000007, 0x04001858, 0x00107000, + 0x00000000, 0x00005555, 0x04001858, 0x00107000, 0x00000007, 0x00005555, 0x03001062, 0x001010f2, + 0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x00000003, 0x0a00000e, 0x00100012, + 0x00000000, 0x00004002, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, 0x0010103a, 0x00000001, + 0x07000038, 0x00100032, 0x00000000, 0x00100006, 0x00000000, 0x00101046, 0x00000001, 0x09000045, + 0x001000f2, 0x00000000, 0x00100046, 0x00000000, 0x00107e46, 0x00000000, 0x00106000, 0x00000000, + 0x09000038, 0x00100072, 0x00000001, 0x00208ff6, 0x00000000, 0x00000000, 0x00208246, 0x00000000, + 0x00000000, 0x06000036, 0x00100082, 0x00000001, 0x0020803a, 0x00000000, 0x00000000, 0x07000038, + 0x001000f2, 0x00000000, 0x00100006, 0x00000000, 0x00100e46, 0x00000001, 0x0700000e, 0x00100012, + 0x00000001, 0x0010102a, 0x00000001, 0x0010103a, 0x00000001, 0x05000036, 0x00100022, 0x00000001, + 0x0010103a, 0x00000001, 0x09000045, 0x001000f2, 0x00000001, 0x00100046, 0x00000001, 0x00107e46, + 0x00000007, 0x00106000, 0x00000007, 0x09000032, 0x00100012, 0x00000002, 0x0010003a, 0x00000000, + 0x0010003a, 0x00000001, 0x00004001, 0xbf000000, 0x07000038, 0x001000f2, 0x00000000, 0x00100e46, + 0x00000000, 0x00100e46, 0x00000001, 0x05000036, 0x001020f2, 0x00000000, 0x00100e46, 0x00000000, + 0x07000031, 0x00100012, 0x00000000, 0x0010000a, 0x00000002, 0x00004001, 0x00000000, 0x0304000d, + 0x0010000a, 0x00000000, 0x0100003e, 0x54415453, 0x00000074, 0x0000000f, 0x00000003, 0x00000000, + 0x00000002, 0x00000007, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000004, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, +}; + +static DWORD pshader_basic_16[339] = { + 0x43425844, 0x254d5609, 0xfb3546e9, 0x05f36a1e, 0x58e4fd27, 0x00000001, 0x0000054c, 0x00000005, + 0x00000034, 0x000001f4, 0x0000024c, 0x00000280, 0x000004d0, 0x46454452, 0x000001b8, 0x00000001, + 0x000000d8, 0x00000005, 0x0000001c, 0xffff0400, 0x00008100, 0x00000185, 0x000000bc, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000000c3, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000007, 0x00000001, 0x00000001, 0x000000ca, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000000, 0x00000001, 0x0000000d, 0x000000cf, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000007, 0x00000001, 0x0000000d, 0x000000d4, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x65745f73, 0x73003078, + 0x7865745f, 0x65740031, 0x74003078, 0x00317865, 0x00635350, 0x000000d4, 0x00000004, 0x000000f0, + 0x00000040, 0x00000000, 0x00000000, 0x00000150, 0x00000000, 0x00000010, 0x00000002, 0x0000015c, + 0x00000000, 0x0000016c, 0x00000010, 0x00000010, 0x00000002, 0x0000015c, 0x00000000, 0x00000176, + 0x00000020, 0x00000010, 0x00000000, 0x0000015c, 0x00000000, 0x0000017c, 0x00000030, 0x00000010, + 0x00000000, 0x0000015c, 0x00000000, 0x6f6c6f63, 0x756d5f72, 0xabab006c, 0x00030001, 0x00040001, + 0x00000000, 0x00000000, 0x6f6c6f63, 0x64615f72, 0x6f660064, 0x006c6163, 0x63736572, 0x31656c61, + 0x63694d00, 0x6f736f72, 0x28207466, 0x48202952, 0x204c534c, 0x64616853, 0x43207265, 0x69706d6f, + 0x2072656c, 0x39322e39, 0x3235392e, 0x3131332e, 0xabab0031, 0x4e475349, 0x00000050, 0x00000002, + 0x00000008, 0x00000038, 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x00000044, + 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x00000f0f, 0x505f5653, 0x7469736f, 0x006e6f69, + 0x43584554, 0x44524f4f, 0xababab00, 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, + 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, + 0x52444853, 0x00000248, 0x00000040, 0x00000092, 0x04000059, 0x00208e46, 0x00000000, 0x00000002, + 0x0300005a, 0x00106000, 0x00000000, 0x0300005a, 0x00106000, 0x00000007, 0x04001858, 0x00107000, + 0x00000000, 0x00005555, 0x04001858, 0x00107000, 0x00000007, 0x00005555, 0x03001062, 0x001010f2, + 0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x00000003, 0x0a00000e, 0x00100012, + 0x00000000, 0x00004002, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, 0x0010103a, 0x00000001, + 0x07000038, 0x00100032, 0x00000000, 0x00100006, 0x00000000, 0x00101046, 0x00000001, 0x09000045, + 0x001000f2, 0x00000000, 0x00100046, 0x00000000, 0x00107e46, 0x00000000, 0x00106000, 0x00000000, + 0x09000038, 0x00100072, 0x00000001, 0x00208ff6, 0x00000000, 0x00000000, 0x00208246, 0x00000000, + 0x00000000, 0x06000036, 0x00100082, 0x00000001, 0x0020803a, 0x00000000, 0x00000000, 0x07000038, + 0x001000f2, 0x00000000, 0x00100006, 0x00000000, 0x00100e46, 0x00000001, 0x0700000e, 0x00100012, + 0x00000001, 0x0010102a, 0x00000001, 0x0010103a, 0x00000001, 0x05000036, 0x00100022, 0x00000001, + 0x0010103a, 0x00000001, 0x09000045, 0x001000f2, 0x00000001, 0x00100046, 0x00000001, 0x00107e46, + 0x00000007, 0x00106000, 0x00000007, 0x09000032, 0x00100012, 0x00000002, 0x0010003a, 0x00000000, + 0x0010003a, 0x00000001, 0x00004001, 0xbf000000, 0x07000038, 0x001000f2, 0x00000000, 0x00100e46, + 0x00000000, 0x00100e46, 0x00000001, 0x07000031, 0x00100012, 0x00000001, 0x0010000a, 0x00000002, + 0x00004001, 0x00000000, 0x0304000d, 0x0010000a, 0x00000001, 0x0a000032, 0x00100072, 0x00000000, + 0x00208246, 0x00000000, 0x00000001, 0x00100ff6, 0x00000000, 0x00100246, 0x00000000, 0x07000033, + 0x00102072, 0x00000000, 0x00100ff6, 0x00000000, 0x00100246, 0x00000000, 0x05000036, 0x00102082, + 0x00000000, 0x0010003a, 0x00000000, 0x0100003e, 0x54415453, 0x00000074, 0x00000011, 0x00000003, + 0x00000000, 0x00000002, 0x00000008, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000004, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, +}; + +static DWORD pshader_basic_17[325] = { + 0x43425844, 0x9b76f721, 0x305d6ada, 0x87db10d5, 0x6ff15183, 0x00000001, 0x00000514, 0x00000005, + 0x00000034, 0x000001f4, 0x0000024c, 0x00000280, 0x00000498, 0x46454452, 0x000001b8, 0x00000001, + 0x000000d8, 0x00000005, 0x0000001c, 0xffff0400, 0x00008100, 0x00000185, 0x000000bc, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000000c3, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000007, 0x00000001, 0x00000001, 0x000000ca, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000000, 0x00000001, 0x0000000d, 0x000000cf, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000007, 0x00000001, 0x0000000d, 0x000000d4, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x65745f73, 0x73003078, + 0x7865745f, 0x65740031, 0x74003078, 0x00317865, 0x00635350, 0x000000d4, 0x00000004, 0x000000f0, + 0x00000040, 0x00000000, 0x00000000, 0x00000150, 0x00000000, 0x00000010, 0x00000002, 0x0000015c, + 0x00000000, 0x0000016c, 0x00000010, 0x00000010, 0x00000002, 0x0000015c, 0x00000000, 0x00000176, + 0x00000020, 0x00000010, 0x00000000, 0x0000015c, 0x00000000, 0x0000017c, 0x00000030, 0x00000010, + 0x00000000, 0x0000015c, 0x00000000, 0x6f6c6f63, 0x756d5f72, 0xabab006c, 0x00030001, 0x00040001, + 0x00000000, 0x00000000, 0x6f6c6f63, 0x64615f72, 0x6f660064, 0x006c6163, 0x63736572, 0x31656c61, + 0x63694d00, 0x6f736f72, 0x28207466, 0x48202952, 0x204c534c, 0x64616853, 0x43207265, 0x69706d6f, + 0x2072656c, 0x39322e39, 0x3235392e, 0x3131332e, 0xabab0031, 0x4e475349, 0x00000050, 0x00000002, + 0x00000008, 0x00000038, 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x00000044, + 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x00000f0f, 0x505f5653, 0x7469736f, 0x006e6f69, + 0x43584554, 0x44524f4f, 0xababab00, 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, + 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, + 0x52444853, 0x00000210, 0x00000040, 0x00000084, 0x04000059, 0x00208e46, 0x00000000, 0x00000002, + 0x0300005a, 0x00106000, 0x00000000, 0x0300005a, 0x00106000, 0x00000007, 0x04001858, 0x00107000, + 0x00000000, 0x00005555, 0x04001858, 0x00107000, 0x00000007, 0x00005555, 0x03001062, 0x001010f2, + 0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x00000002, 0x0a00000e, 0x00100012, + 0x00000000, 0x00004002, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, 0x0010103a, 0x00000001, + 0x07000038, 0x00100032, 0x00000000, 0x00100006, 0x00000000, 0x00101046, 0x00000001, 0x09000045, + 0x001000f2, 0x00000000, 0x00100046, 0x00000000, 0x00107e46, 0x00000000, 0x00106000, 0x00000000, + 0x08000038, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0020803a, 0x00000000, 0x00000000, + 0x0700000e, 0x00100012, 0x00000001, 0x0010102a, 0x00000001, 0x0010103a, 0x00000001, 0x05000036, + 0x00100022, 0x00000001, 0x0010103a, 0x00000001, 0x09000045, 0x001000f2, 0x00000001, 0x00100046, + 0x00000001, 0x00107e46, 0x00000007, 0x00106000, 0x00000007, 0x0a000032, 0x00100012, 0x00000000, + 0x0010000a, 0x00000000, 0x0010003a, 0x00000001, 0x0020803a, 0x00000000, 0x00000001, 0x07000000, + 0x00100022, 0x00000000, 0x0010000a, 0x00000000, 0x00004001, 0xbf000000, 0x07000031, 0x00100022, + 0x00000000, 0x0010001a, 0x00000000, 0x00004001, 0x00000000, 0x0304000d, 0x0010001a, 0x00000000, + 0x09000000, 0x001000e2, 0x00000000, 0x00208906, 0x00000000, 0x00000000, 0x00208906, 0x00000000, + 0x00000001, 0x07000038, 0x00102072, 0x00000000, 0x00100006, 0x00000000, 0x00100796, 0x00000000, + 0x05000036, 0x00102082, 0x00000000, 0x0010000a, 0x00000000, 0x0100003e, 0x54415453, 0x00000074, + 0x0000000f, 0x00000002, 0x00000000, 0x00000002, 0x00000008, 0x00000000, 0x00000000, 0x00000001, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +}; + +static ProgramWithCachedVariableLocations pshader_basic_arr[18] = { + { pshader_basic_0, 956, }, + { pshader_basic_1, 1044, }, + { pshader_basic_2, 996, }, + { pshader_basic_3, 1192, }, + { pshader_basic_4, 1280, }, + { pshader_basic_5, 1348, }, + { pshader_basic_6, 1192, }, + { pshader_basic_7, 1280, }, + { pshader_basic_8, 1232, }, + { pshader_basic_9, 1240, }, + { pshader_basic_10, 1328, }, + { pshader_basic_11, 1396, }, + { pshader_basic_12, 1460, }, + { pshader_basic_13, 1548, }, + { pshader_basic_14, 1616, }, + { pshader_basic_15, 1288, }, + { pshader_basic_16, 1356, }, + { pshader_basic_17, 1300, }, +}; + +static DWORD pshader_exceptional_blend_1[335] = { + 0x43425844, 0x0b4014f2, 0x2a24373f, 0xb6c4e09c, 0xd8c938b5, 0x00000001, 0x0000053c, 0x00000005, + 0x00000034, 0x000001f4, 0x0000024c, 0x00000280, 0x000004c0, 0x46454452, 0x000001b8, 0x00000001, + 0x000000d8, 0x00000005, 0x0000001c, 0xffff0400, 0x00008100, 0x00000185, 0x000000bc, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000000c3, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x000000ca, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000000, 0x00000001, 0x0000000d, 0x000000cf, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000001, 0x00000001, 0x0000000d, 0x000000d4, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x65745f73, 0x73003078, + 0x7865745f, 0x65740031, 0x74003078, 0x00317865, 0x00635350, 0x000000d4, 0x00000004, 0x000000f0, + 0x00000040, 0x00000000, 0x00000000, 0x00000150, 0x00000000, 0x00000010, 0x00000002, 0x0000015c, + 0x00000000, 0x0000016c, 0x00000010, 0x00000010, 0x00000002, 0x0000015c, 0x00000000, 0x00000176, + 0x00000020, 0x00000010, 0x00000000, 0x0000015c, 0x00000000, 0x0000017c, 0x00000030, 0x00000010, + 0x00000002, 0x0000015c, 0x00000000, 0x6f6c6f63, 0x756d5f72, 0xabab006c, 0x00030001, 0x00040001, + 0x00000000, 0x00000000, 0x6f6c6f63, 0x64615f72, 0x6f660064, 0x006c6163, 0x63736572, 0x31656c61, + 0x63694d00, 0x6f736f72, 0x28207466, 0x48202952, 0x204c534c, 0x64616853, 0x43207265, 0x69706d6f, + 0x2072656c, 0x39322e39, 0x3235392e, 0x3131332e, 0xabab0031, 0x4e475349, 0x00000050, 0x00000002, + 0x00000008, 0x00000038, 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x00000044, + 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x0000030f, 0x505f5653, 0x7469736f, 0x006e6f69, + 0x43584554, 0x44524f4f, 0xababab00, 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, + 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, + 0x52444853, 0x00000238, 0x00000040, 0x0000008e, 0x04000059, 0x00208e46, 0x00000000, 0x00000004, + 0x0300005a, 0x00106000, 0x00000000, 0x0300005a, 0x00106000, 0x00000001, 0x04001858, 0x00107000, + 0x00000000, 0x00005555, 0x04001858, 0x00107000, 0x00000001, 0x00005555, 0x03001062, 0x00101032, + 0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x00000003, 0x09000045, 0x001000f2, + 0x00000000, 0x00101046, 0x00000001, 0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x08000038, + 0x00100072, 0x00000000, 0x00100246, 0x00000000, 0x00208246, 0x00000000, 0x00000000, 0x08000038, + 0x001000f2, 0x00000001, 0x00100ff6, 0x00000000, 0x00208e46, 0x00000000, 0x00000001, 0x0a002032, + 0x001000f2, 0x00000000, 0x00100e46, 0x00000000, 0x00208ff6, 0x00000000, 0x00000000, 0x00100e46, + 0x00000001, 0x08000000, 0x00100012, 0x00000001, 0x8010003a, 0x00000041, 0x00000000, 0x00004001, + 0x3f800000, 0x0b000032, 0x00100062, 0x00000001, 0x00101106, 0x00000001, 0x00208106, 0x00000000, + 0x00000003, 0x00208ba6, 0x00000000, 0x00000003, 0x09000045, 0x001000f2, 0x00000002, 0x00100596, + 0x00000001, 0x00107e46, 0x00000001, 0x00106000, 0x00000001, 0x07000038, 0x001000e2, 0x00000001, + 0x00100906, 0x00000000, 0x00100906, 0x00000002, 0x09000032, 0x00100072, 0x00000001, 0x00100006, + 0x00000001, 0x00100246, 0x00000002, 0x00100796, 0x00000001, 0x08000000, 0x00100082, 0x00000001, + 0x8010003a, 0x00000041, 0x00000002, 0x00004001, 0x3f800000, 0x09000032, 0x00102072, 0x00000000, + 0x00100ff6, 0x00000001, 0x00100246, 0x00000000, 0x00100246, 0x00000001, 0x07000000, 0x00100012, + 0x00000000, 0x0010003a, 0x00000000, 0x0010003a, 0x00000002, 0x0a000032, 0x00102082, 0x00000000, + 0x8010003a, 0x00000041, 0x00000000, 0x0010003a, 0x00000002, 0x0010000a, 0x00000000, 0x0100003e, + 0x54415453, 0x00000074, 0x0000000e, 0x00000003, 0x00000000, 0x00000002, 0x00000006, 0x00000000, + 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +}; + +static DWORD pshader_exceptional_blend_2[361] = { + 0x43425844, 0xf906958b, 0x06acfe4b, 0x355048f1, 0x63cfff9c, 0x00000001, 0x000005a4, 0x00000005, + 0x00000034, 0x000001f4, 0x0000024c, 0x00000280, 0x00000528, 0x46454452, 0x000001b8, 0x00000001, + 0x000000d8, 0x00000005, 0x0000001c, 0xffff0400, 0x00008100, 0x00000185, 0x000000bc, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000000c3, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x000000ca, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000000, 0x00000001, 0x0000000d, 0x000000cf, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000001, 0x00000001, 0x0000000d, 0x000000d4, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x65745f73, 0x73003078, + 0x7865745f, 0x65740031, 0x74003078, 0x00317865, 0x00635350, 0x000000d4, 0x00000004, 0x000000f0, + 0x00000040, 0x00000000, 0x00000000, 0x00000150, 0x00000000, 0x00000010, 0x00000002, 0x0000015c, + 0x00000000, 0x0000016c, 0x00000010, 0x00000010, 0x00000002, 0x0000015c, 0x00000000, 0x00000176, + 0x00000020, 0x00000010, 0x00000000, 0x0000015c, 0x00000000, 0x0000017c, 0x00000030, 0x00000010, + 0x00000002, 0x0000015c, 0x00000000, 0x6f6c6f63, 0x756d5f72, 0xabab006c, 0x00030001, 0x00040001, + 0x00000000, 0x00000000, 0x6f6c6f63, 0x64615f72, 0x6f660064, 0x006c6163, 0x63736572, 0x31656c61, + 0x63694d00, 0x6f736f72, 0x28207466, 0x48202952, 0x204c534c, 0x64616853, 0x43207265, 0x69706d6f, + 0x2072656c, 0x39322e39, 0x3235392e, 0x3131332e, 0xabab0031, 0x4e475349, 0x00000050, 0x00000002, + 0x00000008, 0x00000038, 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x00000044, + 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x0000030f, 0x505f5653, 0x7469736f, 0x006e6f69, + 0x43584554, 0x44524f4f, 0xababab00, 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, + 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, + 0x52444853, 0x000002a0, 0x00000040, 0x000000a8, 0x04000059, 0x00208e46, 0x00000000, 0x00000004, + 0x0300005a, 0x00106000, 0x00000000, 0x0300005a, 0x00106000, 0x00000001, 0x04001858, 0x00107000, + 0x00000000, 0x00005555, 0x04001858, 0x00107000, 0x00000001, 0x00005555, 0x03001062, 0x00101032, + 0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x00000004, 0x09000045, 0x001000f2, + 0x00000000, 0x00101046, 0x00000001, 0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x08000038, + 0x00100072, 0x00000000, 0x00100246, 0x00000000, 0x00208246, 0x00000000, 0x00000000, 0x08000038, + 0x001000f2, 0x00000001, 0x00100ff6, 0x00000000, 0x00208e46, 0x00000000, 0x00000001, 0x0a002032, + 0x001000f2, 0x00000000, 0x00100e46, 0x00000000, 0x00208ff6, 0x00000000, 0x00000000, 0x00100e46, + 0x00000001, 0x08000000, 0x00100072, 0x00000001, 0x80100246, 0x00000041, 0x00000000, 0x00100ff6, + 0x00000000, 0x0b000032, 0x00100032, 0x00000002, 0x00101046, 0x00000001, 0x00208046, 0x00000000, + 0x00000003, 0x00208ae6, 0x00000000, 0x00000003, 0x09000045, 0x001000f2, 0x00000002, 0x00100046, + 0x00000002, 0x00107e46, 0x00000001, 0x00106000, 0x00000001, 0x07000038, 0x00100082, 0x00000001, + 0x0010003a, 0x00000000, 0x0010003a, 0x00000002, 0x08000000, 0x00100072, 0x00000003, 0x80100246, + 0x00000041, 0x00000002, 0x00100ff6, 0x00000002, 0x0a000032, 0x00100072, 0x00000001, 0x80100246, + 0x00000041, 0x00000003, 0x00100246, 0x00000001, 0x00100ff6, 0x00000001, 0x08000000, 0x00100082, + 0x00000001, 0x8010003a, 0x00000041, 0x00000000, 0x00004001, 0x3f800000, 0x09000032, 0x00100072, + 0x00000001, 0x00100ff6, 0x00000001, 0x00100246, 0x00000002, 0x00100246, 0x00000001, 0x08000000, + 0x00100082, 0x00000001, 0x8010003a, 0x00000041, 0x00000002, 0x00004001, 0x3f800000, 0x09000032, + 0x00102072, 0x00000000, 0x00100ff6, 0x00000001, 0x00100246, 0x00000000, 0x00100246, 0x00000001, + 0x07000000, 0x00100012, 0x00000000, 0x0010003a, 0x00000000, 0x0010003a, 0x00000002, 0x0a000032, + 0x00102082, 0x00000000, 0x8010003a, 0x00000041, 0x00000000, 0x0010003a, 0x00000002, 0x0010000a, + 0x00000000, 0x0100003e, 0x54415453, 0x00000074, 0x00000011, 0x00000004, 0x00000000, 0x00000002, + 0x00000008, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, +}; + +static DWORD pshader_exceptional_blend_3[356] = { + 0x43425844, 0xfa19bb88, 0xda5ce80c, 0x160c8b13, 0xebac0845, 0x00000001, 0x00000590, 0x00000005, + 0x00000034, 0x000001f4, 0x0000024c, 0x00000280, 0x00000514, 0x46454452, 0x000001b8, 0x00000001, + 0x000000d8, 0x00000005, 0x0000001c, 0xffff0400, 0x00008100, 0x00000185, 0x000000bc, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000000c3, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x000000ca, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000000, 0x00000001, 0x0000000d, 0x000000cf, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000001, 0x00000001, 0x0000000d, 0x000000d4, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x65745f73, 0x73003078, + 0x7865745f, 0x65740031, 0x74003078, 0x00317865, 0x00635350, 0x000000d4, 0x00000004, 0x000000f0, + 0x00000040, 0x00000000, 0x00000000, 0x00000150, 0x00000000, 0x00000010, 0x00000002, 0x0000015c, + 0x00000000, 0x0000016c, 0x00000010, 0x00000010, 0x00000002, 0x0000015c, 0x00000000, 0x00000176, + 0x00000020, 0x00000010, 0x00000000, 0x0000015c, 0x00000000, 0x0000017c, 0x00000030, 0x00000010, + 0x00000002, 0x0000015c, 0x00000000, 0x6f6c6f63, 0x756d5f72, 0xabab006c, 0x00030001, 0x00040001, + 0x00000000, 0x00000000, 0x6f6c6f63, 0x64615f72, 0x6f660064, 0x006c6163, 0x63736572, 0x31656c61, + 0x63694d00, 0x6f736f72, 0x28207466, 0x48202952, 0x204c534c, 0x64616853, 0x43207265, 0x69706d6f, + 0x2072656c, 0x39322e39, 0x3235392e, 0x3131332e, 0xabab0031, 0x4e475349, 0x00000050, 0x00000002, + 0x00000008, 0x00000038, 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x00000044, + 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x0000030f, 0x505f5653, 0x7469736f, 0x006e6f69, + 0x43584554, 0x44524f4f, 0xababab00, 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, + 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, + 0x52444853, 0x0000028c, 0x00000040, 0x000000a3, 0x04000059, 0x00208e46, 0x00000000, 0x00000004, + 0x0300005a, 0x00106000, 0x00000000, 0x0300005a, 0x00106000, 0x00000001, 0x04001858, 0x00107000, + 0x00000000, 0x00005555, 0x04001858, 0x00107000, 0x00000001, 0x00005555, 0x03001062, 0x00101032, + 0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x00000004, 0x09000045, 0x001000f2, + 0x00000000, 0x00101046, 0x00000001, 0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x08000038, + 0x00100072, 0x00000000, 0x00100246, 0x00000000, 0x00208246, 0x00000000, 0x00000000, 0x08000038, + 0x001000f2, 0x00000001, 0x00100ff6, 0x00000000, 0x00208e46, 0x00000000, 0x00000001, 0x0a002032, + 0x001000f2, 0x00000000, 0x00100e46, 0x00000000, 0x00208ff6, 0x00000000, 0x00000000, 0x00100e46, + 0x00000001, 0x08000000, 0x00100012, 0x00000001, 0x8010003a, 0x00000041, 0x00000000, 0x00004001, + 0x3f800000, 0x0b000032, 0x00100062, 0x00000001, 0x00101106, 0x00000001, 0x00208106, 0x00000000, + 0x00000003, 0x00208ba6, 0x00000000, 0x00000003, 0x09000045, 0x001000f2, 0x00000002, 0x00100596, + 0x00000001, 0x00107e46, 0x00000001, 0x00106000, 0x00000001, 0x07000038, 0x001000f2, 0x00000003, + 0x00100736, 0x00000000, 0x00100dc6, 0x00000002, 0x07000034, 0x00100032, 0x00000003, 0x001005d6, + 0x00000003, 0x00100086, 0x00000003, 0x07000038, 0x00100062, 0x00000001, 0x00100ef6, 0x00000000, + 0x00100ba6, 0x00000002, 0x07000034, 0x00100042, 0x00000003, 0x0010002a, 0x00000001, 0x0010001a, + 0x00000001, 0x09000032, 0x00100072, 0x00000001, 0x00100006, 0x00000001, 0x00100246, 0x00000002, + 0x00100246, 0x00000003, 0x08000000, 0x00100082, 0x00000001, 0x8010003a, 0x00000041, 0x00000002, + 0x00004001, 0x3f800000, 0x09000032, 0x00102072, 0x00000000, 0x00100ff6, 0x00000001, 0x00100246, + 0x00000000, 0x00100246, 0x00000001, 0x07000000, 0x00100012, 0x00000000, 0x0010003a, 0x00000000, + 0x0010003a, 0x00000002, 0x0a000032, 0x00102082, 0x00000000, 0x8010003a, 0x00000041, 0x00000000, + 0x0010003a, 0x00000002, 0x0010000a, 0x00000000, 0x0100003e, 0x54415453, 0x00000074, 0x00000011, + 0x00000004, 0x00000000, 0x00000002, 0x00000009, 0x00000000, 0x00000000, 0x00000001, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, +}; + +static DWORD pshader_exceptional_blend_4[356] = { + 0x43425844, 0x51f459c3, 0x15565fe2, 0x4f2b3854, 0x901f8bb9, 0x00000001, 0x00000590, 0x00000005, + 0x00000034, 0x000001f4, 0x0000024c, 0x00000280, 0x00000514, 0x46454452, 0x000001b8, 0x00000001, + 0x000000d8, 0x00000005, 0x0000001c, 0xffff0400, 0x00008100, 0x00000185, 0x000000bc, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000000c3, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x000000ca, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000000, 0x00000001, 0x0000000d, 0x000000cf, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000001, 0x00000001, 0x0000000d, 0x000000d4, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x65745f73, 0x73003078, + 0x7865745f, 0x65740031, 0x74003078, 0x00317865, 0x00635350, 0x000000d4, 0x00000004, 0x000000f0, + 0x00000040, 0x00000000, 0x00000000, 0x00000150, 0x00000000, 0x00000010, 0x00000002, 0x0000015c, + 0x00000000, 0x0000016c, 0x00000010, 0x00000010, 0x00000002, 0x0000015c, 0x00000000, 0x00000176, + 0x00000020, 0x00000010, 0x00000000, 0x0000015c, 0x00000000, 0x0000017c, 0x00000030, 0x00000010, + 0x00000002, 0x0000015c, 0x00000000, 0x6f6c6f63, 0x756d5f72, 0xabab006c, 0x00030001, 0x00040001, + 0x00000000, 0x00000000, 0x6f6c6f63, 0x64615f72, 0x6f660064, 0x006c6163, 0x63736572, 0x31656c61, + 0x63694d00, 0x6f736f72, 0x28207466, 0x48202952, 0x204c534c, 0x64616853, 0x43207265, 0x69706d6f, + 0x2072656c, 0x39322e39, 0x3235392e, 0x3131332e, 0xabab0031, 0x4e475349, 0x00000050, 0x00000002, + 0x00000008, 0x00000038, 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x00000044, + 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x0000030f, 0x505f5653, 0x7469736f, 0x006e6f69, + 0x43584554, 0x44524f4f, 0xababab00, 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, + 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, + 0x52444853, 0x0000028c, 0x00000040, 0x000000a3, 0x04000059, 0x00208e46, 0x00000000, 0x00000004, + 0x0300005a, 0x00106000, 0x00000000, 0x0300005a, 0x00106000, 0x00000001, 0x04001858, 0x00107000, + 0x00000000, 0x00005555, 0x04001858, 0x00107000, 0x00000001, 0x00005555, 0x03001062, 0x00101032, + 0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x00000004, 0x09000045, 0x001000f2, + 0x00000000, 0x00101046, 0x00000001, 0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x08000038, + 0x00100072, 0x00000000, 0x00100246, 0x00000000, 0x00208246, 0x00000000, 0x00000000, 0x08000038, + 0x001000f2, 0x00000001, 0x00100ff6, 0x00000000, 0x00208e46, 0x00000000, 0x00000001, 0x0a002032, + 0x001000f2, 0x00000000, 0x00100e46, 0x00000000, 0x00208ff6, 0x00000000, 0x00000000, 0x00100e46, + 0x00000001, 0x08000000, 0x00100012, 0x00000001, 0x8010003a, 0x00000041, 0x00000000, 0x00004001, + 0x3f800000, 0x0b000032, 0x00100062, 0x00000001, 0x00101106, 0x00000001, 0x00208106, 0x00000000, + 0x00000003, 0x00208ba6, 0x00000000, 0x00000003, 0x09000045, 0x001000f2, 0x00000002, 0x00100596, + 0x00000001, 0x00107e46, 0x00000001, 0x00106000, 0x00000001, 0x07000038, 0x001000f2, 0x00000003, + 0x00100736, 0x00000000, 0x00100dc6, 0x00000002, 0x07000033, 0x00100032, 0x00000003, 0x001005d6, + 0x00000003, 0x00100086, 0x00000003, 0x07000038, 0x00100062, 0x00000001, 0x00100ef6, 0x00000000, + 0x00100ba6, 0x00000002, 0x07000033, 0x00100042, 0x00000003, 0x0010002a, 0x00000001, 0x0010001a, + 0x00000001, 0x09000032, 0x00100072, 0x00000001, 0x00100006, 0x00000001, 0x00100246, 0x00000002, + 0x00100246, 0x00000003, 0x08000000, 0x00100082, 0x00000001, 0x8010003a, 0x00000041, 0x00000002, + 0x00004001, 0x3f800000, 0x09000032, 0x00102072, 0x00000000, 0x00100ff6, 0x00000001, 0x00100246, + 0x00000000, 0x00100246, 0x00000001, 0x07000000, 0x00100012, 0x00000000, 0x0010003a, 0x00000000, + 0x0010003a, 0x00000002, 0x0a000032, 0x00102082, 0x00000000, 0x8010003a, 0x00000041, 0x00000000, + 0x0010003a, 0x00000002, 0x0010000a, 0x00000000, 0x0100003e, 0x54415453, 0x00000074, 0x00000011, + 0x00000004, 0x00000000, 0x00000002, 0x00000009, 0x00000000, 0x00000000, 0x00000001, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, +}; + +static DWORD pshader_exceptional_blend_5[294] = { + 0x43425844, 0x78df9480, 0x22fce9ea, 0x892ac708, 0xebd122be, 0x00000001, 0x00000498, 0x00000005, + 0x00000034, 0x000001f4, 0x0000024c, 0x00000280, 0x0000041c, 0x46454452, 0x000001b8, 0x00000001, + 0x000000d8, 0x00000005, 0x0000001c, 0xffff0400, 0x00008100, 0x00000185, 0x000000bc, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000000c3, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x000000ca, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000000, 0x00000001, 0x0000000d, 0x000000cf, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000001, 0x00000001, 0x0000000d, 0x000000d4, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x65745f73, 0x73003078, + 0x7865745f, 0x65740031, 0x74003078, 0x00317865, 0x00635350, 0x000000d4, 0x00000004, 0x000000f0, + 0x00000040, 0x00000000, 0x00000000, 0x00000150, 0x00000000, 0x00000010, 0x00000002, 0x0000015c, + 0x00000000, 0x0000016c, 0x00000010, 0x00000010, 0x00000002, 0x0000015c, 0x00000000, 0x00000176, + 0x00000020, 0x00000010, 0x00000000, 0x0000015c, 0x00000000, 0x0000017c, 0x00000030, 0x00000010, + 0x00000002, 0x0000015c, 0x00000000, 0x6f6c6f63, 0x756d5f72, 0xabab006c, 0x00030001, 0x00040001, + 0x00000000, 0x00000000, 0x6f6c6f63, 0x64615f72, 0x6f660064, 0x006c6163, 0x63736572, 0x31656c61, + 0x63694d00, 0x6f736f72, 0x28207466, 0x48202952, 0x204c534c, 0x64616853, 0x43207265, 0x69706d6f, + 0x2072656c, 0x39322e39, 0x3235392e, 0x3131332e, 0xabab0031, 0x4e475349, 0x00000050, 0x00000002, + 0x00000008, 0x00000038, 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x00000044, + 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x0000030f, 0x505f5653, 0x7469736f, 0x006e6f69, + 0x43584554, 0x44524f4f, 0xababab00, 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, + 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, + 0x52444853, 0x00000194, 0x00000040, 0x00000065, 0x04000059, 0x00208e46, 0x00000000, 0x00000004, + 0x0300005a, 0x00106000, 0x00000000, 0x0300005a, 0x00106000, 0x00000001, 0x04001858, 0x00107000, + 0x00000000, 0x00005555, 0x04001858, 0x00107000, 0x00000001, 0x00005555, 0x03001062, 0x00101032, + 0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x00000002, 0x09000045, 0x001000f2, + 0x00000000, 0x00101046, 0x00000001, 0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x08000038, + 0x00100072, 0x00000000, 0x00100246, 0x00000000, 0x00208246, 0x00000000, 0x00000000, 0x08000038, + 0x001000f2, 0x00000001, 0x00100ff6, 0x00000000, 0x00208e46, 0x00000000, 0x00000001, 0x0a002032, + 0x001000f2, 0x00000000, 0x00100e46, 0x00000000, 0x00208ff6, 0x00000000, 0x00000000, 0x00100e46, + 0x00000001, 0x0b000032, 0x00100032, 0x00000001, 0x00101046, 0x00000001, 0x00208046, 0x00000000, + 0x00000003, 0x00208ae6, 0x00000000, 0x00000003, 0x09000045, 0x001000f2, 0x00000001, 0x00100046, + 0x00000001, 0x00107e46, 0x00000001, 0x00106000, 0x00000001, 0x07000000, 0x001000f2, 0x00000000, + 0x00100e46, 0x00000000, 0x00100e46, 0x00000001, 0x0a000033, 0x001020f2, 0x00000000, 0x00100e46, + 0x00000000, 0x00004002, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, 0x0100003e, 0x54415453, + 0x00000074, 0x00000009, 0x00000002, 0x00000000, 0x00000002, 0x00000004, 0x00000000, 0x00000000, + 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +}; + +static DWORD pshader_exceptional_blend_6[309] = { + 0x43425844, 0x72cc2469, 0xfeb8ff3a, 0xc3c15aed, 0x5d2bdd8a, 0x00000001, 0x000004d4, 0x00000005, + 0x00000034, 0x000001f4, 0x0000024c, 0x00000280, 0x00000458, 0x46454452, 0x000001b8, 0x00000001, + 0x000000d8, 0x00000005, 0x0000001c, 0xffff0400, 0x00008100, 0x00000185, 0x000000bc, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000000c3, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x000000ca, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000000, 0x00000001, 0x0000000d, 0x000000cf, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000001, 0x00000001, 0x0000000d, 0x000000d4, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x65745f73, 0x73003078, + 0x7865745f, 0x65740031, 0x74003078, 0x00317865, 0x00635350, 0x000000d4, 0x00000004, 0x000000f0, + 0x00000040, 0x00000000, 0x00000000, 0x00000150, 0x00000000, 0x00000010, 0x00000002, 0x0000015c, + 0x00000000, 0x0000016c, 0x00000010, 0x00000010, 0x00000002, 0x0000015c, 0x00000000, 0x00000176, + 0x00000020, 0x00000010, 0x00000000, 0x0000015c, 0x00000000, 0x0000017c, 0x00000030, 0x00000010, + 0x00000002, 0x0000015c, 0x00000000, 0x6f6c6f63, 0x756d5f72, 0xabab006c, 0x00030001, 0x00040001, + 0x00000000, 0x00000000, 0x6f6c6f63, 0x64615f72, 0x6f660064, 0x006c6163, 0x63736572, 0x31656c61, + 0x63694d00, 0x6f736f72, 0x28207466, 0x48202952, 0x204c534c, 0x64616853, 0x43207265, 0x69706d6f, + 0x2072656c, 0x39322e39, 0x3235392e, 0x3131332e, 0xabab0031, 0x4e475349, 0x00000050, 0x00000002, + 0x00000008, 0x00000038, 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x00000044, + 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x0000030f, 0x505f5653, 0x7469736f, 0x006e6f69, + 0x43584554, 0x44524f4f, 0xababab00, 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, + 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, + 0x52444853, 0x000001d0, 0x00000040, 0x00000074, 0x04000059, 0x00208e46, 0x00000000, 0x00000004, + 0x0300005a, 0x00106000, 0x00000000, 0x0300005a, 0x00106000, 0x00000001, 0x04001858, 0x00107000, + 0x00000000, 0x00005555, 0x04001858, 0x00107000, 0x00000001, 0x00005555, 0x03001062, 0x00101032, + 0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x00000002, 0x09000045, 0x001000f2, + 0x00000000, 0x00101046, 0x00000001, 0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x08000038, + 0x00100072, 0x00000000, 0x00100246, 0x00000000, 0x00208246, 0x00000000, 0x00000000, 0x08000038, + 0x001000f2, 0x00000001, 0x00100ff6, 0x00000000, 0x00208e46, 0x00000000, 0x00000001, 0x0a002032, + 0x001000f2, 0x00000000, 0x00100e46, 0x00000000, 0x00208ff6, 0x00000000, 0x00000000, 0x00100e46, + 0x00000001, 0x0b000032, 0x00100032, 0x00000001, 0x00101046, 0x00000001, 0x00208046, 0x00000000, + 0x00000003, 0x00208ae6, 0x00000000, 0x00000003, 0x09000045, 0x001000f2, 0x00000001, 0x00100046, + 0x00000001, 0x00107e46, 0x00000001, 0x00106000, 0x00000001, 0x08000000, 0x00100072, 0x00000000, + 0x80100246, 0x00000041, 0x00000000, 0x00100246, 0x00000001, 0x07000000, 0x00100082, 0x00000000, + 0x0010003a, 0x00000000, 0x0010003a, 0x00000001, 0x07000033, 0x00102082, 0x00000000, 0x0010003a, + 0x00000000, 0x00004001, 0x3f800000, 0x0a000034, 0x00102072, 0x00000000, 0x00100246, 0x00000000, + 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0100003e, 0x54415453, 0x00000074, + 0x0000000b, 0x00000002, 0x00000000, 0x00000002, 0x00000006, 0x00000000, 0x00000000, 0x00000001, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +}; + +static DWORD pshader_exceptional_blend_7[374] = { + 0x43425844, 0xeeebdd02, 0x607b5e55, 0x9b2d4bb0, 0x0c029c3e, 0x00000001, 0x000005d8, 0x00000005, + 0x00000034, 0x000001f4, 0x0000024c, 0x00000280, 0x0000055c, 0x46454452, 0x000001b8, 0x00000001, + 0x000000d8, 0x00000005, 0x0000001c, 0xffff0400, 0x00008100, 0x00000185, 0x000000bc, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000000c3, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x000000ca, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000000, 0x00000001, 0x0000000d, 0x000000cf, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000001, 0x00000001, 0x0000000d, 0x000000d4, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x65745f73, 0x73003078, + 0x7865745f, 0x65740031, 0x74003078, 0x00317865, 0x00635350, 0x000000d4, 0x00000004, 0x000000f0, + 0x00000040, 0x00000000, 0x00000000, 0x00000150, 0x00000000, 0x00000010, 0x00000002, 0x0000015c, + 0x00000000, 0x0000016c, 0x00000010, 0x00000010, 0x00000002, 0x0000015c, 0x00000000, 0x00000176, + 0x00000020, 0x00000010, 0x00000000, 0x0000015c, 0x00000000, 0x0000017c, 0x00000030, 0x00000010, + 0x00000002, 0x0000015c, 0x00000000, 0x6f6c6f63, 0x756d5f72, 0xabab006c, 0x00030001, 0x00040001, + 0x00000000, 0x00000000, 0x6f6c6f63, 0x64615f72, 0x6f660064, 0x006c6163, 0x63736572, 0x31656c61, + 0x63694d00, 0x6f736f72, 0x28207466, 0x48202952, 0x204c534c, 0x64616853, 0x43207265, 0x69706d6f, + 0x2072656c, 0x39322e39, 0x3235392e, 0x3131332e, 0xabab0031, 0x4e475349, 0x00000050, 0x00000002, + 0x00000008, 0x00000038, 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x00000044, + 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x0000030f, 0x505f5653, 0x7469736f, 0x006e6f69, + 0x43584554, 0x44524f4f, 0xababab00, 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, + 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, + 0x52444853, 0x000002d4, 0x00000040, 0x000000b5, 0x04000059, 0x00208e46, 0x00000000, 0x00000004, + 0x0300005a, 0x00106000, 0x00000000, 0x0300005a, 0x00106000, 0x00000001, 0x04001858, 0x00107000, + 0x00000000, 0x00005555, 0x04001858, 0x00107000, 0x00000001, 0x00005555, 0x03001062, 0x00101032, + 0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x00000004, 0x09000045, 0x001000f2, + 0x00000000, 0x00101046, 0x00000001, 0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x08000038, + 0x00100072, 0x00000000, 0x00100246, 0x00000000, 0x00208246, 0x00000000, 0x00000000, 0x08000038, + 0x001000f2, 0x00000001, 0x00100ff6, 0x00000000, 0x00208e46, 0x00000000, 0x00000001, 0x0a002032, + 0x001000f2, 0x00000000, 0x00100e46, 0x00000000, 0x00208ff6, 0x00000000, 0x00000000, 0x00100e46, + 0x00000001, 0x08000000, 0x00100012, 0x00000001, 0x8010003a, 0x00000041, 0x00000000, 0x00004001, + 0x3f800000, 0x0b000032, 0x00100062, 0x00000001, 0x00101106, 0x00000001, 0x00208106, 0x00000000, + 0x00000003, 0x00208ba6, 0x00000000, 0x00000003, 0x09000045, 0x001000f2, 0x00000002, 0x00100596, + 0x00000001, 0x00107e46, 0x00000001, 0x00106000, 0x00000001, 0x07000038, 0x00100062, 0x00000001, + 0x00100106, 0x00000000, 0x00100ff6, 0x00000002, 0x0a000032, 0x00100062, 0x00000001, 0x00100ff6, + 0x00000000, 0x00100106, 0x00000002, 0x80100656, 0x00000041, 0x00000001, 0x06000036, 0x00100032, + 0x00000003, 0x80100596, 0x00000081, 0x00000001, 0x07000038, 0x00100022, 0x00000001, 0x0010002a, + 0x00000000, 0x0010003a, 0x00000002, 0x0a000032, 0x00100022, 0x00000001, 0x0010003a, 0x00000000, + 0x0010002a, 0x00000002, 0x8010001a, 0x00000041, 0x00000001, 0x06000036, 0x00100042, 0x00000003, + 0x8010001a, 0x00000081, 0x00000001, 0x09000032, 0x00100072, 0x00000001, 0x00100006, 0x00000001, + 0x00100246, 0x00000002, 0x00100246, 0x00000003, 0x08000000, 0x00100082, 0x00000001, 0x8010003a, + 0x00000041, 0x00000002, 0x00004001, 0x3f800000, 0x09000032, 0x00102072, 0x00000000, 0x00100ff6, + 0x00000001, 0x00100246, 0x00000000, 0x00100246, 0x00000001, 0x07000000, 0x00100012, 0x00000000, + 0x0010003a, 0x00000000, 0x0010003a, 0x00000002, 0x0a000032, 0x00102082, 0x00000000, 0x8010003a, + 0x00000041, 0x00000000, 0x0010003a, 0x00000002, 0x0010000a, 0x00000000, 0x0100003e, 0x54415453, + 0x00000074, 0x00000013, 0x00000004, 0x00000000, 0x00000002, 0x00000007, 0x00000000, 0x00000000, + 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +}; + +static DWORD pshader_exceptional_blend_8[343] = { + 0x43425844, 0x4c133b76, 0xe54d7a26, 0xec03c69d, 0xd69182c1, 0x00000001, 0x0000055c, 0x00000005, + 0x00000034, 0x000001f4, 0x0000024c, 0x00000280, 0x000004e0, 0x46454452, 0x000001b8, 0x00000001, + 0x000000d8, 0x00000005, 0x0000001c, 0xffff0400, 0x00008100, 0x00000185, 0x000000bc, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000000c3, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x000000ca, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000000, 0x00000001, 0x0000000d, 0x000000cf, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000001, 0x00000001, 0x0000000d, 0x000000d4, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x65745f73, 0x73003078, + 0x7865745f, 0x65740031, 0x74003078, 0x00317865, 0x00635350, 0x000000d4, 0x00000004, 0x000000f0, + 0x00000040, 0x00000000, 0x00000000, 0x00000150, 0x00000000, 0x00000010, 0x00000002, 0x0000015c, + 0x00000000, 0x0000016c, 0x00000010, 0x00000010, 0x00000002, 0x0000015c, 0x00000000, 0x00000176, + 0x00000020, 0x00000010, 0x00000000, 0x0000015c, 0x00000000, 0x0000017c, 0x00000030, 0x00000010, + 0x00000002, 0x0000015c, 0x00000000, 0x6f6c6f63, 0x756d5f72, 0xabab006c, 0x00030001, 0x00040001, + 0x00000000, 0x00000000, 0x6f6c6f63, 0x64615f72, 0x6f660064, 0x006c6163, 0x63736572, 0x31656c61, + 0x63694d00, 0x6f736f72, 0x28207466, 0x48202952, 0x204c534c, 0x64616853, 0x43207265, 0x69706d6f, + 0x2072656c, 0x39322e39, 0x3235392e, 0x3131332e, 0xabab0031, 0x4e475349, 0x00000050, 0x00000002, + 0x00000008, 0x00000038, 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x00000044, + 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x0000030f, 0x505f5653, 0x7469736f, 0x006e6f69, + 0x43584554, 0x44524f4f, 0xababab00, 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, + 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, + 0x52444853, 0x00000258, 0x00000040, 0x00000096, 0x04000059, 0x00208e46, 0x00000000, 0x00000004, + 0x0300005a, 0x00106000, 0x00000000, 0x0300005a, 0x00106000, 0x00000001, 0x04001858, 0x00107000, + 0x00000000, 0x00005555, 0x04001858, 0x00107000, 0x00000001, 0x00005555, 0x03001062, 0x00101032, + 0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x00000003, 0x09000045, 0x001000f2, + 0x00000000, 0x00101046, 0x00000001, 0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x08000038, + 0x00100072, 0x00000000, 0x00100246, 0x00000000, 0x00208246, 0x00000000, 0x00000000, 0x08000038, + 0x001000f2, 0x00000001, 0x00100ff6, 0x00000000, 0x00208e46, 0x00000000, 0x00000001, 0x0a002032, + 0x001000f2, 0x00000000, 0x00100e46, 0x00000000, 0x00208ff6, 0x00000000, 0x00000000, 0x00100e46, + 0x00000001, 0x08000000, 0x00100012, 0x00000001, 0x8010003a, 0x00000041, 0x00000000, 0x00004001, + 0x3f800000, 0x0b000032, 0x00100062, 0x00000001, 0x00101106, 0x00000001, 0x00208106, 0x00000000, + 0x00000003, 0x00208ba6, 0x00000000, 0x00000003, 0x09000045, 0x001000f2, 0x00000002, 0x00100596, + 0x00000001, 0x00107e46, 0x00000001, 0x00106000, 0x00000001, 0x07000038, 0x00100072, 0x00000001, + 0x00100006, 0x00000001, 0x00100246, 0x00000002, 0x08000000, 0x00100072, 0x00000002, 0x80100246, + 0x00000041, 0x00000002, 0x00100ff6, 0x00000002, 0x09000032, 0x00100072, 0x00000001, 0x00100ff6, + 0x00000000, 0x00100246, 0x00000002, 0x00100246, 0x00000001, 0x08000000, 0x00100082, 0x00000001, + 0x8010003a, 0x00000041, 0x00000002, 0x00004001, 0x3f800000, 0x09000032, 0x00102072, 0x00000000, + 0x00100ff6, 0x00000001, 0x00100246, 0x00000000, 0x00100246, 0x00000001, 0x07000000, 0x00100012, + 0x00000000, 0x0010003a, 0x00000000, 0x0010003a, 0x00000002, 0x0a000032, 0x00102082, 0x00000000, + 0x8010003a, 0x00000041, 0x00000000, 0x0010003a, 0x00000002, 0x0010000a, 0x00000000, 0x0100003e, + 0x54415453, 0x00000074, 0x0000000f, 0x00000003, 0x00000000, 0x00000002, 0x00000007, 0x00000000, + 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +}; + +static DWORD pshader_exceptional_blend_9[430] = { + 0x43425844, 0x0e53b9bf, 0xa40806de, 0xc8710d16, 0xff1f73e9, 0x00000001, 0x000006b8, 0x00000005, + 0x00000034, 0x000001f4, 0x0000024c, 0x00000280, 0x0000063c, 0x46454452, 0x000001b8, 0x00000001, + 0x000000d8, 0x00000005, 0x0000001c, 0xffff0400, 0x00008100, 0x00000185, 0x000000bc, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000000c3, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x000000ca, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000000, 0x00000001, 0x0000000d, 0x000000cf, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000001, 0x00000001, 0x0000000d, 0x000000d4, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x65745f73, 0x73003078, + 0x7865745f, 0x65740031, 0x74003078, 0x00317865, 0x00635350, 0x000000d4, 0x00000004, 0x000000f0, + 0x00000040, 0x00000000, 0x00000000, 0x00000150, 0x00000000, 0x00000010, 0x00000002, 0x0000015c, + 0x00000000, 0x0000016c, 0x00000010, 0x00000010, 0x00000002, 0x0000015c, 0x00000000, 0x00000176, + 0x00000020, 0x00000010, 0x00000000, 0x0000015c, 0x00000000, 0x0000017c, 0x00000030, 0x00000010, + 0x00000002, 0x0000015c, 0x00000000, 0x6f6c6f63, 0x756d5f72, 0xabab006c, 0x00030001, 0x00040001, + 0x00000000, 0x00000000, 0x6f6c6f63, 0x64615f72, 0x6f660064, 0x006c6163, 0x63736572, 0x31656c61, + 0x63694d00, 0x6f736f72, 0x28207466, 0x48202952, 0x204c534c, 0x64616853, 0x43207265, 0x69706d6f, + 0x2072656c, 0x39322e39, 0x3235392e, 0x3131332e, 0xabab0031, 0x4e475349, 0x00000050, 0x00000002, + 0x00000008, 0x00000038, 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x00000044, + 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x0000030f, 0x505f5653, 0x7469736f, 0x006e6f69, + 0x43584554, 0x44524f4f, 0xababab00, 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, + 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, + 0x52444853, 0x000003b4, 0x00000040, 0x000000ed, 0x04000059, 0x00208e46, 0x00000000, 0x00000004, + 0x0300005a, 0x00106000, 0x00000000, 0x0300005a, 0x00106000, 0x00000001, 0x04001858, 0x00107000, + 0x00000000, 0x00005555, 0x04001858, 0x00107000, 0x00000001, 0x00005555, 0x03001062, 0x00101032, + 0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x00000005, 0x09000045, 0x001000f2, + 0x00000000, 0x00101046, 0x00000001, 0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x08000038, + 0x00100072, 0x00000000, 0x00100246, 0x00000000, 0x00208246, 0x00000000, 0x00000000, 0x08000038, + 0x001000f2, 0x00000001, 0x00100ff6, 0x00000000, 0x00208e46, 0x00000000, 0x00000001, 0x0a002032, + 0x001000f2, 0x00000000, 0x00100e46, 0x00000000, 0x00208ff6, 0x00000000, 0x00000000, 0x00100e46, + 0x00000001, 0x08000000, 0x00100072, 0x00000001, 0x80100246, 0x00000041, 0x00000000, 0x00100ff6, + 0x00000000, 0x0b000032, 0x00100032, 0x00000002, 0x00101046, 0x00000001, 0x00208046, 0x00000000, + 0x00000003, 0x00208ae6, 0x00000000, 0x00000003, 0x09000045, 0x001000f2, 0x00000002, 0x00100046, + 0x00000002, 0x00107e46, 0x00000001, 0x00106000, 0x00000001, 0x07000038, 0x00100082, 0x00000001, + 0x0010003a, 0x00000000, 0x0010003a, 0x00000002, 0x08000000, 0x00100072, 0x00000003, 0x80100246, + 0x00000041, 0x00000002, 0x00100ff6, 0x00000002, 0x07000000, 0x00100072, 0x00000003, 0x00100246, + 0x00000003, 0x00100246, 0x00000003, 0x0a000032, 0x00100072, 0x00000001, 0x80100246, 0x00000041, + 0x00000003, 0x00100246, 0x00000001, 0x00100ff6, 0x00000001, 0x0700000f, 0x00100082, 0x00000001, + 0x00100006, 0x00000002, 0x00100006, 0x00000000, 0x07000038, 0x00100012, 0x00000003, 0x0010003a, + 0x00000002, 0x00004001, 0x3f000000, 0x07000031, 0x00100072, 0x00000003, 0x00100246, 0x00000002, + 0x00100006, 0x00000003, 0x09000037, 0x00100012, 0x00000004, 0x0010000a, 0x00000003, 0x0010003a, + 0x00000001, 0x0010000a, 0x00000001, 0x0700000f, 0x00100012, 0x00000001, 0x00100556, 0x00000002, + 0x00100556, 0x00000000, 0x09000037, 0x00100022, 0x00000004, 0x0010001a, 0x00000003, 0x0010000a, + 0x00000001, 0x0010001a, 0x00000001, 0x0700000f, 0x00100012, 0x00000001, 0x00100aa6, 0x00000002, + 0x00100aa6, 0x00000000, 0x09000037, 0x00100042, 0x00000004, 0x0010002a, 0x00000003, 0x0010000a, + 0x00000001, 0x0010002a, 0x00000001, 0x08000000, 0x00100012, 0x00000001, 0x8010003a, 0x00000041, + 0x00000000, 0x00004001, 0x3f800000, 0x09000032, 0x00100072, 0x00000001, 0x00100006, 0x00000001, + 0x00100246, 0x00000002, 0x00100246, 0x00000004, 0x08000000, 0x00100082, 0x00000001, 0x8010003a, + 0x00000041, 0x00000002, 0x00004001, 0x3f800000, 0x09000032, 0x00102072, 0x00000000, 0x00100ff6, + 0x00000001, 0x00100246, 0x00000000, 0x00100246, 0x00000001, 0x07000000, 0x00100012, 0x00000000, + 0x0010003a, 0x00000000, 0x0010003a, 0x00000002, 0x0a000032, 0x00102082, 0x00000000, 0x8010003a, + 0x00000041, 0x00000000, 0x0010003a, 0x00000002, 0x0010000a, 0x00000000, 0x0100003e, 0x54415453, + 0x00000074, 0x0000001a, 0x00000005, 0x00000000, 0x00000002, 0x0000000e, 0x00000000, 0x00000000, + 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +}; + +static DWORD pshader_exceptional_blend_10[430] = { + 0x43425844, 0x5b763bc7, 0xa04a2226, 0x01dce3d1, 0xed9b4a05, 0x00000001, 0x000006b8, 0x00000005, + 0x00000034, 0x000001f4, 0x0000024c, 0x00000280, 0x0000063c, 0x46454452, 0x000001b8, 0x00000001, + 0x000000d8, 0x00000005, 0x0000001c, 0xffff0400, 0x00008100, 0x00000185, 0x000000bc, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000000c3, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x000000ca, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000000, 0x00000001, 0x0000000d, 0x000000cf, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000001, 0x00000001, 0x0000000d, 0x000000d4, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x65745f73, 0x73003078, + 0x7865745f, 0x65740031, 0x74003078, 0x00317865, 0x00635350, 0x000000d4, 0x00000004, 0x000000f0, + 0x00000040, 0x00000000, 0x00000000, 0x00000150, 0x00000000, 0x00000010, 0x00000002, 0x0000015c, + 0x00000000, 0x0000016c, 0x00000010, 0x00000010, 0x00000002, 0x0000015c, 0x00000000, 0x00000176, + 0x00000020, 0x00000010, 0x00000000, 0x0000015c, 0x00000000, 0x0000017c, 0x00000030, 0x00000010, + 0x00000002, 0x0000015c, 0x00000000, 0x6f6c6f63, 0x756d5f72, 0xabab006c, 0x00030001, 0x00040001, + 0x00000000, 0x00000000, 0x6f6c6f63, 0x64615f72, 0x6f660064, 0x006c6163, 0x63736572, 0x31656c61, + 0x63694d00, 0x6f736f72, 0x28207466, 0x48202952, 0x204c534c, 0x64616853, 0x43207265, 0x69706d6f, + 0x2072656c, 0x39322e39, 0x3235392e, 0x3131332e, 0xabab0031, 0x4e475349, 0x00000050, 0x00000002, + 0x00000008, 0x00000038, 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x00000044, + 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x0000030f, 0x505f5653, 0x7469736f, 0x006e6f69, + 0x43584554, 0x44524f4f, 0xababab00, 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, + 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, + 0x52444853, 0x000003b4, 0x00000040, 0x000000ed, 0x04000059, 0x00208e46, 0x00000000, 0x00000004, + 0x0300005a, 0x00106000, 0x00000000, 0x0300005a, 0x00106000, 0x00000001, 0x04001858, 0x00107000, + 0x00000000, 0x00005555, 0x04001858, 0x00107000, 0x00000001, 0x00005555, 0x03001062, 0x00101032, + 0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x00000005, 0x09000045, 0x001000f2, + 0x00000000, 0x00101046, 0x00000001, 0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x08000038, + 0x00100072, 0x00000000, 0x00100246, 0x00000000, 0x00208246, 0x00000000, 0x00000000, 0x08000038, + 0x001000f2, 0x00000001, 0x00100ff6, 0x00000000, 0x00208e46, 0x00000000, 0x00000001, 0x0a002032, + 0x001000f2, 0x00000000, 0x00100e46, 0x00000000, 0x00208ff6, 0x00000000, 0x00000000, 0x00100e46, + 0x00000001, 0x08000000, 0x00100072, 0x00000001, 0x80100246, 0x00000041, 0x00000000, 0x00100ff6, + 0x00000000, 0x0b000032, 0x00100032, 0x00000002, 0x00101046, 0x00000001, 0x00208046, 0x00000000, + 0x00000003, 0x00208ae6, 0x00000000, 0x00000003, 0x09000045, 0x001000f2, 0x00000002, 0x00100046, + 0x00000002, 0x00107e46, 0x00000001, 0x00106000, 0x00000001, 0x08000000, 0x00100072, 0x00000003, + 0x80100246, 0x00000041, 0x00000002, 0x00100ff6, 0x00000002, 0x07000000, 0x00100072, 0x00000003, + 0x00100246, 0x00000003, 0x00100246, 0x00000003, 0x07000038, 0x00100082, 0x00000001, 0x0010003a, + 0x00000000, 0x0010003a, 0x00000002, 0x0a000032, 0x00100072, 0x00000001, 0x80100246, 0x00000041, + 0x00000003, 0x00100246, 0x00000001, 0x00100ff6, 0x00000001, 0x07000038, 0x00100082, 0x00000001, + 0x0010003a, 0x00000000, 0x00004001, 0x3f000000, 0x07000031, 0x00100072, 0x00000003, 0x00100246, + 0x00000000, 0x00100ff6, 0x00000001, 0x0700000f, 0x00100082, 0x00000001, 0x00100006, 0x00000002, + 0x00100006, 0x00000000, 0x09000037, 0x00100012, 0x00000004, 0x0010000a, 0x00000003, 0x0010003a, + 0x00000001, 0x0010000a, 0x00000001, 0x0700000f, 0x00100012, 0x00000001, 0x00100556, 0x00000002, + 0x00100556, 0x00000000, 0x09000037, 0x00100022, 0x00000004, 0x0010001a, 0x00000003, 0x0010000a, + 0x00000001, 0x0010001a, 0x00000001, 0x0700000f, 0x00100012, 0x00000001, 0x00100aa6, 0x00000002, + 0x00100aa6, 0x00000000, 0x09000037, 0x00100042, 0x00000004, 0x0010002a, 0x00000003, 0x0010000a, + 0x00000001, 0x0010002a, 0x00000001, 0x08000000, 0x00100012, 0x00000001, 0x8010003a, 0x00000041, + 0x00000000, 0x00004001, 0x3f800000, 0x09000032, 0x00100072, 0x00000001, 0x00100006, 0x00000001, + 0x00100246, 0x00000002, 0x00100246, 0x00000004, 0x08000000, 0x00100082, 0x00000001, 0x8010003a, + 0x00000041, 0x00000002, 0x00004001, 0x3f800000, 0x09000032, 0x00102072, 0x00000000, 0x00100ff6, + 0x00000001, 0x00100246, 0x00000000, 0x00100246, 0x00000001, 0x07000000, 0x00100012, 0x00000000, + 0x0010003a, 0x00000000, 0x0010003a, 0x00000002, 0x0a000032, 0x00102082, 0x00000000, 0x8010003a, + 0x00000041, 0x00000000, 0x0010003a, 0x00000002, 0x0010000a, 0x00000000, 0x0100003e, 0x54415453, + 0x00000074, 0x0000001a, 0x00000005, 0x00000000, 0x00000002, 0x0000000e, 0x00000000, 0x00000000, + 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +}; + +static DWORD pshader_exceptional_blend_11[284] = { + 0x43425844, 0xb5fd5f87, 0x5eef857b, 0xa3d0d13a, 0xf65c919c, 0x00000001, 0x00000470, 0x00000005, + 0x00000034, 0x000001f4, 0x0000024c, 0x00000280, 0x000003f4, 0x46454452, 0x000001b8, 0x00000001, + 0x000000d8, 0x00000005, 0x0000001c, 0xffff0400, 0x00008100, 0x00000185, 0x000000bc, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000000c3, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x000000ca, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000000, 0x00000001, 0x0000000d, 0x000000cf, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000001, 0x00000001, 0x0000000d, 0x000000d4, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x65745f73, 0x73003078, + 0x7865745f, 0x65740031, 0x74003078, 0x00317865, 0x00635350, 0x000000d4, 0x00000004, 0x000000f0, + 0x00000040, 0x00000000, 0x00000000, 0x00000150, 0x00000000, 0x00000010, 0x00000002, 0x0000015c, + 0x00000000, 0x0000016c, 0x00000010, 0x00000010, 0x00000002, 0x0000015c, 0x00000000, 0x00000176, + 0x00000020, 0x00000010, 0x00000000, 0x0000015c, 0x00000000, 0x0000017c, 0x00000030, 0x00000010, + 0x00000002, 0x0000015c, 0x00000000, 0x6f6c6f63, 0x756d5f72, 0xabab006c, 0x00030001, 0x00040001, + 0x00000000, 0x00000000, 0x6f6c6f63, 0x64615f72, 0x6f660064, 0x006c6163, 0x63736572, 0x31656c61, + 0x63694d00, 0x6f736f72, 0x28207466, 0x48202952, 0x204c534c, 0x64616853, 0x43207265, 0x69706d6f, + 0x2072656c, 0x39322e39, 0x3235392e, 0x3131332e, 0xabab0031, 0x4e475349, 0x00000050, 0x00000002, + 0x00000008, 0x00000038, 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x00000044, + 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x0000030f, 0x505f5653, 0x7469736f, 0x006e6f69, + 0x43584554, 0x44524f4f, 0xababab00, 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, + 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, + 0x52444853, 0x0000016c, 0x00000040, 0x0000005b, 0x04000059, 0x00208e46, 0x00000000, 0x00000004, + 0x0300005a, 0x00106000, 0x00000000, 0x0300005a, 0x00106000, 0x00000001, 0x04001858, 0x00107000, + 0x00000000, 0x00005555, 0x04001858, 0x00107000, 0x00000001, 0x00005555, 0x03001062, 0x00101032, + 0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x00000002, 0x09000045, 0x001000f2, + 0x00000000, 0x00101046, 0x00000001, 0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x08000038, + 0x00100012, 0x00000000, 0x0010003a, 0x00000000, 0x0020803a, 0x00000000, 0x00000001, 0x0a002032, + 0x00100012, 0x00000000, 0x0010003a, 0x00000000, 0x0020803a, 0x00000000, 0x00000000, 0x0010000a, + 0x00000000, 0x08000000, 0x00100012, 0x00000000, 0x8010000a, 0x00000041, 0x00000000, 0x00004001, + 0x3f800000, 0x0b000032, 0x00100062, 0x00000000, 0x00101106, 0x00000001, 0x00208106, 0x00000000, + 0x00000003, 0x00208ba6, 0x00000000, 0x00000003, 0x09000045, 0x001000f2, 0x00000001, 0x00100596, + 0x00000000, 0x00107e46, 0x00000001, 0x00106000, 0x00000001, 0x07000038, 0x001020f2, 0x00000000, + 0x00100006, 0x00000000, 0x00100e46, 0x00000001, 0x0100003e, 0x54415453, 0x00000074, 0x00000008, + 0x00000002, 0x00000000, 0x00000002, 0x00000003, 0x00000000, 0x00000000, 0x00000001, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, +}; + +static DWORD pshader_exceptional_blend_12[276] = { + 0x43425844, 0x8aa79ff3, 0xa0220437, 0x6186c7a6, 0x358ad839, 0x00000001, 0x00000450, 0x00000005, + 0x00000034, 0x000001f4, 0x0000024c, 0x00000280, 0x000003d4, 0x46454452, 0x000001b8, 0x00000001, + 0x000000d8, 0x00000005, 0x0000001c, 0xffff0400, 0x00008100, 0x00000185, 0x000000bc, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000000c3, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x000000ca, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000000, 0x00000001, 0x0000000d, 0x000000cf, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000001, 0x00000001, 0x0000000d, 0x000000d4, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x65745f73, 0x73003078, + 0x7865745f, 0x65740031, 0x74003078, 0x00317865, 0x00635350, 0x000000d4, 0x00000004, 0x000000f0, + 0x00000040, 0x00000000, 0x00000000, 0x00000150, 0x00000000, 0x00000010, 0x00000002, 0x0000015c, + 0x00000000, 0x0000016c, 0x00000010, 0x00000010, 0x00000002, 0x0000015c, 0x00000000, 0x00000176, + 0x00000020, 0x00000010, 0x00000000, 0x0000015c, 0x00000000, 0x0000017c, 0x00000030, 0x00000010, + 0x00000002, 0x0000015c, 0x00000000, 0x6f6c6f63, 0x756d5f72, 0xabab006c, 0x00030001, 0x00040001, + 0x00000000, 0x00000000, 0x6f6c6f63, 0x64615f72, 0x6f660064, 0x006c6163, 0x63736572, 0x31656c61, + 0x63694d00, 0x6f736f72, 0x28207466, 0x48202952, 0x204c534c, 0x64616853, 0x43207265, 0x69706d6f, + 0x2072656c, 0x39322e39, 0x3235392e, 0x3131332e, 0xabab0031, 0x4e475349, 0x00000050, 0x00000002, + 0x00000008, 0x00000038, 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x00000044, + 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x0000030f, 0x505f5653, 0x7469736f, 0x006e6f69, + 0x43584554, 0x44524f4f, 0xababab00, 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, + 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, + 0x52444853, 0x0000014c, 0x00000040, 0x00000053, 0x04000059, 0x00208e46, 0x00000000, 0x00000004, + 0x0300005a, 0x00106000, 0x00000000, 0x0300005a, 0x00106000, 0x00000001, 0x04001858, 0x00107000, + 0x00000000, 0x00005555, 0x04001858, 0x00107000, 0x00000001, 0x00005555, 0x03001062, 0x00101032, + 0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x00000002, 0x09000045, 0x001000f2, + 0x00000000, 0x00101046, 0x00000001, 0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x08000038, + 0x00100012, 0x00000000, 0x0010003a, 0x00000000, 0x0020803a, 0x00000000, 0x00000001, 0x0a002032, + 0x00100012, 0x00000000, 0x0010003a, 0x00000000, 0x0020803a, 0x00000000, 0x00000000, 0x0010000a, + 0x00000000, 0x0b000032, 0x00100062, 0x00000000, 0x00101106, 0x00000001, 0x00208106, 0x00000000, + 0x00000003, 0x00208ba6, 0x00000000, 0x00000003, 0x09000045, 0x001000f2, 0x00000001, 0x00100596, + 0x00000000, 0x00107e46, 0x00000001, 0x00106000, 0x00000001, 0x07000038, 0x001020f2, 0x00000000, + 0x00100006, 0x00000000, 0x00100e46, 0x00000001, 0x0100003e, 0x54415453, 0x00000074, 0x00000007, + 0x00000002, 0x00000000, 0x00000002, 0x00000002, 0x00000000, 0x00000000, 0x00000001, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, +}; + +static ProgramWithCachedVariableLocations pshader_exceptional_blend_arr[13] = { + { NULL, 0, }, + { pshader_exceptional_blend_1, 1340, }, + { pshader_exceptional_blend_2, 1444, }, + { pshader_exceptional_blend_3, 1424, }, + { pshader_exceptional_blend_4, 1424, }, + { pshader_exceptional_blend_5, 1176, }, + { pshader_exceptional_blend_6, 1236, }, + { pshader_exceptional_blend_7, 1496, }, + { pshader_exceptional_blend_8, 1372, }, + { pshader_exceptional_blend_9, 1720, }, + { pshader_exceptional_blend_10, 1720, }, + { pshader_exceptional_blend_11, 1136, }, + { pshader_exceptional_blend_12, 1104, }, +}; + +static DWORD pshader_filter_0[379] = { + 0x43425844, 0x24aad9c6, 0x43cc8801, 0x5ba2dc0b, 0xffe933e2, 0x00000001, 0x000005ec, 0x00000005, + 0x00000034, 0x000002d0, 0x00000328, 0x0000035c, 0x00000570, 0x46454452, 0x00000294, 0x00000002, + 0x00000100, 0x00000006, 0x0000001c, 0xffff0400, 0x00008100, 0x00000262, 0x000000dc, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000000e3, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x000000ea, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000000, 0x00000001, 0x0000000d, 0x000000ef, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000001, 0x00000001, 0x0000000d, 0x000000f4, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000000f8, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x65745f73, 0x73003078, + 0x7865745f, 0x65740031, 0x74003078, 0x00317865, 0x00635350, 0x61726170, 0xababab00, 0x000000f4, + 0x00000004, 0x00000130, 0x00000040, 0x00000000, 0x00000000, 0x000000f8, 0x00000005, 0x000001c8, + 0x00000050, 0x00000000, 0x00000000, 0x00000190, 0x00000000, 0x00000010, 0x00000000, 0x0000019c, + 0x00000000, 0x000001ac, 0x00000010, 0x00000010, 0x00000000, 0x0000019c, 0x00000000, 0x000001b6, + 0x00000020, 0x00000010, 0x00000000, 0x0000019c, 0x00000000, 0x000001bc, 0x00000030, 0x00000010, + 0x00000000, 0x0000019c, 0x00000000, 0x6f6c6f63, 0x756d5f72, 0xabab006c, 0x00030001, 0x00040001, + 0x00000000, 0x00000000, 0x6f6c6f63, 0x64615f72, 0x6f660064, 0x006c6163, 0x63736572, 0x31656c61, + 0xababab00, 0x00000240, 0x00000000, 0x00000010, 0x00000002, 0x0000019c, 0x00000000, 0x00000247, + 0x00000010, 0x00000010, 0x00000002, 0x0000019c, 0x00000000, 0x0000024e, 0x00000020, 0x00000010, + 0x00000002, 0x0000019c, 0x00000000, 0x00000254, 0x00000030, 0x00000010, 0x00000000, 0x0000019c, + 0x00000000, 0x0000025b, 0x00000040, 0x00000010, 0x00000002, 0x0000019c, 0x00000000, 0x6d616c63, + 0x63003070, 0x706d616c, 0x6f630031, 0x00726f6c, 0x6f6c6f63, 0x74003272, 0x666f5f63, 0x694d0066, + 0x736f7263, 0x2074666f, 0x20295228, 0x4c534c48, 0x61685320, 0x20726564, 0x706d6f43, 0x72656c69, + 0x322e3920, 0x35392e39, 0x31332e32, 0xab003131, 0x4e475349, 0x00000050, 0x00000002, 0x00000008, + 0x00000038, 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x00000044, 0x00000000, + 0x00000000, 0x00000003, 0x00000001, 0x0000030f, 0x505f5653, 0x7469736f, 0x006e6f69, 0x43584554, + 0x44524f4f, 0xababab00, 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, + 0x00000000, 0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x52444853, + 0x0000020c, 0x00000040, 0x00000083, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x04000059, + 0x00208e46, 0x00000001, 0x00000005, 0x0300005a, 0x00106000, 0x00000000, 0x0300005a, 0x00106000, + 0x00000001, 0x04001858, 0x00107000, 0x00000000, 0x00005555, 0x04001858, 0x00107000, 0x00000001, + 0x00005555, 0x03001062, 0x00101032, 0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x02000068, + 0x00000003, 0x08000000, 0x00100032, 0x00000000, 0x00101046, 0x00000001, 0x00208046, 0x00000001, + 0x00000004, 0x08000034, 0x00100032, 0x00000000, 0x00100046, 0x00000000, 0x00208046, 0x00000001, + 0x00000000, 0x08000033, 0x00100032, 0x00000000, 0x00100046, 0x00000000, 0x00208ae6, 0x00000001, + 0x00000000, 0x09000045, 0x001000f2, 0x00000000, 0x00100046, 0x00000000, 0x00107e46, 0x00000000, + 0x00106000, 0x00000000, 0x08000038, 0x00100012, 0x00000000, 0x0010003a, 0x00000000, 0x0020802a, + 0x00000001, 0x00000004, 0x07000033, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x00004001, + 0x3f800000, 0x08000038, 0x001000f2, 0x00000000, 0x00100006, 0x00000000, 0x00208e46, 0x00000001, + 0x00000002, 0x08000034, 0x00100032, 0x00000001, 0x00101046, 0x00000001, 0x00208046, 0x00000001, + 0x00000001, 0x08000033, 0x00100032, 0x00000001, 0x00100046, 0x00000001, 0x00208ae6, 0x00000001, + 0x00000001, 0x09000045, 0x001000f2, 0x00000001, 0x00100046, 0x00000001, 0x00107e46, 0x00000001, + 0x00106000, 0x00000001, 0x08000000, 0x00100012, 0x00000002, 0x8010003a, 0x00000041, 0x00000001, + 0x00004001, 0x3f800000, 0x09000032, 0x001020f2, 0x00000000, 0x00100e46, 0x00000000, 0x00100006, + 0x00000002, 0x00100e46, 0x00000001, 0x0100003e, 0x54415453, 0x00000074, 0x0000000d, 0x00000003, + 0x00000000, 0x00000002, 0x00000009, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, +}; + +static DWORD pshader_filter_1[377] = { + 0x43425844, 0x1e4f7d74, 0xaaf944d6, 0xb5f0a484, 0xc246b059, 0x00000001, 0x000005e4, 0x00000005, + 0x00000034, 0x000002d0, 0x00000328, 0x0000035c, 0x00000568, 0x46454452, 0x00000294, 0x00000002, + 0x00000100, 0x00000006, 0x0000001c, 0xffff0400, 0x00008100, 0x00000262, 0x000000dc, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000000e3, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x000000ea, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000000, 0x00000001, 0x0000000d, 0x000000ef, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000001, 0x00000001, 0x0000000d, 0x000000f4, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000000f8, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x65745f73, 0x73003078, + 0x7865745f, 0x65740031, 0x74003078, 0x00317865, 0x00635350, 0x61726170, 0xababab00, 0x000000f4, + 0x00000004, 0x00000130, 0x00000040, 0x00000000, 0x00000000, 0x000000f8, 0x00000005, 0x000001c8, + 0x00000050, 0x00000000, 0x00000000, 0x00000190, 0x00000000, 0x00000010, 0x00000000, 0x0000019c, + 0x00000000, 0x000001ac, 0x00000010, 0x00000010, 0x00000000, 0x0000019c, 0x00000000, 0x000001b6, + 0x00000020, 0x00000010, 0x00000000, 0x0000019c, 0x00000000, 0x000001bc, 0x00000030, 0x00000010, + 0x00000000, 0x0000019c, 0x00000000, 0x6f6c6f63, 0x756d5f72, 0xabab006c, 0x00030001, 0x00040001, + 0x00000000, 0x00000000, 0x6f6c6f63, 0x64615f72, 0x6f660064, 0x006c6163, 0x63736572, 0x31656c61, + 0xababab00, 0x00000240, 0x00000000, 0x00000010, 0x00000002, 0x0000019c, 0x00000000, 0x00000247, + 0x00000010, 0x00000010, 0x00000002, 0x0000019c, 0x00000000, 0x0000024e, 0x00000020, 0x00000010, + 0x00000002, 0x0000019c, 0x00000000, 0x00000254, 0x00000030, 0x00000010, 0x00000000, 0x0000019c, + 0x00000000, 0x0000025b, 0x00000040, 0x00000010, 0x00000002, 0x0000019c, 0x00000000, 0x6d616c63, + 0x63003070, 0x706d616c, 0x6f630031, 0x00726f6c, 0x6f6c6f63, 0x74003272, 0x666f5f63, 0x694d0066, + 0x736f7263, 0x2074666f, 0x20295228, 0x4c534c48, 0x61685320, 0x20726564, 0x706d6f43, 0x72656c69, + 0x322e3920, 0x35392e39, 0x31332e32, 0xab003131, 0x4e475349, 0x00000050, 0x00000002, 0x00000008, + 0x00000038, 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x00000044, 0x00000000, + 0x00000000, 0x00000003, 0x00000001, 0x0000030f, 0x505f5653, 0x7469736f, 0x006e6f69, 0x43584554, + 0x44524f4f, 0xababab00, 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, + 0x00000000, 0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x52444853, + 0x00000204, 0x00000040, 0x00000081, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x04000059, + 0x00208e46, 0x00000001, 0x00000005, 0x0300005a, 0x00106000, 0x00000000, 0x0300005a, 0x00106000, + 0x00000001, 0x04001858, 0x00107000, 0x00000000, 0x00005555, 0x04001858, 0x00107000, 0x00000001, + 0x00005555, 0x03001062, 0x00101032, 0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x02000068, + 0x00000002, 0x08000000, 0x00100032, 0x00000000, 0x00101046, 0x00000001, 0x00208046, 0x00000001, + 0x00000004, 0x08000034, 0x00100032, 0x00000000, 0x00100046, 0x00000000, 0x00208046, 0x00000001, + 0x00000000, 0x08000033, 0x00100032, 0x00000000, 0x00100046, 0x00000000, 0x00208ae6, 0x00000001, + 0x00000000, 0x09000045, 0x001000f2, 0x00000000, 0x00100046, 0x00000000, 0x00107e46, 0x00000000, + 0x00106000, 0x00000000, 0x08000038, 0x00100012, 0x00000000, 0x0010003a, 0x00000000, 0x0020802a, + 0x00000001, 0x00000004, 0x07000033, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x00004001, + 0x3f800000, 0x08000034, 0x00100062, 0x00000000, 0x00101106, 0x00000001, 0x00208106, 0x00000001, + 0x00000001, 0x08000033, 0x00100062, 0x00000000, 0x00100656, 0x00000000, 0x00208ba6, 0x00000001, + 0x00000001, 0x09000045, 0x001000f2, 0x00000001, 0x00100596, 0x00000000, 0x00107e46, 0x00000001, + 0x00106000, 0x00000001, 0x08000000, 0x00100022, 0x00000000, 0x8010003a, 0x00000041, 0x00000001, + 0x00004001, 0x3f800000, 0x08000038, 0x001000f2, 0x00000001, 0x00100556, 0x00000000, 0x00208e46, + 0x00000001, 0x00000002, 0x07000038, 0x001020f2, 0x00000000, 0x00100006, 0x00000000, 0x00100e46, + 0x00000001, 0x0100003e, 0x54415453, 0x00000074, 0x0000000d, 0x00000002, 0x00000000, 0x00000002, + 0x0000000a, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, +}; + +static DWORD pshader_filter_2[411] = { + 0x43425844, 0x434da1c1, 0xc6277d6b, 0xf3644d3f, 0x33d647fa, 0x00000001, 0x0000066c, 0x00000005, + 0x00000034, 0x0000031c, 0x00000374, 0x000003a8, 0x000005f0, 0x46454452, 0x000002e0, 0x00000002, + 0x0000014c, 0x00000008, 0x0000001c, 0xffff0400, 0x00008100, 0x000002ae, 0x0000011c, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000123, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x0000012a, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0x00000001, 0x00000001, 0x00000131, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000000, 0x00000001, 0x0000000d, 0x00000136, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000001, 0x00000001, 0x0000000d, 0x0000013b, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000002, 0x00000001, 0x0000000d, 0x00000140, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000144, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x65745f73, 0x73003078, + 0x7865745f, 0x5f730031, 0x32786574, 0x78657400, 0x65740030, 0x74003178, 0x00327865, 0x00635350, + 0x61726170, 0xababab00, 0x00000140, 0x00000004, 0x0000017c, 0x00000040, 0x00000000, 0x00000000, + 0x00000144, 0x00000005, 0x00000214, 0x00000050, 0x00000000, 0x00000000, 0x000001dc, 0x00000000, + 0x00000010, 0x00000000, 0x000001e8, 0x00000000, 0x000001f8, 0x00000010, 0x00000010, 0x00000000, + 0x000001e8, 0x00000000, 0x00000202, 0x00000020, 0x00000010, 0x00000000, 0x000001e8, 0x00000000, + 0x00000208, 0x00000030, 0x00000010, 0x00000000, 0x000001e8, 0x00000000, 0x6f6c6f63, 0x756d5f72, + 0xabab006c, 0x00030001, 0x00040001, 0x00000000, 0x00000000, 0x6f6c6f63, 0x64615f72, 0x6f660064, + 0x006c6163, 0x63736572, 0x31656c61, 0xababab00, 0x0000028c, 0x00000000, 0x00000010, 0x00000002, + 0x000001e8, 0x00000000, 0x00000293, 0x00000010, 0x00000010, 0x00000002, 0x000001e8, 0x00000000, + 0x0000029a, 0x00000020, 0x00000010, 0x00000000, 0x000001e8, 0x00000000, 0x000002a0, 0x00000030, + 0x00000010, 0x00000000, 0x000001e8, 0x00000000, 0x000002a7, 0x00000040, 0x00000010, 0x00000002, + 0x000001e8, 0x00000000, 0x6d616c63, 0x63003070, 0x706d616c, 0x6f630031, 0x00726f6c, 0x6f6c6f63, + 0x74003272, 0x666f5f63, 0x694d0066, 0x736f7263, 0x2074666f, 0x20295228, 0x4c534c48, 0x61685320, + 0x20726564, 0x706d6f43, 0x72656c69, 0x322e3920, 0x35392e39, 0x31332e32, 0xab003131, 0x4e475349, + 0x00000050, 0x00000002, 0x00000008, 0x00000038, 0x00000000, 0x00000001, 0x00000003, 0x00000000, + 0x0000000f, 0x00000044, 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x0000030f, 0x505f5653, + 0x7469736f, 0x006e6f69, 0x43584554, 0x44524f4f, 0xababab00, 0x4e47534f, 0x0000002c, 0x00000001, + 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x0000000f, 0x545f5653, + 0x65677261, 0xabab0074, 0x52444853, 0x00000240, 0x00000040, 0x00000090, 0x04000059, 0x00208e46, + 0x00000000, 0x00000001, 0x04000059, 0x00208e46, 0x00000001, 0x00000005, 0x0300005a, 0x00106000, + 0x00000000, 0x0300005a, 0x00106000, 0x00000001, 0x0300005a, 0x00106000, 0x00000002, 0x04001858, + 0x00107000, 0x00000000, 0x00005555, 0x04001858, 0x00107000, 0x00000001, 0x00005555, 0x04001858, + 0x00107000, 0x00000002, 0x00005555, 0x03001062, 0x00101032, 0x00000001, 0x03000065, 0x001020f2, + 0x00000000, 0x02000068, 0x00000003, 0x08000000, 0x00100032, 0x00000000, 0x00101046, 0x00000001, + 0x00208046, 0x00000001, 0x00000004, 0x08000034, 0x00100032, 0x00000000, 0x00100046, 0x00000000, + 0x00208046, 0x00000001, 0x00000000, 0x08000033, 0x00100032, 0x00000000, 0x00100046, 0x00000000, + 0x00208ae6, 0x00000001, 0x00000000, 0x09000045, 0x001000f2, 0x00000000, 0x00100046, 0x00000000, + 0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x08000038, 0x00100012, 0x00000000, 0x0010003a, + 0x00000000, 0x0020802a, 0x00000001, 0x00000004, 0x07000033, 0x00100012, 0x00000000, 0x0010000a, + 0x00000000, 0x00004001, 0x3f800000, 0x05000036, 0x00100022, 0x00000000, 0x00004001, 0x3f000000, + 0x09000045, 0x001000f2, 0x00000000, 0x00100046, 0x00000000, 0x00107e46, 0x00000002, 0x00106000, + 0x00000002, 0x08000034, 0x00100032, 0x00000001, 0x00101046, 0x00000001, 0x00208046, 0x00000001, + 0x00000001, 0x08000033, 0x00100032, 0x00000001, 0x00100046, 0x00000001, 0x00208ae6, 0x00000001, + 0x00000001, 0x09000045, 0x001000f2, 0x00000001, 0x00100046, 0x00000001, 0x00107e46, 0x00000001, + 0x00106000, 0x00000001, 0x08000000, 0x00100012, 0x00000002, 0x8010003a, 0x00000041, 0x00000001, + 0x00004001, 0x3f800000, 0x09000032, 0x001020f2, 0x00000000, 0x00100e46, 0x00000000, 0x00100006, + 0x00000002, 0x00100e46, 0x00000001, 0x0100003e, 0x54415453, 0x00000074, 0x0000000e, 0x00000003, + 0x00000000, 0x00000002, 0x00000008, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, +}; + +static DWORD pshader_filter_3[409] = { + 0x43425844, 0x965f1059, 0xcdafe63f, 0x73c062f4, 0xcd63b2ea, 0x00000001, 0x00000664, 0x00000005, + 0x00000034, 0x0000031c, 0x00000374, 0x000003a8, 0x000005e8, 0x46454452, 0x000002e0, 0x00000002, + 0x0000014c, 0x00000008, 0x0000001c, 0xffff0400, 0x00008100, 0x000002ae, 0x0000011c, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000123, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x0000012a, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0x00000001, 0x00000001, 0x00000131, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000000, 0x00000001, 0x0000000d, 0x00000136, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000001, 0x00000001, 0x0000000d, 0x0000013b, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000002, 0x00000001, 0x0000000d, 0x00000140, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000144, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x65745f73, 0x73003078, + 0x7865745f, 0x5f730031, 0x32786574, 0x78657400, 0x65740030, 0x74003178, 0x00327865, 0x00635350, + 0x61726170, 0xababab00, 0x00000140, 0x00000004, 0x0000017c, 0x00000040, 0x00000000, 0x00000000, + 0x00000144, 0x00000005, 0x00000214, 0x00000050, 0x00000000, 0x00000000, 0x000001dc, 0x00000000, + 0x00000010, 0x00000000, 0x000001e8, 0x00000000, 0x000001f8, 0x00000010, 0x00000010, 0x00000000, + 0x000001e8, 0x00000000, 0x00000202, 0x00000020, 0x00000010, 0x00000000, 0x000001e8, 0x00000000, + 0x00000208, 0x00000030, 0x00000010, 0x00000000, 0x000001e8, 0x00000000, 0x6f6c6f63, 0x756d5f72, + 0xabab006c, 0x00030001, 0x00040001, 0x00000000, 0x00000000, 0x6f6c6f63, 0x64615f72, 0x6f660064, + 0x006c6163, 0x63736572, 0x31656c61, 0xababab00, 0x0000028c, 0x00000000, 0x00000010, 0x00000002, + 0x000001e8, 0x00000000, 0x00000293, 0x00000010, 0x00000010, 0x00000002, 0x000001e8, 0x00000000, + 0x0000029a, 0x00000020, 0x00000010, 0x00000000, 0x000001e8, 0x00000000, 0x000002a0, 0x00000030, + 0x00000010, 0x00000000, 0x000001e8, 0x00000000, 0x000002a7, 0x00000040, 0x00000010, 0x00000002, + 0x000001e8, 0x00000000, 0x6d616c63, 0x63003070, 0x706d616c, 0x6f630031, 0x00726f6c, 0x6f6c6f63, + 0x74003272, 0x666f5f63, 0x694d0066, 0x736f7263, 0x2074666f, 0x20295228, 0x4c534c48, 0x61685320, + 0x20726564, 0x706d6f43, 0x72656c69, 0x322e3920, 0x35392e39, 0x31332e32, 0xab003131, 0x4e475349, + 0x00000050, 0x00000002, 0x00000008, 0x00000038, 0x00000000, 0x00000001, 0x00000003, 0x00000000, + 0x0000000f, 0x00000044, 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x0000030f, 0x505f5653, + 0x7469736f, 0x006e6f69, 0x43584554, 0x44524f4f, 0xababab00, 0x4e47534f, 0x0000002c, 0x00000001, + 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x0000000f, 0x545f5653, + 0x65677261, 0xabab0074, 0x52444853, 0x00000238, 0x00000040, 0x0000008e, 0x04000059, 0x00208e46, + 0x00000000, 0x00000001, 0x04000059, 0x00208e46, 0x00000001, 0x00000005, 0x0300005a, 0x00106000, + 0x00000000, 0x0300005a, 0x00106000, 0x00000001, 0x0300005a, 0x00106000, 0x00000002, 0x04001858, + 0x00107000, 0x00000000, 0x00005555, 0x04001858, 0x00107000, 0x00000001, 0x00005555, 0x04001858, + 0x00107000, 0x00000002, 0x00005555, 0x03001062, 0x00101032, 0x00000001, 0x03000065, 0x001020f2, + 0x00000000, 0x02000068, 0x00000002, 0x08000000, 0x00100032, 0x00000000, 0x00101046, 0x00000001, + 0x00208046, 0x00000001, 0x00000004, 0x08000034, 0x00100032, 0x00000000, 0x00100046, 0x00000000, + 0x00208046, 0x00000001, 0x00000000, 0x08000033, 0x00100032, 0x00000000, 0x00100046, 0x00000000, + 0x00208ae6, 0x00000001, 0x00000000, 0x09000045, 0x001000f2, 0x00000000, 0x00100046, 0x00000000, + 0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x08000038, 0x00100012, 0x00000000, 0x0010003a, + 0x00000000, 0x0020802a, 0x00000001, 0x00000004, 0x07000033, 0x00100012, 0x00000000, 0x0010000a, + 0x00000000, 0x00004001, 0x3f800000, 0x05000036, 0x00100022, 0x00000000, 0x00004001, 0x3f000000, + 0x09000045, 0x001000f2, 0x00000000, 0x00100046, 0x00000000, 0x00107e46, 0x00000002, 0x00106000, + 0x00000002, 0x08000034, 0x00100032, 0x00000001, 0x00101046, 0x00000001, 0x00208046, 0x00000001, + 0x00000001, 0x08000033, 0x00100032, 0x00000001, 0x00100046, 0x00000001, 0x00208ae6, 0x00000001, + 0x00000001, 0x09000045, 0x001000f2, 0x00000001, 0x00100046, 0x00000001, 0x00107e46, 0x00000001, + 0x00106000, 0x00000001, 0x08000000, 0x00100012, 0x00000001, 0x8010003a, 0x00000041, 0x00000001, + 0x00004001, 0x3f800000, 0x07000038, 0x001020f2, 0x00000000, 0x00100e46, 0x00000000, 0x00100006, + 0x00000001, 0x0100003e, 0x54415453, 0x00000074, 0x0000000e, 0x00000002, 0x00000000, 0x00000002, + 0x00000009, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, +}; + +static DWORD pshader_filter_4[402] = { + 0x43425844, 0x4c377bd9, 0xfb4c5258, 0xe793fa9d, 0xf685a588, 0x00000001, 0x00000648, 0x00000005, + 0x00000034, 0x000002d0, 0x00000328, 0x0000035c, 0x000005cc, 0x46454452, 0x00000294, 0x00000002, + 0x00000100, 0x00000006, 0x0000001c, 0xffff0400, 0x00008100, 0x00000262, 0x000000dc, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000000e3, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x000000ea, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000000, 0x00000001, 0x0000000d, 0x000000ef, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000001, 0x00000001, 0x0000000d, 0x000000f4, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000000f8, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x65745f73, 0x73003078, + 0x7865745f, 0x65740031, 0x74003078, 0x00317865, 0x00635350, 0x61726170, 0xababab00, 0x000000f4, + 0x00000004, 0x00000130, 0x00000040, 0x00000000, 0x00000000, 0x000000f8, 0x00000005, 0x000001c8, + 0x00000050, 0x00000000, 0x00000000, 0x00000190, 0x00000000, 0x00000010, 0x00000000, 0x0000019c, + 0x00000000, 0x000001ac, 0x00000010, 0x00000010, 0x00000000, 0x0000019c, 0x00000000, 0x000001b6, + 0x00000020, 0x00000010, 0x00000000, 0x0000019c, 0x00000000, 0x000001bc, 0x00000030, 0x00000010, + 0x00000000, 0x0000019c, 0x00000000, 0x6f6c6f63, 0x756d5f72, 0xabab006c, 0x00030001, 0x00040001, + 0x00000000, 0x00000000, 0x6f6c6f63, 0x64615f72, 0x6f660064, 0x006c6163, 0x63736572, 0x31656c61, + 0xababab00, 0x00000240, 0x00000000, 0x00000010, 0x00000002, 0x0000019c, 0x00000000, 0x00000247, + 0x00000010, 0x00000010, 0x00000002, 0x0000019c, 0x00000000, 0x0000024e, 0x00000020, 0x00000010, + 0x00000002, 0x0000019c, 0x00000000, 0x00000254, 0x00000030, 0x00000010, 0x00000000, 0x0000019c, + 0x00000000, 0x0000025b, 0x00000040, 0x00000010, 0x00000002, 0x0000019c, 0x00000000, 0x6d616c63, + 0x63003070, 0x706d616c, 0x6f630031, 0x00726f6c, 0x6f6c6f63, 0x74003272, 0x666f5f63, 0x694d0066, + 0x736f7263, 0x2074666f, 0x20295228, 0x4c534c48, 0x61685320, 0x20726564, 0x706d6f43, 0x72656c69, + 0x322e3920, 0x35392e39, 0x31332e32, 0xab003131, 0x4e475349, 0x00000050, 0x00000002, 0x00000008, + 0x00000038, 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x00000044, 0x00000000, + 0x00000000, 0x00000003, 0x00000001, 0x0000030f, 0x505f5653, 0x7469736f, 0x006e6f69, 0x43584554, + 0x44524f4f, 0xababab00, 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, + 0x00000000, 0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x52444853, + 0x00000268, 0x00000040, 0x0000009a, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x04000059, + 0x00208e46, 0x00000001, 0x00000005, 0x0300005a, 0x00106000, 0x00000000, 0x0300005a, 0x00106000, + 0x00000001, 0x04001858, 0x00107000, 0x00000000, 0x00005555, 0x04001858, 0x00107000, 0x00000001, + 0x00005555, 0x03001062, 0x00101032, 0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x02000068, + 0x00000002, 0x08000000, 0x00100032, 0x00000000, 0x00101046, 0x00000001, 0x00208046, 0x00000001, + 0x00000004, 0x08000034, 0x00100032, 0x00000000, 0x00100046, 0x00000000, 0x00208046, 0x00000001, + 0x00000000, 0x08000033, 0x00100032, 0x00000000, 0x00100046, 0x00000000, 0x00208ae6, 0x00000001, + 0x00000000, 0x09000045, 0x001000f2, 0x00000000, 0x00100046, 0x00000000, 0x00107e46, 0x00000000, + 0x00106000, 0x00000000, 0x08000000, 0x00100012, 0x00000000, 0x8010003a, 0x00000041, 0x00000000, + 0x00004001, 0x3f800000, 0x08000038, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0020802a, + 0x00000001, 0x00000004, 0x07000033, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x00004001, + 0x3f800000, 0x08000038, 0x001000e2, 0x00000000, 0x00100006, 0x00000000, 0x00208906, 0x00000001, + 0x00000002, 0x0b000032, 0x00100012, 0x00000000, 0x8020803a, 0x00000041, 0x00000001, 0x00000002, + 0x0010000a, 0x00000000, 0x00004001, 0x3f800000, 0x08000034, 0x00100032, 0x00000001, 0x00101046, + 0x00000001, 0x00208046, 0x00000001, 0x00000001, 0x08000033, 0x00100032, 0x00000001, 0x00100046, + 0x00000001, 0x00208ae6, 0x00000001, 0x00000001, 0x09000045, 0x001000f2, 0x00000001, 0x00100046, + 0x00000001, 0x00107e46, 0x00000001, 0x00106000, 0x00000001, 0x07000038, 0x00100072, 0x00000001, + 0x00100006, 0x00000000, 0x00100246, 0x00000001, 0x09000032, 0x00102072, 0x00000000, 0x00100796, + 0x00000000, 0x00100ff6, 0x00000001, 0x00100246, 0x00000001, 0x05000036, 0x00102082, 0x00000000, + 0x0010003a, 0x00000001, 0x0100003e, 0x54415453, 0x00000074, 0x00000010, 0x00000002, 0x00000000, + 0x00000002, 0x0000000a, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, +}; + +static DWORD pshader_filter_5[377] = { + 0x43425844, 0x9ff592ef, 0xe7109a8c, 0xc01f276d, 0x73f691c7, 0x00000001, 0x000005e4, 0x00000005, + 0x00000034, 0x000002d0, 0x00000328, 0x0000035c, 0x00000568, 0x46454452, 0x00000294, 0x00000002, + 0x00000100, 0x00000006, 0x0000001c, 0xffff0400, 0x00008100, 0x00000262, 0x000000dc, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000000e3, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x000000ea, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000000, 0x00000001, 0x0000000d, 0x000000ef, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000001, 0x00000001, 0x0000000d, 0x000000f4, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000000f8, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x65745f73, 0x73003078, + 0x7865745f, 0x65740031, 0x74003078, 0x00317865, 0x00635350, 0x61726170, 0xababab00, 0x000000f4, + 0x00000004, 0x00000130, 0x00000040, 0x00000000, 0x00000000, 0x000000f8, 0x00000005, 0x000001c8, + 0x00000050, 0x00000000, 0x00000000, 0x00000190, 0x00000000, 0x00000010, 0x00000000, 0x0000019c, + 0x00000000, 0x000001ac, 0x00000010, 0x00000010, 0x00000000, 0x0000019c, 0x00000000, 0x000001b6, + 0x00000020, 0x00000010, 0x00000000, 0x0000019c, 0x00000000, 0x000001bc, 0x00000030, 0x00000010, + 0x00000000, 0x0000019c, 0x00000000, 0x6f6c6f63, 0x756d5f72, 0xabab006c, 0x00030001, 0x00040001, + 0x00000000, 0x00000000, 0x6f6c6f63, 0x64615f72, 0x6f660064, 0x006c6163, 0x63736572, 0x31656c61, + 0xababab00, 0x00000240, 0x00000000, 0x00000010, 0x00000002, 0x0000019c, 0x00000000, 0x00000247, + 0x00000010, 0x00000010, 0x00000002, 0x0000019c, 0x00000000, 0x0000024e, 0x00000020, 0x00000010, + 0x00000002, 0x0000019c, 0x00000000, 0x00000254, 0x00000030, 0x00000010, 0x00000000, 0x0000019c, + 0x00000000, 0x0000025b, 0x00000040, 0x00000010, 0x00000002, 0x0000019c, 0x00000000, 0x6d616c63, + 0x63003070, 0x706d616c, 0x6f630031, 0x00726f6c, 0x6f6c6f63, 0x74003272, 0x666f5f63, 0x694d0066, + 0x736f7263, 0x2074666f, 0x20295228, 0x4c534c48, 0x61685320, 0x20726564, 0x706d6f43, 0x72656c69, + 0x322e3920, 0x35392e39, 0x31332e32, 0xab003131, 0x4e475349, 0x00000050, 0x00000002, 0x00000008, + 0x00000038, 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x00000044, 0x00000000, + 0x00000000, 0x00000003, 0x00000001, 0x0000030f, 0x505f5653, 0x7469736f, 0x006e6f69, 0x43584554, + 0x44524f4f, 0xababab00, 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, + 0x00000000, 0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x52444853, + 0x00000204, 0x00000040, 0x00000081, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x04000059, + 0x00208e46, 0x00000001, 0x00000005, 0x0300005a, 0x00106000, 0x00000000, 0x0300005a, 0x00106000, + 0x00000001, 0x04001858, 0x00107000, 0x00000000, 0x00005555, 0x04001858, 0x00107000, 0x00000001, + 0x00005555, 0x03001062, 0x00101032, 0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x02000068, + 0x00000002, 0x08000000, 0x00100032, 0x00000000, 0x00101046, 0x00000001, 0x00208046, 0x00000001, + 0x00000004, 0x08000034, 0x00100032, 0x00000000, 0x00100046, 0x00000000, 0x00208046, 0x00000001, + 0x00000000, 0x08000033, 0x00100032, 0x00000000, 0x00100046, 0x00000000, 0x00208ae6, 0x00000001, + 0x00000000, 0x09000045, 0x001000f2, 0x00000000, 0x00100046, 0x00000000, 0x00107e46, 0x00000000, + 0x00106000, 0x00000000, 0x08000000, 0x00100012, 0x00000000, 0x8010003a, 0x00000041, 0x00000000, + 0x00004001, 0x3f800000, 0x08000038, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0020802a, + 0x00000001, 0x00000004, 0x07000033, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x00004001, + 0x3f800000, 0x08000034, 0x00100062, 0x00000000, 0x00101106, 0x00000001, 0x00208106, 0x00000001, + 0x00000001, 0x08000033, 0x00100062, 0x00000000, 0x00100656, 0x00000000, 0x00208ba6, 0x00000001, + 0x00000001, 0x09000045, 0x001000f2, 0x00000001, 0x00100596, 0x00000000, 0x00107e46, 0x00000001, + 0x00106000, 0x00000001, 0x08000038, 0x001000f2, 0x00000001, 0x00100ff6, 0x00000001, 0x00208e46, + 0x00000001, 0x00000002, 0x07000038, 0x001020f2, 0x00000000, 0x00100006, 0x00000000, 0x00100e46, + 0x00000001, 0x0100003e, 0x54415453, 0x00000074, 0x0000000d, 0x00000002, 0x00000000, 0x00000002, + 0x0000000a, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, +}; + +static DWORD pshader_filter_6[423] = { + 0x43425844, 0x5360f80d, 0x54f4e830, 0xa8cabb2e, 0x51c8fc74, 0x00000001, 0x0000069c, 0x00000005, + 0x00000034, 0x0000031c, 0x00000374, 0x000003a8, 0x00000620, 0x46454452, 0x000002e0, 0x00000002, + 0x0000014c, 0x00000008, 0x0000001c, 0xffff0400, 0x00008100, 0x000002ae, 0x0000011c, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000123, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x0000012a, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0x00000001, 0x00000001, 0x00000131, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000000, 0x00000001, 0x0000000d, 0x00000136, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000001, 0x00000001, 0x0000000d, 0x0000013b, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000002, 0x00000001, 0x0000000d, 0x00000140, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000144, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x65745f73, 0x73003078, + 0x7865745f, 0x5f730031, 0x32786574, 0x78657400, 0x65740030, 0x74003178, 0x00327865, 0x00635350, + 0x61726170, 0xababab00, 0x00000140, 0x00000004, 0x0000017c, 0x00000040, 0x00000000, 0x00000000, + 0x00000144, 0x00000005, 0x00000214, 0x00000050, 0x00000000, 0x00000000, 0x000001dc, 0x00000000, + 0x00000010, 0x00000000, 0x000001e8, 0x00000000, 0x000001f8, 0x00000010, 0x00000010, 0x00000000, + 0x000001e8, 0x00000000, 0x00000202, 0x00000020, 0x00000010, 0x00000000, 0x000001e8, 0x00000000, + 0x00000208, 0x00000030, 0x00000010, 0x00000000, 0x000001e8, 0x00000000, 0x6f6c6f63, 0x756d5f72, + 0xabab006c, 0x00030001, 0x00040001, 0x00000000, 0x00000000, 0x6f6c6f63, 0x64615f72, 0x6f660064, + 0x006c6163, 0x63736572, 0x31656c61, 0xababab00, 0x0000028c, 0x00000000, 0x00000010, 0x00000002, + 0x000001e8, 0x00000000, 0x00000293, 0x00000010, 0x00000010, 0x00000002, 0x000001e8, 0x00000000, + 0x0000029a, 0x00000020, 0x00000010, 0x00000000, 0x000001e8, 0x00000000, 0x000002a0, 0x00000030, + 0x00000010, 0x00000000, 0x000001e8, 0x00000000, 0x000002a7, 0x00000040, 0x00000010, 0x00000002, + 0x000001e8, 0x00000000, 0x6d616c63, 0x63003070, 0x706d616c, 0x6f630031, 0x00726f6c, 0x6f6c6f63, + 0x74003272, 0x666f5f63, 0x694d0066, 0x736f7263, 0x2074666f, 0x20295228, 0x4c534c48, 0x61685320, + 0x20726564, 0x706d6f43, 0x72656c69, 0x322e3920, 0x35392e39, 0x31332e32, 0xab003131, 0x4e475349, + 0x00000050, 0x00000002, 0x00000008, 0x00000038, 0x00000000, 0x00000001, 0x00000003, 0x00000000, + 0x0000000f, 0x00000044, 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x0000030f, 0x505f5653, + 0x7469736f, 0x006e6f69, 0x43584554, 0x44524f4f, 0xababab00, 0x4e47534f, 0x0000002c, 0x00000001, + 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x0000000f, 0x545f5653, + 0x65677261, 0xabab0074, 0x52444853, 0x00000270, 0x00000040, 0x0000009c, 0x04000059, 0x00208e46, + 0x00000000, 0x00000001, 0x04000059, 0x00208e46, 0x00000001, 0x00000005, 0x0300005a, 0x00106000, + 0x00000000, 0x0300005a, 0x00106000, 0x00000001, 0x0300005a, 0x00106000, 0x00000002, 0x04001858, + 0x00107000, 0x00000000, 0x00005555, 0x04001858, 0x00107000, 0x00000001, 0x00005555, 0x04001858, + 0x00107000, 0x00000002, 0x00005555, 0x03001062, 0x00101032, 0x00000001, 0x03000065, 0x001020f2, + 0x00000000, 0x02000068, 0x00000002, 0x08000000, 0x00100032, 0x00000000, 0x00101046, 0x00000001, + 0x00208046, 0x00000001, 0x00000004, 0x08000034, 0x00100032, 0x00000000, 0x00100046, 0x00000000, + 0x00208046, 0x00000001, 0x00000000, 0x08000033, 0x00100032, 0x00000000, 0x00100046, 0x00000000, + 0x00208ae6, 0x00000001, 0x00000000, 0x09000045, 0x001000f2, 0x00000000, 0x00100046, 0x00000000, + 0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x08000038, 0x00100012, 0x00000000, 0x0010003a, + 0x00000000, 0x0020802a, 0x00000001, 0x00000004, 0x07000033, 0x00100012, 0x00000000, 0x0010000a, + 0x00000000, 0x00004001, 0x3f800000, 0x05000036, 0x00100022, 0x00000000, 0x00004001, 0x3f000000, + 0x09000045, 0x001000f2, 0x00000000, 0x00100046, 0x00000000, 0x00107e46, 0x00000002, 0x00106000, + 0x00000002, 0x08000000, 0x00100082, 0x00000000, 0x8010003a, 0x00000041, 0x00000000, 0x00004001, + 0x3f800000, 0x08000034, 0x00100032, 0x00000001, 0x00101046, 0x00000001, 0x00208046, 0x00000001, + 0x00000001, 0x08000033, 0x00100032, 0x00000001, 0x00100046, 0x00000001, 0x00208ae6, 0x00000001, + 0x00000001, 0x09000045, 0x001000f2, 0x00000001, 0x00100046, 0x00000001, 0x00107e46, 0x00000001, + 0x00106000, 0x00000001, 0x07000038, 0x00100072, 0x00000001, 0x00100ff6, 0x00000000, 0x00100246, + 0x00000001, 0x09000032, 0x00102072, 0x00000000, 0x00100246, 0x00000000, 0x00100ff6, 0x00000001, + 0x00100246, 0x00000001, 0x05000036, 0x00102082, 0x00000000, 0x0010003a, 0x00000001, 0x0100003e, + 0x54415453, 0x00000074, 0x00000010, 0x00000002, 0x00000000, 0x00000002, 0x00000009, 0x00000000, + 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000003, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +}; + +static DWORD pshader_filter_7[401] = { + 0x43425844, 0x0439e6c7, 0xa22f2670, 0x44e3f549, 0xd957dde0, 0x00000001, 0x00000644, 0x00000005, + 0x00000034, 0x0000031c, 0x00000374, 0x000003a8, 0x000005c8, 0x46454452, 0x000002e0, 0x00000002, + 0x0000014c, 0x00000008, 0x0000001c, 0xffff0400, 0x00008100, 0x000002ae, 0x0000011c, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000123, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x0000012a, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0x00000001, 0x00000001, 0x00000131, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000000, 0x00000001, 0x0000000d, 0x00000136, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000001, 0x00000001, 0x0000000d, 0x0000013b, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000002, 0x00000001, 0x0000000d, 0x00000140, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000144, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x65745f73, 0x73003078, + 0x7865745f, 0x5f730031, 0x32786574, 0x78657400, 0x65740030, 0x74003178, 0x00327865, 0x00635350, + 0x61726170, 0xababab00, 0x00000140, 0x00000004, 0x0000017c, 0x00000040, 0x00000000, 0x00000000, + 0x00000144, 0x00000005, 0x00000214, 0x00000050, 0x00000000, 0x00000000, 0x000001dc, 0x00000000, + 0x00000010, 0x00000000, 0x000001e8, 0x00000000, 0x000001f8, 0x00000010, 0x00000010, 0x00000000, + 0x000001e8, 0x00000000, 0x00000202, 0x00000020, 0x00000010, 0x00000000, 0x000001e8, 0x00000000, + 0x00000208, 0x00000030, 0x00000010, 0x00000000, 0x000001e8, 0x00000000, 0x6f6c6f63, 0x756d5f72, + 0xabab006c, 0x00030001, 0x00040001, 0x00000000, 0x00000000, 0x6f6c6f63, 0x64615f72, 0x6f660064, + 0x006c6163, 0x63736572, 0x31656c61, 0xababab00, 0x0000028c, 0x00000000, 0x00000010, 0x00000002, + 0x000001e8, 0x00000000, 0x00000293, 0x00000010, 0x00000010, 0x00000002, 0x000001e8, 0x00000000, + 0x0000029a, 0x00000020, 0x00000010, 0x00000000, 0x000001e8, 0x00000000, 0x000002a0, 0x00000030, + 0x00000010, 0x00000000, 0x000001e8, 0x00000000, 0x000002a7, 0x00000040, 0x00000010, 0x00000002, + 0x000001e8, 0x00000000, 0x6d616c63, 0x63003070, 0x706d616c, 0x6f630031, 0x00726f6c, 0x6f6c6f63, + 0x74003272, 0x666f5f63, 0x694d0066, 0x736f7263, 0x2074666f, 0x20295228, 0x4c534c48, 0x61685320, + 0x20726564, 0x706d6f43, 0x72656c69, 0x322e3920, 0x35392e39, 0x31332e32, 0xab003131, 0x4e475349, + 0x00000050, 0x00000002, 0x00000008, 0x00000038, 0x00000000, 0x00000001, 0x00000003, 0x00000000, + 0x0000000f, 0x00000044, 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x0000030f, 0x505f5653, + 0x7469736f, 0x006e6f69, 0x43584554, 0x44524f4f, 0xababab00, 0x4e47534f, 0x0000002c, 0x00000001, + 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x0000000f, 0x545f5653, + 0x65677261, 0xabab0074, 0x52444853, 0x00000218, 0x00000040, 0x00000086, 0x04000059, 0x00208e46, + 0x00000000, 0x00000001, 0x04000059, 0x00208e46, 0x00000001, 0x00000005, 0x0300005a, 0x00106000, + 0x00000000, 0x0300005a, 0x00106000, 0x00000001, 0x0300005a, 0x00106000, 0x00000002, 0x04001858, + 0x00107000, 0x00000000, 0x00005555, 0x04001858, 0x00107000, 0x00000001, 0x00005555, 0x04001858, + 0x00107000, 0x00000002, 0x00005555, 0x03001062, 0x00101032, 0x00000001, 0x03000065, 0x001020f2, + 0x00000000, 0x02000068, 0x00000002, 0x08000000, 0x00100032, 0x00000000, 0x00101046, 0x00000001, + 0x00208046, 0x00000001, 0x00000004, 0x08000034, 0x00100032, 0x00000000, 0x00100046, 0x00000000, + 0x00208046, 0x00000001, 0x00000000, 0x08000033, 0x00100032, 0x00000000, 0x00100046, 0x00000000, + 0x00208ae6, 0x00000001, 0x00000000, 0x09000045, 0x001000f2, 0x00000000, 0x00100046, 0x00000000, + 0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x08000038, 0x00100012, 0x00000000, 0x0010003a, + 0x00000000, 0x0020802a, 0x00000001, 0x00000004, 0x07000033, 0x00100012, 0x00000000, 0x0010000a, + 0x00000000, 0x00004001, 0x3f800000, 0x05000036, 0x00100022, 0x00000000, 0x00004001, 0x3f000000, + 0x09000045, 0x001000f2, 0x00000000, 0x00100046, 0x00000000, 0x00107e46, 0x00000002, 0x00106000, + 0x00000002, 0x08000034, 0x00100032, 0x00000001, 0x00101046, 0x00000001, 0x00208046, 0x00000001, + 0x00000001, 0x08000033, 0x00100032, 0x00000001, 0x00100046, 0x00000001, 0x00208ae6, 0x00000001, + 0x00000001, 0x09000045, 0x001000f2, 0x00000001, 0x00100046, 0x00000001, 0x00107e46, 0x00000001, + 0x00106000, 0x00000001, 0x07000038, 0x001020f2, 0x00000000, 0x00100e46, 0x00000000, 0x00100ff6, + 0x00000001, 0x0100003e, 0x54415453, 0x00000074, 0x0000000d, 0x00000002, 0x00000000, 0x00000002, + 0x00000008, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, +}; + +static DWORD pshader_filter_8[246] = { + 0x43425844, 0xd318033e, 0x780e8795, 0xb2e4d27b, 0x11bd4a8f, 0x00000001, 0x000003d8, 0x00000005, + 0x00000034, 0x000001c0, 0x00000218, 0x0000024c, 0x0000035c, 0x46454452, 0x00000184, 0x00000001, + 0x00000090, 0x00000003, 0x0000001c, 0xffff0400, 0x00008100, 0x00000153, 0x0000007c, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000083, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000001, 0x00000001, 0x0000000d, 0x00000088, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x65745f73, 0x74003178, + 0x00317865, 0x61726170, 0xababab00, 0x00000088, 0x00000005, 0x000000a8, 0x00000050, 0x00000000, + 0x00000000, 0x00000120, 0x00000000, 0x00000010, 0x00000000, 0x00000128, 0x00000000, 0x00000138, + 0x00000010, 0x00000010, 0x00000002, 0x00000128, 0x00000000, 0x0000013f, 0x00000020, 0x00000010, + 0x00000002, 0x00000128, 0x00000000, 0x00000145, 0x00000030, 0x00000010, 0x00000000, 0x00000128, + 0x00000000, 0x0000014c, 0x00000040, 0x00000010, 0x00000000, 0x00000128, 0x00000000, 0x6d616c63, + 0xab003070, 0x00030001, 0x00040001, 0x00000000, 0x00000000, 0x6d616c63, 0x63003170, 0x726f6c6f, + 0x6c6f6300, 0x0032726f, 0x6f5f6374, 0x4d006666, 0x6f726369, 0x74666f73, 0x29522820, 0x534c4820, + 0x6853204c, 0x72656461, 0x6d6f4320, 0x656c6970, 0x2e392072, 0x392e3932, 0x332e3235, 0x00313131, + 0x4e475349, 0x00000050, 0x00000002, 0x00000008, 0x00000038, 0x00000000, 0x00000001, 0x00000003, + 0x00000000, 0x0000000f, 0x00000044, 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x0000030f, + 0x505f5653, 0x7469736f, 0x006e6f69, 0x43584554, 0x44524f4f, 0xababab00, 0x4e47534f, 0x0000002c, + 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x0000000f, + 0x545f5653, 0x65677261, 0xabab0074, 0x52444853, 0x00000108, 0x00000040, 0x00000042, 0x04000059, + 0x00208e46, 0x00000001, 0x00000003, 0x0300005a, 0x00106000, 0x00000001, 0x04001858, 0x00107000, + 0x00000001, 0x00005555, 0x03001062, 0x00101032, 0x00000001, 0x03000065, 0x001020f2, 0x00000000, + 0x02000068, 0x00000002, 0x08000034, 0x00100032, 0x00000000, 0x00101046, 0x00000001, 0x00208046, + 0x00000001, 0x00000001, 0x08000033, 0x00100032, 0x00000000, 0x00100046, 0x00000000, 0x00208ae6, + 0x00000001, 0x00000001, 0x09000045, 0x001000f2, 0x00000000, 0x00100046, 0x00000000, 0x00107e46, + 0x00000001, 0x00106000, 0x00000001, 0x09000000, 0x00100012, 0x00000001, 0x8020803a, 0x00000041, + 0x00000001, 0x00000002, 0x00004001, 0x3f800000, 0x0a000032, 0x001020f2, 0x00000000, 0x00100e46, + 0x00000000, 0x00100006, 0x00000001, 0x00208e46, 0x00000001, 0x00000002, 0x0100003e, 0x54415453, + 0x00000074, 0x00000006, 0x00000002, 0x00000000, 0x00000002, 0x00000003, 0x00000000, 0x00000000, + 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +}; + +static DWORD pshader_filter_9[177] = { + 0x43425844, 0x6be5959a, 0xfbf9f786, 0x3ad2a2c2, 0xed03ea11, 0x00000001, 0x000002c4, 0x00000005, + 0x00000034, 0x00000174, 0x000001cc, 0x00000200, 0x00000248, 0x46454452, 0x00000138, 0x00000001, + 0x00000044, 0x00000001, 0x0000001c, 0xffff0400, 0x00008100, 0x00000107, 0x0000003c, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x61726170, 0xababab00, + 0x0000003c, 0x00000005, 0x0000005c, 0x00000050, 0x00000000, 0x00000000, 0x000000d4, 0x00000000, + 0x00000010, 0x00000000, 0x000000dc, 0x00000000, 0x000000ec, 0x00000010, 0x00000010, 0x00000000, + 0x000000dc, 0x00000000, 0x000000f3, 0x00000020, 0x00000010, 0x00000002, 0x000000dc, 0x00000000, + 0x000000f9, 0x00000030, 0x00000010, 0x00000000, 0x000000dc, 0x00000000, 0x00000100, 0x00000040, + 0x00000010, 0x00000000, 0x000000dc, 0x00000000, 0x6d616c63, 0xab003070, 0x00030001, 0x00040001, + 0x00000000, 0x00000000, 0x6d616c63, 0x63003170, 0x726f6c6f, 0x6c6f6300, 0x0032726f, 0x6f5f6374, + 0x4d006666, 0x6f726369, 0x74666f73, 0x29522820, 0x534c4820, 0x6853204c, 0x72656461, 0x6d6f4320, + 0x656c6970, 0x2e392072, 0x392e3932, 0x332e3235, 0x00313131, 0x4e475349, 0x00000050, 0x00000002, + 0x00000008, 0x00000038, 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x00000044, + 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x0000000f, 0x505f5653, 0x7469736f, 0x006e6f69, + 0x43584554, 0x44524f4f, 0xababab00, 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, + 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, + 0x52444853, 0x00000040, 0x00000040, 0x00000010, 0x04000059, 0x00208e46, 0x00000001, 0x00000003, + 0x03000065, 0x001020f2, 0x00000000, 0x06000036, 0x001020f2, 0x00000000, 0x00208e46, 0x00000001, + 0x00000002, 0x0100003e, 0x54415453, 0x00000074, 0x00000002, 0x00000000, 0x00000000, 0x00000001, + 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, +}; + +static DWORD pshader_filter_10[411] = { + 0x43425844, 0x06c32e7c, 0xd1fa07e2, 0x2d208e5f, 0x5002e2cc, 0x00000001, 0x0000066c, 0x00000005, + 0x00000034, 0x0000031c, 0x00000374, 0x000003a8, 0x000005f0, 0x46454452, 0x000002e0, 0x00000002, + 0x0000014c, 0x00000008, 0x0000001c, 0xffff0400, 0x00008100, 0x000002ae, 0x0000011c, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000123, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x0000012a, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0x00000001, 0x00000001, 0x00000131, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000000, 0x00000001, 0x0000000d, 0x00000136, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000001, 0x00000001, 0x0000000d, 0x0000013b, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000002, 0x00000001, 0x0000000d, 0x00000140, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000144, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x65745f73, 0x73003078, + 0x7865745f, 0x5f730031, 0x32786574, 0x78657400, 0x65740030, 0x74003178, 0x00327865, 0x00635350, + 0x61726170, 0xababab00, 0x00000140, 0x00000004, 0x0000017c, 0x00000040, 0x00000000, 0x00000000, + 0x00000144, 0x00000005, 0x00000214, 0x00000050, 0x00000000, 0x00000000, 0x000001dc, 0x00000000, + 0x00000010, 0x00000000, 0x000001e8, 0x00000000, 0x000001f8, 0x00000010, 0x00000010, 0x00000000, + 0x000001e8, 0x00000000, 0x00000202, 0x00000020, 0x00000010, 0x00000000, 0x000001e8, 0x00000000, + 0x00000208, 0x00000030, 0x00000010, 0x00000000, 0x000001e8, 0x00000000, 0x6f6c6f63, 0x756d5f72, + 0xabab006c, 0x00030001, 0x00040001, 0x00000000, 0x00000000, 0x6f6c6f63, 0x64615f72, 0x6f660064, + 0x006c6163, 0x63736572, 0x31656c61, 0xababab00, 0x0000028c, 0x00000000, 0x00000010, 0x00000002, + 0x000001e8, 0x00000000, 0x00000293, 0x00000010, 0x00000010, 0x00000002, 0x000001e8, 0x00000000, + 0x0000029a, 0x00000020, 0x00000010, 0x00000000, 0x000001e8, 0x00000000, 0x000002a0, 0x00000030, + 0x00000010, 0x00000000, 0x000001e8, 0x00000000, 0x000002a7, 0x00000040, 0x00000010, 0x00000002, + 0x000001e8, 0x00000000, 0x6d616c63, 0x63003070, 0x706d616c, 0x6f630031, 0x00726f6c, 0x6f6c6f63, + 0x74003272, 0x666f5f63, 0x694d0066, 0x736f7263, 0x2074666f, 0x20295228, 0x4c534c48, 0x61685320, + 0x20726564, 0x706d6f43, 0x72656c69, 0x322e3920, 0x35392e39, 0x31332e32, 0xab003131, 0x4e475349, + 0x00000050, 0x00000002, 0x00000008, 0x00000038, 0x00000000, 0x00000001, 0x00000003, 0x00000000, + 0x0000000f, 0x00000044, 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x0000030f, 0x505f5653, + 0x7469736f, 0x006e6f69, 0x43584554, 0x44524f4f, 0xababab00, 0x4e47534f, 0x0000002c, 0x00000001, + 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x0000000f, 0x545f5653, + 0x65677261, 0xabab0074, 0x52444853, 0x00000240, 0x00000040, 0x00000090, 0x04000059, 0x00208e46, + 0x00000000, 0x00000001, 0x04000059, 0x00208e46, 0x00000001, 0x00000005, 0x0300005a, 0x00106000, + 0x00000000, 0x0300005a, 0x00106000, 0x00000001, 0x0300005a, 0x00106000, 0x00000002, 0x04001858, + 0x00107000, 0x00000000, 0x00005555, 0x04001858, 0x00107000, 0x00000001, 0x00005555, 0x04001858, + 0x00107000, 0x00000002, 0x00005555, 0x03001062, 0x00101032, 0x00000001, 0x03000065, 0x001020f2, + 0x00000000, 0x02000068, 0x00000003, 0x08000000, 0x00100032, 0x00000000, 0x00101046, 0x00000001, + 0x00208046, 0x00000001, 0x00000004, 0x08000034, 0x00100032, 0x00000000, 0x00100046, 0x00000000, + 0x00208046, 0x00000001, 0x00000000, 0x08000033, 0x00100032, 0x00000000, 0x00100046, 0x00000000, + 0x00208ae6, 0x00000001, 0x00000000, 0x09000045, 0x001000f2, 0x00000000, 0x00100046, 0x00000000, + 0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x08000038, 0x00100012, 0x00000000, 0x0010003a, + 0x00000000, 0x0020802a, 0x00000001, 0x00000004, 0x07000033, 0x00100012, 0x00000000, 0x0010000a, + 0x00000000, 0x00004001, 0x3f800000, 0x05000036, 0x00100022, 0x00000000, 0x00004001, 0x3f000000, + 0x09000045, 0x001000f2, 0x00000000, 0x00100046, 0x00000000, 0x00107e46, 0x00000002, 0x00106000, + 0x00000002, 0x08000000, 0x00100012, 0x00000001, 0x8010003a, 0x00000041, 0x00000000, 0x00004001, + 0x3f800000, 0x08000034, 0x00100062, 0x00000001, 0x00101106, 0x00000001, 0x00208106, 0x00000001, + 0x00000001, 0x08000033, 0x00100062, 0x00000001, 0x00100656, 0x00000001, 0x00208ba6, 0x00000001, + 0x00000001, 0x09000045, 0x001000f2, 0x00000002, 0x00100596, 0x00000001, 0x00107e46, 0x00000001, + 0x00106000, 0x00000001, 0x09000032, 0x001020f2, 0x00000000, 0x00100e46, 0x00000002, 0x00100006, + 0x00000001, 0x00100e46, 0x00000000, 0x0100003e, 0x54415453, 0x00000074, 0x0000000e, 0x00000003, + 0x00000000, 0x00000002, 0x00000008, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, +}; + +static DWORD pshader_filter_11[343] = { + 0x43425844, 0xba36eafb, 0x7eb5939c, 0xf32591ec, 0x30eeb32a, 0x00000001, 0x0000055c, 0x00000005, + 0x00000034, 0x000002d0, 0x00000328, 0x0000035c, 0x000004e0, 0x46454452, 0x00000294, 0x00000002, + 0x00000100, 0x00000006, 0x0000001c, 0xffff0400, 0x00008100, 0x00000262, 0x000000dc, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000000e3, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0x00000001, 0x00000001, 0x000000ea, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000000, 0x00000001, 0x0000000d, 0x000000ef, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000002, 0x00000001, 0x0000000d, 0x000000f4, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000000f8, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x65745f73, 0x73003078, + 0x7865745f, 0x65740032, 0x74003078, 0x00327865, 0x00635350, 0x61726170, 0xababab00, 0x000000f4, + 0x00000004, 0x00000130, 0x00000040, 0x00000000, 0x00000000, 0x000000f8, 0x00000005, 0x000001c8, + 0x00000050, 0x00000000, 0x00000000, 0x00000190, 0x00000000, 0x00000010, 0x00000000, 0x0000019c, + 0x00000000, 0x000001ac, 0x00000010, 0x00000010, 0x00000000, 0x0000019c, 0x00000000, 0x000001b6, + 0x00000020, 0x00000010, 0x00000000, 0x0000019c, 0x00000000, 0x000001bc, 0x00000030, 0x00000010, + 0x00000000, 0x0000019c, 0x00000000, 0x6f6c6f63, 0x756d5f72, 0xabab006c, 0x00030001, 0x00040001, + 0x00000000, 0x00000000, 0x6f6c6f63, 0x64615f72, 0x6f660064, 0x006c6163, 0x63736572, 0x31656c61, + 0xababab00, 0x00000240, 0x00000000, 0x00000010, 0x00000002, 0x0000019c, 0x00000000, 0x00000247, + 0x00000010, 0x00000010, 0x00000000, 0x0000019c, 0x00000000, 0x0000024e, 0x00000020, 0x00000010, + 0x00000000, 0x0000019c, 0x00000000, 0x00000254, 0x00000030, 0x00000010, 0x00000000, 0x0000019c, + 0x00000000, 0x0000025b, 0x00000040, 0x00000010, 0x00000002, 0x0000019c, 0x00000000, 0x6d616c63, + 0x63003070, 0x706d616c, 0x6f630031, 0x00726f6c, 0x6f6c6f63, 0x74003272, 0x666f5f63, 0x694d0066, + 0x736f7263, 0x2074666f, 0x20295228, 0x4c534c48, 0x61685320, 0x20726564, 0x706d6f43, 0x72656c69, + 0x322e3920, 0x35392e39, 0x31332e32, 0xab003131, 0x4e475349, 0x00000050, 0x00000002, 0x00000008, + 0x00000038, 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x00000044, 0x00000000, + 0x00000000, 0x00000003, 0x00000001, 0x0000030f, 0x505f5653, 0x7469736f, 0x006e6f69, 0x43584554, + 0x44524f4f, 0xababab00, 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, + 0x00000000, 0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x52444853, + 0x0000017c, 0x00000040, 0x0000005f, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x04000059, + 0x00208e46, 0x00000001, 0x00000005, 0x0300005a, 0x00106000, 0x00000000, 0x0300005a, 0x00106000, + 0x00000002, 0x04001858, 0x00107000, 0x00000000, 0x00005555, 0x04001858, 0x00107000, 0x00000002, + 0x00005555, 0x03001062, 0x00101032, 0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x02000068, + 0x00000001, 0x08000000, 0x00100032, 0x00000000, 0x00101046, 0x00000001, 0x00208046, 0x00000001, + 0x00000004, 0x08000034, 0x00100032, 0x00000000, 0x00100046, 0x00000000, 0x00208046, 0x00000001, + 0x00000000, 0x08000033, 0x00100032, 0x00000000, 0x00100046, 0x00000000, 0x00208ae6, 0x00000001, + 0x00000000, 0x09000045, 0x001000f2, 0x00000000, 0x00100046, 0x00000000, 0x00107e46, 0x00000000, + 0x00106000, 0x00000000, 0x08000038, 0x00100012, 0x00000000, 0x0010003a, 0x00000000, 0x0020802a, + 0x00000001, 0x00000004, 0x07000033, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x00004001, + 0x3f800000, 0x05000036, 0x00100022, 0x00000000, 0x00004001, 0x3f000000, 0x09000045, 0x001020f2, + 0x00000000, 0x00100046, 0x00000000, 0x00107e46, 0x00000002, 0x00106000, 0x00000002, 0x0100003e, + 0x54415453, 0x00000074, 0x00000009, 0x00000001, 0x00000000, 0x00000002, 0x00000005, 0x00000000, + 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +}; + +static DWORD pshader_filter_16[435] = { + 0x43425844, 0x6063564a, 0xa8def096, 0xcca0d8e9, 0xfad099ba, 0x00000001, 0x000006cc, 0x00000005, + 0x00000034, 0x000002d0, 0x00000328, 0x0000035c, 0x00000650, 0x46454452, 0x00000294, 0x00000002, + 0x00000100, 0x00000006, 0x0000001c, 0xffff0400, 0x00008100, 0x00000262, 0x000000dc, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000000e3, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x000000ea, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000000, 0x00000001, 0x0000000d, 0x000000ef, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000001, 0x00000001, 0x0000000d, 0x000000f4, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000000f8, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x65745f73, 0x73003078, + 0x7865745f, 0x65740031, 0x74003078, 0x00317865, 0x00635350, 0x61726170, 0xababab00, 0x000000f4, + 0x00000004, 0x00000130, 0x00000040, 0x00000000, 0x00000000, 0x000000f8, 0x00000005, 0x000001c8, + 0x00000050, 0x00000000, 0x00000000, 0x00000190, 0x00000000, 0x00000010, 0x00000000, 0x0000019c, + 0x00000000, 0x000001ac, 0x00000010, 0x00000010, 0x00000000, 0x0000019c, 0x00000000, 0x000001b6, + 0x00000020, 0x00000010, 0x00000000, 0x0000019c, 0x00000000, 0x000001bc, 0x00000030, 0x00000010, + 0x00000000, 0x0000019c, 0x00000000, 0x6f6c6f63, 0x756d5f72, 0xabab006c, 0x00030001, 0x00040001, + 0x00000000, 0x00000000, 0x6f6c6f63, 0x64615f72, 0x6f660064, 0x006c6163, 0x63736572, 0x31656c61, + 0xababab00, 0x00000240, 0x00000000, 0x00000010, 0x00000002, 0x0000019c, 0x00000000, 0x00000247, + 0x00000010, 0x00000010, 0x00000002, 0x0000019c, 0x00000000, 0x0000024e, 0x00000020, 0x00000010, + 0x00000002, 0x0000019c, 0x00000000, 0x00000254, 0x00000030, 0x00000010, 0x00000002, 0x0000019c, + 0x00000000, 0x0000025b, 0x00000040, 0x00000010, 0x00000002, 0x0000019c, 0x00000000, 0x6d616c63, + 0x63003070, 0x706d616c, 0x6f630031, 0x00726f6c, 0x6f6c6f63, 0x74003272, 0x666f5f63, 0x694d0066, + 0x736f7263, 0x2074666f, 0x20295228, 0x4c534c48, 0x61685320, 0x20726564, 0x706d6f43, 0x72656c69, + 0x322e3920, 0x35392e39, 0x31332e32, 0xab003131, 0x4e475349, 0x00000050, 0x00000002, 0x00000008, + 0x00000038, 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x00000044, 0x00000000, + 0x00000000, 0x00000003, 0x00000001, 0x0000030f, 0x505f5653, 0x7469736f, 0x006e6f69, 0x43584554, + 0x44524f4f, 0xababab00, 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, + 0x00000000, 0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x52444853, + 0x000002ec, 0x00000040, 0x000000bb, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x04000059, + 0x00208e46, 0x00000001, 0x00000005, 0x0300005a, 0x00106000, 0x00000000, 0x0300005a, 0x00106000, + 0x00000001, 0x04001858, 0x00107000, 0x00000000, 0x00005555, 0x04001858, 0x00107000, 0x00000001, + 0x00005555, 0x03001062, 0x00101032, 0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x02000068, + 0x00000003, 0x08000000, 0x00100032, 0x00000000, 0x00101046, 0x00000001, 0x00208046, 0x00000001, + 0x00000004, 0x08000034, 0x00100032, 0x00000000, 0x00100046, 0x00000000, 0x00208046, 0x00000001, + 0x00000000, 0x08000033, 0x00100032, 0x00000000, 0x00100046, 0x00000000, 0x00208ae6, 0x00000001, + 0x00000000, 0x09000045, 0x001000f2, 0x00000000, 0x00100046, 0x00000000, 0x00107e46, 0x00000000, + 0x00106000, 0x00000000, 0x09000000, 0x00100032, 0x00000000, 0x00101046, 0x00000001, 0x80208046, + 0x00000041, 0x00000001, 0x00000004, 0x08000034, 0x00100032, 0x00000000, 0x00100046, 0x00000000, + 0x00208046, 0x00000001, 0x00000000, 0x08000033, 0x00100032, 0x00000000, 0x00100046, 0x00000000, + 0x00208ae6, 0x00000001, 0x00000000, 0x09000045, 0x001000f2, 0x00000001, 0x00100046, 0x00000000, + 0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x08000000, 0x00100012, 0x00000000, 0x8010003a, + 0x00000041, 0x00000000, 0x0010003a, 0x00000001, 0x08000038, 0x00100012, 0x00000000, 0x0010000a, + 0x00000000, 0x0020802a, 0x00000001, 0x00000004, 0x05002036, 0x00100022, 0x00000000, 0x0010000a, + 0x00000000, 0x06002036, 0x00100012, 0x00000000, 0x8010000a, 0x00000041, 0x00000000, 0x08000038, + 0x001000f2, 0x00000001, 0x00100556, 0x00000000, 0x00208e46, 0x00000001, 0x00000003, 0x0a000032, + 0x001000f2, 0x00000000, 0x00100006, 0x00000000, 0x00208e46, 0x00000001, 0x00000002, 0x00100e46, + 0x00000001, 0x08000034, 0x00100032, 0x00000001, 0x00101046, 0x00000001, 0x00208046, 0x00000001, + 0x00000001, 0x08000033, 0x00100032, 0x00000001, 0x00100046, 0x00000001, 0x00208ae6, 0x00000001, + 0x00000001, 0x09000045, 0x001000f2, 0x00000001, 0x00100046, 0x00000001, 0x00107e46, 0x00000001, + 0x00106000, 0x00000001, 0x08000000, 0x00100012, 0x00000002, 0x8010003a, 0x00000041, 0x00000001, + 0x00004001, 0x3f800000, 0x09000032, 0x001020f2, 0x00000000, 0x00100e46, 0x00000000, 0x00100006, + 0x00000002, 0x00100e46, 0x00000001, 0x0100003e, 0x54415453, 0x00000074, 0x00000014, 0x00000003, + 0x00000000, 0x00000002, 0x0000000c, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, +}; + +static DWORD pshader_filter_17[433] = { + 0x43425844, 0x9d251e4d, 0x6df18823, 0x51817ea5, 0xa8eeefd8, 0x00000001, 0x000006c4, 0x00000005, + 0x00000034, 0x000002d0, 0x00000328, 0x0000035c, 0x00000648, 0x46454452, 0x00000294, 0x00000002, + 0x00000100, 0x00000006, 0x0000001c, 0xffff0400, 0x00008100, 0x00000262, 0x000000dc, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000000e3, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x000000ea, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000000, 0x00000001, 0x0000000d, 0x000000ef, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000001, 0x00000001, 0x0000000d, 0x000000f4, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000000f8, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x65745f73, 0x73003078, + 0x7865745f, 0x65740031, 0x74003078, 0x00317865, 0x00635350, 0x61726170, 0xababab00, 0x000000f4, + 0x00000004, 0x00000130, 0x00000040, 0x00000000, 0x00000000, 0x000000f8, 0x00000005, 0x000001c8, + 0x00000050, 0x00000000, 0x00000000, 0x00000190, 0x00000000, 0x00000010, 0x00000000, 0x0000019c, + 0x00000000, 0x000001ac, 0x00000010, 0x00000010, 0x00000000, 0x0000019c, 0x00000000, 0x000001b6, + 0x00000020, 0x00000010, 0x00000000, 0x0000019c, 0x00000000, 0x000001bc, 0x00000030, 0x00000010, + 0x00000000, 0x0000019c, 0x00000000, 0x6f6c6f63, 0x756d5f72, 0xabab006c, 0x00030001, 0x00040001, + 0x00000000, 0x00000000, 0x6f6c6f63, 0x64615f72, 0x6f660064, 0x006c6163, 0x63736572, 0x31656c61, + 0xababab00, 0x00000240, 0x00000000, 0x00000010, 0x00000002, 0x0000019c, 0x00000000, 0x00000247, + 0x00000010, 0x00000010, 0x00000002, 0x0000019c, 0x00000000, 0x0000024e, 0x00000020, 0x00000010, + 0x00000002, 0x0000019c, 0x00000000, 0x00000254, 0x00000030, 0x00000010, 0x00000002, 0x0000019c, + 0x00000000, 0x0000025b, 0x00000040, 0x00000010, 0x00000002, 0x0000019c, 0x00000000, 0x6d616c63, + 0x63003070, 0x706d616c, 0x6f630031, 0x00726f6c, 0x6f6c6f63, 0x74003272, 0x666f5f63, 0x694d0066, + 0x736f7263, 0x2074666f, 0x20295228, 0x4c534c48, 0x61685320, 0x20726564, 0x706d6f43, 0x72656c69, + 0x322e3920, 0x35392e39, 0x31332e32, 0xab003131, 0x4e475349, 0x00000050, 0x00000002, 0x00000008, + 0x00000038, 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x00000044, 0x00000000, + 0x00000000, 0x00000003, 0x00000001, 0x0000030f, 0x505f5653, 0x7469736f, 0x006e6f69, 0x43584554, + 0x44524f4f, 0xababab00, 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, + 0x00000000, 0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x52444853, + 0x000002e4, 0x00000040, 0x000000b9, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x04000059, + 0x00208e46, 0x00000001, 0x00000005, 0x0300005a, 0x00106000, 0x00000000, 0x0300005a, 0x00106000, + 0x00000001, 0x04001858, 0x00107000, 0x00000000, 0x00005555, 0x04001858, 0x00107000, 0x00000001, + 0x00005555, 0x03001062, 0x00101032, 0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x02000068, + 0x00000002, 0x08000000, 0x00100032, 0x00000000, 0x00101046, 0x00000001, 0x00208046, 0x00000001, + 0x00000004, 0x08000034, 0x00100032, 0x00000000, 0x00100046, 0x00000000, 0x00208046, 0x00000001, + 0x00000000, 0x08000033, 0x00100032, 0x00000000, 0x00100046, 0x00000000, 0x00208ae6, 0x00000001, + 0x00000000, 0x09000045, 0x001000f2, 0x00000000, 0x00100046, 0x00000000, 0x00107e46, 0x00000000, + 0x00106000, 0x00000000, 0x09000000, 0x00100032, 0x00000000, 0x00101046, 0x00000001, 0x80208046, + 0x00000041, 0x00000001, 0x00000004, 0x08000034, 0x00100032, 0x00000000, 0x00100046, 0x00000000, + 0x00208046, 0x00000001, 0x00000000, 0x08000033, 0x00100032, 0x00000000, 0x00100046, 0x00000000, + 0x00208ae6, 0x00000001, 0x00000000, 0x09000045, 0x001000f2, 0x00000001, 0x00100046, 0x00000000, + 0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x08000000, 0x00100012, 0x00000000, 0x8010003a, + 0x00000041, 0x00000000, 0x0010003a, 0x00000001, 0x08000038, 0x00100012, 0x00000000, 0x0010000a, + 0x00000000, 0x0020802a, 0x00000001, 0x00000004, 0x05002036, 0x00100022, 0x00000000, 0x0010000a, + 0x00000000, 0x06002036, 0x00100012, 0x00000000, 0x8010000a, 0x00000041, 0x00000000, 0x08000038, + 0x001000f2, 0x00000001, 0x00100556, 0x00000000, 0x00208e46, 0x00000001, 0x00000003, 0x0a000032, + 0x001000f2, 0x00000000, 0x00100006, 0x00000000, 0x00208e46, 0x00000001, 0x00000002, 0x00100e46, + 0x00000001, 0x08000034, 0x00100032, 0x00000001, 0x00101046, 0x00000001, 0x00208046, 0x00000001, + 0x00000001, 0x08000033, 0x00100032, 0x00000001, 0x00100046, 0x00000001, 0x00208ae6, 0x00000001, + 0x00000001, 0x09000045, 0x001000f2, 0x00000001, 0x00100046, 0x00000001, 0x00107e46, 0x00000001, + 0x00106000, 0x00000001, 0x08000000, 0x00100012, 0x00000001, 0x8010003a, 0x00000041, 0x00000001, + 0x00004001, 0x3f800000, 0x07000038, 0x001020f2, 0x00000000, 0x00100e46, 0x00000000, 0x00100006, + 0x00000001, 0x0100003e, 0x54415453, 0x00000074, 0x00000014, 0x00000002, 0x00000000, 0x00000002, + 0x0000000d, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, +}; + +static DWORD pshader_filter_18[455] = { + 0x43425844, 0x01fc38b9, 0x9e8809ca, 0x9767109e, 0x3100f672, 0x00000001, 0x0000071c, 0x00000005, + 0x00000034, 0x0000031c, 0x00000374, 0x000003a8, 0x000006a0, 0x46454452, 0x000002e0, 0x00000002, + 0x0000014c, 0x00000008, 0x0000001c, 0xffff0400, 0x00008100, 0x000002ae, 0x0000011c, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000123, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x0000012a, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0x00000001, 0x00000001, 0x00000131, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000000, 0x00000001, 0x0000000d, 0x00000136, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000001, 0x00000001, 0x0000000d, 0x0000013b, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000002, 0x00000001, 0x0000000d, 0x00000140, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000144, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x65745f73, 0x73003078, + 0x7865745f, 0x5f730031, 0x32786574, 0x78657400, 0x65740030, 0x74003178, 0x00327865, 0x00635350, + 0x61726170, 0xababab00, 0x00000140, 0x00000004, 0x0000017c, 0x00000040, 0x00000000, 0x00000000, + 0x00000144, 0x00000005, 0x00000214, 0x00000050, 0x00000000, 0x00000000, 0x000001dc, 0x00000000, + 0x00000010, 0x00000000, 0x000001e8, 0x00000000, 0x000001f8, 0x00000010, 0x00000010, 0x00000000, + 0x000001e8, 0x00000000, 0x00000202, 0x00000020, 0x00000010, 0x00000000, 0x000001e8, 0x00000000, + 0x00000208, 0x00000030, 0x00000010, 0x00000000, 0x000001e8, 0x00000000, 0x6f6c6f63, 0x756d5f72, + 0xabab006c, 0x00030001, 0x00040001, 0x00000000, 0x00000000, 0x6f6c6f63, 0x64615f72, 0x6f660064, + 0x006c6163, 0x63736572, 0x31656c61, 0xababab00, 0x0000028c, 0x00000000, 0x00000010, 0x00000002, + 0x000001e8, 0x00000000, 0x00000293, 0x00000010, 0x00000010, 0x00000002, 0x000001e8, 0x00000000, + 0x0000029a, 0x00000020, 0x00000010, 0x00000000, 0x000001e8, 0x00000000, 0x000002a0, 0x00000030, + 0x00000010, 0x00000000, 0x000001e8, 0x00000000, 0x000002a7, 0x00000040, 0x00000010, 0x00000002, + 0x000001e8, 0x00000000, 0x6d616c63, 0x63003070, 0x706d616c, 0x6f630031, 0x00726f6c, 0x6f6c6f63, + 0x74003272, 0x666f5f63, 0x694d0066, 0x736f7263, 0x2074666f, 0x20295228, 0x4c534c48, 0x61685320, + 0x20726564, 0x706d6f43, 0x72656c69, 0x322e3920, 0x35392e39, 0x31332e32, 0xab003131, 0x4e475349, + 0x00000050, 0x00000002, 0x00000008, 0x00000038, 0x00000000, 0x00000001, 0x00000003, 0x00000000, + 0x0000000f, 0x00000044, 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x0000030f, 0x505f5653, + 0x7469736f, 0x006e6f69, 0x43584554, 0x44524f4f, 0xababab00, 0x4e47534f, 0x0000002c, 0x00000001, + 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x0000000f, 0x545f5653, + 0x65677261, 0xabab0074, 0x52444853, 0x000002f0, 0x00000040, 0x000000bc, 0x04000059, 0x00208e46, + 0x00000000, 0x00000001, 0x04000059, 0x00208e46, 0x00000001, 0x00000005, 0x0300005a, 0x00106000, + 0x00000000, 0x0300005a, 0x00106000, 0x00000001, 0x0300005a, 0x00106000, 0x00000002, 0x04001858, + 0x00107000, 0x00000000, 0x00005555, 0x04001858, 0x00107000, 0x00000001, 0x00005555, 0x04001858, + 0x00107000, 0x00000002, 0x00005555, 0x03001062, 0x00101032, 0x00000001, 0x03000065, 0x001020f2, + 0x00000000, 0x02000068, 0x00000003, 0x08000000, 0x00100032, 0x00000000, 0x00101046, 0x00000001, + 0x00208046, 0x00000001, 0x00000004, 0x08000034, 0x00100032, 0x00000000, 0x00100046, 0x00000000, + 0x00208046, 0x00000001, 0x00000000, 0x08000033, 0x00100032, 0x00000000, 0x00100046, 0x00000000, + 0x00208ae6, 0x00000001, 0x00000000, 0x09000045, 0x001000f2, 0x00000000, 0x00100046, 0x00000000, + 0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x09000000, 0x00100032, 0x00000000, 0x00101046, + 0x00000001, 0x80208046, 0x00000041, 0x00000001, 0x00000004, 0x08000034, 0x00100032, 0x00000000, + 0x00100046, 0x00000000, 0x00208046, 0x00000001, 0x00000000, 0x08000033, 0x00100032, 0x00000000, + 0x00100046, 0x00000000, 0x00208ae6, 0x00000001, 0x00000000, 0x09000045, 0x001000f2, 0x00000001, + 0x00100046, 0x00000000, 0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x08000000, 0x00100012, + 0x00000000, 0x8010003a, 0x00000041, 0x00000000, 0x0010003a, 0x00000001, 0x08000038, 0x00100012, + 0x00000000, 0x0010000a, 0x00000000, 0x0020802a, 0x00000001, 0x00000004, 0x09002032, 0x00100012, + 0x00000000, 0x0010000a, 0x00000000, 0x00004001, 0x3f000000, 0x00004001, 0x3f000000, 0x05000036, + 0x00100022, 0x00000000, 0x00004001, 0x3f000000, 0x09000045, 0x001000f2, 0x00000000, 0x00100046, + 0x00000000, 0x00107e46, 0x00000002, 0x00106000, 0x00000002, 0x08000034, 0x00100032, 0x00000001, + 0x00101046, 0x00000001, 0x00208046, 0x00000001, 0x00000001, 0x08000033, 0x00100032, 0x00000001, + 0x00100046, 0x00000001, 0x00208ae6, 0x00000001, 0x00000001, 0x09000045, 0x001000f2, 0x00000001, + 0x00100046, 0x00000001, 0x00107e46, 0x00000001, 0x00106000, 0x00000001, 0x08000000, 0x00100012, + 0x00000002, 0x8010003a, 0x00000041, 0x00000001, 0x00004001, 0x3f800000, 0x09000032, 0x001020f2, + 0x00000000, 0x00100e46, 0x00000000, 0x00100006, 0x00000002, 0x00100e46, 0x00000001, 0x0100003e, + 0x54415453, 0x00000074, 0x00000013, 0x00000003, 0x00000000, 0x00000002, 0x0000000b, 0x00000000, + 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000004, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +}; + +static DWORD pshader_filter_19[453] = { + 0x43425844, 0x93b178e0, 0xac5fae3d, 0x5854ccdb, 0x646aa2b1, 0x00000001, 0x00000714, 0x00000005, + 0x00000034, 0x0000031c, 0x00000374, 0x000003a8, 0x00000698, 0x46454452, 0x000002e0, 0x00000002, + 0x0000014c, 0x00000008, 0x0000001c, 0xffff0400, 0x00008100, 0x000002ae, 0x0000011c, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000123, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x0000012a, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0x00000001, 0x00000001, 0x00000131, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000000, 0x00000001, 0x0000000d, 0x00000136, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000001, 0x00000001, 0x0000000d, 0x0000013b, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000002, 0x00000001, 0x0000000d, 0x00000140, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000144, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x65745f73, 0x73003078, + 0x7865745f, 0x5f730031, 0x32786574, 0x78657400, 0x65740030, 0x74003178, 0x00327865, 0x00635350, + 0x61726170, 0xababab00, 0x00000140, 0x00000004, 0x0000017c, 0x00000040, 0x00000000, 0x00000000, + 0x00000144, 0x00000005, 0x00000214, 0x00000050, 0x00000000, 0x00000000, 0x000001dc, 0x00000000, + 0x00000010, 0x00000000, 0x000001e8, 0x00000000, 0x000001f8, 0x00000010, 0x00000010, 0x00000000, + 0x000001e8, 0x00000000, 0x00000202, 0x00000020, 0x00000010, 0x00000000, 0x000001e8, 0x00000000, + 0x00000208, 0x00000030, 0x00000010, 0x00000000, 0x000001e8, 0x00000000, 0x6f6c6f63, 0x756d5f72, + 0xabab006c, 0x00030001, 0x00040001, 0x00000000, 0x00000000, 0x6f6c6f63, 0x64615f72, 0x6f660064, + 0x006c6163, 0x63736572, 0x31656c61, 0xababab00, 0x0000028c, 0x00000000, 0x00000010, 0x00000002, + 0x000001e8, 0x00000000, 0x00000293, 0x00000010, 0x00000010, 0x00000002, 0x000001e8, 0x00000000, + 0x0000029a, 0x00000020, 0x00000010, 0x00000000, 0x000001e8, 0x00000000, 0x000002a0, 0x00000030, + 0x00000010, 0x00000000, 0x000001e8, 0x00000000, 0x000002a7, 0x00000040, 0x00000010, 0x00000002, + 0x000001e8, 0x00000000, 0x6d616c63, 0x63003070, 0x706d616c, 0x6f630031, 0x00726f6c, 0x6f6c6f63, + 0x74003272, 0x666f5f63, 0x694d0066, 0x736f7263, 0x2074666f, 0x20295228, 0x4c534c48, 0x61685320, + 0x20726564, 0x706d6f43, 0x72656c69, 0x322e3920, 0x35392e39, 0x31332e32, 0xab003131, 0x4e475349, + 0x00000050, 0x00000002, 0x00000008, 0x00000038, 0x00000000, 0x00000001, 0x00000003, 0x00000000, + 0x0000000f, 0x00000044, 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x0000030f, 0x505f5653, + 0x7469736f, 0x006e6f69, 0x43584554, 0x44524f4f, 0xababab00, 0x4e47534f, 0x0000002c, 0x00000001, + 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x0000000f, 0x545f5653, + 0x65677261, 0xabab0074, 0x52444853, 0x000002e8, 0x00000040, 0x000000ba, 0x04000059, 0x00208e46, + 0x00000000, 0x00000001, 0x04000059, 0x00208e46, 0x00000001, 0x00000005, 0x0300005a, 0x00106000, + 0x00000000, 0x0300005a, 0x00106000, 0x00000001, 0x0300005a, 0x00106000, 0x00000002, 0x04001858, + 0x00107000, 0x00000000, 0x00005555, 0x04001858, 0x00107000, 0x00000001, 0x00005555, 0x04001858, + 0x00107000, 0x00000002, 0x00005555, 0x03001062, 0x00101032, 0x00000001, 0x03000065, 0x001020f2, + 0x00000000, 0x02000068, 0x00000002, 0x08000000, 0x00100032, 0x00000000, 0x00101046, 0x00000001, + 0x00208046, 0x00000001, 0x00000004, 0x08000034, 0x00100032, 0x00000000, 0x00100046, 0x00000000, + 0x00208046, 0x00000001, 0x00000000, 0x08000033, 0x00100032, 0x00000000, 0x00100046, 0x00000000, + 0x00208ae6, 0x00000001, 0x00000000, 0x09000045, 0x001000f2, 0x00000000, 0x00100046, 0x00000000, + 0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x09000000, 0x00100032, 0x00000000, 0x00101046, + 0x00000001, 0x80208046, 0x00000041, 0x00000001, 0x00000004, 0x08000034, 0x00100032, 0x00000000, + 0x00100046, 0x00000000, 0x00208046, 0x00000001, 0x00000000, 0x08000033, 0x00100032, 0x00000000, + 0x00100046, 0x00000000, 0x00208ae6, 0x00000001, 0x00000000, 0x09000045, 0x001000f2, 0x00000001, + 0x00100046, 0x00000000, 0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x08000000, 0x00100012, + 0x00000000, 0x8010003a, 0x00000041, 0x00000000, 0x0010003a, 0x00000001, 0x08000038, 0x00100012, + 0x00000000, 0x0010000a, 0x00000000, 0x0020802a, 0x00000001, 0x00000004, 0x09002032, 0x00100012, + 0x00000000, 0x0010000a, 0x00000000, 0x00004001, 0x3f000000, 0x00004001, 0x3f000000, 0x05000036, + 0x00100022, 0x00000000, 0x00004001, 0x3f000000, 0x09000045, 0x001000f2, 0x00000000, 0x00100046, + 0x00000000, 0x00107e46, 0x00000002, 0x00106000, 0x00000002, 0x08000034, 0x00100032, 0x00000001, + 0x00101046, 0x00000001, 0x00208046, 0x00000001, 0x00000001, 0x08000033, 0x00100032, 0x00000001, + 0x00100046, 0x00000001, 0x00208ae6, 0x00000001, 0x00000001, 0x09000045, 0x001000f2, 0x00000001, + 0x00100046, 0x00000001, 0x00107e46, 0x00000001, 0x00106000, 0x00000001, 0x08000000, 0x00100012, + 0x00000001, 0x8010003a, 0x00000041, 0x00000001, 0x00004001, 0x3f800000, 0x07000038, 0x001020f2, + 0x00000000, 0x00100e46, 0x00000000, 0x00100006, 0x00000001, 0x0100003e, 0x54415453, 0x00000074, + 0x00000013, 0x00000002, 0x00000000, 0x00000002, 0x0000000c, 0x00000000, 0x00000000, 0x00000001, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000004, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +}; + +static DWORD pshader_filter_20[447] = { + 0x43425844, 0x9a125209, 0xf5c56096, 0xd7eccf22, 0x9fa5961c, 0x00000001, 0x000006fc, 0x00000005, + 0x00000034, 0x000002d0, 0x00000328, 0x0000035c, 0x00000680, 0x46454452, 0x00000294, 0x00000002, + 0x00000100, 0x00000006, 0x0000001c, 0xffff0400, 0x00008100, 0x00000262, 0x000000dc, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000000e3, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x000000ea, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000000, 0x00000001, 0x0000000d, 0x000000ef, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000001, 0x00000001, 0x0000000d, 0x000000f4, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000000f8, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x65745f73, 0x73003078, + 0x7865745f, 0x65740031, 0x74003078, 0x00317865, 0x00635350, 0x61726170, 0xababab00, 0x000000f4, + 0x00000004, 0x00000130, 0x00000040, 0x00000000, 0x00000000, 0x000000f8, 0x00000005, 0x000001c8, + 0x00000050, 0x00000000, 0x00000000, 0x00000190, 0x00000000, 0x00000010, 0x00000000, 0x0000019c, + 0x00000000, 0x000001ac, 0x00000010, 0x00000010, 0x00000000, 0x0000019c, 0x00000000, 0x000001b6, + 0x00000020, 0x00000010, 0x00000000, 0x0000019c, 0x00000000, 0x000001bc, 0x00000030, 0x00000010, + 0x00000000, 0x0000019c, 0x00000000, 0x6f6c6f63, 0x756d5f72, 0xabab006c, 0x00030001, 0x00040001, + 0x00000000, 0x00000000, 0x6f6c6f63, 0x64615f72, 0x6f660064, 0x006c6163, 0x63736572, 0x31656c61, + 0xababab00, 0x00000240, 0x00000000, 0x00000010, 0x00000002, 0x0000019c, 0x00000000, 0x00000247, + 0x00000010, 0x00000010, 0x00000002, 0x0000019c, 0x00000000, 0x0000024e, 0x00000020, 0x00000010, + 0x00000002, 0x0000019c, 0x00000000, 0x00000254, 0x00000030, 0x00000010, 0x00000002, 0x0000019c, + 0x00000000, 0x0000025b, 0x00000040, 0x00000010, 0x00000002, 0x0000019c, 0x00000000, 0x6d616c63, + 0x63003070, 0x706d616c, 0x6f630031, 0x00726f6c, 0x6f6c6f63, 0x74003272, 0x666f5f63, 0x694d0066, + 0x736f7263, 0x2074666f, 0x20295228, 0x4c534c48, 0x61685320, 0x20726564, 0x706d6f43, 0x72656c69, + 0x322e3920, 0x35392e39, 0x31332e32, 0xab003131, 0x4e475349, 0x00000050, 0x00000002, 0x00000008, + 0x00000038, 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x00000044, 0x00000000, + 0x00000000, 0x00000003, 0x00000001, 0x0000030f, 0x505f5653, 0x7469736f, 0x006e6f69, 0x43584554, + 0x44524f4f, 0xababab00, 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, + 0x00000000, 0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x52444853, + 0x0000031c, 0x00000040, 0x000000c7, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x04000059, + 0x00208e46, 0x00000001, 0x00000005, 0x0300005a, 0x00106000, 0x00000000, 0x0300005a, 0x00106000, + 0x00000001, 0x04001858, 0x00107000, 0x00000000, 0x00005555, 0x04001858, 0x00107000, 0x00000001, + 0x00005555, 0x03001062, 0x00101032, 0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x02000068, + 0x00000002, 0x08000000, 0x00100032, 0x00000000, 0x00101046, 0x00000001, 0x00208046, 0x00000001, + 0x00000004, 0x08000034, 0x00100032, 0x00000000, 0x00100046, 0x00000000, 0x00208046, 0x00000001, + 0x00000000, 0x08000033, 0x00100032, 0x00000000, 0x00100046, 0x00000000, 0x00208ae6, 0x00000001, + 0x00000000, 0x09000045, 0x001000f2, 0x00000000, 0x00100046, 0x00000000, 0x00107e46, 0x00000000, + 0x00106000, 0x00000000, 0x09000000, 0x00100032, 0x00000000, 0x00101046, 0x00000001, 0x80208046, + 0x00000041, 0x00000001, 0x00000004, 0x08000034, 0x00100032, 0x00000000, 0x00100046, 0x00000000, + 0x00208046, 0x00000001, 0x00000000, 0x08000033, 0x00100032, 0x00000000, 0x00100046, 0x00000000, + 0x00208ae6, 0x00000001, 0x00000000, 0x09000045, 0x001000f2, 0x00000001, 0x00100046, 0x00000000, + 0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x08000000, 0x00100012, 0x00000000, 0x8010003a, + 0x00000041, 0x00000000, 0x0010003a, 0x00000001, 0x08000038, 0x00100012, 0x00000000, 0x0010000a, + 0x00000000, 0x0020802a, 0x00000001, 0x00000004, 0x05002036, 0x00100022, 0x00000000, 0x0010000a, + 0x00000000, 0x06002036, 0x00100012, 0x00000000, 0x8010000a, 0x00000041, 0x00000000, 0x08000038, + 0x001000f2, 0x00000001, 0x00100556, 0x00000000, 0x00208e46, 0x00000001, 0x00000003, 0x0a000032, + 0x001000f2, 0x00000000, 0x00100006, 0x00000000, 0x00208e46, 0x00000001, 0x00000002, 0x00100e46, + 0x00000001, 0x08000000, 0x00100082, 0x00000000, 0x8010003a, 0x00000041, 0x00000000, 0x00004001, + 0x3f800000, 0x08000034, 0x00100032, 0x00000001, 0x00101046, 0x00000001, 0x00208046, 0x00000001, + 0x00000001, 0x08000033, 0x00100032, 0x00000001, 0x00100046, 0x00000001, 0x00208ae6, 0x00000001, + 0x00000001, 0x09000045, 0x001000f2, 0x00000001, 0x00100046, 0x00000001, 0x00107e46, 0x00000001, + 0x00106000, 0x00000001, 0x07000038, 0x00100072, 0x00000001, 0x00100ff6, 0x00000000, 0x00100246, + 0x00000001, 0x09000032, 0x00102072, 0x00000000, 0x00100246, 0x00000000, 0x00100ff6, 0x00000001, + 0x00100246, 0x00000001, 0x05000036, 0x00102082, 0x00000000, 0x0010003a, 0x00000001, 0x0100003e, + 0x54415453, 0x00000074, 0x00000016, 0x00000002, 0x00000000, 0x00000002, 0x0000000d, 0x00000000, + 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000003, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +}; + +static DWORD pshader_filter_21[425] = { + 0x43425844, 0x893ebdf3, 0x678513c8, 0xea77bccb, 0x915f5370, 0x00000001, 0x000006a4, 0x00000005, + 0x00000034, 0x000002d0, 0x00000328, 0x0000035c, 0x00000628, 0x46454452, 0x00000294, 0x00000002, + 0x00000100, 0x00000006, 0x0000001c, 0xffff0400, 0x00008100, 0x00000262, 0x000000dc, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000000e3, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x000000ea, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000000, 0x00000001, 0x0000000d, 0x000000ef, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000001, 0x00000001, 0x0000000d, 0x000000f4, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000000f8, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x65745f73, 0x73003078, + 0x7865745f, 0x65740031, 0x74003078, 0x00317865, 0x00635350, 0x61726170, 0xababab00, 0x000000f4, + 0x00000004, 0x00000130, 0x00000040, 0x00000000, 0x00000000, 0x000000f8, 0x00000005, 0x000001c8, + 0x00000050, 0x00000000, 0x00000000, 0x00000190, 0x00000000, 0x00000010, 0x00000000, 0x0000019c, + 0x00000000, 0x000001ac, 0x00000010, 0x00000010, 0x00000000, 0x0000019c, 0x00000000, 0x000001b6, + 0x00000020, 0x00000010, 0x00000000, 0x0000019c, 0x00000000, 0x000001bc, 0x00000030, 0x00000010, + 0x00000000, 0x0000019c, 0x00000000, 0x6f6c6f63, 0x756d5f72, 0xabab006c, 0x00030001, 0x00040001, + 0x00000000, 0x00000000, 0x6f6c6f63, 0x64615f72, 0x6f660064, 0x006c6163, 0x63736572, 0x31656c61, + 0xababab00, 0x00000240, 0x00000000, 0x00000010, 0x00000002, 0x0000019c, 0x00000000, 0x00000247, + 0x00000010, 0x00000010, 0x00000002, 0x0000019c, 0x00000000, 0x0000024e, 0x00000020, 0x00000010, + 0x00000002, 0x0000019c, 0x00000000, 0x00000254, 0x00000030, 0x00000010, 0x00000002, 0x0000019c, + 0x00000000, 0x0000025b, 0x00000040, 0x00000010, 0x00000002, 0x0000019c, 0x00000000, 0x6d616c63, + 0x63003070, 0x706d616c, 0x6f630031, 0x00726f6c, 0x6f6c6f63, 0x74003272, 0x666f5f63, 0x694d0066, + 0x736f7263, 0x2074666f, 0x20295228, 0x4c534c48, 0x61685320, 0x20726564, 0x706d6f43, 0x72656c69, + 0x322e3920, 0x35392e39, 0x31332e32, 0xab003131, 0x4e475349, 0x00000050, 0x00000002, 0x00000008, + 0x00000038, 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x00000044, 0x00000000, + 0x00000000, 0x00000003, 0x00000001, 0x0000030f, 0x505f5653, 0x7469736f, 0x006e6f69, 0x43584554, + 0x44524f4f, 0xababab00, 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, + 0x00000000, 0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x52444853, + 0x000002c4, 0x00000040, 0x000000b1, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x04000059, + 0x00208e46, 0x00000001, 0x00000005, 0x0300005a, 0x00106000, 0x00000000, 0x0300005a, 0x00106000, + 0x00000001, 0x04001858, 0x00107000, 0x00000000, 0x00005555, 0x04001858, 0x00107000, 0x00000001, + 0x00005555, 0x03001062, 0x00101032, 0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x02000068, + 0x00000002, 0x08000000, 0x00100032, 0x00000000, 0x00101046, 0x00000001, 0x00208046, 0x00000001, + 0x00000004, 0x08000034, 0x00100032, 0x00000000, 0x00100046, 0x00000000, 0x00208046, 0x00000001, + 0x00000000, 0x08000033, 0x00100032, 0x00000000, 0x00100046, 0x00000000, 0x00208ae6, 0x00000001, + 0x00000000, 0x09000045, 0x001000f2, 0x00000000, 0x00100046, 0x00000000, 0x00107e46, 0x00000000, + 0x00106000, 0x00000000, 0x09000000, 0x00100032, 0x00000000, 0x00101046, 0x00000001, 0x80208046, + 0x00000041, 0x00000001, 0x00000004, 0x08000034, 0x00100032, 0x00000000, 0x00100046, 0x00000000, + 0x00208046, 0x00000001, 0x00000000, 0x08000033, 0x00100032, 0x00000000, 0x00100046, 0x00000000, + 0x00208ae6, 0x00000001, 0x00000000, 0x09000045, 0x001000f2, 0x00000001, 0x00100046, 0x00000000, + 0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x08000000, 0x00100012, 0x00000000, 0x8010003a, + 0x00000041, 0x00000000, 0x0010003a, 0x00000001, 0x08000038, 0x00100012, 0x00000000, 0x0010000a, + 0x00000000, 0x0020802a, 0x00000001, 0x00000004, 0x05002036, 0x00100022, 0x00000000, 0x0010000a, + 0x00000000, 0x06002036, 0x00100012, 0x00000000, 0x8010000a, 0x00000041, 0x00000000, 0x08000038, + 0x001000f2, 0x00000001, 0x00100556, 0x00000000, 0x00208e46, 0x00000001, 0x00000003, 0x0a000032, + 0x001000f2, 0x00000000, 0x00100006, 0x00000000, 0x00208e46, 0x00000001, 0x00000002, 0x00100e46, + 0x00000001, 0x08000034, 0x00100032, 0x00000001, 0x00101046, 0x00000001, 0x00208046, 0x00000001, + 0x00000001, 0x08000033, 0x00100032, 0x00000001, 0x00100046, 0x00000001, 0x00208ae6, 0x00000001, + 0x00000001, 0x09000045, 0x001000f2, 0x00000001, 0x00100046, 0x00000001, 0x00107e46, 0x00000001, + 0x00106000, 0x00000001, 0x07000038, 0x001020f2, 0x00000000, 0x00100e46, 0x00000000, 0x00100ff6, + 0x00000001, 0x0100003e, 0x54415453, 0x00000074, 0x00000013, 0x00000002, 0x00000000, 0x00000002, + 0x0000000c, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, +}; + +static DWORD pshader_filter_22[467] = { + 0x43425844, 0x2b2ebefd, 0x99c6691a, 0xf5589278, 0x00bf4796, 0x00000001, 0x0000074c, 0x00000005, + 0x00000034, 0x0000031c, 0x00000374, 0x000003a8, 0x000006d0, 0x46454452, 0x000002e0, 0x00000002, + 0x0000014c, 0x00000008, 0x0000001c, 0xffff0400, 0x00008100, 0x000002ae, 0x0000011c, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000123, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x0000012a, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0x00000001, 0x00000001, 0x00000131, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000000, 0x00000001, 0x0000000d, 0x00000136, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000001, 0x00000001, 0x0000000d, 0x0000013b, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000002, 0x00000001, 0x0000000d, 0x00000140, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000144, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x65745f73, 0x73003078, + 0x7865745f, 0x5f730031, 0x32786574, 0x78657400, 0x65740030, 0x74003178, 0x00327865, 0x00635350, + 0x61726170, 0xababab00, 0x00000140, 0x00000004, 0x0000017c, 0x00000040, 0x00000000, 0x00000000, + 0x00000144, 0x00000005, 0x00000214, 0x00000050, 0x00000000, 0x00000000, 0x000001dc, 0x00000000, + 0x00000010, 0x00000000, 0x000001e8, 0x00000000, 0x000001f8, 0x00000010, 0x00000010, 0x00000000, + 0x000001e8, 0x00000000, 0x00000202, 0x00000020, 0x00000010, 0x00000000, 0x000001e8, 0x00000000, + 0x00000208, 0x00000030, 0x00000010, 0x00000000, 0x000001e8, 0x00000000, 0x6f6c6f63, 0x756d5f72, + 0xabab006c, 0x00030001, 0x00040001, 0x00000000, 0x00000000, 0x6f6c6f63, 0x64615f72, 0x6f660064, + 0x006c6163, 0x63736572, 0x31656c61, 0xababab00, 0x0000028c, 0x00000000, 0x00000010, 0x00000002, + 0x000001e8, 0x00000000, 0x00000293, 0x00000010, 0x00000010, 0x00000002, 0x000001e8, 0x00000000, + 0x0000029a, 0x00000020, 0x00000010, 0x00000000, 0x000001e8, 0x00000000, 0x000002a0, 0x00000030, + 0x00000010, 0x00000000, 0x000001e8, 0x00000000, 0x000002a7, 0x00000040, 0x00000010, 0x00000002, + 0x000001e8, 0x00000000, 0x6d616c63, 0x63003070, 0x706d616c, 0x6f630031, 0x00726f6c, 0x6f6c6f63, + 0x74003272, 0x666f5f63, 0x694d0066, 0x736f7263, 0x2074666f, 0x20295228, 0x4c534c48, 0x61685320, + 0x20726564, 0x706d6f43, 0x72656c69, 0x322e3920, 0x35392e39, 0x31332e32, 0xab003131, 0x4e475349, + 0x00000050, 0x00000002, 0x00000008, 0x00000038, 0x00000000, 0x00000001, 0x00000003, 0x00000000, + 0x0000000f, 0x00000044, 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x0000030f, 0x505f5653, + 0x7469736f, 0x006e6f69, 0x43584554, 0x44524f4f, 0xababab00, 0x4e47534f, 0x0000002c, 0x00000001, + 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x0000000f, 0x545f5653, + 0x65677261, 0xabab0074, 0x52444853, 0x00000320, 0x00000040, 0x000000c8, 0x04000059, 0x00208e46, + 0x00000000, 0x00000001, 0x04000059, 0x00208e46, 0x00000001, 0x00000005, 0x0300005a, 0x00106000, + 0x00000000, 0x0300005a, 0x00106000, 0x00000001, 0x0300005a, 0x00106000, 0x00000002, 0x04001858, + 0x00107000, 0x00000000, 0x00005555, 0x04001858, 0x00107000, 0x00000001, 0x00005555, 0x04001858, + 0x00107000, 0x00000002, 0x00005555, 0x03001062, 0x00101032, 0x00000001, 0x03000065, 0x001020f2, + 0x00000000, 0x02000068, 0x00000002, 0x08000000, 0x00100032, 0x00000000, 0x00101046, 0x00000001, + 0x00208046, 0x00000001, 0x00000004, 0x08000034, 0x00100032, 0x00000000, 0x00100046, 0x00000000, + 0x00208046, 0x00000001, 0x00000000, 0x08000033, 0x00100032, 0x00000000, 0x00100046, 0x00000000, + 0x00208ae6, 0x00000001, 0x00000000, 0x09000045, 0x001000f2, 0x00000000, 0x00100046, 0x00000000, + 0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x09000000, 0x00100032, 0x00000000, 0x00101046, + 0x00000001, 0x80208046, 0x00000041, 0x00000001, 0x00000004, 0x08000034, 0x00100032, 0x00000000, + 0x00100046, 0x00000000, 0x00208046, 0x00000001, 0x00000000, 0x08000033, 0x00100032, 0x00000000, + 0x00100046, 0x00000000, 0x00208ae6, 0x00000001, 0x00000000, 0x09000045, 0x001000f2, 0x00000001, + 0x00100046, 0x00000000, 0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x08000000, 0x00100012, + 0x00000000, 0x8010003a, 0x00000041, 0x00000000, 0x0010003a, 0x00000001, 0x08000038, 0x00100012, + 0x00000000, 0x0010000a, 0x00000000, 0x0020802a, 0x00000001, 0x00000004, 0x09002032, 0x00100012, + 0x00000000, 0x0010000a, 0x00000000, 0x00004001, 0x3f000000, 0x00004001, 0x3f000000, 0x05000036, + 0x00100022, 0x00000000, 0x00004001, 0x3f000000, 0x09000045, 0x001000f2, 0x00000000, 0x00100046, + 0x00000000, 0x00107e46, 0x00000002, 0x00106000, 0x00000002, 0x08000000, 0x00100082, 0x00000000, + 0x8010003a, 0x00000041, 0x00000000, 0x00004001, 0x3f800000, 0x08000034, 0x00100032, 0x00000001, + 0x00101046, 0x00000001, 0x00208046, 0x00000001, 0x00000001, 0x08000033, 0x00100032, 0x00000001, + 0x00100046, 0x00000001, 0x00208ae6, 0x00000001, 0x00000001, 0x09000045, 0x001000f2, 0x00000001, + 0x00100046, 0x00000001, 0x00107e46, 0x00000001, 0x00106000, 0x00000001, 0x07000038, 0x00100072, + 0x00000001, 0x00100ff6, 0x00000000, 0x00100246, 0x00000001, 0x09000032, 0x00102072, 0x00000000, + 0x00100246, 0x00000000, 0x00100ff6, 0x00000001, 0x00100246, 0x00000001, 0x05000036, 0x00102082, + 0x00000000, 0x0010003a, 0x00000001, 0x0100003e, 0x54415453, 0x00000074, 0x00000015, 0x00000002, + 0x00000000, 0x00000002, 0x0000000c, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000004, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, +}; + +static DWORD pshader_filter_23[445] = { + 0x43425844, 0xc733b29b, 0xcc301191, 0xb70dd0eb, 0xb530bacb, 0x00000001, 0x000006f4, 0x00000005, + 0x00000034, 0x0000031c, 0x00000374, 0x000003a8, 0x00000678, 0x46454452, 0x000002e0, 0x00000002, + 0x0000014c, 0x00000008, 0x0000001c, 0xffff0400, 0x00008100, 0x000002ae, 0x0000011c, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000123, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x0000012a, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0x00000001, 0x00000001, 0x00000131, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000000, 0x00000001, 0x0000000d, 0x00000136, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000001, 0x00000001, 0x0000000d, 0x0000013b, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000002, 0x00000001, 0x0000000d, 0x00000140, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000144, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x65745f73, 0x73003078, + 0x7865745f, 0x5f730031, 0x32786574, 0x78657400, 0x65740030, 0x74003178, 0x00327865, 0x00635350, + 0x61726170, 0xababab00, 0x00000140, 0x00000004, 0x0000017c, 0x00000040, 0x00000000, 0x00000000, + 0x00000144, 0x00000005, 0x00000214, 0x00000050, 0x00000000, 0x00000000, 0x000001dc, 0x00000000, + 0x00000010, 0x00000000, 0x000001e8, 0x00000000, 0x000001f8, 0x00000010, 0x00000010, 0x00000000, + 0x000001e8, 0x00000000, 0x00000202, 0x00000020, 0x00000010, 0x00000000, 0x000001e8, 0x00000000, + 0x00000208, 0x00000030, 0x00000010, 0x00000000, 0x000001e8, 0x00000000, 0x6f6c6f63, 0x756d5f72, + 0xabab006c, 0x00030001, 0x00040001, 0x00000000, 0x00000000, 0x6f6c6f63, 0x64615f72, 0x6f660064, + 0x006c6163, 0x63736572, 0x31656c61, 0xababab00, 0x0000028c, 0x00000000, 0x00000010, 0x00000002, + 0x000001e8, 0x00000000, 0x00000293, 0x00000010, 0x00000010, 0x00000002, 0x000001e8, 0x00000000, + 0x0000029a, 0x00000020, 0x00000010, 0x00000000, 0x000001e8, 0x00000000, 0x000002a0, 0x00000030, + 0x00000010, 0x00000000, 0x000001e8, 0x00000000, 0x000002a7, 0x00000040, 0x00000010, 0x00000002, + 0x000001e8, 0x00000000, 0x6d616c63, 0x63003070, 0x706d616c, 0x6f630031, 0x00726f6c, 0x6f6c6f63, + 0x74003272, 0x666f5f63, 0x694d0066, 0x736f7263, 0x2074666f, 0x20295228, 0x4c534c48, 0x61685320, + 0x20726564, 0x706d6f43, 0x72656c69, 0x322e3920, 0x35392e39, 0x31332e32, 0xab003131, 0x4e475349, + 0x00000050, 0x00000002, 0x00000008, 0x00000038, 0x00000000, 0x00000001, 0x00000003, 0x00000000, + 0x0000000f, 0x00000044, 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x0000030f, 0x505f5653, + 0x7469736f, 0x006e6f69, 0x43584554, 0x44524f4f, 0xababab00, 0x4e47534f, 0x0000002c, 0x00000001, + 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x0000000f, 0x545f5653, + 0x65677261, 0xabab0074, 0x52444853, 0x000002c8, 0x00000040, 0x000000b2, 0x04000059, 0x00208e46, + 0x00000000, 0x00000001, 0x04000059, 0x00208e46, 0x00000001, 0x00000005, 0x0300005a, 0x00106000, + 0x00000000, 0x0300005a, 0x00106000, 0x00000001, 0x0300005a, 0x00106000, 0x00000002, 0x04001858, + 0x00107000, 0x00000000, 0x00005555, 0x04001858, 0x00107000, 0x00000001, 0x00005555, 0x04001858, + 0x00107000, 0x00000002, 0x00005555, 0x03001062, 0x00101032, 0x00000001, 0x03000065, 0x001020f2, + 0x00000000, 0x02000068, 0x00000002, 0x08000000, 0x00100032, 0x00000000, 0x00101046, 0x00000001, + 0x00208046, 0x00000001, 0x00000004, 0x08000034, 0x00100032, 0x00000000, 0x00100046, 0x00000000, + 0x00208046, 0x00000001, 0x00000000, 0x08000033, 0x00100032, 0x00000000, 0x00100046, 0x00000000, + 0x00208ae6, 0x00000001, 0x00000000, 0x09000045, 0x001000f2, 0x00000000, 0x00100046, 0x00000000, + 0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x09000000, 0x00100032, 0x00000000, 0x00101046, + 0x00000001, 0x80208046, 0x00000041, 0x00000001, 0x00000004, 0x08000034, 0x00100032, 0x00000000, + 0x00100046, 0x00000000, 0x00208046, 0x00000001, 0x00000000, 0x08000033, 0x00100032, 0x00000000, + 0x00100046, 0x00000000, 0x00208ae6, 0x00000001, 0x00000000, 0x09000045, 0x001000f2, 0x00000001, + 0x00100046, 0x00000000, 0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x08000000, 0x00100012, + 0x00000000, 0x8010003a, 0x00000041, 0x00000000, 0x0010003a, 0x00000001, 0x08000038, 0x00100012, + 0x00000000, 0x0010000a, 0x00000000, 0x0020802a, 0x00000001, 0x00000004, 0x09002032, 0x00100012, + 0x00000000, 0x0010000a, 0x00000000, 0x00004001, 0x3f000000, 0x00004001, 0x3f000000, 0x05000036, + 0x00100022, 0x00000000, 0x00004001, 0x3f000000, 0x09000045, 0x001000f2, 0x00000000, 0x00100046, + 0x00000000, 0x00107e46, 0x00000002, 0x00106000, 0x00000002, 0x08000034, 0x00100032, 0x00000001, + 0x00101046, 0x00000001, 0x00208046, 0x00000001, 0x00000001, 0x08000033, 0x00100032, 0x00000001, + 0x00100046, 0x00000001, 0x00208ae6, 0x00000001, 0x00000001, 0x09000045, 0x001000f2, 0x00000001, + 0x00100046, 0x00000001, 0x00107e46, 0x00000001, 0x00106000, 0x00000001, 0x07000038, 0x001020f2, + 0x00000000, 0x00100e46, 0x00000000, 0x00100ff6, 0x00000001, 0x0100003e, 0x54415453, 0x00000074, + 0x00000012, 0x00000002, 0x00000000, 0x00000002, 0x0000000b, 0x00000000, 0x00000000, 0x00000001, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000004, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +}; + +static DWORD pshader_filter_24[435] = { + 0x43425844, 0x19fff495, 0xbd100eb6, 0x9012a014, 0xcb173d4f, 0x00000001, 0x000006cc, 0x00000005, + 0x00000034, 0x000002d0, 0x00000328, 0x0000035c, 0x00000650, 0x46454452, 0x00000294, 0x00000002, + 0x00000100, 0x00000006, 0x0000001c, 0xffff0400, 0x00008100, 0x00000262, 0x000000dc, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000000e3, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x000000ea, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000000, 0x00000001, 0x0000000d, 0x000000ef, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000001, 0x00000001, 0x0000000d, 0x000000f4, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000000f8, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x65745f73, 0x73003078, + 0x7865745f, 0x65740031, 0x74003078, 0x00317865, 0x00635350, 0x61726170, 0xababab00, 0x000000f4, + 0x00000004, 0x00000130, 0x00000040, 0x00000000, 0x00000000, 0x000000f8, 0x00000005, 0x000001c8, + 0x00000050, 0x00000000, 0x00000000, 0x00000190, 0x00000000, 0x00000010, 0x00000000, 0x0000019c, + 0x00000000, 0x000001ac, 0x00000010, 0x00000010, 0x00000000, 0x0000019c, 0x00000000, 0x000001b6, + 0x00000020, 0x00000010, 0x00000000, 0x0000019c, 0x00000000, 0x000001bc, 0x00000030, 0x00000010, + 0x00000000, 0x0000019c, 0x00000000, 0x6f6c6f63, 0x756d5f72, 0xabab006c, 0x00030001, 0x00040001, + 0x00000000, 0x00000000, 0x6f6c6f63, 0x64615f72, 0x6f660064, 0x006c6163, 0x63736572, 0x31656c61, + 0xababab00, 0x00000240, 0x00000000, 0x00000010, 0x00000002, 0x0000019c, 0x00000000, 0x00000247, + 0x00000010, 0x00000010, 0x00000002, 0x0000019c, 0x00000000, 0x0000024e, 0x00000020, 0x00000010, + 0x00000002, 0x0000019c, 0x00000000, 0x00000254, 0x00000030, 0x00000010, 0x00000002, 0x0000019c, + 0x00000000, 0x0000025b, 0x00000040, 0x00000010, 0x00000002, 0x0000019c, 0x00000000, 0x6d616c63, + 0x63003070, 0x706d616c, 0x6f630031, 0x00726f6c, 0x6f6c6f63, 0x74003272, 0x666f5f63, 0x694d0066, + 0x736f7263, 0x2074666f, 0x20295228, 0x4c534c48, 0x61685320, 0x20726564, 0x706d6f43, 0x72656c69, + 0x322e3920, 0x35392e39, 0x31332e32, 0xab003131, 0x4e475349, 0x00000050, 0x00000002, 0x00000008, + 0x00000038, 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x00000044, 0x00000000, + 0x00000000, 0x00000003, 0x00000001, 0x0000030f, 0x505f5653, 0x7469736f, 0x006e6f69, 0x43584554, + 0x44524f4f, 0xababab00, 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, + 0x00000000, 0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x52444853, + 0x000002ec, 0x00000040, 0x000000bb, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x04000059, + 0x00208e46, 0x00000001, 0x00000005, 0x0300005a, 0x00106000, 0x00000000, 0x0300005a, 0x00106000, + 0x00000001, 0x04001858, 0x00107000, 0x00000000, 0x00005555, 0x04001858, 0x00107000, 0x00000001, + 0x00005555, 0x03001062, 0x00101032, 0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x02000068, + 0x00000003, 0x08000000, 0x00100032, 0x00000000, 0x00101046, 0x00000001, 0x00208046, 0x00000001, + 0x00000004, 0x08000034, 0x00100032, 0x00000000, 0x00100046, 0x00000000, 0x00208046, 0x00000001, + 0x00000000, 0x08000033, 0x00100032, 0x00000000, 0x00100046, 0x00000000, 0x00208ae6, 0x00000001, + 0x00000000, 0x09000045, 0x001000f2, 0x00000000, 0x00100046, 0x00000000, 0x00107e46, 0x00000000, + 0x00106000, 0x00000000, 0x09000000, 0x00100032, 0x00000000, 0x00101046, 0x00000001, 0x80208046, + 0x00000041, 0x00000001, 0x00000004, 0x08000034, 0x00100032, 0x00000000, 0x00100046, 0x00000000, + 0x00208046, 0x00000001, 0x00000000, 0x08000033, 0x00100032, 0x00000000, 0x00100046, 0x00000000, + 0x00208ae6, 0x00000001, 0x00000000, 0x09000045, 0x001000f2, 0x00000001, 0x00100046, 0x00000000, + 0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x08000000, 0x00100012, 0x00000000, 0x8010003a, + 0x00000041, 0x00000000, 0x0010003a, 0x00000001, 0x08000038, 0x00100012, 0x00000000, 0x0010000a, + 0x00000000, 0x0020802a, 0x00000001, 0x00000004, 0x05002036, 0x00100022, 0x00000000, 0x0010000a, + 0x00000000, 0x06002036, 0x00100012, 0x00000000, 0x8010000a, 0x00000041, 0x00000000, 0x08000038, + 0x001000f2, 0x00000001, 0x00100556, 0x00000000, 0x00208e46, 0x00000001, 0x00000003, 0x0a000032, + 0x001000f2, 0x00000000, 0x00100006, 0x00000000, 0x00208e46, 0x00000001, 0x00000002, 0x00100e46, + 0x00000001, 0x08000000, 0x00100012, 0x00000001, 0x8010003a, 0x00000041, 0x00000000, 0x00004001, + 0x3f800000, 0x08000034, 0x00100062, 0x00000001, 0x00101106, 0x00000001, 0x00208106, 0x00000001, + 0x00000001, 0x08000033, 0x00100062, 0x00000001, 0x00100656, 0x00000001, 0x00208ba6, 0x00000001, + 0x00000001, 0x09000045, 0x001000f2, 0x00000002, 0x00100596, 0x00000001, 0x00107e46, 0x00000001, + 0x00106000, 0x00000001, 0x09000032, 0x001020f2, 0x00000000, 0x00100e46, 0x00000002, 0x00100006, + 0x00000001, 0x00100e46, 0x00000000, 0x0100003e, 0x54415453, 0x00000074, 0x00000014, 0x00000003, + 0x00000000, 0x00000002, 0x0000000c, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, +}; + +static DWORD pshader_filter_25[367] = { + 0x43425844, 0x23e9ff30, 0xa49b9308, 0xc4b02a07, 0xfe240ca9, 0x00000001, 0x000005bc, 0x00000005, + 0x00000034, 0x00000284, 0x000002dc, 0x00000310, 0x00000540, 0x46454452, 0x00000248, 0x00000002, + 0x000000b4, 0x00000004, 0x0000001c, 0xffff0400, 0x00008100, 0x00000216, 0x0000009c, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000000a3, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000000, 0x00000001, 0x0000000d, 0x000000a8, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000000ac, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x65745f73, 0x74003078, + 0x00307865, 0x00635350, 0x61726170, 0xababab00, 0x000000a8, 0x00000004, 0x000000e4, 0x00000040, + 0x00000000, 0x00000000, 0x000000ac, 0x00000005, 0x0000017c, 0x00000050, 0x00000000, 0x00000000, + 0x00000144, 0x00000000, 0x00000010, 0x00000000, 0x00000150, 0x00000000, 0x00000160, 0x00000010, + 0x00000010, 0x00000000, 0x00000150, 0x00000000, 0x0000016a, 0x00000020, 0x00000010, 0x00000000, + 0x00000150, 0x00000000, 0x00000170, 0x00000030, 0x00000010, 0x00000000, 0x00000150, 0x00000000, + 0x6f6c6f63, 0x756d5f72, 0xabab006c, 0x00030001, 0x00040001, 0x00000000, 0x00000000, 0x6f6c6f63, + 0x64615f72, 0x6f660064, 0x006c6163, 0x63736572, 0x31656c61, 0xababab00, 0x000001f4, 0x00000000, + 0x00000010, 0x00000002, 0x00000150, 0x00000000, 0x000001fb, 0x00000010, 0x00000010, 0x00000000, + 0x00000150, 0x00000000, 0x00000202, 0x00000020, 0x00000010, 0x00000002, 0x00000150, 0x00000000, + 0x00000208, 0x00000030, 0x00000010, 0x00000002, 0x00000150, 0x00000000, 0x0000020f, 0x00000040, + 0x00000010, 0x00000002, 0x00000150, 0x00000000, 0x6d616c63, 0x63003070, 0x706d616c, 0x6f630031, + 0x00726f6c, 0x6f6c6f63, 0x74003272, 0x666f5f63, 0x694d0066, 0x736f7263, 0x2074666f, 0x20295228, + 0x4c534c48, 0x61685320, 0x20726564, 0x706d6f43, 0x72656c69, 0x322e3920, 0x35392e39, 0x31332e32, + 0xab003131, 0x4e475349, 0x00000050, 0x00000002, 0x00000008, 0x00000038, 0x00000000, 0x00000001, + 0x00000003, 0x00000000, 0x0000000f, 0x00000044, 0x00000000, 0x00000000, 0x00000003, 0x00000001, + 0x0000030f, 0x505f5653, 0x7469736f, 0x006e6f69, 0x43584554, 0x44524f4f, 0xababab00, 0x4e47534f, + 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000, + 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x52444853, 0x00000228, 0x00000040, 0x0000008a, + 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x04000059, 0x00208e46, 0x00000001, 0x00000005, + 0x0300005a, 0x00106000, 0x00000000, 0x04001858, 0x00107000, 0x00000000, 0x00005555, 0x03001062, + 0x00101032, 0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x00000002, 0x08000000, + 0x00100032, 0x00000000, 0x00101046, 0x00000001, 0x00208046, 0x00000001, 0x00000004, 0x08000034, + 0x00100032, 0x00000000, 0x00100046, 0x00000000, 0x00208046, 0x00000001, 0x00000000, 0x08000033, + 0x00100032, 0x00000000, 0x00100046, 0x00000000, 0x00208ae6, 0x00000001, 0x00000000, 0x09000045, + 0x001000f2, 0x00000000, 0x00100046, 0x00000000, 0x00107e46, 0x00000000, 0x00106000, 0x00000000, + 0x09000000, 0x00100032, 0x00000000, 0x00101046, 0x00000001, 0x80208046, 0x00000041, 0x00000001, + 0x00000004, 0x08000034, 0x00100032, 0x00000000, 0x00100046, 0x00000000, 0x00208046, 0x00000001, + 0x00000000, 0x08000033, 0x00100032, 0x00000000, 0x00100046, 0x00000000, 0x00208ae6, 0x00000001, + 0x00000000, 0x09000045, 0x001000f2, 0x00000001, 0x00100046, 0x00000000, 0x00107e46, 0x00000000, + 0x00106000, 0x00000000, 0x08000000, 0x00100012, 0x00000000, 0x8010003a, 0x00000041, 0x00000000, + 0x0010003a, 0x00000001, 0x08000038, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0020802a, + 0x00000001, 0x00000004, 0x05002036, 0x00100022, 0x00000000, 0x0010000a, 0x00000000, 0x06002036, + 0x00100012, 0x00000000, 0x8010000a, 0x00000041, 0x00000000, 0x08000038, 0x001000f2, 0x00000001, + 0x00100556, 0x00000000, 0x00208e46, 0x00000001, 0x00000003, 0x0a000032, 0x001020f2, 0x00000000, + 0x00100006, 0x00000000, 0x00208e46, 0x00000001, 0x00000002, 0x00100e46, 0x00000001, 0x0100003e, + 0x54415453, 0x00000074, 0x0000000f, 0x00000002, 0x00000000, 0x00000002, 0x00000009, 0x00000000, + 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +}; + +static DWORD pshader_filter_26[455] = { + 0x43425844, 0x77befa0f, 0xa8c6f51f, 0x871b10c5, 0x56e7a09b, 0x00000001, 0x0000071c, 0x00000005, + 0x00000034, 0x0000031c, 0x00000374, 0x000003a8, 0x000006a0, 0x46454452, 0x000002e0, 0x00000002, + 0x0000014c, 0x00000008, 0x0000001c, 0xffff0400, 0x00008100, 0x000002ae, 0x0000011c, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000123, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x0000012a, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0x00000001, 0x00000001, 0x00000131, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000000, 0x00000001, 0x0000000d, 0x00000136, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000001, 0x00000001, 0x0000000d, 0x0000013b, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000002, 0x00000001, 0x0000000d, 0x00000140, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000144, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x65745f73, 0x73003078, + 0x7865745f, 0x5f730031, 0x32786574, 0x78657400, 0x65740030, 0x74003178, 0x00327865, 0x00635350, + 0x61726170, 0xababab00, 0x00000140, 0x00000004, 0x0000017c, 0x00000040, 0x00000000, 0x00000000, + 0x00000144, 0x00000005, 0x00000214, 0x00000050, 0x00000000, 0x00000000, 0x000001dc, 0x00000000, + 0x00000010, 0x00000000, 0x000001e8, 0x00000000, 0x000001f8, 0x00000010, 0x00000010, 0x00000000, + 0x000001e8, 0x00000000, 0x00000202, 0x00000020, 0x00000010, 0x00000000, 0x000001e8, 0x00000000, + 0x00000208, 0x00000030, 0x00000010, 0x00000000, 0x000001e8, 0x00000000, 0x6f6c6f63, 0x756d5f72, + 0xabab006c, 0x00030001, 0x00040001, 0x00000000, 0x00000000, 0x6f6c6f63, 0x64615f72, 0x6f660064, + 0x006c6163, 0x63736572, 0x31656c61, 0xababab00, 0x0000028c, 0x00000000, 0x00000010, 0x00000002, + 0x000001e8, 0x00000000, 0x00000293, 0x00000010, 0x00000010, 0x00000002, 0x000001e8, 0x00000000, + 0x0000029a, 0x00000020, 0x00000010, 0x00000000, 0x000001e8, 0x00000000, 0x000002a0, 0x00000030, + 0x00000010, 0x00000000, 0x000001e8, 0x00000000, 0x000002a7, 0x00000040, 0x00000010, 0x00000002, + 0x000001e8, 0x00000000, 0x6d616c63, 0x63003070, 0x706d616c, 0x6f630031, 0x00726f6c, 0x6f6c6f63, + 0x74003272, 0x666f5f63, 0x694d0066, 0x736f7263, 0x2074666f, 0x20295228, 0x4c534c48, 0x61685320, + 0x20726564, 0x706d6f43, 0x72656c69, 0x322e3920, 0x35392e39, 0x31332e32, 0xab003131, 0x4e475349, + 0x00000050, 0x00000002, 0x00000008, 0x00000038, 0x00000000, 0x00000001, 0x00000003, 0x00000000, + 0x0000000f, 0x00000044, 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x0000030f, 0x505f5653, + 0x7469736f, 0x006e6f69, 0x43584554, 0x44524f4f, 0xababab00, 0x4e47534f, 0x0000002c, 0x00000001, + 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x0000000f, 0x545f5653, + 0x65677261, 0xabab0074, 0x52444853, 0x000002f0, 0x00000040, 0x000000bc, 0x04000059, 0x00208e46, + 0x00000000, 0x00000001, 0x04000059, 0x00208e46, 0x00000001, 0x00000005, 0x0300005a, 0x00106000, + 0x00000000, 0x0300005a, 0x00106000, 0x00000001, 0x0300005a, 0x00106000, 0x00000002, 0x04001858, + 0x00107000, 0x00000000, 0x00005555, 0x04001858, 0x00107000, 0x00000001, 0x00005555, 0x04001858, + 0x00107000, 0x00000002, 0x00005555, 0x03001062, 0x00101032, 0x00000001, 0x03000065, 0x001020f2, + 0x00000000, 0x02000068, 0x00000003, 0x08000000, 0x00100032, 0x00000000, 0x00101046, 0x00000001, + 0x00208046, 0x00000001, 0x00000004, 0x08000034, 0x00100032, 0x00000000, 0x00100046, 0x00000000, + 0x00208046, 0x00000001, 0x00000000, 0x08000033, 0x00100032, 0x00000000, 0x00100046, 0x00000000, + 0x00208ae6, 0x00000001, 0x00000000, 0x09000045, 0x001000f2, 0x00000000, 0x00100046, 0x00000000, + 0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x09000000, 0x00100032, 0x00000000, 0x00101046, + 0x00000001, 0x80208046, 0x00000041, 0x00000001, 0x00000004, 0x08000034, 0x00100032, 0x00000000, + 0x00100046, 0x00000000, 0x00208046, 0x00000001, 0x00000000, 0x08000033, 0x00100032, 0x00000000, + 0x00100046, 0x00000000, 0x00208ae6, 0x00000001, 0x00000000, 0x09000045, 0x001000f2, 0x00000001, + 0x00100046, 0x00000000, 0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x08000000, 0x00100012, + 0x00000000, 0x8010003a, 0x00000041, 0x00000000, 0x0010003a, 0x00000001, 0x08000038, 0x00100012, + 0x00000000, 0x0010000a, 0x00000000, 0x0020802a, 0x00000001, 0x00000004, 0x09002032, 0x00100012, + 0x00000000, 0x0010000a, 0x00000000, 0x00004001, 0x3f000000, 0x00004001, 0x3f000000, 0x05000036, + 0x00100022, 0x00000000, 0x00004001, 0x3f000000, 0x09000045, 0x001000f2, 0x00000000, 0x00100046, + 0x00000000, 0x00107e46, 0x00000002, 0x00106000, 0x00000002, 0x08000000, 0x00100012, 0x00000001, + 0x8010003a, 0x00000041, 0x00000000, 0x00004001, 0x3f800000, 0x08000034, 0x00100062, 0x00000001, + 0x00101106, 0x00000001, 0x00208106, 0x00000001, 0x00000001, 0x08000033, 0x00100062, 0x00000001, + 0x00100656, 0x00000001, 0x00208ba6, 0x00000001, 0x00000001, 0x09000045, 0x001000f2, 0x00000002, + 0x00100596, 0x00000001, 0x00107e46, 0x00000001, 0x00106000, 0x00000001, 0x09000032, 0x001020f2, + 0x00000000, 0x00100e46, 0x00000002, 0x00100006, 0x00000001, 0x00100e46, 0x00000000, 0x0100003e, + 0x54415453, 0x00000074, 0x00000013, 0x00000003, 0x00000000, 0x00000002, 0x0000000b, 0x00000000, + 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000004, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +}; + +static DWORD pshader_filter_27[387] = { + 0x43425844, 0xf3f7a1fb, 0xbd22ef0c, 0x3d9cc820, 0xe4ffde46, 0x00000001, 0x0000060c, 0x00000005, + 0x00000034, 0x000002d0, 0x00000328, 0x0000035c, 0x00000590, 0x46454452, 0x00000294, 0x00000002, + 0x00000100, 0x00000006, 0x0000001c, 0xffff0400, 0x00008100, 0x00000262, 0x000000dc, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000000e3, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0x00000001, 0x00000001, 0x000000ea, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000000, 0x00000001, 0x0000000d, 0x000000ef, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000002, 0x00000001, 0x0000000d, 0x000000f4, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000000f8, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x65745f73, 0x73003078, + 0x7865745f, 0x65740032, 0x74003078, 0x00327865, 0x00635350, 0x61726170, 0xababab00, 0x000000f4, + 0x00000004, 0x00000130, 0x00000040, 0x00000000, 0x00000000, 0x000000f8, 0x00000005, 0x000001c8, + 0x00000050, 0x00000000, 0x00000000, 0x00000190, 0x00000000, 0x00000010, 0x00000000, 0x0000019c, + 0x00000000, 0x000001ac, 0x00000010, 0x00000010, 0x00000000, 0x0000019c, 0x00000000, 0x000001b6, + 0x00000020, 0x00000010, 0x00000000, 0x0000019c, 0x00000000, 0x000001bc, 0x00000030, 0x00000010, + 0x00000000, 0x0000019c, 0x00000000, 0x6f6c6f63, 0x756d5f72, 0xabab006c, 0x00030001, 0x00040001, + 0x00000000, 0x00000000, 0x6f6c6f63, 0x64615f72, 0x6f660064, 0x006c6163, 0x63736572, 0x31656c61, + 0xababab00, 0x00000240, 0x00000000, 0x00000010, 0x00000002, 0x0000019c, 0x00000000, 0x00000247, + 0x00000010, 0x00000010, 0x00000000, 0x0000019c, 0x00000000, 0x0000024e, 0x00000020, 0x00000010, + 0x00000000, 0x0000019c, 0x00000000, 0x00000254, 0x00000030, 0x00000010, 0x00000000, 0x0000019c, + 0x00000000, 0x0000025b, 0x00000040, 0x00000010, 0x00000002, 0x0000019c, 0x00000000, 0x6d616c63, + 0x63003070, 0x706d616c, 0x6f630031, 0x00726f6c, 0x6f6c6f63, 0x74003272, 0x666f5f63, 0x694d0066, + 0x736f7263, 0x2074666f, 0x20295228, 0x4c534c48, 0x61685320, 0x20726564, 0x706d6f43, 0x72656c69, + 0x322e3920, 0x35392e39, 0x31332e32, 0xab003131, 0x4e475349, 0x00000050, 0x00000002, 0x00000008, + 0x00000038, 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x00000044, 0x00000000, + 0x00000000, 0x00000003, 0x00000001, 0x0000030f, 0x505f5653, 0x7469736f, 0x006e6f69, 0x43584554, + 0x44524f4f, 0xababab00, 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, + 0x00000000, 0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x52444853, + 0x0000022c, 0x00000040, 0x0000008b, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x04000059, + 0x00208e46, 0x00000001, 0x00000005, 0x0300005a, 0x00106000, 0x00000000, 0x0300005a, 0x00106000, + 0x00000002, 0x04001858, 0x00107000, 0x00000000, 0x00005555, 0x04001858, 0x00107000, 0x00000002, + 0x00005555, 0x03001062, 0x00101032, 0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x02000068, + 0x00000002, 0x08000000, 0x00100032, 0x00000000, 0x00101046, 0x00000001, 0x00208046, 0x00000001, + 0x00000004, 0x08000034, 0x00100032, 0x00000000, 0x00100046, 0x00000000, 0x00208046, 0x00000001, + 0x00000000, 0x08000033, 0x00100032, 0x00000000, 0x00100046, 0x00000000, 0x00208ae6, 0x00000001, + 0x00000000, 0x09000045, 0x001000f2, 0x00000000, 0x00100046, 0x00000000, 0x00107e46, 0x00000000, + 0x00106000, 0x00000000, 0x09000000, 0x00100032, 0x00000000, 0x00101046, 0x00000001, 0x80208046, + 0x00000041, 0x00000001, 0x00000004, 0x08000034, 0x00100032, 0x00000000, 0x00100046, 0x00000000, + 0x00208046, 0x00000001, 0x00000000, 0x08000033, 0x00100032, 0x00000000, 0x00100046, 0x00000000, + 0x00208ae6, 0x00000001, 0x00000000, 0x09000045, 0x001000f2, 0x00000001, 0x00100046, 0x00000000, + 0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x08000000, 0x00100012, 0x00000000, 0x8010003a, + 0x00000041, 0x00000000, 0x0010003a, 0x00000001, 0x08000038, 0x00100012, 0x00000000, 0x0010000a, + 0x00000000, 0x0020802a, 0x00000001, 0x00000004, 0x09002032, 0x00100012, 0x00000000, 0x0010000a, + 0x00000000, 0x00004001, 0x3f000000, 0x00004001, 0x3f000000, 0x05000036, 0x00100022, 0x00000000, + 0x00004001, 0x3f000000, 0x09000045, 0x001020f2, 0x00000000, 0x00100046, 0x00000000, 0x00107e46, + 0x00000002, 0x00106000, 0x00000002, 0x0100003e, 0x54415453, 0x00000074, 0x0000000e, 0x00000002, + 0x00000000, 0x00000002, 0x00000008, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, +}; + +static ProgramWithCachedVariableLocations pshader_filter_arr[32] = { + { pshader_filter_0, 1516, }, + { pshader_filter_1, 1508, }, + { pshader_filter_2, 1644, }, + { pshader_filter_3, 1636, }, + { pshader_filter_4, 1608, }, + { pshader_filter_5, 1508, }, + { pshader_filter_6, 1692, }, + { pshader_filter_7, 1604, }, + { pshader_filter_8, 984, }, + { pshader_filter_9, 708, }, + { pshader_filter_10, 1644, }, + { pshader_filter_11, 1372, }, + { NULL, 0, }, + { NULL, 0, }, + { NULL, 0, }, + { NULL, 0, }, + { pshader_filter_16, 1740, }, + { pshader_filter_17, 1732, }, + { pshader_filter_18, 1820, }, + { pshader_filter_19, 1812, }, + { pshader_filter_20, 1788, }, + { pshader_filter_21, 1700, }, + { pshader_filter_22, 1868, }, + { pshader_filter_23, 1780, }, + { pshader_filter_24, 1740, }, + { pshader_filter_25, 1468, }, + { pshader_filter_26, 1820, }, + { pshader_filter_27, 1548, }, + { NULL, 0, }, + { NULL, 0, }, + { NULL, 0, }, + { NULL, 0, }, +}; + +static DWORD pshader_blur_2[320] = { + 0x43425844, 0x67a35e3a, 0x560d90ec, 0x256f19fd, 0x4a310ce8, 0x00000001, 0x00000500, 0x00000005, + 0x00000034, 0x00000238, 0x00000290, 0x000002c4, 0x00000484, 0x46454452, 0x000001fc, 0x00000002, + 0x000000b4, 0x00000004, 0x0000001c, 0xffff0400, 0x00008100, 0x000001c8, 0x0000009c, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000000a3, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000000, 0x00000001, 0x0000000d, 0x000000a8, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000000ac, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x65745f73, 0x74003078, + 0x00307865, 0x00635350, 0x61726170, 0xababab00, 0x000000a8, 0x00000004, 0x000000e4, 0x00000040, + 0x00000000, 0x00000000, 0x000000ac, 0x00000002, 0x0000017c, 0x000000a0, 0x00000000, 0x00000000, + 0x00000144, 0x00000000, 0x00000010, 0x00000000, 0x00000150, 0x00000000, 0x00000160, 0x00000010, + 0x00000010, 0x00000000, 0x00000150, 0x00000000, 0x0000016a, 0x00000020, 0x00000010, 0x00000000, + 0x00000150, 0x00000000, 0x00000170, 0x00000030, 0x00000010, 0x00000000, 0x00000150, 0x00000000, + 0x6f6c6f63, 0x756d5f72, 0xabab006c, 0x00030001, 0x00040001, 0x00000000, 0x00000000, 0x6f6c6f63, + 0x64615f72, 0x6f660064, 0x006c6163, 0x63736572, 0x31656c61, 0xababab00, 0x000001ac, 0x00000000, + 0x00000010, 0x00000002, 0x00000150, 0x00000000, 0x000001b3, 0x00000010, 0x00000090, 0x00000002, + 0x000001b8, 0x00000000, 0x6d616c63, 0x74007670, 0xab007061, 0x00030001, 0x00040001, 0x00000009, + 0x00000000, 0x7263694d, 0x666f736f, 0x52282074, 0x4c482029, 0x53204c53, 0x65646168, 0x6f432072, + 0x6c69706d, 0x39207265, 0x2e39322e, 0x2e323539, 0x31313133, 0xababab00, 0x4e475349, 0x00000050, + 0x00000002, 0x00000008, 0x00000038, 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, + 0x00000044, 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x0000030f, 0x505f5653, 0x7469736f, + 0x006e6f69, 0x43584554, 0x44524f4f, 0xababab00, 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, + 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, + 0xabab0074, 0x52444853, 0x000001b8, 0x00000040, 0x0000006e, 0x04000059, 0x00208e46, 0x00000000, + 0x00000001, 0x04000059, 0x00208e46, 0x00000001, 0x00000003, 0x0300005a, 0x00106000, 0x00000000, + 0x04001858, 0x00107000, 0x00000000, 0x00005555, 0x03001062, 0x00101032, 0x00000001, 0x03000065, + 0x001020f2, 0x00000000, 0x02000068, 0x00000002, 0x08000000, 0x00100032, 0x00000000, 0x00101046, + 0x00000001, 0x00208046, 0x00000001, 0x00000002, 0x08000034, 0x00100032, 0x00000000, 0x00100046, + 0x00000000, 0x00208046, 0x00000001, 0x00000000, 0x08000033, 0x00100032, 0x00000000, 0x00100046, + 0x00000000, 0x00208ae6, 0x00000001, 0x00000000, 0x09000045, 0x001000f2, 0x00000000, 0x00100046, + 0x00000000, 0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x08000038, 0x001000f2, 0x00000000, + 0x00100e46, 0x00000000, 0x00208aa6, 0x00000001, 0x00000002, 0x08000000, 0x00100032, 0x00000001, + 0x00101046, 0x00000001, 0x00208046, 0x00000001, 0x00000001, 0x08000034, 0x00100032, 0x00000001, + 0x00100046, 0x00000001, 0x00208046, 0x00000001, 0x00000000, 0x08000033, 0x00100032, 0x00000001, + 0x00100046, 0x00000001, 0x00208ae6, 0x00000001, 0x00000000, 0x09000045, 0x001000f2, 0x00000001, + 0x00100046, 0x00000001, 0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x0a000032, 0x001020f2, + 0x00000000, 0x00100e46, 0x00000001, 0x00208aa6, 0x00000001, 0x00000001, 0x00100e46, 0x00000000, + 0x0100003e, 0x54415453, 0x00000074, 0x0000000b, 0x00000002, 0x00000000, 0x00000002, 0x00000007, + 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +}; + +static DWORD pshader_blur_3[363] = { + 0x43425844, 0xceb6aa80, 0x47281357, 0x6546706b, 0x9a86cc96, 0x00000001, 0x000005ac, 0x00000005, + 0x00000034, 0x00000238, 0x00000290, 0x000002c4, 0x00000530, 0x46454452, 0x000001fc, 0x00000002, + 0x000000b4, 0x00000004, 0x0000001c, 0xffff0400, 0x00008100, 0x000001c8, 0x0000009c, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000000a3, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000000, 0x00000001, 0x0000000d, 0x000000a8, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000000ac, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x65745f73, 0x74003078, + 0x00307865, 0x00635350, 0x61726170, 0xababab00, 0x000000a8, 0x00000004, 0x000000e4, 0x00000040, + 0x00000000, 0x00000000, 0x000000ac, 0x00000002, 0x0000017c, 0x000000a0, 0x00000000, 0x00000000, + 0x00000144, 0x00000000, 0x00000010, 0x00000000, 0x00000150, 0x00000000, 0x00000160, 0x00000010, + 0x00000010, 0x00000000, 0x00000150, 0x00000000, 0x0000016a, 0x00000020, 0x00000010, 0x00000000, + 0x00000150, 0x00000000, 0x00000170, 0x00000030, 0x00000010, 0x00000000, 0x00000150, 0x00000000, + 0x6f6c6f63, 0x756d5f72, 0xabab006c, 0x00030001, 0x00040001, 0x00000000, 0x00000000, 0x6f6c6f63, + 0x64615f72, 0x6f660064, 0x006c6163, 0x63736572, 0x31656c61, 0xababab00, 0x000001ac, 0x00000000, + 0x00000010, 0x00000002, 0x00000150, 0x00000000, 0x000001b3, 0x00000010, 0x00000090, 0x00000002, + 0x000001b8, 0x00000000, 0x6d616c63, 0x74007670, 0xab007061, 0x00030001, 0x00040001, 0x00000009, + 0x00000000, 0x7263694d, 0x666f736f, 0x52282074, 0x4c482029, 0x53204c53, 0x65646168, 0x6f432072, + 0x6c69706d, 0x39207265, 0x2e39322e, 0x2e323539, 0x31313133, 0xababab00, 0x4e475349, 0x00000050, + 0x00000002, 0x00000008, 0x00000038, 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, + 0x00000044, 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x0000030f, 0x505f5653, 0x7469736f, + 0x006e6f69, 0x43584554, 0x44524f4f, 0xababab00, 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, + 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, + 0xabab0074, 0x52444853, 0x00000264, 0x00000040, 0x00000099, 0x04000059, 0x00208e46, 0x00000000, + 0x00000001, 0x04000059, 0x00208e46, 0x00000001, 0x00000004, 0x0300005a, 0x00106000, 0x00000000, + 0x04001858, 0x00107000, 0x00000000, 0x00005555, 0x03001062, 0x00101032, 0x00000001, 0x03000065, + 0x001020f2, 0x00000000, 0x02000068, 0x00000002, 0x08000000, 0x00100032, 0x00000000, 0x00101046, + 0x00000001, 0x00208046, 0x00000001, 0x00000002, 0x08000034, 0x00100032, 0x00000000, 0x00100046, + 0x00000000, 0x00208046, 0x00000001, 0x00000000, 0x08000033, 0x00100032, 0x00000000, 0x00100046, + 0x00000000, 0x00208ae6, 0x00000001, 0x00000000, 0x09000045, 0x001000f2, 0x00000000, 0x00100046, + 0x00000000, 0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x08000038, 0x001000f2, 0x00000000, + 0x00100e46, 0x00000000, 0x00208aa6, 0x00000001, 0x00000002, 0x08000000, 0x00100032, 0x00000001, + 0x00101046, 0x00000001, 0x00208046, 0x00000001, 0x00000001, 0x08000034, 0x00100032, 0x00000001, + 0x00100046, 0x00000001, 0x00208046, 0x00000001, 0x00000000, 0x08000033, 0x00100032, 0x00000001, + 0x00100046, 0x00000001, 0x00208ae6, 0x00000001, 0x00000000, 0x09000045, 0x001000f2, 0x00000001, + 0x00100046, 0x00000001, 0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x0a000032, 0x001000f2, + 0x00000000, 0x00100e46, 0x00000001, 0x00208aa6, 0x00000001, 0x00000001, 0x00100e46, 0x00000000, + 0x08000000, 0x00100032, 0x00000001, 0x00101046, 0x00000001, 0x00208046, 0x00000001, 0x00000003, + 0x08000034, 0x00100032, 0x00000001, 0x00100046, 0x00000001, 0x00208046, 0x00000001, 0x00000000, + 0x08000033, 0x00100032, 0x00000001, 0x00100046, 0x00000001, 0x00208ae6, 0x00000001, 0x00000000, + 0x09000045, 0x001000f2, 0x00000001, 0x00100046, 0x00000001, 0x00107e46, 0x00000000, 0x00106000, + 0x00000000, 0x0a000032, 0x001020f2, 0x00000000, 0x00100e46, 0x00000001, 0x00208aa6, 0x00000001, + 0x00000003, 0x00100e46, 0x00000000, 0x0100003e, 0x54415453, 0x00000074, 0x00000010, 0x00000002, + 0x00000000, 0x00000002, 0x0000000a, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, +}; + +static DWORD pshader_blur_4[406] = { + 0x43425844, 0x28bb4db6, 0x76164852, 0x9c2d5fab, 0x2f864c24, 0x00000001, 0x00000658, 0x00000005, + 0x00000034, 0x00000238, 0x00000290, 0x000002c4, 0x000005dc, 0x46454452, 0x000001fc, 0x00000002, + 0x000000b4, 0x00000004, 0x0000001c, 0xffff0400, 0x00008100, 0x000001c8, 0x0000009c, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000000a3, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000000, 0x00000001, 0x0000000d, 0x000000a8, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000000ac, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x65745f73, 0x74003078, + 0x00307865, 0x00635350, 0x61726170, 0xababab00, 0x000000a8, 0x00000004, 0x000000e4, 0x00000040, + 0x00000000, 0x00000000, 0x000000ac, 0x00000002, 0x0000017c, 0x000000a0, 0x00000000, 0x00000000, + 0x00000144, 0x00000000, 0x00000010, 0x00000000, 0x00000150, 0x00000000, 0x00000160, 0x00000010, + 0x00000010, 0x00000000, 0x00000150, 0x00000000, 0x0000016a, 0x00000020, 0x00000010, 0x00000000, + 0x00000150, 0x00000000, 0x00000170, 0x00000030, 0x00000010, 0x00000000, 0x00000150, 0x00000000, + 0x6f6c6f63, 0x756d5f72, 0xabab006c, 0x00030001, 0x00040001, 0x00000000, 0x00000000, 0x6f6c6f63, + 0x64615f72, 0x6f660064, 0x006c6163, 0x63736572, 0x31656c61, 0xababab00, 0x000001ac, 0x00000000, + 0x00000010, 0x00000002, 0x00000150, 0x00000000, 0x000001b3, 0x00000010, 0x00000090, 0x00000002, + 0x000001b8, 0x00000000, 0x6d616c63, 0x74007670, 0xab007061, 0x00030001, 0x00040001, 0x00000009, + 0x00000000, 0x7263694d, 0x666f736f, 0x52282074, 0x4c482029, 0x53204c53, 0x65646168, 0x6f432072, + 0x6c69706d, 0x39207265, 0x2e39322e, 0x2e323539, 0x31313133, 0xababab00, 0x4e475349, 0x00000050, + 0x00000002, 0x00000008, 0x00000038, 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, + 0x00000044, 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x0000030f, 0x505f5653, 0x7469736f, + 0x006e6f69, 0x43584554, 0x44524f4f, 0xababab00, 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, + 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, + 0xabab0074, 0x52444853, 0x00000310, 0x00000040, 0x000000c4, 0x04000059, 0x00208e46, 0x00000000, + 0x00000001, 0x04000059, 0x00208e46, 0x00000001, 0x00000005, 0x0300005a, 0x00106000, 0x00000000, + 0x04001858, 0x00107000, 0x00000000, 0x00005555, 0x03001062, 0x00101032, 0x00000001, 0x03000065, + 0x001020f2, 0x00000000, 0x02000068, 0x00000002, 0x08000000, 0x00100032, 0x00000000, 0x00101046, + 0x00000001, 0x00208046, 0x00000001, 0x00000002, 0x08000034, 0x00100032, 0x00000000, 0x00100046, + 0x00000000, 0x00208046, 0x00000001, 0x00000000, 0x08000033, 0x00100032, 0x00000000, 0x00100046, + 0x00000000, 0x00208ae6, 0x00000001, 0x00000000, 0x09000045, 0x001000f2, 0x00000000, 0x00100046, + 0x00000000, 0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x08000038, 0x001000f2, 0x00000000, + 0x00100e46, 0x00000000, 0x00208aa6, 0x00000001, 0x00000002, 0x08000000, 0x00100032, 0x00000001, + 0x00101046, 0x00000001, 0x00208046, 0x00000001, 0x00000001, 0x08000034, 0x00100032, 0x00000001, + 0x00100046, 0x00000001, 0x00208046, 0x00000001, 0x00000000, 0x08000033, 0x00100032, 0x00000001, + 0x00100046, 0x00000001, 0x00208ae6, 0x00000001, 0x00000000, 0x09000045, 0x001000f2, 0x00000001, + 0x00100046, 0x00000001, 0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x0a000032, 0x001000f2, + 0x00000000, 0x00100e46, 0x00000001, 0x00208aa6, 0x00000001, 0x00000001, 0x00100e46, 0x00000000, + 0x08000000, 0x00100032, 0x00000001, 0x00101046, 0x00000001, 0x00208046, 0x00000001, 0x00000003, + 0x08000034, 0x00100032, 0x00000001, 0x00100046, 0x00000001, 0x00208046, 0x00000001, 0x00000000, + 0x08000033, 0x00100032, 0x00000001, 0x00100046, 0x00000001, 0x00208ae6, 0x00000001, 0x00000000, + 0x09000045, 0x001000f2, 0x00000001, 0x00100046, 0x00000001, 0x00107e46, 0x00000000, 0x00106000, + 0x00000000, 0x0a000032, 0x001000f2, 0x00000000, 0x00100e46, 0x00000001, 0x00208aa6, 0x00000001, + 0x00000003, 0x00100e46, 0x00000000, 0x08000000, 0x00100032, 0x00000001, 0x00101046, 0x00000001, + 0x00208046, 0x00000001, 0x00000004, 0x08000034, 0x00100032, 0x00000001, 0x00100046, 0x00000001, + 0x00208046, 0x00000001, 0x00000000, 0x08000033, 0x00100032, 0x00000001, 0x00100046, 0x00000001, + 0x00208ae6, 0x00000001, 0x00000000, 0x09000045, 0x001000f2, 0x00000001, 0x00100046, 0x00000001, + 0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x0a000032, 0x001020f2, 0x00000000, 0x00100e46, + 0x00000001, 0x00208aa6, 0x00000001, 0x00000004, 0x00100e46, 0x00000000, 0x0100003e, 0x54415453, + 0x00000074, 0x00000015, 0x00000002, 0x00000000, 0x00000002, 0x0000000d, 0x00000000, 0x00000000, + 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000004, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +}; + +static DWORD pshader_blur_5[449] = { + 0x43425844, 0x750da756, 0x7d011ff8, 0xac8d5660, 0x8246b36e, 0x00000001, 0x00000704, 0x00000005, + 0x00000034, 0x00000238, 0x00000290, 0x000002c4, 0x00000688, 0x46454452, 0x000001fc, 0x00000002, + 0x000000b4, 0x00000004, 0x0000001c, 0xffff0400, 0x00008100, 0x000001c8, 0x0000009c, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000000a3, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000000, 0x00000001, 0x0000000d, 0x000000a8, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000000ac, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x65745f73, 0x74003078, + 0x00307865, 0x00635350, 0x61726170, 0xababab00, 0x000000a8, 0x00000004, 0x000000e4, 0x00000040, + 0x00000000, 0x00000000, 0x000000ac, 0x00000002, 0x0000017c, 0x000000a0, 0x00000000, 0x00000000, + 0x00000144, 0x00000000, 0x00000010, 0x00000000, 0x00000150, 0x00000000, 0x00000160, 0x00000010, + 0x00000010, 0x00000000, 0x00000150, 0x00000000, 0x0000016a, 0x00000020, 0x00000010, 0x00000000, + 0x00000150, 0x00000000, 0x00000170, 0x00000030, 0x00000010, 0x00000000, 0x00000150, 0x00000000, + 0x6f6c6f63, 0x756d5f72, 0xabab006c, 0x00030001, 0x00040001, 0x00000000, 0x00000000, 0x6f6c6f63, + 0x64615f72, 0x6f660064, 0x006c6163, 0x63736572, 0x31656c61, 0xababab00, 0x000001ac, 0x00000000, + 0x00000010, 0x00000002, 0x00000150, 0x00000000, 0x000001b3, 0x00000010, 0x00000090, 0x00000002, + 0x000001b8, 0x00000000, 0x6d616c63, 0x74007670, 0xab007061, 0x00030001, 0x00040001, 0x00000009, + 0x00000000, 0x7263694d, 0x666f736f, 0x52282074, 0x4c482029, 0x53204c53, 0x65646168, 0x6f432072, + 0x6c69706d, 0x39207265, 0x2e39322e, 0x2e323539, 0x31313133, 0xababab00, 0x4e475349, 0x00000050, + 0x00000002, 0x00000008, 0x00000038, 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, + 0x00000044, 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x0000030f, 0x505f5653, 0x7469736f, + 0x006e6f69, 0x43584554, 0x44524f4f, 0xababab00, 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, + 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, + 0xabab0074, 0x52444853, 0x000003bc, 0x00000040, 0x000000ef, 0x04000059, 0x00208e46, 0x00000000, + 0x00000001, 0x04000059, 0x00208e46, 0x00000001, 0x00000006, 0x0300005a, 0x00106000, 0x00000000, + 0x04001858, 0x00107000, 0x00000000, 0x00005555, 0x03001062, 0x00101032, 0x00000001, 0x03000065, + 0x001020f2, 0x00000000, 0x02000068, 0x00000002, 0x08000000, 0x00100032, 0x00000000, 0x00101046, + 0x00000001, 0x00208046, 0x00000001, 0x00000002, 0x08000034, 0x00100032, 0x00000000, 0x00100046, + 0x00000000, 0x00208046, 0x00000001, 0x00000000, 0x08000033, 0x00100032, 0x00000000, 0x00100046, + 0x00000000, 0x00208ae6, 0x00000001, 0x00000000, 0x09000045, 0x001000f2, 0x00000000, 0x00100046, + 0x00000000, 0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x08000038, 0x001000f2, 0x00000000, + 0x00100e46, 0x00000000, 0x00208aa6, 0x00000001, 0x00000002, 0x08000000, 0x00100032, 0x00000001, + 0x00101046, 0x00000001, 0x00208046, 0x00000001, 0x00000001, 0x08000034, 0x00100032, 0x00000001, + 0x00100046, 0x00000001, 0x00208046, 0x00000001, 0x00000000, 0x08000033, 0x00100032, 0x00000001, + 0x00100046, 0x00000001, 0x00208ae6, 0x00000001, 0x00000000, 0x09000045, 0x001000f2, 0x00000001, + 0x00100046, 0x00000001, 0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x0a000032, 0x001000f2, + 0x00000000, 0x00100e46, 0x00000001, 0x00208aa6, 0x00000001, 0x00000001, 0x00100e46, 0x00000000, + 0x08000000, 0x00100032, 0x00000001, 0x00101046, 0x00000001, 0x00208046, 0x00000001, 0x00000003, + 0x08000034, 0x00100032, 0x00000001, 0x00100046, 0x00000001, 0x00208046, 0x00000001, 0x00000000, + 0x08000033, 0x00100032, 0x00000001, 0x00100046, 0x00000001, 0x00208ae6, 0x00000001, 0x00000000, + 0x09000045, 0x001000f2, 0x00000001, 0x00100046, 0x00000001, 0x00107e46, 0x00000000, 0x00106000, + 0x00000000, 0x0a000032, 0x001000f2, 0x00000000, 0x00100e46, 0x00000001, 0x00208aa6, 0x00000001, + 0x00000003, 0x00100e46, 0x00000000, 0x08000000, 0x00100032, 0x00000001, 0x00101046, 0x00000001, + 0x00208046, 0x00000001, 0x00000004, 0x08000034, 0x00100032, 0x00000001, 0x00100046, 0x00000001, + 0x00208046, 0x00000001, 0x00000000, 0x08000033, 0x00100032, 0x00000001, 0x00100046, 0x00000001, + 0x00208ae6, 0x00000001, 0x00000000, 0x09000045, 0x001000f2, 0x00000001, 0x00100046, 0x00000001, + 0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x0a000032, 0x001000f2, 0x00000000, 0x00100e46, + 0x00000001, 0x00208aa6, 0x00000001, 0x00000004, 0x00100e46, 0x00000000, 0x08000000, 0x00100032, + 0x00000001, 0x00101046, 0x00000001, 0x00208046, 0x00000001, 0x00000005, 0x08000034, 0x00100032, + 0x00000001, 0x00100046, 0x00000001, 0x00208046, 0x00000001, 0x00000000, 0x08000033, 0x00100032, + 0x00000001, 0x00100046, 0x00000001, 0x00208ae6, 0x00000001, 0x00000000, 0x09000045, 0x001000f2, + 0x00000001, 0x00100046, 0x00000001, 0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x0a000032, + 0x001020f2, 0x00000000, 0x00100e46, 0x00000001, 0x00208aa6, 0x00000001, 0x00000005, 0x00100e46, + 0x00000000, 0x0100003e, 0x54415453, 0x00000074, 0x0000001a, 0x00000002, 0x00000000, 0x00000002, + 0x00000010, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000005, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, +}; + +static DWORD pshader_blur_6[492] = { + 0x43425844, 0xaa04fad9, 0xf1b31202, 0xbebf01fc, 0xc2f4f30e, 0x00000001, 0x000007b0, 0x00000005, + 0x00000034, 0x00000238, 0x00000290, 0x000002c4, 0x00000734, 0x46454452, 0x000001fc, 0x00000002, + 0x000000b4, 0x00000004, 0x0000001c, 0xffff0400, 0x00008100, 0x000001c8, 0x0000009c, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000000a3, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000000, 0x00000001, 0x0000000d, 0x000000a8, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000000ac, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x65745f73, 0x74003078, + 0x00307865, 0x00635350, 0x61726170, 0xababab00, 0x000000a8, 0x00000004, 0x000000e4, 0x00000040, + 0x00000000, 0x00000000, 0x000000ac, 0x00000002, 0x0000017c, 0x000000a0, 0x00000000, 0x00000000, + 0x00000144, 0x00000000, 0x00000010, 0x00000000, 0x00000150, 0x00000000, 0x00000160, 0x00000010, + 0x00000010, 0x00000000, 0x00000150, 0x00000000, 0x0000016a, 0x00000020, 0x00000010, 0x00000000, + 0x00000150, 0x00000000, 0x00000170, 0x00000030, 0x00000010, 0x00000000, 0x00000150, 0x00000000, + 0x6f6c6f63, 0x756d5f72, 0xabab006c, 0x00030001, 0x00040001, 0x00000000, 0x00000000, 0x6f6c6f63, + 0x64615f72, 0x6f660064, 0x006c6163, 0x63736572, 0x31656c61, 0xababab00, 0x000001ac, 0x00000000, + 0x00000010, 0x00000002, 0x00000150, 0x00000000, 0x000001b3, 0x00000010, 0x00000090, 0x00000002, + 0x000001b8, 0x00000000, 0x6d616c63, 0x74007670, 0xab007061, 0x00030001, 0x00040001, 0x00000009, + 0x00000000, 0x7263694d, 0x666f736f, 0x52282074, 0x4c482029, 0x53204c53, 0x65646168, 0x6f432072, + 0x6c69706d, 0x39207265, 0x2e39322e, 0x2e323539, 0x31313133, 0xababab00, 0x4e475349, 0x00000050, + 0x00000002, 0x00000008, 0x00000038, 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, + 0x00000044, 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x0000030f, 0x505f5653, 0x7469736f, + 0x006e6f69, 0x43584554, 0x44524f4f, 0xababab00, 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, + 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, + 0xabab0074, 0x52444853, 0x00000468, 0x00000040, 0x0000011a, 0x04000059, 0x00208e46, 0x00000000, + 0x00000001, 0x04000059, 0x00208e46, 0x00000001, 0x00000007, 0x0300005a, 0x00106000, 0x00000000, + 0x04001858, 0x00107000, 0x00000000, 0x00005555, 0x03001062, 0x00101032, 0x00000001, 0x03000065, + 0x001020f2, 0x00000000, 0x02000068, 0x00000002, 0x08000000, 0x00100032, 0x00000000, 0x00101046, + 0x00000001, 0x00208046, 0x00000001, 0x00000002, 0x08000034, 0x00100032, 0x00000000, 0x00100046, + 0x00000000, 0x00208046, 0x00000001, 0x00000000, 0x08000033, 0x00100032, 0x00000000, 0x00100046, + 0x00000000, 0x00208ae6, 0x00000001, 0x00000000, 0x09000045, 0x001000f2, 0x00000000, 0x00100046, + 0x00000000, 0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x08000038, 0x001000f2, 0x00000000, + 0x00100e46, 0x00000000, 0x00208aa6, 0x00000001, 0x00000002, 0x08000000, 0x00100032, 0x00000001, + 0x00101046, 0x00000001, 0x00208046, 0x00000001, 0x00000001, 0x08000034, 0x00100032, 0x00000001, + 0x00100046, 0x00000001, 0x00208046, 0x00000001, 0x00000000, 0x08000033, 0x00100032, 0x00000001, + 0x00100046, 0x00000001, 0x00208ae6, 0x00000001, 0x00000000, 0x09000045, 0x001000f2, 0x00000001, + 0x00100046, 0x00000001, 0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x0a000032, 0x001000f2, + 0x00000000, 0x00100e46, 0x00000001, 0x00208aa6, 0x00000001, 0x00000001, 0x00100e46, 0x00000000, + 0x08000000, 0x00100032, 0x00000001, 0x00101046, 0x00000001, 0x00208046, 0x00000001, 0x00000003, + 0x08000034, 0x00100032, 0x00000001, 0x00100046, 0x00000001, 0x00208046, 0x00000001, 0x00000000, + 0x08000033, 0x00100032, 0x00000001, 0x00100046, 0x00000001, 0x00208ae6, 0x00000001, 0x00000000, + 0x09000045, 0x001000f2, 0x00000001, 0x00100046, 0x00000001, 0x00107e46, 0x00000000, 0x00106000, + 0x00000000, 0x0a000032, 0x001000f2, 0x00000000, 0x00100e46, 0x00000001, 0x00208aa6, 0x00000001, + 0x00000003, 0x00100e46, 0x00000000, 0x08000000, 0x00100032, 0x00000001, 0x00101046, 0x00000001, + 0x00208046, 0x00000001, 0x00000004, 0x08000034, 0x00100032, 0x00000001, 0x00100046, 0x00000001, + 0x00208046, 0x00000001, 0x00000000, 0x08000033, 0x00100032, 0x00000001, 0x00100046, 0x00000001, + 0x00208ae6, 0x00000001, 0x00000000, 0x09000045, 0x001000f2, 0x00000001, 0x00100046, 0x00000001, + 0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x0a000032, 0x001000f2, 0x00000000, 0x00100e46, + 0x00000001, 0x00208aa6, 0x00000001, 0x00000004, 0x00100e46, 0x00000000, 0x08000000, 0x00100032, + 0x00000001, 0x00101046, 0x00000001, 0x00208046, 0x00000001, 0x00000005, 0x08000034, 0x00100032, + 0x00000001, 0x00100046, 0x00000001, 0x00208046, 0x00000001, 0x00000000, 0x08000033, 0x00100032, + 0x00000001, 0x00100046, 0x00000001, 0x00208ae6, 0x00000001, 0x00000000, 0x09000045, 0x001000f2, + 0x00000001, 0x00100046, 0x00000001, 0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x0a000032, + 0x001000f2, 0x00000000, 0x00100e46, 0x00000001, 0x00208aa6, 0x00000001, 0x00000005, 0x00100e46, + 0x00000000, 0x08000000, 0x00100032, 0x00000001, 0x00101046, 0x00000001, 0x00208046, 0x00000001, + 0x00000006, 0x08000034, 0x00100032, 0x00000001, 0x00100046, 0x00000001, 0x00208046, 0x00000001, + 0x00000000, 0x08000033, 0x00100032, 0x00000001, 0x00100046, 0x00000001, 0x00208ae6, 0x00000001, + 0x00000000, 0x09000045, 0x001000f2, 0x00000001, 0x00100046, 0x00000001, 0x00107e46, 0x00000000, + 0x00106000, 0x00000000, 0x0a000032, 0x001020f2, 0x00000000, 0x00100e46, 0x00000001, 0x00208aa6, + 0x00000001, 0x00000006, 0x00100e46, 0x00000000, 0x0100003e, 0x54415453, 0x00000074, 0x0000001f, + 0x00000002, 0x00000000, 0x00000002, 0x00000013, 0x00000000, 0x00000000, 0x00000001, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000006, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, +}; + +static DWORD pshader_blur_7[535] = { + 0x43425844, 0xd887ebb4, 0xc4924177, 0xe04802c2, 0xf91cc99d, 0x00000001, 0x0000085c, 0x00000005, + 0x00000034, 0x00000238, 0x00000290, 0x000002c4, 0x000007e0, 0x46454452, 0x000001fc, 0x00000002, + 0x000000b4, 0x00000004, 0x0000001c, 0xffff0400, 0x00008100, 0x000001c8, 0x0000009c, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000000a3, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000000, 0x00000001, 0x0000000d, 0x000000a8, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000000ac, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x65745f73, 0x74003078, + 0x00307865, 0x00635350, 0x61726170, 0xababab00, 0x000000a8, 0x00000004, 0x000000e4, 0x00000040, + 0x00000000, 0x00000000, 0x000000ac, 0x00000002, 0x0000017c, 0x000000a0, 0x00000000, 0x00000000, + 0x00000144, 0x00000000, 0x00000010, 0x00000000, 0x00000150, 0x00000000, 0x00000160, 0x00000010, + 0x00000010, 0x00000000, 0x00000150, 0x00000000, 0x0000016a, 0x00000020, 0x00000010, 0x00000000, + 0x00000150, 0x00000000, 0x00000170, 0x00000030, 0x00000010, 0x00000000, 0x00000150, 0x00000000, + 0x6f6c6f63, 0x756d5f72, 0xabab006c, 0x00030001, 0x00040001, 0x00000000, 0x00000000, 0x6f6c6f63, + 0x64615f72, 0x6f660064, 0x006c6163, 0x63736572, 0x31656c61, 0xababab00, 0x000001ac, 0x00000000, + 0x00000010, 0x00000002, 0x00000150, 0x00000000, 0x000001b3, 0x00000010, 0x00000090, 0x00000002, + 0x000001b8, 0x00000000, 0x6d616c63, 0x74007670, 0xab007061, 0x00030001, 0x00040001, 0x00000009, + 0x00000000, 0x7263694d, 0x666f736f, 0x52282074, 0x4c482029, 0x53204c53, 0x65646168, 0x6f432072, + 0x6c69706d, 0x39207265, 0x2e39322e, 0x2e323539, 0x31313133, 0xababab00, 0x4e475349, 0x00000050, + 0x00000002, 0x00000008, 0x00000038, 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, + 0x00000044, 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x0000030f, 0x505f5653, 0x7469736f, + 0x006e6f69, 0x43584554, 0x44524f4f, 0xababab00, 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, + 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, + 0xabab0074, 0x52444853, 0x00000514, 0x00000040, 0x00000145, 0x04000059, 0x00208e46, 0x00000000, + 0x00000001, 0x04000059, 0x00208e46, 0x00000001, 0x00000008, 0x0300005a, 0x00106000, 0x00000000, + 0x04001858, 0x00107000, 0x00000000, 0x00005555, 0x03001062, 0x00101032, 0x00000001, 0x03000065, + 0x001020f2, 0x00000000, 0x02000068, 0x00000002, 0x08000000, 0x00100032, 0x00000000, 0x00101046, + 0x00000001, 0x00208046, 0x00000001, 0x00000002, 0x08000034, 0x00100032, 0x00000000, 0x00100046, + 0x00000000, 0x00208046, 0x00000001, 0x00000000, 0x08000033, 0x00100032, 0x00000000, 0x00100046, + 0x00000000, 0x00208ae6, 0x00000001, 0x00000000, 0x09000045, 0x001000f2, 0x00000000, 0x00100046, + 0x00000000, 0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x08000038, 0x001000f2, 0x00000000, + 0x00100e46, 0x00000000, 0x00208aa6, 0x00000001, 0x00000002, 0x08000000, 0x00100032, 0x00000001, + 0x00101046, 0x00000001, 0x00208046, 0x00000001, 0x00000001, 0x08000034, 0x00100032, 0x00000001, + 0x00100046, 0x00000001, 0x00208046, 0x00000001, 0x00000000, 0x08000033, 0x00100032, 0x00000001, + 0x00100046, 0x00000001, 0x00208ae6, 0x00000001, 0x00000000, 0x09000045, 0x001000f2, 0x00000001, + 0x00100046, 0x00000001, 0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x0a000032, 0x001000f2, + 0x00000000, 0x00100e46, 0x00000001, 0x00208aa6, 0x00000001, 0x00000001, 0x00100e46, 0x00000000, + 0x08000000, 0x00100032, 0x00000001, 0x00101046, 0x00000001, 0x00208046, 0x00000001, 0x00000003, + 0x08000034, 0x00100032, 0x00000001, 0x00100046, 0x00000001, 0x00208046, 0x00000001, 0x00000000, + 0x08000033, 0x00100032, 0x00000001, 0x00100046, 0x00000001, 0x00208ae6, 0x00000001, 0x00000000, + 0x09000045, 0x001000f2, 0x00000001, 0x00100046, 0x00000001, 0x00107e46, 0x00000000, 0x00106000, + 0x00000000, 0x0a000032, 0x001000f2, 0x00000000, 0x00100e46, 0x00000001, 0x00208aa6, 0x00000001, + 0x00000003, 0x00100e46, 0x00000000, 0x08000000, 0x00100032, 0x00000001, 0x00101046, 0x00000001, + 0x00208046, 0x00000001, 0x00000004, 0x08000034, 0x00100032, 0x00000001, 0x00100046, 0x00000001, + 0x00208046, 0x00000001, 0x00000000, 0x08000033, 0x00100032, 0x00000001, 0x00100046, 0x00000001, + 0x00208ae6, 0x00000001, 0x00000000, 0x09000045, 0x001000f2, 0x00000001, 0x00100046, 0x00000001, + 0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x0a000032, 0x001000f2, 0x00000000, 0x00100e46, + 0x00000001, 0x00208aa6, 0x00000001, 0x00000004, 0x00100e46, 0x00000000, 0x08000000, 0x00100032, + 0x00000001, 0x00101046, 0x00000001, 0x00208046, 0x00000001, 0x00000005, 0x08000034, 0x00100032, + 0x00000001, 0x00100046, 0x00000001, 0x00208046, 0x00000001, 0x00000000, 0x08000033, 0x00100032, + 0x00000001, 0x00100046, 0x00000001, 0x00208ae6, 0x00000001, 0x00000000, 0x09000045, 0x001000f2, + 0x00000001, 0x00100046, 0x00000001, 0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x0a000032, + 0x001000f2, 0x00000000, 0x00100e46, 0x00000001, 0x00208aa6, 0x00000001, 0x00000005, 0x00100e46, + 0x00000000, 0x08000000, 0x00100032, 0x00000001, 0x00101046, 0x00000001, 0x00208046, 0x00000001, + 0x00000006, 0x08000034, 0x00100032, 0x00000001, 0x00100046, 0x00000001, 0x00208046, 0x00000001, + 0x00000000, 0x08000033, 0x00100032, 0x00000001, 0x00100046, 0x00000001, 0x00208ae6, 0x00000001, + 0x00000000, 0x09000045, 0x001000f2, 0x00000001, 0x00100046, 0x00000001, 0x00107e46, 0x00000000, + 0x00106000, 0x00000000, 0x0a000032, 0x001000f2, 0x00000000, 0x00100e46, 0x00000001, 0x00208aa6, + 0x00000001, 0x00000006, 0x00100e46, 0x00000000, 0x08000000, 0x00100032, 0x00000001, 0x00101046, + 0x00000001, 0x00208046, 0x00000001, 0x00000007, 0x08000034, 0x00100032, 0x00000001, 0x00100046, + 0x00000001, 0x00208046, 0x00000001, 0x00000000, 0x08000033, 0x00100032, 0x00000001, 0x00100046, + 0x00000001, 0x00208ae6, 0x00000001, 0x00000000, 0x09000045, 0x001000f2, 0x00000001, 0x00100046, + 0x00000001, 0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x0a000032, 0x001020f2, 0x00000000, + 0x00100e46, 0x00000001, 0x00208aa6, 0x00000001, 0x00000007, 0x00100e46, 0x00000000, 0x0100003e, + 0x54415453, 0x00000074, 0x00000024, 0x00000002, 0x00000000, 0x00000002, 0x00000016, 0x00000000, + 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000007, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +}; + +static DWORD pshader_blur_8[578] = { + 0x43425844, 0x27ab5347, 0x36a0e6bc, 0xb93d307d, 0xb1f00bc0, 0x00000001, 0x00000908, 0x00000005, + 0x00000034, 0x00000238, 0x00000290, 0x000002c4, 0x0000088c, 0x46454452, 0x000001fc, 0x00000002, + 0x000000b4, 0x00000004, 0x0000001c, 0xffff0400, 0x00008100, 0x000001c8, 0x0000009c, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000000a3, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000000, 0x00000001, 0x0000000d, 0x000000a8, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000000ac, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x65745f73, 0x74003078, + 0x00307865, 0x00635350, 0x61726170, 0xababab00, 0x000000a8, 0x00000004, 0x000000e4, 0x00000040, + 0x00000000, 0x00000000, 0x000000ac, 0x00000002, 0x0000017c, 0x000000a0, 0x00000000, 0x00000000, + 0x00000144, 0x00000000, 0x00000010, 0x00000000, 0x00000150, 0x00000000, 0x00000160, 0x00000010, + 0x00000010, 0x00000000, 0x00000150, 0x00000000, 0x0000016a, 0x00000020, 0x00000010, 0x00000000, + 0x00000150, 0x00000000, 0x00000170, 0x00000030, 0x00000010, 0x00000000, 0x00000150, 0x00000000, + 0x6f6c6f63, 0x756d5f72, 0xabab006c, 0x00030001, 0x00040001, 0x00000000, 0x00000000, 0x6f6c6f63, + 0x64615f72, 0x6f660064, 0x006c6163, 0x63736572, 0x31656c61, 0xababab00, 0x000001ac, 0x00000000, + 0x00000010, 0x00000002, 0x00000150, 0x00000000, 0x000001b3, 0x00000010, 0x00000090, 0x00000002, + 0x000001b8, 0x00000000, 0x6d616c63, 0x74007670, 0xab007061, 0x00030001, 0x00040001, 0x00000009, + 0x00000000, 0x7263694d, 0x666f736f, 0x52282074, 0x4c482029, 0x53204c53, 0x65646168, 0x6f432072, + 0x6c69706d, 0x39207265, 0x2e39322e, 0x2e323539, 0x31313133, 0xababab00, 0x4e475349, 0x00000050, + 0x00000002, 0x00000008, 0x00000038, 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, + 0x00000044, 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x0000030f, 0x505f5653, 0x7469736f, + 0x006e6f69, 0x43584554, 0x44524f4f, 0xababab00, 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, + 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, + 0xabab0074, 0x52444853, 0x000005c0, 0x00000040, 0x00000170, 0x04000059, 0x00208e46, 0x00000000, + 0x00000001, 0x04000059, 0x00208e46, 0x00000001, 0x00000009, 0x0300005a, 0x00106000, 0x00000000, + 0x04001858, 0x00107000, 0x00000000, 0x00005555, 0x03001062, 0x00101032, 0x00000001, 0x03000065, + 0x001020f2, 0x00000000, 0x02000068, 0x00000002, 0x08000000, 0x00100032, 0x00000000, 0x00101046, + 0x00000001, 0x00208046, 0x00000001, 0x00000002, 0x08000034, 0x00100032, 0x00000000, 0x00100046, + 0x00000000, 0x00208046, 0x00000001, 0x00000000, 0x08000033, 0x00100032, 0x00000000, 0x00100046, + 0x00000000, 0x00208ae6, 0x00000001, 0x00000000, 0x09000045, 0x001000f2, 0x00000000, 0x00100046, + 0x00000000, 0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x08000038, 0x001000f2, 0x00000000, + 0x00100e46, 0x00000000, 0x00208aa6, 0x00000001, 0x00000002, 0x08000000, 0x00100032, 0x00000001, + 0x00101046, 0x00000001, 0x00208046, 0x00000001, 0x00000001, 0x08000034, 0x00100032, 0x00000001, + 0x00100046, 0x00000001, 0x00208046, 0x00000001, 0x00000000, 0x08000033, 0x00100032, 0x00000001, + 0x00100046, 0x00000001, 0x00208ae6, 0x00000001, 0x00000000, 0x09000045, 0x001000f2, 0x00000001, + 0x00100046, 0x00000001, 0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x0a000032, 0x001000f2, + 0x00000000, 0x00100e46, 0x00000001, 0x00208aa6, 0x00000001, 0x00000001, 0x00100e46, 0x00000000, + 0x08000000, 0x00100032, 0x00000001, 0x00101046, 0x00000001, 0x00208046, 0x00000001, 0x00000003, + 0x08000034, 0x00100032, 0x00000001, 0x00100046, 0x00000001, 0x00208046, 0x00000001, 0x00000000, + 0x08000033, 0x00100032, 0x00000001, 0x00100046, 0x00000001, 0x00208ae6, 0x00000001, 0x00000000, + 0x09000045, 0x001000f2, 0x00000001, 0x00100046, 0x00000001, 0x00107e46, 0x00000000, 0x00106000, + 0x00000000, 0x0a000032, 0x001000f2, 0x00000000, 0x00100e46, 0x00000001, 0x00208aa6, 0x00000001, + 0x00000003, 0x00100e46, 0x00000000, 0x08000000, 0x00100032, 0x00000001, 0x00101046, 0x00000001, + 0x00208046, 0x00000001, 0x00000004, 0x08000034, 0x00100032, 0x00000001, 0x00100046, 0x00000001, + 0x00208046, 0x00000001, 0x00000000, 0x08000033, 0x00100032, 0x00000001, 0x00100046, 0x00000001, + 0x00208ae6, 0x00000001, 0x00000000, 0x09000045, 0x001000f2, 0x00000001, 0x00100046, 0x00000001, + 0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x0a000032, 0x001000f2, 0x00000000, 0x00100e46, + 0x00000001, 0x00208aa6, 0x00000001, 0x00000004, 0x00100e46, 0x00000000, 0x08000000, 0x00100032, + 0x00000001, 0x00101046, 0x00000001, 0x00208046, 0x00000001, 0x00000005, 0x08000034, 0x00100032, + 0x00000001, 0x00100046, 0x00000001, 0x00208046, 0x00000001, 0x00000000, 0x08000033, 0x00100032, + 0x00000001, 0x00100046, 0x00000001, 0x00208ae6, 0x00000001, 0x00000000, 0x09000045, 0x001000f2, + 0x00000001, 0x00100046, 0x00000001, 0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x0a000032, + 0x001000f2, 0x00000000, 0x00100e46, 0x00000001, 0x00208aa6, 0x00000001, 0x00000005, 0x00100e46, + 0x00000000, 0x08000000, 0x00100032, 0x00000001, 0x00101046, 0x00000001, 0x00208046, 0x00000001, + 0x00000006, 0x08000034, 0x00100032, 0x00000001, 0x00100046, 0x00000001, 0x00208046, 0x00000001, + 0x00000000, 0x08000033, 0x00100032, 0x00000001, 0x00100046, 0x00000001, 0x00208ae6, 0x00000001, + 0x00000000, 0x09000045, 0x001000f2, 0x00000001, 0x00100046, 0x00000001, 0x00107e46, 0x00000000, + 0x00106000, 0x00000000, 0x0a000032, 0x001000f2, 0x00000000, 0x00100e46, 0x00000001, 0x00208aa6, + 0x00000001, 0x00000006, 0x00100e46, 0x00000000, 0x08000000, 0x00100032, 0x00000001, 0x00101046, + 0x00000001, 0x00208046, 0x00000001, 0x00000007, 0x08000034, 0x00100032, 0x00000001, 0x00100046, + 0x00000001, 0x00208046, 0x00000001, 0x00000000, 0x08000033, 0x00100032, 0x00000001, 0x00100046, + 0x00000001, 0x00208ae6, 0x00000001, 0x00000000, 0x09000045, 0x001000f2, 0x00000001, 0x00100046, + 0x00000001, 0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x0a000032, 0x001000f2, 0x00000000, + 0x00100e46, 0x00000001, 0x00208aa6, 0x00000001, 0x00000007, 0x00100e46, 0x00000000, 0x08000000, + 0x00100032, 0x00000001, 0x00101046, 0x00000001, 0x00208046, 0x00000001, 0x00000008, 0x08000034, + 0x00100032, 0x00000001, 0x00100046, 0x00000001, 0x00208046, 0x00000001, 0x00000000, 0x08000033, + 0x00100032, 0x00000001, 0x00100046, 0x00000001, 0x00208ae6, 0x00000001, 0x00000000, 0x09000045, + 0x001000f2, 0x00000001, 0x00100046, 0x00000001, 0x00107e46, 0x00000000, 0x00106000, 0x00000000, + 0x0a000032, 0x001020f2, 0x00000000, 0x00100e46, 0x00000001, 0x00208aa6, 0x00000001, 0x00000008, + 0x00100e46, 0x00000000, 0x0100003e, 0x54415453, 0x00000074, 0x00000029, 0x00000002, 0x00000000, + 0x00000002, 0x00000019, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000008, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, +}; + +static DWORD pshader_blur_9[621] = { + 0x43425844, 0xab49c198, 0x28ead186, 0xcdcc1184, 0x605159a1, 0x00000001, 0x000009b4, 0x00000005, + 0x00000034, 0x00000238, 0x00000290, 0x000002c4, 0x00000938, 0x46454452, 0x000001fc, 0x00000002, + 0x000000b4, 0x00000004, 0x0000001c, 0xffff0400, 0x00008100, 0x000001c8, 0x0000009c, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000000a3, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000000, 0x00000001, 0x0000000d, 0x000000a8, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000000ac, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x65745f73, 0x74003078, + 0x00307865, 0x00635350, 0x61726170, 0xababab00, 0x000000a8, 0x00000004, 0x000000e4, 0x00000040, + 0x00000000, 0x00000000, 0x000000ac, 0x00000002, 0x0000017c, 0x000000a0, 0x00000000, 0x00000000, + 0x00000144, 0x00000000, 0x00000010, 0x00000000, 0x00000150, 0x00000000, 0x00000160, 0x00000010, + 0x00000010, 0x00000000, 0x00000150, 0x00000000, 0x0000016a, 0x00000020, 0x00000010, 0x00000000, + 0x00000150, 0x00000000, 0x00000170, 0x00000030, 0x00000010, 0x00000000, 0x00000150, 0x00000000, + 0x6f6c6f63, 0x756d5f72, 0xabab006c, 0x00030001, 0x00040001, 0x00000000, 0x00000000, 0x6f6c6f63, + 0x64615f72, 0x6f660064, 0x006c6163, 0x63736572, 0x31656c61, 0xababab00, 0x000001ac, 0x00000000, + 0x00000010, 0x00000002, 0x00000150, 0x00000000, 0x000001b3, 0x00000010, 0x00000090, 0x00000002, + 0x000001b8, 0x00000000, 0x6d616c63, 0x74007670, 0xab007061, 0x00030001, 0x00040001, 0x00000009, + 0x00000000, 0x7263694d, 0x666f736f, 0x52282074, 0x4c482029, 0x53204c53, 0x65646168, 0x6f432072, + 0x6c69706d, 0x39207265, 0x2e39322e, 0x2e323539, 0x31313133, 0xababab00, 0x4e475349, 0x00000050, + 0x00000002, 0x00000008, 0x00000038, 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, + 0x00000044, 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x0000030f, 0x505f5653, 0x7469736f, + 0x006e6f69, 0x43584554, 0x44524f4f, 0xababab00, 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, + 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, + 0xabab0074, 0x52444853, 0x0000066c, 0x00000040, 0x0000019b, 0x04000059, 0x00208e46, 0x00000000, + 0x00000001, 0x04000059, 0x00208e46, 0x00000001, 0x0000000a, 0x0300005a, 0x00106000, 0x00000000, + 0x04001858, 0x00107000, 0x00000000, 0x00005555, 0x03001062, 0x00101032, 0x00000001, 0x03000065, + 0x001020f2, 0x00000000, 0x02000068, 0x00000002, 0x08000000, 0x00100032, 0x00000000, 0x00101046, + 0x00000001, 0x00208046, 0x00000001, 0x00000002, 0x08000034, 0x00100032, 0x00000000, 0x00100046, + 0x00000000, 0x00208046, 0x00000001, 0x00000000, 0x08000033, 0x00100032, 0x00000000, 0x00100046, + 0x00000000, 0x00208ae6, 0x00000001, 0x00000000, 0x09000045, 0x001000f2, 0x00000000, 0x00100046, + 0x00000000, 0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x08000038, 0x001000f2, 0x00000000, + 0x00100e46, 0x00000000, 0x00208aa6, 0x00000001, 0x00000002, 0x08000000, 0x00100032, 0x00000001, + 0x00101046, 0x00000001, 0x00208046, 0x00000001, 0x00000001, 0x08000034, 0x00100032, 0x00000001, + 0x00100046, 0x00000001, 0x00208046, 0x00000001, 0x00000000, 0x08000033, 0x00100032, 0x00000001, + 0x00100046, 0x00000001, 0x00208ae6, 0x00000001, 0x00000000, 0x09000045, 0x001000f2, 0x00000001, + 0x00100046, 0x00000001, 0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x0a000032, 0x001000f2, + 0x00000000, 0x00100e46, 0x00000001, 0x00208aa6, 0x00000001, 0x00000001, 0x00100e46, 0x00000000, + 0x08000000, 0x00100032, 0x00000001, 0x00101046, 0x00000001, 0x00208046, 0x00000001, 0x00000003, + 0x08000034, 0x00100032, 0x00000001, 0x00100046, 0x00000001, 0x00208046, 0x00000001, 0x00000000, + 0x08000033, 0x00100032, 0x00000001, 0x00100046, 0x00000001, 0x00208ae6, 0x00000001, 0x00000000, + 0x09000045, 0x001000f2, 0x00000001, 0x00100046, 0x00000001, 0x00107e46, 0x00000000, 0x00106000, + 0x00000000, 0x0a000032, 0x001000f2, 0x00000000, 0x00100e46, 0x00000001, 0x00208aa6, 0x00000001, + 0x00000003, 0x00100e46, 0x00000000, 0x08000000, 0x00100032, 0x00000001, 0x00101046, 0x00000001, + 0x00208046, 0x00000001, 0x00000004, 0x08000034, 0x00100032, 0x00000001, 0x00100046, 0x00000001, + 0x00208046, 0x00000001, 0x00000000, 0x08000033, 0x00100032, 0x00000001, 0x00100046, 0x00000001, + 0x00208ae6, 0x00000001, 0x00000000, 0x09000045, 0x001000f2, 0x00000001, 0x00100046, 0x00000001, + 0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x0a000032, 0x001000f2, 0x00000000, 0x00100e46, + 0x00000001, 0x00208aa6, 0x00000001, 0x00000004, 0x00100e46, 0x00000000, 0x08000000, 0x00100032, + 0x00000001, 0x00101046, 0x00000001, 0x00208046, 0x00000001, 0x00000005, 0x08000034, 0x00100032, + 0x00000001, 0x00100046, 0x00000001, 0x00208046, 0x00000001, 0x00000000, 0x08000033, 0x00100032, + 0x00000001, 0x00100046, 0x00000001, 0x00208ae6, 0x00000001, 0x00000000, 0x09000045, 0x001000f2, + 0x00000001, 0x00100046, 0x00000001, 0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x0a000032, + 0x001000f2, 0x00000000, 0x00100e46, 0x00000001, 0x00208aa6, 0x00000001, 0x00000005, 0x00100e46, + 0x00000000, 0x08000000, 0x00100032, 0x00000001, 0x00101046, 0x00000001, 0x00208046, 0x00000001, + 0x00000006, 0x08000034, 0x00100032, 0x00000001, 0x00100046, 0x00000001, 0x00208046, 0x00000001, + 0x00000000, 0x08000033, 0x00100032, 0x00000001, 0x00100046, 0x00000001, 0x00208ae6, 0x00000001, + 0x00000000, 0x09000045, 0x001000f2, 0x00000001, 0x00100046, 0x00000001, 0x00107e46, 0x00000000, + 0x00106000, 0x00000000, 0x0a000032, 0x001000f2, 0x00000000, 0x00100e46, 0x00000001, 0x00208aa6, + 0x00000001, 0x00000006, 0x00100e46, 0x00000000, 0x08000000, 0x00100032, 0x00000001, 0x00101046, + 0x00000001, 0x00208046, 0x00000001, 0x00000007, 0x08000034, 0x00100032, 0x00000001, 0x00100046, + 0x00000001, 0x00208046, 0x00000001, 0x00000000, 0x08000033, 0x00100032, 0x00000001, 0x00100046, + 0x00000001, 0x00208ae6, 0x00000001, 0x00000000, 0x09000045, 0x001000f2, 0x00000001, 0x00100046, + 0x00000001, 0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x0a000032, 0x001000f2, 0x00000000, + 0x00100e46, 0x00000001, 0x00208aa6, 0x00000001, 0x00000007, 0x00100e46, 0x00000000, 0x08000000, + 0x00100032, 0x00000001, 0x00101046, 0x00000001, 0x00208046, 0x00000001, 0x00000008, 0x08000034, + 0x00100032, 0x00000001, 0x00100046, 0x00000001, 0x00208046, 0x00000001, 0x00000000, 0x08000033, + 0x00100032, 0x00000001, 0x00100046, 0x00000001, 0x00208ae6, 0x00000001, 0x00000000, 0x09000045, + 0x001000f2, 0x00000001, 0x00100046, 0x00000001, 0x00107e46, 0x00000000, 0x00106000, 0x00000000, + 0x0a000032, 0x001000f2, 0x00000000, 0x00100e46, 0x00000001, 0x00208aa6, 0x00000001, 0x00000008, + 0x00100e46, 0x00000000, 0x08000000, 0x00100032, 0x00000001, 0x00101046, 0x00000001, 0x00208046, + 0x00000001, 0x00000009, 0x08000034, 0x00100032, 0x00000001, 0x00100046, 0x00000001, 0x00208046, + 0x00000001, 0x00000000, 0x08000033, 0x00100032, 0x00000001, 0x00100046, 0x00000001, 0x00208ae6, + 0x00000001, 0x00000000, 0x09000045, 0x001000f2, 0x00000001, 0x00100046, 0x00000001, 0x00107e46, + 0x00000000, 0x00106000, 0x00000000, 0x0a000032, 0x001020f2, 0x00000000, 0x00100e46, 0x00000001, + 0x00208aa6, 0x00000001, 0x00000009, 0x00100e46, 0x00000000, 0x0100003e, 0x54415453, 0x00000074, + 0x0000002e, 0x00000002, 0x00000000, 0x00000002, 0x0000001c, 0x00000000, 0x00000000, 0x00000001, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000009, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +}; + +static ProgramWithCachedVariableLocations pshader_blur_arr[10] = { + { NULL, 0, }, + { NULL, 0, }, + { pshader_blur_2, 1280, }, + { pshader_blur_3, 1452, }, + { pshader_blur_4, 1624, }, + { pshader_blur_5, 1796, }, + { pshader_blur_6, 1968, }, + { pshader_blur_7, 2140, }, + { pshader_blur_8, 2312, }, + { pshader_blur_9, 2484, }, +}; + +static DWORD pshader_color_matrix_0[308] = { + 0x43425844, 0x5b914181, 0xde722329, 0xe875a0ba, 0xa156b551, 0x00000001, 0x000004d0, 0x00000005, + 0x00000034, 0x0000021c, 0x00000274, 0x000002a8, 0x00000454, 0x46454452, 0x000001e0, 0x00000002, + 0x000000b4, 0x00000004, 0x0000001c, 0xffff0400, 0x00008100, 0x000001ac, 0x0000009c, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000000a3, 0x00000002, + 0x00000005, 0x00000004, 0xffffffff, 0x00000000, 0x00000001, 0x0000000d, 0x000000a8, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000000ac, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x65745f73, 0x74003078, + 0x00307865, 0x00635350, 0x61726170, 0xababab00, 0x000000a8, 0x00000004, 0x000000e4, 0x00000040, + 0x00000000, 0x00000000, 0x000000ac, 0x00000001, 0x0000017c, 0x00000050, 0x00000000, 0x00000000, + 0x00000144, 0x00000000, 0x00000010, 0x00000000, 0x00000150, 0x00000000, 0x00000160, 0x00000010, + 0x00000010, 0x00000000, 0x00000150, 0x00000000, 0x0000016a, 0x00000020, 0x00000010, 0x00000000, + 0x00000150, 0x00000000, 0x00000170, 0x00000030, 0x00000010, 0x00000000, 0x00000150, 0x00000000, + 0x6f6c6f63, 0x756d5f72, 0xabab006c, 0x00030001, 0x00040001, 0x00000000, 0x00000000, 0x6f6c6f63, + 0x64615f72, 0x6f660064, 0x006c6163, 0x63736572, 0x31656c61, 0xababab00, 0x00000194, 0x00000000, + 0x00000050, 0x00000002, 0x0000019c, 0x00000000, 0x61746164, 0xababab00, 0x00030001, 0x00040001, + 0x00000005, 0x00000000, 0x7263694d, 0x666f736f, 0x52282074, 0x4c482029, 0x53204c53, 0x65646168, + 0x6f432072, 0x6c69706d, 0x39207265, 0x2e39322e, 0x2e323539, 0x31313133, 0xababab00, 0x4e475349, + 0x00000050, 0x00000002, 0x00000008, 0x00000038, 0x00000000, 0x00000001, 0x00000003, 0x00000000, + 0x0000000f, 0x00000044, 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x0000030f, 0x505f5653, + 0x7469736f, 0x006e6f69, 0x43584554, 0x44524f4f, 0xababab00, 0x4e47534f, 0x0000002c, 0x00000001, + 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x0000000f, 0x545f5653, + 0x65677261, 0xabab0074, 0x52444853, 0x000001a4, 0x00000040, 0x00000069, 0x04000059, 0x00208e46, + 0x00000000, 0x00000001, 0x04000059, 0x00208e46, 0x00000001, 0x00000005, 0x0300005a, 0x00106000, + 0x00000000, 0x04001858, 0x00107000, 0x00000000, 0x00005555, 0x03001062, 0x00101032, 0x00000001, + 0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x00000002, 0x09000045, 0x001000f2, 0x00000000, + 0x00101046, 0x00000001, 0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x08000011, 0x00100012, + 0x00000001, 0x00208e46, 0x00000001, 0x00000000, 0x00100e46, 0x00000000, 0x0a000032, 0x00100012, + 0x00000001, 0x0020800a, 0x00000001, 0x00000004, 0x0010003a, 0x00000000, 0x0010000a, 0x00000001, + 0x08000011, 0x00100082, 0x00000001, 0x00208e46, 0x00000001, 0x00000001, 0x00100e46, 0x00000000, + 0x0a000032, 0x00100022, 0x00000001, 0x0020801a, 0x00000001, 0x00000004, 0x0010003a, 0x00000000, + 0x0010003a, 0x00000001, 0x08000011, 0x00100012, 0x00000000, 0x00208e46, 0x00000001, 0x00000002, + 0x00100e46, 0x00000000, 0x0a000032, 0x00100042, 0x00000001, 0x0020802a, 0x00000001, 0x00000004, + 0x0010003a, 0x00000000, 0x0010000a, 0x00000000, 0x08000038, 0x00102082, 0x00000000, 0x0010003a, + 0x00000000, 0x0020803a, 0x00000001, 0x00000003, 0x08000038, 0x00102072, 0x00000000, 0x00100246, + 0x00000001, 0x00208ff6, 0x00000001, 0x00000003, 0x0100003e, 0x54415453, 0x00000074, 0x0000000a, + 0x00000002, 0x00000000, 0x00000002, 0x00000005, 0x00000000, 0x00000000, 0x00000001, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, +}; + +static ProgramWithCachedVariableLocations pshader_color_matrix_arr[1] = { + { pshader_color_matrix_0, 1232, }, +}; + +static DWORD pshader_manual_clear_0[171] = { + 0x43425844, 0xeb343b5a, 0xfec80b96, 0xf65a4d5b, 0xb96aacbe, 0x00000001, 0x000002ac, 0x00000005, + 0x00000034, 0x0000015c, 0x000001b4, 0x000001e8, 0x00000230, 0x46454452, 0x00000120, 0x00000001, + 0x00000040, 0x00000001, 0x0000001c, 0xffff0400, 0x00008100, 0x000000ed, 0x0000003c, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00635350, 0x0000003c, + 0x00000004, 0x00000058, 0x00000040, 0x00000000, 0x00000000, 0x000000b8, 0x00000000, 0x00000010, + 0x00000002, 0x000000c4, 0x00000000, 0x000000d4, 0x00000010, 0x00000010, 0x00000000, 0x000000c4, + 0x00000000, 0x000000de, 0x00000020, 0x00000010, 0x00000000, 0x000000c4, 0x00000000, 0x000000e4, + 0x00000030, 0x00000010, 0x00000000, 0x000000c4, 0x00000000, 0x6f6c6f63, 0x756d5f72, 0xabab006c, + 0x00030001, 0x00040001, 0x00000000, 0x00000000, 0x6f6c6f63, 0x64615f72, 0x6f660064, 0x006c6163, + 0x63736572, 0x31656c61, 0x63694d00, 0x6f736f72, 0x28207466, 0x48202952, 0x204c534c, 0x64616853, + 0x43207265, 0x69706d6f, 0x2072656c, 0x39322e39, 0x3235392e, 0x3131332e, 0xabab0031, 0x4e475349, + 0x00000050, 0x00000002, 0x00000008, 0x00000038, 0x00000000, 0x00000001, 0x00000003, 0x00000000, + 0x0000000f, 0x00000044, 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x0000000f, 0x505f5653, + 0x7469736f, 0x006e6f69, 0x43584554, 0x44524f4f, 0xababab00, 0x4e47534f, 0x0000002c, 0x00000001, + 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x0000000f, 0x545f5653, + 0x65677261, 0xabab0074, 0x52444853, 0x00000040, 0x00000040, 0x00000010, 0x04000059, 0x00208e46, + 0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x06000036, 0x001020f2, 0x00000000, + 0x00208e46, 0x00000000, 0x00000000, 0x0100003e, 0x54415453, 0x00000074, 0x00000002, 0x00000000, + 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, +}; + +static ProgramWithCachedVariableLocations pshader_manual_clear_arr[1] = { + { pshader_manual_clear_0, 684, }, +}; + +static DWORD vshader_vsd3d10_0[305] = { + 0x43425844, 0xbcb06f4b, 0x808953d6, 0x687571c0, 0x1b5b041c, 0x00000001, 0x000004c4, 0x00000005, + 0x00000034, 0x000001cc, 0x00000200, 0x00000258, 0x00000448, 0x46454452, 0x00000190, 0x00000001, + 0x00000044, 0x00000001, 0x0000001c, 0xfffe0400, 0x00008100, 0x0000015f, 0x0000003c, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x61726170, 0xababab00, + 0x0000003c, 0x00000008, 0x0000005c, 0x00000080, 0x00000000, 0x00000000, 0x0000011c, 0x00000000, + 0x00000010, 0x00000002, 0x00000124, 0x00000000, 0x00000134, 0x00000010, 0x00000010, 0x00000002, + 0x00000124, 0x00000000, 0x0000013b, 0x00000020, 0x00000010, 0x00000000, 0x00000124, 0x00000000, + 0x00000141, 0x00000030, 0x00000010, 0x00000002, 0x00000124, 0x00000000, 0x0000014a, 0x00000040, + 0x00000010, 0x00000002, 0x00000124, 0x00000000, 0x00000153, 0x00000050, 0x00000010, 0x00000002, + 0x00000124, 0x00000000, 0x00000157, 0x00000060, 0x00000010, 0x00000002, 0x00000124, 0x00000000, + 0x0000015b, 0x00000070, 0x00000010, 0x00000002, 0x00000124, 0x00000000, 0x6c726f77, 0xab003064, + 0x00030001, 0x00040001, 0x00000000, 0x00000000, 0x6c726f77, 0x78003164, 0x66666f5f, 0x78657400, + 0x5f6e6567, 0x65740073, 0x6e656778, 0x7800745f, 0x79006433, 0x77006433, 0x4d006433, 0x6f726369, + 0x74666f73, 0x29522820, 0x534c4820, 0x6853204c, 0x72656461, 0x6d6f4320, 0x656c6970, 0x2e392072, + 0x392e3932, 0x332e3235, 0x00313131, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, + 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000f0f, 0x49534f50, 0x4e4f4954, 0xababab00, + 0x4e47534f, 0x00000050, 0x00000002, 0x00000008, 0x00000038, 0x00000000, 0x00000001, 0x00000003, + 0x00000000, 0x0000000f, 0x00000044, 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x0000000f, + 0x505f5653, 0x7469736f, 0x006e6f69, 0x43584554, 0x44524f4f, 0xababab00, 0x52444853, 0x000001e8, + 0x00010040, 0x0000007a, 0x04000059, 0x00208e46, 0x00000000, 0x00000008, 0x0300005f, 0x001010f2, + 0x00000000, 0x04000067, 0x001020f2, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000001, + 0x02000068, 0x00000001, 0x08000011, 0x00100012, 0x00000000, 0x00101e46, 0x00000000, 0x00208e46, + 0x00000000, 0x00000001, 0x08000038, 0x00100072, 0x00000000, 0x00100006, 0x00000000, 0x00208246, + 0x00000000, 0x00000006, 0x08000011, 0x00100082, 0x00000000, 0x00101e46, 0x00000000, 0x00208e46, + 0x00000000, 0x00000000, 0x0a000032, 0x00100072, 0x00000000, 0x00100ff6, 0x00000000, 0x00208246, + 0x00000000, 0x00000005, 0x00100246, 0x00000000, 0x08000000, 0x00100072, 0x00000000, 0x00100246, + 0x00000000, 0x00208246, 0x00000000, 0x00000007, 0x0a00000e, 0x00100042, 0x00000000, 0x00004002, + 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, 0x0010002a, 0x00000000, 0x07000038, 0x00102032, + 0x00000000, 0x00100aa6, 0x00000000, 0x00100046, 0x00000000, 0x06000036, 0x00102042, 0x00000000, + 0x0020802a, 0x00000000, 0x00000000, 0x05000036, 0x00102082, 0x00000000, 0x00004001, 0x3f800000, + 0x08000011, 0x00100012, 0x00000000, 0x00208e46, 0x00000000, 0x00000003, 0x00101e46, 0x00000000, + 0x08000011, 0x00100022, 0x00000000, 0x00208e46, 0x00000000, 0x00000004, 0x00101e46, 0x00000000, + 0x07000038, 0x00102032, 0x00000001, 0x00100aa6, 0x00000000, 0x00100046, 0x00000000, 0x05000036, + 0x00102082, 0x00000001, 0x0010002a, 0x00000000, 0x05000036, 0x00102042, 0x00000001, 0x00004001, + 0x3f800000, 0x0100003e, 0x54415453, 0x00000074, 0x0000000f, 0x00000001, 0x00000000, 0x00000003, + 0x00000009, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000004, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, +}; + +static DWORD vshader_vsd3d10_1[417] = { + 0x43425844, 0x79f68211, 0x83ecd840, 0x5fea9f88, 0xed27bac2, 0x00000001, 0x00000684, 0x00000005, + 0x00000034, 0x000001cc, 0x00000220, 0x00000278, 0x00000608, 0x46454452, 0x00000190, 0x00000001, + 0x00000044, 0x00000001, 0x0000001c, 0xfffe0400, 0x00008100, 0x0000015f, 0x0000003c, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x61726170, 0xababab00, + 0x0000003c, 0x00000008, 0x0000005c, 0x00000080, 0x00000000, 0x00000000, 0x0000011c, 0x00000000, + 0x00000010, 0x00000002, 0x00000124, 0x00000000, 0x00000134, 0x00000010, 0x00000010, 0x00000002, + 0x00000124, 0x00000000, 0x0000013b, 0x00000020, 0x00000010, 0x00000002, 0x00000124, 0x00000000, + 0x00000141, 0x00000030, 0x00000010, 0x00000002, 0x00000124, 0x00000000, 0x0000014a, 0x00000040, + 0x00000010, 0x00000002, 0x00000124, 0x00000000, 0x00000153, 0x00000050, 0x00000010, 0x00000002, + 0x00000124, 0x00000000, 0x00000157, 0x00000060, 0x00000010, 0x00000002, 0x00000124, 0x00000000, + 0x0000015b, 0x00000070, 0x00000010, 0x00000002, 0x00000124, 0x00000000, 0x6c726f77, 0xab003064, + 0x00030001, 0x00040001, 0x00000000, 0x00000000, 0x6c726f77, 0x78003164, 0x66666f5f, 0x78657400, + 0x5f6e6567, 0x65740073, 0x6e656778, 0x7800745f, 0x79006433, 0x77006433, 0x4d006433, 0x6f726369, + 0x74666f73, 0x29522820, 0x534c4820, 0x6853204c, 0x72656461, 0x6d6f4320, 0x656c6970, 0x2e392072, + 0x392e3932, 0x332e3235, 0x00313131, 0x4e475349, 0x0000004c, 0x00000002, 0x00000008, 0x00000038, + 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000f0f, 0x00000041, 0x00000000, 0x00000000, + 0x00000002, 0x00000001, 0x0000070f, 0x49534f50, 0x4e4f4954, 0x58455400, 0x524f4f43, 0xabab0044, + 0x4e47534f, 0x00000050, 0x00000002, 0x00000008, 0x00000038, 0x00000000, 0x00000001, 0x00000003, + 0x00000000, 0x0000000f, 0x00000044, 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x0000000f, + 0x505f5653, 0x7469736f, 0x006e6f69, 0x43584554, 0x44524f4f, 0xababab00, 0x52444853, 0x00000388, + 0x00010040, 0x000000e2, 0x04000059, 0x00208e46, 0x00000000, 0x00000008, 0x0300005f, 0x001010f2, + 0x00000000, 0x0300005f, 0x00101072, 0x00000001, 0x04000067, 0x001020f2, 0x00000000, 0x00000001, + 0x03000065, 0x001020f2, 0x00000001, 0x02000068, 0x00000003, 0x0500002b, 0x00100072, 0x00000000, + 0x00101496, 0x00000001, 0x0a000038, 0x00100072, 0x00000000, 0x00100246, 0x00000000, 0x00004002, + 0x3c800000, 0x3c800000, 0x3d000000, 0x00000000, 0x0800000f, 0x00100012, 0x00000001, 0x00100046, + 0x00000000, 0x00208046, 0x00000000, 0x00000002, 0x0800000f, 0x00100022, 0x00000001, 0x00100046, + 0x00000000, 0x00208ae6, 0x00000000, 0x00000002, 0x0800000f, 0x00100012, 0x00000002, 0x00100046, + 0x00000001, 0x00208046, 0x00000000, 0x00000000, 0x0800000f, 0x00100022, 0x00000002, 0x00100046, + 0x00000001, 0x00208046, 0x00000000, 0x00000001, 0x0700000f, 0x00100082, 0x00000000, 0x00100046, + 0x00000002, 0x00100046, 0x00000002, 0x0500004b, 0x00100082, 0x00000000, 0x0010003a, 0x00000000, + 0x0a000039, 0x00100012, 0x00000001, 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x0010003a, 0x00000000, 0x09000037, 0x00100082, 0x00000000, 0x0010000a, 0x00000001, 0x0010003a, + 0x00000000, 0x00004001, 0x3f800000, 0x0700000f, 0x00100012, 0x00000000, 0x00100046, 0x00000000, + 0x00100046, 0x00000000, 0x0500004b, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0700000e, + 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0010003a, 0x00000000, 0x08000011, 0x00100012, + 0x00000001, 0x00101e46, 0x00000000, 0x00208e46, 0x00000000, 0x00000000, 0x08000011, 0x00100022, + 0x00000001, 0x00101e46, 0x00000000, 0x00208e46, 0x00000000, 0x00000001, 0x09000032, 0x00100032, + 0x00000000, 0x00100046, 0x00000002, 0x00100006, 0x00000000, 0x00100046, 0x00000001, 0x08000038, + 0x00100072, 0x00000001, 0x00100556, 0x00000000, 0x00208246, 0x00000000, 0x00000006, 0x0a000032, + 0x001000b2, 0x00000000, 0x00100006, 0x00000000, 0x00208846, 0x00000000, 0x00000005, 0x00100846, + 0x00000001, 0x08000000, 0x001000b2, 0x00000000, 0x00100c46, 0x00000000, 0x00208846, 0x00000000, + 0x00000007, 0x0a00000e, 0x00100082, 0x00000000, 0x00004002, 0x3f800000, 0x3f800000, 0x3f800000, + 0x3f800000, 0x0010003a, 0x00000000, 0x07000038, 0x00102032, 0x00000000, 0x00100ff6, 0x00000000, + 0x00100046, 0x00000000, 0x06000036, 0x00102042, 0x00000000, 0x0020802a, 0x00000000, 0x00000000, + 0x05000036, 0x00102082, 0x00000000, 0x00004001, 0x3f800000, 0x08000011, 0x00100012, 0x00000000, + 0x00208e46, 0x00000000, 0x00000003, 0x00101e46, 0x00000000, 0x08000011, 0x00100022, 0x00000000, + 0x00208e46, 0x00000000, 0x00000004, 0x00101e46, 0x00000000, 0x07000038, 0x00102072, 0x00000001, + 0x00100ff6, 0x00000000, 0x00100246, 0x00000000, 0x05000036, 0x00102082, 0x00000001, 0x0010003a, + 0x00000000, 0x0100003e, 0x54415453, 0x00000074, 0x0000001c, 0x00000003, 0x00000000, 0x00000004, + 0x00000013, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003, + 0x00000001, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, +}; + +static DWORD vshader_vsd3d10_2[300] = { + 0x43425844, 0x50edc469, 0x3be0d512, 0xffa16ac1, 0x10a3602c, 0x00000001, 0x000004b0, 0x00000005, + 0x00000034, 0x000001cc, 0x00000220, 0x00000278, 0x00000434, 0x46454452, 0x00000190, 0x00000001, + 0x00000044, 0x00000001, 0x0000001c, 0xfffe0400, 0x00008100, 0x0000015f, 0x0000003c, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x61726170, 0xababab00, + 0x0000003c, 0x00000008, 0x0000005c, 0x00000080, 0x00000000, 0x00000000, 0x0000011c, 0x00000000, + 0x00000010, 0x00000002, 0x00000124, 0x00000000, 0x00000134, 0x00000010, 0x00000010, 0x00000002, + 0x00000124, 0x00000000, 0x0000013b, 0x00000020, 0x00000010, 0x00000000, 0x00000124, 0x00000000, + 0x00000141, 0x00000030, 0x00000010, 0x00000000, 0x00000124, 0x00000000, 0x0000014a, 0x00000040, + 0x00000010, 0x00000000, 0x00000124, 0x00000000, 0x00000153, 0x00000050, 0x00000010, 0x00000002, + 0x00000124, 0x00000000, 0x00000157, 0x00000060, 0x00000010, 0x00000002, 0x00000124, 0x00000000, + 0x0000015b, 0x00000070, 0x00000010, 0x00000002, 0x00000124, 0x00000000, 0x6c726f77, 0xab003064, + 0x00030001, 0x00040001, 0x00000000, 0x00000000, 0x6c726f77, 0x78003164, 0x66666f5f, 0x78657400, + 0x5f6e6567, 0x65740073, 0x6e656778, 0x7800745f, 0x79006433, 0x77006433, 0x4d006433, 0x6f726369, + 0x74666f73, 0x29522820, 0x534c4820, 0x6853204c, 0x72656461, 0x6d6f4320, 0x656c6970, 0x2e392072, + 0x392e3932, 0x332e3235, 0x00313131, 0x4e475349, 0x0000004c, 0x00000002, 0x00000008, 0x00000038, + 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000f0f, 0x00000041, 0x00000000, 0x00000000, + 0x00000003, 0x00000001, 0x0000030f, 0x49534f50, 0x4e4f4954, 0x58455400, 0x524f4f43, 0xabab0044, + 0x4e47534f, 0x00000050, 0x00000002, 0x00000008, 0x00000038, 0x00000000, 0x00000001, 0x00000003, + 0x00000000, 0x0000000f, 0x00000044, 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x0000000f, + 0x505f5653, 0x7469736f, 0x006e6f69, 0x43584554, 0x44524f4f, 0xababab00, 0x52444853, 0x000001b4, + 0x00010040, 0x0000006d, 0x04000059, 0x00208e46, 0x00000000, 0x00000008, 0x0300005f, 0x001010f2, + 0x00000000, 0x0300005f, 0x00101032, 0x00000001, 0x04000067, 0x001020f2, 0x00000000, 0x00000001, + 0x03000065, 0x001020f2, 0x00000001, 0x02000068, 0x00000001, 0x08000011, 0x00100012, 0x00000000, + 0x00101e46, 0x00000000, 0x00208e46, 0x00000000, 0x00000001, 0x08000038, 0x00100072, 0x00000000, + 0x00100006, 0x00000000, 0x00208246, 0x00000000, 0x00000006, 0x08000011, 0x00100082, 0x00000000, + 0x00101e46, 0x00000000, 0x00208e46, 0x00000000, 0x00000000, 0x0a000032, 0x00100072, 0x00000000, + 0x00100ff6, 0x00000000, 0x00208246, 0x00000000, 0x00000005, 0x00100246, 0x00000000, 0x08000000, + 0x00100072, 0x00000000, 0x00100246, 0x00000000, 0x00208246, 0x00000000, 0x00000007, 0x0a00000e, + 0x00100042, 0x00000000, 0x00004002, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, 0x0010002a, + 0x00000000, 0x07000038, 0x00102032, 0x00000000, 0x00100aa6, 0x00000000, 0x00100046, 0x00000000, + 0x06000036, 0x00102042, 0x00000000, 0x0020802a, 0x00000000, 0x00000000, 0x05000036, 0x00102082, + 0x00000000, 0x00004001, 0x3f800000, 0x07000038, 0x00102032, 0x00000001, 0x00100aa6, 0x00000000, + 0x00101046, 0x00000001, 0x05000036, 0x00102082, 0x00000001, 0x0010002a, 0x00000000, 0x05000036, + 0x00102042, 0x00000001, 0x00004001, 0x3f800000, 0x0100003e, 0x54415453, 0x00000074, 0x0000000d, + 0x00000001, 0x00000000, 0x00000004, 0x00000007, 0x00000000, 0x00000000, 0x00000001, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000004, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, +}; + +static ProgramWithCachedVariableLocations vshader_vsd3d10_arr[3] = { + { vshader_vsd3d10_0, 1220, }, + { vshader_vsd3d10_1, 1668, }, + { vshader_vsd3d10_2, 1200, }, +}; + diff --git a/Minecraft.Client/Windows64/Iggy/gdraw/gdraw_d3d11.cpp b/Minecraft.Client/Windows64/Iggy/gdraw/gdraw_d3d11.cpp new file mode 100644 index 00000000..dea9e315 --- /dev/null +++ b/Minecraft.Client/Windows64/Iggy/gdraw/gdraw_d3d11.cpp @@ -0,0 +1,147 @@ +#include "stdafx.h" // 4J + +// gdraw_d3d11.cpp - author: Fabian Giesen - copyright 2011 RAD Game Tools +// +// This implements the Iggy graphics driver layer for D3D 11. + +// GDraw consists of several components that interact fairly loosely with each other; +// e.g. the resource management, drawing and filtering parts are all fairly independent +// of each other. If you want to modify some aspect of GDraw - say the texture allocation +// logic - your best bet is usually to just look for one of the related entry points, +// e.g. MakeTextureBegin, and take it from there. There's a bunch of code in this file, +// but none of it is really complicated. +// +// The one bit you might want to change that's not that localized is to integrate +// GDraw with an existing state caching system. The following bits all modify D3D state +// in some way: +// - The rendering helpers (set_viewport_raw, set_projection_raw, set_*_renderstate) +// - RenderTile*/TextureDrawBuffer* may change the active rendertarget and depth/stencil surface, +// as do D3D1X_(NoMoreGDrawThisFrame) and set_render_target +// - set_texture +// - set_renderstate and set_renderstate_full. These are the main places where render state changes occur; +// you should probably start here. +// - DrawIndexedTriangles sets the active vertex/index buffers and vertex declaration +// - Most of the functions in the "filter effects" section modify D3D state, mostly +// pixel shader constants and textures + +#define GDRAW_ASSERTS + +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif + +// We temporarily disable this warning for the shared interface portions +#pragma warning (push) +#pragma warning (disable: 4201) // nonstandard extension used : nameless struct/union + +#include +#include +#include "gdraw.h" +#include "iggy.h" +#include +#include + +#include "gdraw_d3d11.h" + +#pragma warning (pop) + +// Some macros to allow as much sharing between D3D10 and D3D11 code as possible. +#define D3D1X_(id) D3D11_##id +#define ID3D1X(id) ID3D11##id +#define gdraw_D3D1X_(id) gdraw_D3D11_##id +#define GDRAW_D3D1X_(id) GDRAW_D3D11_##id + +typedef ID3D11Device ID3D1XDevice; +typedef ID3D11DeviceContext ID3D1XContext; +typedef F32 ViewCoord; +typedef gdraw_d3d11_resourcetype gdraw_resourcetype; + +static void report_d3d_error(HRESULT hr, char *call, char *context); + +static void *map_buffer(ID3D1XContext *ctx, ID3D11Buffer *buf, bool discard) +{ + D3D11_MAPPED_SUBRESOURCE msr; + HRESULT hr = ctx->Map(buf, 0, discard ? D3D11_MAP_WRITE_DISCARD : D3D11_MAP_WRITE_NO_OVERWRITE, 0, &msr); + if (FAILED(hr)) { + report_d3d_error(hr, "Map", "of buffer"); + return NULL; + } else + return msr.pData; +} + +static void unmap_buffer(ID3D1XContext *ctx, ID3D11Buffer *buf) +{ + ctx->Unmap(buf, 0); +} + +static RADINLINE void set_pixel_shader(ID3D11DeviceContext *ctx, ID3D11PixelShader *shader) +{ + ctx->PSSetShader(shader, NULL, 0); +} + +static RADINLINE void set_vertex_shader(ID3D11DeviceContext *ctx, ID3D11VertexShader *shader) +{ + ctx->VSSetShader(shader, NULL, 0); +} + +static ID3D11BlendState *create_blend_state(ID3D11Device *dev, BOOL blend, D3D11_BLEND src, D3D11_BLEND dst) +{ + D3D11_BLEND_DESC desc = {}; + desc.RenderTarget[0].BlendEnable = blend; + desc.RenderTarget[0].SrcBlend = src; + desc.RenderTarget[0].DestBlend = dst; + desc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; + desc.RenderTarget[0].SrcBlendAlpha = (src == D3D11_BLEND_DEST_COLOR ) ? D3D11_BLEND_DEST_ALPHA : src; + desc.RenderTarget[0].DestBlendAlpha = dst; + desc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; + desc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL; + + ID3D11BlendState *res; + HRESULT hr = dev->CreateBlendState(&desc, &res); + if (FAILED(hr)) { + report_d3d_error(hr, "CreateBlendState", ""); + res = NULL; + } + + return res; +} + +#define GDRAW_SHADER_FILE "gdraw_d3d10_shaders.inl" +#include "gdraw_d3d1x_shared.inl" + +static void create_pixel_shader(ProgramWithCachedVariableLocations *p, ProgramWithCachedVariableLocations *src) +{ + *p = *src; + if(p->bytecode) { + HRESULT hr = gdraw->d3d_device->CreatePixelShader(p->bytecode, p->size, NULL, &p->pshader); + if (FAILED(hr)) { + report_d3d_error(hr, "CreatePixelShader", ""); + p->pshader = NULL; + return; + } + } +} + +static void create_vertex_shader(ProgramWithCachedVariableLocations *p, ProgramWithCachedVariableLocations *src) +{ + *p = *src; + if(p->bytecode) { + HRESULT hr = gdraw->d3d_device->CreateVertexShader(p->bytecode, p->size, NULL, &p->vshader); + if (FAILED(hr)) { + report_d3d_error(hr, "CreateVertexShader", ""); + p->vshader = NULL; + return; + } + } +} + +GDrawFunctions *gdraw_D3D11_CreateContext(ID3D11Device *dev, ID3D11DeviceContext *ctx, S32 w, S32 h) +{ + return create_context(dev, ctx, w, h); +} + +// 4J added - interface so we can set the viewport back to the one that Iggy last set up +void gdraw_D3D11_setViewport_4J() +{ + set_viewport(); +} \ No newline at end of file diff --git a/Minecraft.Client/Windows64/Iggy/gdraw/gdraw_d3d11.h b/Minecraft.Client/Windows64/Iggy/gdraw/gdraw_d3d11.h new file mode 100644 index 00000000..7fd7012f --- /dev/null +++ b/Minecraft.Client/Windows64/Iggy/gdraw/gdraw_d3d11.h @@ -0,0 +1,139 @@ +#pragma once // 4J + +// gdraw_d3d11.h - author: Fabian Giesen - copyright 2011 RAD Game Tools +// +// Interface for creating a D3D11 GDraw driver. + +#define IDOC +//idoc(parent,GDraw_d3d11) + +typedef enum gdraw_d3d11_resourcetype +{ + GDRAW_D3D11_RESOURCE_rendertarget, + GDRAW_D3D11_RESOURCE_texture, + GDRAW_D3D11_RESOURCE_vertexbuffer, + GDRAW_D3D11_RESOURCE_dynbuffer, // Streaming buffer for dynamic vertex/index data (handle count ignored) + + GDRAW_D3D11_RESOURCE__count, +} gdraw_d3d11_resourcetype; + +IDOC extern int gdraw_D3D11_SetResourceLimits(gdraw_d3d11_resourcetype type, S32 num_handles, S32 num_bytes); +/* This sets how large the memory pool for a given resource types is, and how many handles + GDraw should allocate for it. GDraw keeps track of allocations in each pool, and will free + old resources in a LRU manner to make space if one of the limits is about to be exceeded. + + Returns 1 if value successfully changed, 0 on error. + You need to call IggyPlayerFlushAll on all active Iggys before you do this to make + them flush their resources since changing the resource limits invalidates all handles. + You also need to call IggyFlushInstalledFonts if you have any installed fonts. +*/ + +IDOC extern GDrawFunctions * gdraw_D3D11_CreateContext(ID3D11Device *dev, ID3D11DeviceContext *ctx, S32 w, S32 h); +/* Creates a GDraw context for rendering using D3D. You need to pass in the D3D device, + the device context to use for rendering, and the width/height of render target textures. + + The width/height is used solely for sizing internal rendertargets. They will be + allocated to the larger of this size and the size of any rendered tiles (with padding). + In other words, you can pass in (0,0) and the rendertargets will be allocated to the + right size. However, if you draw multiple Iggy files or tiles of different sizes, + they might first be allocated too small; it's best to pass in the correct size initially + to avoid unnecessary allocation/deallocation of too-small rendertargets. + + There can only be one D3D GDraw context active at any one time. + + If initialization fails for some reason (the main reason would be an out of memory condition), + NULL is returned. Otherwise, you can pass the return value to IggySetGDraw. */ + +IDOC extern void gdraw_D3D11_DestroyContext(void); +/* Destroys the current GDraw context, if any. */ + +IDOC extern void gdraw_D3D11_SetErrorHandler(void (__cdecl *error_handler)(HRESULT hr)); +/* Sets the GDraw D3D error handler. + + This will get called with the respective D3D error code if GDraw encounters an error + that it can't handle by itself (e.g. running out of state objects). */ + +IDOC extern void gdraw_D3D11_SetRendertargetSize(S32 w, S32 h); +/* Changes the current render target size (and recreates all rendertargets if necessary). + This allows you to shrink the rendertargets if the new needed size is smaller + than it was previously. As with $gdraw_D3D11_CreateContext, the width and + height specified here are only minimums; GDraw will reallocate larger rendertargets + as needed. */ + +IDOC extern void gdraw_D3D11_SetTileOrigin(ID3D11RenderTargetView *main_rt, ID3D11DepthStencilView *main_ds, + ID3D11ShaderResourceView *non_msaa_rt, S32 x, S32 y); +/* This sets the main rendertarget and matching depth/stencil buffer that GDraw + should render to and the x/y position of the output location of the top-left + of the current tile (allowing you to finely-position content, or to do tiled + rendering). + + If your rendertarget uses multisampling, you also need to specify a shader + resource view for a non-MSAA rendertarget texture (identically sized to main_rt) + in non_msaa_rt. This is only used if the Flash content includes non-standard + blend modes which have to use a special blend shader, so you can leave it NULL + if you forbid such content. + + You need to call this before Iggy calls any rendering functions. */ + +IDOC extern void gdraw_D3D11_NoMoreGDrawThisFrame(void); +/* Tells GDraw that no more rendering operations will occur this frame. This triggers + some end-of-frame processing; most importantly, GDraw uses this call as a marker to + detect thrashing (and react accordingly), so please do not forget to call this + every frame! (As long as Iggy does any rendering, that is) */ + +IDOC extern void gdraw_D3D11_PreReset(void); +/* Call this before D3D device Reset(); it will free all default pool resources allocated + by GDraw. */ + +IDOC extern void gdraw_D3D11_PostReset(void); +/* Call after D3D device Reset(). */ + +IDOC extern void RADLINK gdraw_D3D11_BeginCustomDraw_4J(IggyCustomDrawCallbackRegion *Region, F32 mat[16]); +IDOC extern void RADLINK gdraw_D3D11_CalculateCustomDraw_4J(IggyCustomDrawCallbackRegion *Region, F32 mat[16]); +IDOC extern void RADLINK gdraw_D3D11_BeginCustomDraw(IggyCustomDrawCallbackRegion *Region, F32 mat[4][4]); +/* Call at the beginning of Iggy custom draw callback to clear any odd render states GDraw has + set on the D3D device, and to get the current 2D object-to-world transformation. */ + +IDOC extern void RADLINK gdraw_D3D11_EndCustomDraw(IggyCustomDrawCallbackRegion *Region); +/* Call at the end of Iggy custom draw callback so GDraw can restore its render states. */ + +IDOC extern void RADLINK gdraw_D3D11_GetResourceUsageStats(gdraw_d3d11_resourcetype type, S32 *handles_used, S32 *bytes_used); +/* D3D only: Get resource usage stats for last frame. + This can be used to get an estimate of how much graphics memory got used by GDraw + during the last frame. + + For the dynbuffer, this always returns 0 in handles_used and the *size of the largest + single allocation* in bytes_used. It needs to be sized so that this allocation fits; + make it smaller and it won't work, but if you make it much larger (say more than 2x + as big), it's just a waste of memory. That said, we still recommend to make it no + smaller than 64k, and the default is 256k. + + Caveat: This counts the number of bytes that GDraw knows about. 3D hardware usually + has its own management overhead, alignment requirements, allocation granularity + and so on. In short, this is not an accurate estimate of how much memory is actually + used by the GPU - it is a lower bound, though, and makes for a useful ballpark estimate. */ + +IDOC extern GDrawTexture *gdraw_D3D11_WrappedTextureCreate(ID3D11ShaderResourceView *tex_view); +/* Create a wrapped texture from a shader resource view. + A wrapped texture can be used to let Iggy draw using the contents of a texture + you create and manage on your own. For example, you might render to this texture, + or stream video into it. Wrapped textures take up a handle. They will never be + freed or otherwise modified by GDraw; nor will GDraw change any reference counts. + All this is up to the application. */ + +IDOC extern void gdraw_D3D11_WrappedTextureChange(GDrawTexture *tex, ID3D11ShaderResourceView *tex_view); +/* Switch an existing GDrawTexture * that represents a wrapped texture to use + a new underlying D3D view. For example, you might internally double-buffer + a dynamically updated texture. As above, GDraw will leave this texture alone + and not touch any reference counts. */ + +IDOC extern void gdraw_D3D11_WrappedTextureDestroy(GDrawTexture *tex); +/* Destroys the GDraw wrapper for a wrapped texture object. This will free up + a GDraw texture handle but not release the associated D3D texture; that is + up to you. */ + +GDrawTexture * RADLINK gdraw_D3D11_MakeTextureFromResource(U8 *resource_file, S32 length, IggyFileTextureRaw *texture); +void RADLINK gdraw_D3D11_DestroyTextureFromResource(GDrawTexture *tex); + +// 4J added +extern void RADLINK gdraw_D3D11_setViewport_4J(); \ No newline at end of file diff --git a/Minecraft.Client/Windows64/Iggy/gdraw/gdraw_d3d1x_shared.inl b/Minecraft.Client/Windows64/Iggy/gdraw/gdraw_d3d1x_shared.inl new file mode 100644 index 00000000..1ab1f13f --- /dev/null +++ b/Minecraft.Client/Windows64/Iggy/gdraw/gdraw_d3d1x_shared.inl @@ -0,0 +1,2491 @@ +// gdraw_d3d1x_shared.inl - author: Fabian Giesen - copyright 2012 RAD Game Tools +// +// This file implements the part of the Iggy graphics driver layer shared between +// D3D10 and 11 (which is most of it). It heavily depends on a bunch of typedefs, +// #defines and utility functions that need to be set up correctly for the D3D version +// being targeted. This is a bit ugly, but much easier to maintain than the original +// solution, where we just kept two almost identical versions of this code. + +// That native handle type holds resource handles and a coarse description. +typedef union { + // handle that is a texture + struct { + ID3D1X(Texture2D) *d3d; + ID3D1X(ShaderResourceView) *d3d_view; + ID3D1X(RenderTargetView) *d3d_rtview; + U32 w, h; + } tex; + + // handle that is a vertex buffer + struct { + ID3D1X(Buffer) *verts; + ID3D1X(Buffer) *inds; + } vbuf; +} GDrawNativeHandle; + +#define GDRAW_NO_STREAMING_MIPGEN // This renderer doesn't use GDraw-internal mipmap generation +#include "gdraw_shared.inl" + +// max rendertarget stack depth. this depends on the extent to which you +// use filters and non-standard blend modes, and how nested they are. +#define MAX_RENDER_STACK_DEPTH 8 // Iggy is hardcoded to a limit of 16... probably 1-3 is realistic +#define AATEX_SAMPLER 7 // sampler that aa_tex gets set in +#define STENCIL_STATE_CACHE_SIZE 32 // number of distinct stencil states we cache DepthStencilStates for +#define QUAD_IB_COUNT 2048 // quad index buffer has indices for this many quads + +#define ASSERT_COUNT(a,b) ((a) == (b) ? (b) : -1) + +static GDrawFunctions gdraw_funcs; + +// render target state +typedef struct +{ + GDrawHandle *color_buffer; + S32 base_x, base_y, width, height; + U32 flags; + rrbool cached; +} GDrawFramebufferState; + +struct ProgramWithCachedVariableLocations +{ + DWORD *bytecode; + union { + DWORD size; + ID3D1X(PixelShader) *pshader; + ID3D1X(VertexShader) *vshader; + }; +}; + +struct DynBuffer +{ + ID3D1X(Buffer) *buffer; + U32 size; // size of buffer + U32 write_pos; // start of most recently allocated chunk + U32 alloc_pos; // end of most recently allocated chunk (=start of next allocation) +}; + +/////////////////////////////////////////////////////////////////////////////// +// +// GDraw data structure +// +// +// This is the primary rendering abstraction, which hides all +// the platform-specific rendering behavior from Iggy. It is +// full of platform-specific graphics state, and also general +// graphics state so that it doesn't have to callback into Iggy +// to get at that graphics state. + +typedef struct +{ + ID3D1XDevice *d3d_device; + ID3D1XContext *d3d_context; + + // fragment shaders + ProgramWithCachedVariableLocations fprog[GDRAW_TEXTURE__count][3]; + ProgramWithCachedVariableLocations exceptional_blend[GDRAW_BLENDSPECIAL__count]; + ProgramWithCachedVariableLocations filter_prog[2][16]; + ProgramWithCachedVariableLocations blur_prog[MAX_TAPS+1]; + ProgramWithCachedVariableLocations colormatrix; + ProgramWithCachedVariableLocations clear_ps; + + // vertex input layouts + ID3D1X(InputLayout) *inlayout[GDRAW_vformat__count]; + + // vertex shaders + ProgramWithCachedVariableLocations vert[GDRAW_vformat__count]; // [format] + + // render targets + GDrawHandleCache rendertargets; + GDrawHandle rendertarget_handles[MAX_RENDER_STACK_DEPTH]; // not -1, because we use +1 to initialize + + gswf_recti rt_valid[MAX_RENDER_STACK_DEPTH+1]; // valid rect for texture clamping + + // size of framebuffer-sized texture used for implementing blend modes + S32 frametex_width, frametex_height; + + // viewport setting (in pixels) for current frame + S32 vx,vy; + S32 fw,fh; // full width/height of virtual display + S32 tw,th; // actual width/height of current tile + S32 tpw,tph; // width/height of padded version of tile + + S32 tx0,ty0; + S32 tx0p,ty0p; + rrbool in_blur; + struct { + S32 x,y,w,h; + } cview; // current viewport + + F32 projection[4]; // scalex,scaley,transx,transy + F32 projmat[3][4]; + F32 xform_3d[3][4]; + rrbool use_3d; + + ID3D1X(RenderTargetView) *main_framebuffer; + ID3D1X(DepthStencilView) *depth_buffer[2]; // 0=main, 1=rendertarget + ID3D1X(ShaderResourceView) *main_resolve_target; + rrbool main_msaa; // does main framebuffer have MSAA enabled? + + ID3D1X(Texture2D) *rt_depth_buffer; + ID3D1X(Texture2D) *aa_tex; + ID3D1X(ShaderResourceView) *aa_tex_view; + ID3D1X(Buffer) *quad_ib; // canned quad indices + + // scale factor converting worldspace to viewspace <0,0>.. + F32 world_to_pixel[2]; + + // state objects + ID3D1X(RasterizerState) *raster_state[2]; // [msaa] + ID3D1X(SamplerState) *sampler_state[2][GDRAW_WRAP__count]; // [nearest][wrap] + ID3D1X(BlendState) *blend_state[GDRAW_BLEND__count]; + ID3D1X(BlendState) *blend_no_color_write; + ID3D1X(DepthStencilState) *depth_state[2][2]; // [set_id][test_id] + + // stencil state cache + // SOA so the keys are tightly packed in a few cache lines! + U32 stencil_cache_key[STENCIL_STATE_CACHE_SIZE]; + ID3D1X(DepthStencilState) *stencil_cache[STENCIL_STATE_CACHE_SIZE]; + U32 stencil_cache_lru[STENCIL_STATE_CACHE_SIZE]; + U32 stencil_cache_now; + + // constant buffers + ID3D1X(Buffer) *cb_vertex; + ID3D1X(Buffer) *cb_ps_common; + ID3D1X(Buffer) *cb_filter; + ID3D1X(Buffer) *cb_colormatrix; + ID3D1X(Buffer) *cb_blur; + + // streaming buffers for dynamic vertex/index data + DynBuffer dyn_vb; + DynBuffer dyn_ib; + + U32 dyn_maxalloc, last_dyn_maxalloc; + S32 max_quad_vert_count; + + // cached state + U32 scissor_state; // ~0 if unknown, otherwise 0 or 1 + S32 blend_mode; // -1 if unknown, otherwise GDRAW_BLEND_* + + // render-state stack described above for 'temporary' rendering + GDrawFramebufferState frame[MAX_RENDER_STACK_DEPTH]; + GDrawFramebufferState *cur; + + // texture and vertex buffer pools + GDrawHandleCache *texturecache; + GDrawHandleCache *vbufcache; + + // stat tracking + rrbool frame_done; + U64 frame_counter; + + // error handler + void (__cdecl *error_handler)(HRESULT hr); +} GDraw; + +static GDraw *gdraw; + +static const F32 four_zeros[4] = { 0 }; // used in several places + +//////////////////////////////////////////////////////////////////////// +// +// General resource management for both textures and vertex buffers +// + +template +static void safe_release(T *&p) +{ + if (p) { + p->Release(); + p = NULL; + } +} + +static void report_d3d_error(HRESULT hr, char *call, char *context) +{ + if (hr == E_OUTOFMEMORY) + IggyGDrawSendWarning(NULL, "GDraw D3D out of memory in %s%s", call, context); + else + IggyGDrawSendWarning(NULL, "GDraw D3D error in %s%s: 0x%08x", call, context, hr); +} + +static void unbind_resources(void) +{ + ID3D1XContext *d3d = gdraw->d3d_context; + + // unset active textures and vertex/index buffers, + // to make sure there are no dangling refs + static ID3D1X(ShaderResourceView) *no_views[3] = { 0 }; + ID3D1X(Buffer) *no_vb = NULL; + UINT no_offs = 0; + + d3d->PSSetShaderResources(0, 3, no_views); + d3d->IASetVertexBuffers(0, 1, &no_vb, &no_offs, &no_offs); + d3d->IASetIndexBuffer(NULL, DXGI_FORMAT_UNKNOWN, 0); +} + +static void api_free_resource(GDrawHandle *r) +{ + unbind_resources(); + if (r->state != GDRAW_HANDLE_STATE_user_owned) { + if (!r->cache->is_vertex) { + safe_release(r->handle.tex.d3d_view); + safe_release(r->handle.tex.d3d_rtview); + safe_release(r->handle.tex.d3d); + } else { + safe_release(r->handle.vbuf.verts); + safe_release(r->handle.vbuf.inds); + } + } +} + +static void RADLINK gdraw_UnlockHandles(GDrawStats * /*stats*/) +{ + gdraw_HandleCacheUnlockAll(gdraw->texturecache); + gdraw_HandleCacheUnlockAll(gdraw->vbufcache); +} + +//////////////////////////////////////////////////////////////////////// +// +// Dynamic buffer +// + +static void *start_write_dyn(DynBuffer *buf, U32 size) +{ + U8 *ptr = NULL; + + if (size > buf->size) { + IggyGDrawSendWarning(NULL, "GDraw dynamic vertex buffer usage of %d bytes in one call larger than buffer size %d", size, buf->size); + return NULL; + } + + // update statistics + gdraw->dyn_maxalloc = RR_MAX(gdraw->dyn_maxalloc, size); + + // invariant: current alloc_pos is in [0,size] + assert(buf->alloc_pos <= buf->size); + + // wrap around when less than "size" bytes left in buffer + buf->write_pos = ((buf->size - buf->alloc_pos) < size) ? 0 : buf->alloc_pos; + + // discard buffer whenever the current write position is 0; + // done this way so that if a DISCARD Map() were to fail, we would + // just keep retrying the next time around. + ptr = (U8 *) map_buffer(gdraw->d3d_context, buf->buffer, buf->write_pos == 0); + if (ptr) { + ptr += buf->write_pos; // we return pointer to write position in buffer + buf->alloc_pos = buf->write_pos + size; // bump alloc position + assert(buf->alloc_pos <= buf->size); // invariant again + } + // if map_buffer fails, it will have sent a warning + + return ptr; +} + +static U32 end_write_dyn(DynBuffer *buf) +{ + unmap_buffer(gdraw->d3d_context, buf->buffer); + return buf->write_pos; +} + +//////////////////////////////////////////////////////////////////////// +// +// Stencil state cache +// + +static void stencil_state_cache_clear() +{ + S32 i; + + for (i=0; i < STENCIL_STATE_CACHE_SIZE; ++i) { + gdraw->stencil_cache_key[i] = 0; + safe_release(gdraw->stencil_cache[i]); + gdraw->stencil_cache_lru[i] = 0; + } + + gdraw->stencil_cache_now = 0; +} + +static ID3D1X(DepthStencilState) *stencil_state_cache_lookup(rrbool set_id, rrbool test_id, U8 read_mask, U8 write_mask) +{ + D3D1X_(DEPTH_STENCIL_DESC) desc; + S32 i, best = 0; + U32 key = (set_id << 1) | test_id | (read_mask << 8) | (write_mask << 16); + U32 now, age, highest_age; + HRESULT hr; + + // for LRU + now = ++gdraw->stencil_cache_now; + + // do we have this in the cache? + for (i=0; i < STENCIL_STATE_CACHE_SIZE; ++i) { + if (gdraw->stencil_cache_key[i] == key) { + gdraw->stencil_cache_lru[i] = now; + return gdraw->stencil_cache[i]; + } + } + + // not in the cache, find the best slot to replace it with (LRU) + highest_age = 0; + for (i=0; i < STENCIL_STATE_CACHE_SIZE; ++i) { + if (!gdraw->stencil_cache[i]) { // unused slot! + best = i; + break; + } + + age = now - gdraw->stencil_cache_lru[i]; + if (age > highest_age) { + highest_age = age; + best = i; + } + } + + // release old depth/stencil state at that position and create new one + safe_release(gdraw->stencil_cache[best]); + + gdraw->depth_state[set_id][test_id]->GetDesc(&desc); // reference state + desc.StencilEnable = TRUE; + desc.StencilReadMask = read_mask; + desc.StencilWriteMask = write_mask; + desc.FrontFace.StencilFailOp = D3D1X_(STENCIL_OP_KEEP); + desc.FrontFace.StencilDepthFailOp = D3D1X_(STENCIL_OP_KEEP); + desc.FrontFace.StencilPassOp = D3D1X_(STENCIL_OP_REPLACE); + desc.FrontFace.StencilFunc = D3D1X_(COMPARISON_EQUAL); + desc.BackFace.StencilFailOp = D3D1X_(STENCIL_OP_KEEP); + desc.BackFace.StencilDepthFailOp = D3D1X_(STENCIL_OP_KEEP); + desc.BackFace.StencilPassOp = D3D1X_(STENCIL_OP_REPLACE); + desc.BackFace.StencilFunc = D3D1X_(COMPARISON_EQUAL); + + hr = gdraw->d3d_device->CreateDepthStencilState(&desc, &gdraw->stencil_cache[best]); + if (FAILED(hr)) + report_d3d_error(hr, "CreateDepthStencilState", ""); + + gdraw->stencil_cache_key[best] = key; + gdraw->stencil_cache_lru[best] = now; + return gdraw->stencil_cache[best]; +} + +//////////////////////////////////////////////////////////////////////// +// +// Texture creation/updating/deletion +// + +extern GDrawTexture *gdraw_D3D1X_(WrappedTextureCreate)(ID3D1X(ShaderResourceView) *tex_view) +{ + GDrawStats stats={0}; + GDrawHandle *p = gdraw_res_alloc_begin(gdraw->texturecache, 0, &stats); // it may need to free one item to give us a handle + p->handle.tex.d3d = NULL; + p->handle.tex.d3d_view = tex_view; + p->handle.tex.d3d_rtview = NULL; + p->handle.tex.w = 1; + p->handle.tex.h = 1; + gdraw_HandleCacheAllocateEnd(p, 0, NULL, GDRAW_HANDLE_STATE_user_owned); + return (GDrawTexture *) p; +} + +extern void gdraw_D3D1X_(WrappedTextureChange)(GDrawTexture *tex, ID3D1X(ShaderResourceView) *tex_view) +{ + GDrawHandle *p = (GDrawHandle *) tex; + p->handle.tex.d3d = NULL; + p->handle.tex.d3d_view = tex_view; +} + +extern void gdraw_D3D1X_(WrappedTextureDestroy)(GDrawTexture *tex) +{ + GDrawStats stats={0}; + gdraw_res_free((GDrawHandle *) tex, &stats); +} + +static void RADLINK gdraw_SetTextureUniqueID(GDrawTexture *tex, void *old_id, void *new_id) +{ + GDrawHandle *p = (GDrawHandle *) tex; + // if this is still the handle it's thought to be, change the owner; + // if the owner *doesn't* match, then they're changing a stale handle, so ignore + if (p->owner == old_id) + p->owner = new_id; +} + + +static rrbool RADLINK gdraw_MakeTextureBegin(void *owner, S32 width, S32 height, gdraw_texture_format format, U32 flags, GDraw_MakeTexture_ProcessingInfo *p, GDrawStats *stats) +{ + GDrawHandle *t = NULL; + DXGI_FORMAT dxgi_fmt; + S32 bpp, size = 0, nmips = 0; + + if (width >= 16384 || height >= 16384) { + IggyGDrawSendWarning(NULL, "GDraw texture size too large (%d x %d), dimension limit is 16384", width, height); + return false; + } + + if (format == GDRAW_TEXTURE_FORMAT_rgba32) { + dxgi_fmt = DXGI_FORMAT_R8G8B8A8_UNORM; + bpp = 4; + } else { + dxgi_fmt = DXGI_FORMAT_R8_UNORM; + bpp = 1; + } + + // compute estimated size of texture in video memory + do { + size += RR_MAX(width >> nmips, 1) * RR_MAX(height >> nmips, 1) * bpp; + ++nmips; + } while ((flags & GDRAW_MAKETEXTURE_FLAGS_mipmap) && ((width >> nmips) || (height >> nmips))); + + // try to allocate memory for the client to write to + p->texture_data = (U8 *) IggyGDrawMalloc(size); + if (!p->texture_data) { + IggyGDrawSendWarning(NULL, "GDraw out of memory to store texture data to pass to D3D for %d x %d texture", width, height); + return false; + } + + // allocate a handle and make room in the cache for this much data + t = gdraw_res_alloc_begin(gdraw->texturecache, size, stats); + if (!t) { + IggyGDrawFree(p->texture_data); + return false; + } + + t->handle.tex.w = width; + t->handle.tex.h = height; + t->handle.tex.d3d = NULL; + t->handle.tex.d3d_view = NULL; + t->handle.tex.d3d_rtview = NULL; + + p->texture_type = GDRAW_TEXTURE_TYPE_rgba; + p->p0 = t; + p->p1 = owner; + p->i0 = width; + p->i1 = height; + p->i2 = flags; + p->i3 = dxgi_fmt; + p->i4 = size; + p->i5 = nmips; + p->i6 = bpp; + + p->stride_in_bytes = width * bpp; + p->num_rows = height; + + return true; +} + +static rrbool RADLINK gdraw_MakeTextureMore(GDraw_MakeTexture_ProcessingInfo * /*p*/) +{ + return false; +} + +static GDrawTexture * RADLINK gdraw_MakeTextureEnd(GDraw_MakeTexture_ProcessingInfo *p, GDrawStats *stats) +{ + GDrawHandle *t = (GDrawHandle *) p->p0; + D3D1X_(SUBRESOURCE_DATA) mipdata[24]; + S32 i, w, h, nmips, bpp; + HRESULT hr = S_OK; + char *failed_call; + U8 *ptr; + + // generate mip maps and set up descriptors for them + assert(p->i5 <= 24); + ptr = p->texture_data; + w = p->i0; + h = p->i1; + nmips = p->i5; + bpp = p->i6; + + for (i=0; i < nmips; ++i) { + mipdata[i].pSysMem = ptr; + mipdata[i].SysMemPitch = RR_MAX(w >> i, 1) * bpp; + mipdata[i].SysMemSlicePitch = 0; + ptr += mipdata[i].SysMemPitch * RR_MAX(h >> i, 1); + + // create mip data by downsampling + if (i) + gdraw_Downsample((U8 *) mipdata[i].pSysMem, mipdata[i].SysMemPitch, w >> i, h >> i, + (U8 *) mipdata[i-1].pSysMem, mipdata[i-1].SysMemPitch, bpp); + } + + // actually create texture + D3D1X_(TEXTURE2D_DESC) desc = { w, h, nmips, 1, (DXGI_FORMAT) p->i3, { 1, 0 }, + (p->i2 & GDRAW_MAKETEXTURE_FLAGS_updatable) ? D3D1X_(USAGE_DEFAULT) : D3D1X_(USAGE_IMMUTABLE), + D3D1X_(BIND_SHADER_RESOURCE), 0, 0 }; + + failed_call = "CreateTexture2D"; + hr = gdraw->d3d_device->CreateTexture2D(&desc, mipdata, &t->handle.tex.d3d); + if (FAILED(hr)) goto done; + + // and create a corresponding shader resource view + failed_call = "CreateShaderResourceView"; + hr = gdraw->d3d_device->CreateShaderResourceView(t->handle.tex.d3d, NULL, &t->handle.tex.d3d_view); + +done: + if (!FAILED(hr)) { + gdraw_HandleCacheAllocateEnd(t, p->i4, p->p1, (p->i2 & GDRAW_MAKETEXTURE_FLAGS_never_flush) ? GDRAW_HANDLE_STATE_pinned : GDRAW_HANDLE_STATE_locked); + stats->nonzero_flags |= GDRAW_STATS_alloc_tex; + stats->alloc_tex += 1; + stats->alloc_tex_bytes += p->i4; + } else { + safe_release(t->handle.tex.d3d); + safe_release(t->handle.tex.d3d_view); + + gdraw_HandleCacheAllocateFail(t); + t = NULL; + report_d3d_error(hr, failed_call, " while creating texture"); + } + + IggyGDrawFree(p->texture_data); + return (GDrawTexture *) t; +} + +static rrbool RADLINK gdraw_UpdateTextureBegin(GDrawTexture *t, void *unique_id, GDrawStats * /*stats*/) +{ + return gdraw_HandleCacheLock((GDrawHandle *) t, unique_id); +} + +static void RADLINK gdraw_UpdateTextureRect(GDrawTexture *t, void * /*unique_id*/, S32 x, S32 y, S32 stride, S32 w, S32 h, U8 *samples, gdraw_texture_format /*format*/) +{ + GDrawHandle *s = (GDrawHandle *) t; + D3D1X_(BOX) box = { x, y, 0, x+w, y+h, 1 }; + + gdraw->d3d_context->UpdateSubresource(s->handle.tex.d3d, 0, &box, samples, stride, 0); +} + +static void RADLINK gdraw_UpdateTextureEnd(GDrawTexture *t, void * /*unique_id*/, GDrawStats * /*stats*/) +{ + gdraw_HandleCacheUnlock((GDrawHandle *) t); +} + +static void RADLINK gdraw_FreeTexture(GDrawTexture *tt, void *unique_id, GDrawStats *stats) +{ + GDrawHandle *t = (GDrawHandle *) tt; + assert(t != NULL); // @GDRAW_ASSERT + if (t->owner == unique_id || unique_id == NULL) { + if (t->cache == &gdraw->rendertargets) { + gdraw_HandleCacheUnlock(t); + // cache it by simply not freeing it + return; + } + + gdraw_res_free(t, stats); + } +} + +static rrbool RADLINK gdraw_TryToLockTexture(GDrawTexture *t, void *unique_id, GDrawStats * /*stats*/) +{ + return gdraw_HandleCacheLock((GDrawHandle *) t, unique_id); +} + +static void RADLINK gdraw_DescribeTexture(GDrawTexture *tex, GDraw_Texture_Description *desc) +{ + GDrawHandle *p = (GDrawHandle *) tex; + desc->width = p->handle.tex.w; + desc->height = p->handle.tex.h; + desc->size_in_bytes = p->bytes; +} + +static void RADLINK gdraw_SetAntialiasTexture(S32 width, U8 *rgba) +{ + HRESULT hr; + + safe_release(gdraw->aa_tex_view); + safe_release(gdraw->aa_tex); + + D3D1X_(TEXTURE2D_DESC) desc = { width, 1, 1, 1, DXGI_FORMAT_R8G8B8A8_UNORM, { 1, 0 }, D3D1X_(USAGE_IMMUTABLE), D3D1X_(BIND_SHADER_RESOURCE), 0, 0 }; + D3D1X_(SUBRESOURCE_DATA) data = { rgba, width*4, 0 }; + + hr = gdraw->d3d_device->CreateTexture2D(&desc, &data, &gdraw->aa_tex); + if (FAILED(hr)) { + report_d3d_error(hr, "CreateTexture2D", ""); + return; + } + + hr = gdraw->d3d_device->CreateShaderResourceView(gdraw->aa_tex, NULL, &gdraw->aa_tex_view); + if (FAILED(hr)) { + report_d3d_error(hr, "CreateShaderResourceView", " while creating texture"); + safe_release(gdraw->aa_tex); + return; + } +} + +//////////////////////////////////////////////////////////////////////// +// +// Vertex buffer creation/deletion +// + +static rrbool RADLINK gdraw_MakeVertexBufferBegin(void *unique_id, gdraw_vformat /*vformat*/, S32 vbuf_size, S32 ibuf_size, GDraw_MakeVertexBuffer_ProcessingInfo *p, GDrawStats *stats) +{ + // prepare staging buffers for the app to put data into + p->vertex_data = (U8 *) IggyGDrawMalloc(vbuf_size); + p->index_data = (U8 *) IggyGDrawMalloc(ibuf_size); + if (p->vertex_data && p->index_data) { + GDrawHandle *vb = gdraw_res_alloc_begin(gdraw->vbufcache, vbuf_size + ibuf_size, stats); + if (vb) { + vb->handle.vbuf.verts = NULL; + vb->handle.vbuf.inds = NULL; + + p->vertex_data_length = vbuf_size; + p->index_data_length = ibuf_size; + p->p0 = vb; + p->p1 = unique_id; + return true; + } + } + + if (p->vertex_data) + IggyGDrawFree(p->vertex_data); + if (p->index_data) + IggyGDrawFree(p->index_data); + + return false; +} + +static rrbool RADLINK gdraw_MakeVertexBufferMore(GDraw_MakeVertexBuffer_ProcessingInfo * /*p*/) +{ + assert(0); + return false; +} + +static GDrawVertexBuffer * RADLINK gdraw_MakeVertexBufferEnd(GDraw_MakeVertexBuffer_ProcessingInfo *p, GDrawStats * /*stats*/) +{ + GDrawHandle *vb = (GDrawHandle *) p->p0; + + HRESULT hr; + D3D1X_(BUFFER_DESC) vbdesc = { p->vertex_data_length, D3D1X_(USAGE_IMMUTABLE), D3D1X_(BIND_VERTEX_BUFFER), 0, 0 }; + D3D1X_(SUBRESOURCE_DATA) vbdata = { p->vertex_data, 0, 0 }; + + D3D1X_(BUFFER_DESC) ibdesc = { p->index_data_length, D3D1X_(USAGE_IMMUTABLE), D3D1X_(BIND_INDEX_BUFFER), 0, 0 }; + D3D1X_(SUBRESOURCE_DATA) ibdata = { p->index_data, 0, 0 }; + + hr = gdraw->d3d_device->CreateBuffer(&vbdesc, &vbdata, &vb->handle.vbuf.verts); + if (!FAILED(hr)) + hr = gdraw->d3d_device->CreateBuffer(&ibdesc, &ibdata, &vb->handle.vbuf.inds); + + if (FAILED(hr)) { + safe_release(vb->handle.vbuf.verts); + safe_release(vb->handle.vbuf.inds); + + gdraw_HandleCacheAllocateFail(vb); + vb = NULL; + + report_d3d_error(hr, "CreateBuffer", " creating vertex buffer"); + } else { + gdraw_HandleCacheAllocateEnd(vb, p->vertex_data_length + p->index_data_length, p->p1, GDRAW_HANDLE_STATE_locked); + } + + IggyGDrawFree(p->vertex_data); + IggyGDrawFree(p->index_data); + + return (GDrawVertexBuffer *) vb; +} + +static rrbool RADLINK gdraw_TryLockVertexBuffer(GDrawVertexBuffer *vb, void *unique_id, GDrawStats * /*stats*/) +{ + return gdraw_HandleCacheLock((GDrawHandle *) vb, unique_id); +} + +static void RADLINK gdraw_FreeVertexBuffer(GDrawVertexBuffer *vb, void *unique_id, GDrawStats *stats) +{ + GDrawHandle *h = (GDrawHandle *) vb; + assert(h != NULL); // @GDRAW_ASSERT + if (h->owner == unique_id) + gdraw_res_free(h, stats); +} + +static void RADLINK gdraw_DescribeVertexBuffer(GDrawVertexBuffer *vbuf, GDraw_VertexBuffer_Description *desc) +{ + GDrawHandle *p = (GDrawHandle *) vbuf; + desc->size_in_bytes = p->bytes; +} + +//////////////////////////////////////////////////////////////////////// +// +// Create/free (or cache) render targets +// + +static GDrawHandle *get_color_rendertarget(GDrawStats *stats) +{ + char *failed_call; + + // try to recycle LRU rendertarget + GDrawHandle *t = gdraw_HandleCacheGetLRU(&gdraw->rendertargets); + if (t) { + gdraw_HandleCacheLock(t, (void *) 1); + return t; + } + + // ran out of RTs, allocate a new one + S32 size = gdraw->frametex_width * gdraw->frametex_height * 4; + if (gdraw->rendertargets.bytes_free < size) { + IggyGDrawSendWarning(NULL, "GDraw rendertarget allocation failed: hit size limit of %d bytes", gdraw->rendertargets.total_bytes); + return NULL; + } + + t = gdraw_HandleCacheAllocateBegin(&gdraw->rendertargets); + if (!t) { + IggyGDrawSendWarning(NULL, "GDraw rendertarget allocation failed: hit handle limit"); + return t; + } + + D3D1X_(TEXTURE2D_DESC) desc = { gdraw->frametex_width, gdraw->frametex_height, 1, 1, DXGI_FORMAT_R8G8B8A8_UNORM, { 1, 0 }, + D3D1X_(USAGE_DEFAULT), D3D1X_(BIND_SHADER_RESOURCE) | D3D1X_(BIND_RENDER_TARGET), 0, 0 }; + + t->handle.tex.d3d = NULL; + t->handle.tex.d3d_view = NULL; + t->handle.tex.d3d_rtview = NULL; + + HRESULT hr = gdraw->d3d_device->CreateTexture2D(&desc, NULL, &t->handle.tex.d3d); + failed_call = "CreateTexture2D"; + if (!FAILED(hr)) { + hr = gdraw->d3d_device->CreateShaderResourceView(t->handle.tex.d3d, NULL, &t->handle.tex.d3d_view); + failed_call = "CreateTexture2D"; + } + if (!FAILED(hr)) { + hr = gdraw->d3d_device->CreateRenderTargetView(t->handle.tex.d3d, NULL, &t->handle.tex.d3d_rtview); + failed_call = "CreateRenderTargetView"; + } + + if (FAILED(hr)) { + safe_release(t->handle.tex.d3d); + safe_release(t->handle.tex.d3d_view); + safe_release(t->handle.tex.d3d_rtview); + gdraw_HandleCacheAllocateFail(t); + + report_d3d_error(hr, failed_call, " creating rendertarget"); + + return NULL; + } + + gdraw_HandleCacheAllocateEnd(t, size, (void *) 1, GDRAW_HANDLE_STATE_locked); + stats->nonzero_flags |= GDRAW_STATS_alloc_tex; + stats->alloc_tex += 1; + stats->alloc_tex_bytes += size; + + return t; +} + +static ID3D1X(DepthStencilView) *get_rendertarget_depthbuffer(GDrawStats *stats) +{ + if (!gdraw->depth_buffer[1]) { + char *failed_call; + assert(!gdraw->rt_depth_buffer); + + D3D1X_(TEXTURE2D_DESC) desc = { gdraw->frametex_width, gdraw->frametex_height, 1, 1, DXGI_FORMAT_D24_UNORM_S8_UINT, { 1, 0 }, + D3D1X_(USAGE_DEFAULT), D3D1X_(BIND_DEPTH_STENCIL), 0, 0 }; + + HRESULT hr = gdraw->d3d_device->CreateTexture2D(&desc, NULL, &gdraw->rt_depth_buffer); + failed_call = "CreateTexture2D"; + if (!FAILED(hr)) { + hr = gdraw->d3d_device->CreateDepthStencilView(gdraw->rt_depth_buffer, NULL, &gdraw->depth_buffer[1]); + failed_call = "CreateDepthStencilView while creating rendertarget"; + } + + if (FAILED(hr)) { + report_d3d_error(hr, failed_call, ""); + safe_release(gdraw->rt_depth_buffer); + safe_release(gdraw->depth_buffer[1]); + } else { + stats->nonzero_flags |= GDRAW_STATS_alloc_tex; + stats->alloc_tex += 1; + stats->alloc_tex_bytes += gdraw->frametex_width * gdraw->frametex_height * 4; + + gdraw->d3d_context->ClearDepthStencilView(gdraw->depth_buffer[1], D3D1X_(CLEAR_DEPTH) | D3D1X_(CLEAR_STENCIL), 1.0f, 0); + } + } + + return gdraw->depth_buffer[1]; +} + +static void flush_rendertargets(GDrawStats *stats) +{ + gdraw_res_flush(&gdraw->rendertargets, stats); + + safe_release(gdraw->depth_buffer[1]); + safe_release(gdraw->rt_depth_buffer); +} + +//////////////////////////////////////////////////////////////////////// +// +// Constant buffer layouts +// + +struct VertexVars +{ + F32 world[2][4]; + F32 x_off[4]; + F32 texgen_s[4]; + F32 texgen_t[4]; + F32 x3d[4]; + F32 y3d[4]; + F32 w3d[4]; +}; + +struct PixelCommonVars +{ + F32 color_mul[4]; + F32 color_add[4]; + F32 focal[4]; + F32 rescale1[4]; +}; + +struct PixelParaFilter +{ + F32 clamp0[4], clamp1[4]; + F32 color[4], color2[4]; + F32 tc_off[4]; +}; + +struct PixelParaBlur +{ + F32 clamp[4]; + F32 tap[9][4]; +}; + +struct PixelParaColorMatrix +{ + F32 data[5][4]; +}; + +//////////////////////////////////////////////////////////////////////// +// +// Rendering helpers +// + +static void disable_scissor(int force) +{ + if (force || gdraw->scissor_state) { + // disable scissor by setting whole viewport as scissor rect + S32 x = gdraw->cview.x; + S32 y = gdraw->cview.y; + D3D1X_(RECT) r = { x, y, x + gdraw->cview.w, y + gdraw->cview.h }; + + gdraw->d3d_context->RSSetScissorRects(1, &r); + gdraw->scissor_state = 0; + } +} + +static void set_viewport_raw(S32 x, S32 y, S32 w, S32 h) +{ + D3D1X_(VIEWPORT) vp = { (ViewCoord) x, (ViewCoord) y, (ViewCoord) w, (ViewCoord) h, 0.0f, 1.0f }; + gdraw->d3d_context->RSSetViewports(1, &vp); + gdraw->cview.x = x; + gdraw->cview.y = y; + gdraw->cview.w = w; + gdraw->cview.h = h; + + disable_scissor(1); +} + +static void set_projection_base(void) +{ + // x3d = < viewproj.x, 0, 0, 0 > + // y3d = < 0, viewproj.y, 0, 0 > + // w3d = < viewproj.z, viewproj.w, 1.0, 1.0 > + + memset(gdraw->projmat[0], 0, sizeof(gdraw->projmat)); + gdraw->projmat[0][0] = gdraw->projection[0]; + gdraw->projmat[1][1] = gdraw->projection[1]; + gdraw->projmat[2][0] = gdraw->projection[2]; + gdraw->projmat[2][1] = gdraw->projection[3]; + + gdraw->projmat[2][2] = 1.0; + gdraw->projmat[2][3] = 1.0; +} + +static void set_projection_raw(S32 x0, S32 x1, S32 y0, S32 y1) +{ + gdraw->projection[0] = 2.0f / (x1-x0); + gdraw->projection[1] = 2.0f / (y1-y0); + gdraw->projection[2] = (x1+x0)/(F32)(x0-x1); + gdraw->projection[3] = (y1+y0)/(F32)(y0-y1); + + set_projection_base(); +} + + +static void set_viewport(void) +{ + if (gdraw->in_blur) { + set_viewport_raw(0, 0, gdraw->tpw, gdraw->tph); + return; + } + + if (gdraw->cur == gdraw->frame) // if the rendering stack is empty + // render a tile-sized region to the user-request tile location + set_viewport_raw(gdraw->vx, gdraw->vy, gdraw->tw, gdraw->th); + else if (gdraw->cur->cached) + set_viewport_raw(0, 0, gdraw->cur->width, gdraw->cur->height); + else + // if on the render stack, draw a padded-tile-sized region at the origin + set_viewport_raw(0, 0, gdraw->tpw, gdraw->tph); +} + +static void set_projection(void) +{ + if (gdraw->in_blur) return; + if (gdraw->cur == gdraw->frame) // if the render stack is empty + set_projection_raw(gdraw->tx0, gdraw->tx0+gdraw->tw, gdraw->ty0+gdraw->th, gdraw->ty0); + else if (gdraw->cur->cached) + set_projection_raw(gdraw->cur->base_x, gdraw->cur->base_x+gdraw->cur->width, gdraw->cur->base_y, gdraw->cur->base_y+gdraw->cur->height); + else + set_projection_raw(gdraw->tx0p, gdraw->tx0p+gdraw->tpw, gdraw->ty0p+gdraw->tph, gdraw->ty0p); +} + +static void clear_renderstate(void) +{ + gdraw->d3d_context->ClearState(); +} + +static void set_common_renderstate() +{ + ID3D1XContext *d3d = gdraw->d3d_context; + S32 i; + + clear_renderstate(); + + // all the render states we never change while drawing + d3d->IASetPrimitiveTopology(D3D1X_(PRIMITIVE_TOPOLOGY_TRIANGLELIST)); + + d3d->PSSetShaderResources(7, 1, &gdraw->aa_tex_view); + d3d->PSSetSamplers(7, 1, &gdraw->sampler_state[0][GDRAW_WRAP_clamp]); + + // set a well-defined default sampler for all PS textures we use + for (i=0; i < 3; ++i) + d3d->PSSetSamplers(i, 1, &gdraw->sampler_state[0][GDRAW_WRAP_clamp]); + + // reset our state caching + gdraw->scissor_state = ~0u; + gdraw->blend_mode = -1; +} + +static void manual_clear(gswf_recti *r, GDrawStats *stats); +static void set_render_target(GDrawStats *stats); + +//////////////////////////////////////////////////////////////////////// +// +// Begin/end rendering of a tile and per-frame processing +// + +void gdraw_D3D1X_(SetRendertargetSize)(S32 w, S32 h) +{ + if (gdraw && (w != gdraw->frametex_width || h != gdraw->frametex_height)) { + GDrawStats stats = { 0 }; + gdraw->frametex_width = w; + gdraw->frametex_height = h; + flush_rendertargets(&stats); + } +} + +void gdraw_D3D1X_(SetTileOrigin)(ID3D1X(RenderTargetView) *main_rt, ID3D1X(DepthStencilView) *main_ds, ID3D1X(ShaderResourceView) *non_msaa_rt, S32 x, S32 y) +{ + D3D1X_(RENDER_TARGET_VIEW_DESC) desc; + + if (gdraw->frame_done) { + ++gdraw->frame_counter; + gdraw->frame_done = false; + } + + main_rt->GetDesc(&desc); + + gdraw->main_framebuffer = main_rt; + gdraw->main_resolve_target = non_msaa_rt; + gdraw->main_msaa = (desc.ViewDimension == D3D1X_(RTV_DIMENSION_TEXTURE2DMS)); + gdraw->depth_buffer[0] = main_ds; + + gdraw->vx = x; + gdraw->vy = y; +} + +static void RADLINK gdraw_SetViewSizeAndWorldScale(S32 w, S32 h, F32 scalex, F32 scaley) +{ + memset(gdraw->frame, 0, sizeof(gdraw->frame)); + gdraw->cur = gdraw->frame; + gdraw->fw = w; + gdraw->fh = h; + gdraw->tw = w; + gdraw->th = h; + gdraw->world_to_pixel[0] = scalex; + gdraw->world_to_pixel[1] = scaley; + set_viewport(); +} + +// must include anything necessary for texture creation/update +static void RADLINK gdraw_RenderingBegin(void) +{ +} +static void RADLINK gdraw_RenderingEnd(void) +{ +} + +static void RADLINK gdraw_RenderTileBegin(S32 x0, S32 y0, S32 x1, S32 y1, S32 pad, GDrawStats *stats) +{ + if (x0 == 0 && y0 == 0 && x1 == gdraw->fw && y1 == gdraw->fh) + pad = 0; + + gdraw->tx0 = x0; + gdraw->ty0 = y0; + gdraw->tw = x1-x0; + gdraw->th = y1-y0; + + // padded region + gdraw->tx0p = RR_MAX(x0 - pad, 0); + gdraw->ty0p = RR_MAX(y0 - pad, 0); + gdraw->tpw = RR_MIN(x1 + pad, gdraw->fw) - gdraw->tx0p; + gdraw->tph = RR_MIN(y1 + pad, gdraw->fh) - gdraw->ty0p; + + // make sure our rendertargets are large enough to contain the tile + if (gdraw->tpw > gdraw->frametex_width || gdraw->tph > gdraw->frametex_height) { + gdraw->frametex_width = RR_MAX(gdraw->tpw, gdraw->frametex_width); + gdraw->frametex_height = RR_MAX(gdraw->tph, gdraw->frametex_height); + + flush_rendertargets(stats); + } + assert(gdraw->tpw <= gdraw->frametex_width && gdraw->tph <= gdraw->frametex_height); + + // set up rendertargets we'll use + set_common_renderstate(); + gdraw->d3d_context->ClearDepthStencilView(gdraw->depth_buffer[0], D3D1X_(CLEAR_DEPTH) | D3D1X_(CLEAR_STENCIL), 1.0f, 0); + if (gdraw->depth_buffer[1]) + gdraw->d3d_context->ClearDepthStencilView(gdraw->depth_buffer[1], D3D1X_(CLEAR_DEPTH) | D3D1X_(CLEAR_STENCIL), 1.0f, 0); + + set_projection(); + set_viewport(); + set_render_target(stats); +} + +static void RADLINK gdraw_RenderTileEnd(GDrawStats * /*stats*/) +{ +} + +void gdraw_D3D1X_(NoMoreGDrawThisFrame)(void) +{ + clear_renderstate(); + gdraw->frame_done = true; + + gdraw->last_dyn_maxalloc = gdraw->dyn_maxalloc; + gdraw->dyn_maxalloc = 0; + + // reset dynamic buffer alloc position so they get DISCARDed + // next time around. + gdraw->dyn_vb.alloc_pos = 0; + gdraw->dyn_ib.alloc_pos = 0; + + GDrawFence now = { gdraw->frame_counter }; + gdraw_HandleCacheTick(gdraw->texturecache, now); + gdraw_HandleCacheTick(gdraw->vbufcache, now); +} + +#define MAX_DEPTH_VALUE (1 << 13) + +static void RADLINK gdraw_GetInfo(GDrawInfo *d) +{ + d->num_stencil_bits = 8; + d->max_id = MAX_DEPTH_VALUE-2; + // for floating point depth, just use mantissa, e.g. 16-20 bits + d->buffer_format = GDRAW_BFORMAT_vbib; + d->shared_depth_stencil = 1; + d->always_mipmap = 1; +#ifndef GDRAW_D3D11_LEVEL9 + d->max_texture_size = 8192; + d->conditional_nonpow2 = 0; +#else + d->max_texture_size = 2048; + d->conditional_nonpow2 = 1; +#endif +} + +//////////////////////////////////////////////////////////////////////// +// +// Enable/disable rendertargets in stack fashion +// + +static ID3D1X(RenderTargetView) *get_active_render_target() +{ + if (gdraw->cur->color_buffer) { + unbind_resources(); // to make sure this RT isn't accidentally set as a texture (avoid D3D warnings) + return gdraw->cur->color_buffer->handle.tex.d3d_rtview; + } else + return gdraw->main_framebuffer; +} + +static void set_render_target(GDrawStats *stats) +{ + ID3D1X(RenderTargetView) *target = get_active_render_target(); + if (target == gdraw->main_framebuffer) { + gdraw->d3d_context->OMSetRenderTargets(1, &target, gdraw->depth_buffer[0]); + gdraw->d3d_context->RSSetState(gdraw->raster_state[gdraw->main_msaa]); + } else { + ID3D1X(DepthStencilView) *depth = NULL; + if (gdraw->cur->flags & (GDRAW_TEXTUREDRAWBUFFER_FLAGS_needs_id | GDRAW_TEXTUREDRAWBUFFER_FLAGS_needs_stencil)) + depth = get_rendertarget_depthbuffer(stats); + + gdraw->d3d_context->OMSetRenderTargets(1, &target, depth); + gdraw->d3d_context->RSSetState(gdraw->raster_state[0]); + } + + stats->nonzero_flags |= GDRAW_STATS_rendtarg; + stats->rendertarget_changes += 1; +} + +static rrbool RADLINK gdraw_TextureDrawBufferBegin(gswf_recti *region, gdraw_texture_format /*format*/, U32 flags, void *owner, GDrawStats *stats) +{ + GDrawFramebufferState *n = gdraw->cur+1; + GDrawHandle *t = NULL; + if (gdraw->tw == 0 || gdraw->th == 0) { + IggyGDrawSendWarning(NULL, "GDraw warning: w=0,h=0 rendertarget"); + return false; + } + + if (n >= &gdraw->frame[MAX_RENDER_STACK_DEPTH]) { + assert(0); + IggyGDrawSendWarning(NULL, "GDraw rendertarget nesting exceeds MAX_RENDER_STACK_DEPTH"); + return false; + } + + if (owner) { + // nyi + } else { + t = get_color_rendertarget(stats); + if (!t) + return false; + } + + n->flags = flags; + n->color_buffer = t; + assert(n->color_buffer != NULL); // @GDRAW_ASSERT + + ++gdraw->cur; + gdraw->cur->cached = owner != NULL; + if (owner) { + gdraw->cur->base_x = region->x0; + gdraw->cur->base_y = region->y0; + gdraw->cur->width = region->x1 - region->x0; + gdraw->cur->height = region->y1 - region->y0; + } + + set_render_target(stats); + assert(gdraw->frametex_width >= gdraw->tw && gdraw->frametex_height >= gdraw->th); // @GDRAW_ASSERT + + S32 k = (S32) (t - gdraw->rendertargets.handle); + + if (region) { + gswf_recti r; + S32 ox, oy, pad = 2; // 2 pixels of border on all sides + // 1 pixel turns out to be not quite enough with the interpolator precision we get. + + if (gdraw->in_blur) + ox = oy = 0; + else + ox = gdraw->tx0p, oy = gdraw->ty0p; + + // clamp region to tile + S32 xt0 = RR_MAX(region->x0 - ox, 0); + S32 yt0 = RR_MAX(region->y0 - oy, 0); + S32 xt1 = RR_MIN(region->x1 - ox, gdraw->tpw); + S32 yt1 = RR_MIN(region->y1 - oy, gdraw->tph); + + // but the padding needs to clamp to render target bounds + r.x0 = RR_MAX(xt0 - pad, 0); + r.y0 = RR_MAX(yt0 - pad, 0); + r.x1 = RR_MIN(xt1 + pad, gdraw->frametex_width); + r.y1 = RR_MIN(yt1 + pad, gdraw->frametex_height); + + if (r.x1 <= r.x0 || r.y1 <= r.y0) { // region doesn't intersect with current tile + --gdraw->cur; + gdraw_FreeTexture((GDrawTexture *) t, 0, stats); + // note: don't send a warning since this will happen during regular tiled rendering + return false; + } + + manual_clear(&r, stats); + + gdraw->rt_valid[k].x0 = xt0; + gdraw->rt_valid[k].y0 = yt0; + gdraw->rt_valid[k].x1 = xt1; + gdraw->rt_valid[k].y1 = yt1; + } else { + gdraw->d3d_context->ClearRenderTargetView(gdraw->cur->color_buffer->handle.tex.d3d_rtview, four_zeros); + gdraw->rt_valid[k].x0 = 0; + gdraw->rt_valid[k].y0 = 0; + gdraw->rt_valid[k].x1 = gdraw->frametex_width; + gdraw->rt_valid[k].y1 = gdraw->frametex_height; + } + + if (!gdraw->in_blur) { + set_viewport(); + set_projection(); + } else { + set_viewport_raw(0, 0, gdraw->tpw, gdraw->tph); + set_projection_raw(0, gdraw->tpw, gdraw->tph, 0); + } + + return true; +} + +static GDrawTexture *RADLINK gdraw_TextureDrawBufferEnd(GDrawStats *stats) +{ + GDrawFramebufferState *n = gdraw->cur; + GDrawFramebufferState *m = --gdraw->cur; + if (gdraw->tw == 0 || gdraw->th == 0) return 0; + + if (n >= &gdraw->frame[MAX_RENDER_STACK_DEPTH]) + return 0; // already returned a warning in Begin + + assert(m >= gdraw->frame); // bug in Iggy -- unbalanced + + if (m != gdraw->frame) { + assert(m->color_buffer != NULL); // @GDRAW_ASSERT + } + assert(n->color_buffer != NULL); // @GDRAW_ASSERT + + // switch back to old render target + set_render_target(stats); + + // if we're at the root, set the viewport back + set_viewport(); + set_projection(); + + return (GDrawTexture *) n->color_buffer; +} + + +//////////////////////////////////////////////////////////////////////// +// +// Clear stencil/depth buffers +// +// Open question whether we'd be better off finding bounding boxes +// and only clearing those; it depends exactly how fast clearing works. +// + +static void RADLINK gdraw_ClearStencilBits(U32 /*bits*/) +{ + gdraw->d3d_context->ClearDepthStencilView(gdraw->depth_buffer[0], D3D1X_(CLEAR_STENCIL), 1.0f, 0); + if (gdraw->depth_buffer[1]) + gdraw->d3d_context->ClearDepthStencilView(gdraw->depth_buffer[1], D3D1X_(CLEAR_STENCIL), 1.0f, 0); +} + +// this only happens rarely (hopefully never) if we use the depth buffer, +// so we can just clear the whole thing +static void RADLINK gdraw_ClearID(void) +{ + gdraw->d3d_context->ClearDepthStencilView(gdraw->depth_buffer[0], D3D1X_(CLEAR_DEPTH), 1.0f, 0); + if (gdraw->depth_buffer[1]) + gdraw->d3d_context->ClearDepthStencilView(gdraw->depth_buffer[1], D3D1X_(CLEAR_DEPTH), 1.0f, 0); +} + +//////////////////////////////////////////////////////////////////////// +// +// Set all the render state from GDrawRenderState +// +// This also is responsible for getting the framebuffer into a texture +// if the read-modify-write blend operation can't be expressed with +// the native blend operators. (E.g. "screen") +// + +// convert an ID request to a value suitable for the depth buffer, +// assuming the depth buffer has been mappped to 0..1 +static F32 depth_from_id(S32 id) +{ + return 1.0f - ((F32) id + 1.0f) / MAX_DEPTH_VALUE; +} + +static void set_texture(S32 texunit, GDrawTexture *tex, rrbool nearest, S32 wrap) +{ + ID3D1XContext *d3d = gdraw->d3d_context; + + if (tex == NULL) { + ID3D1X(ShaderResourceView) *notex = NULL; + d3d->PSSetShaderResources(texunit, 1, ¬ex); + } else { + GDrawHandle *h = (GDrawHandle *) tex; + d3d->PSSetShaderResources(texunit, 1, &h->handle.tex.d3d_view); + d3d->PSSetSamplers(texunit, 1, &gdraw->sampler_state[nearest][wrap]); + } +} + +static void RADLINK gdraw_Set3DTransform(F32 *mat) +{ + if (mat == NULL) + gdraw->use_3d = 0; + else { + gdraw->use_3d = 1; + memcpy(gdraw->xform_3d, mat, sizeof(gdraw->xform_3d)); + } +} + +static int set_renderstate_full(S32 vertex_format, GDrawRenderState *r, GDrawStats * /* stats */, const F32 *rescale1) +{ + ID3D1XContext *d3d = gdraw->d3d_context; + + // set vertex shader + set_vertex_shader(d3d, gdraw->vert[vertex_format].vshader); + + // set vertex shader constants + if (VertexVars *vvars = (VertexVars *) map_buffer(gdraw->d3d_context, gdraw->cb_vertex, true)) { + F32 depth = depth_from_id(r->id); + if (!r->use_world_space) + gdraw_ObjectSpace(vvars->world[0], r->o2w, depth, 0.0f); + else + gdraw_WorldSpace(vvars->world[0], gdraw->world_to_pixel, depth, 0.0f); + + memcpy(&vvars->x_off, r->edge_matrix, 4*sizeof(F32)); + + if (r->texgen0_enabled) { + memcpy(&vvars->texgen_s, r->s0_texgen, 4*sizeof(F32)); + memcpy(&vvars->texgen_t, r->t0_texgen, 4*sizeof(F32)); + } + + if (gdraw->use_3d) + memcpy(vvars->x3d, gdraw->xform_3d, 12*sizeof(F32)); + else + memcpy(vvars->x3d, gdraw->projmat, 12*sizeof(F32)); + + unmap_buffer(gdraw->d3d_context, gdraw->cb_vertex); + + d3d->VSSetConstantBuffers(0, 1, &gdraw->cb_vertex); + } + + // set the blend mode + int blend_mode = r->blend_mode; + if (blend_mode != gdraw->blend_mode) { + gdraw->blend_mode = blend_mode; + d3d->OMSetBlendState(gdraw->blend_state[blend_mode], four_zeros, ~0u); + } + + // set the fragment program + if (blend_mode != GDRAW_BLEND_special) { + int which = r->tex0_mode; + assert(which >= 0 && which < sizeof(gdraw->fprog) / sizeof(*gdraw->fprog)); + + int additive = 0; + if (r->cxf_add) { + additive = 1; + if (r->cxf_add[3]) additive = 2; + } + + ID3D1X(PixelShader) *program = gdraw->fprog[which][additive].pshader; + if (r->stencil_set) { + // in stencil set mode, prefer not doing any shading at all + // but if alpha test is on, we need to make an exception + +#ifndef GDRAW_D3D11_LEVEL9 // level9 can't do NULL PS it seems + if (which != GDRAW_TEXTURE_alpha_test) + program = NULL; + else +#endif + { + gdraw->blend_mode = -1; + d3d->OMSetBlendState(gdraw->blend_no_color_write, four_zeros, ~0u); + } + } + + set_pixel_shader(d3d, program); + } else + set_pixel_shader(d3d, gdraw->exceptional_blend[r->special_blend].pshader); + + set_texture(0, r->tex[0], r->nearest0, r->wrap0); + + // pixel shader constants + if (PixelCommonVars *pvars = (PixelCommonVars *) map_buffer(gdraw->d3d_context, gdraw->cb_ps_common, true)) { + memcpy(pvars->color_mul, r->color, 4*sizeof(float)); + + if (r->cxf_add) { + pvars->color_add[0] = r->cxf_add[0] / 255.0f; + pvars->color_add[1] = r->cxf_add[1] / 255.0f; + pvars->color_add[2] = r->cxf_add[2] / 255.0f; + pvars->color_add[3] = r->cxf_add[3] / 255.0f; + } else + pvars->color_add[0] = pvars->color_add[1] = pvars->color_add[2] = pvars->color_add[3] = 0.0f; + + if (r->tex0_mode == GDRAW_TEXTURE_focal_gradient) memcpy(pvars->focal, r->focal_point, 4*sizeof(float)); + if (r->blend_mode == GDRAW_BLEND_special) memcpy(pvars->rescale1, rescale1, 4*sizeof(float)); + unmap_buffer(gdraw->d3d_context, gdraw->cb_ps_common); + d3d->PSSetConstantBuffers(0, 1, &gdraw->cb_ps_common); + } + + // Set pixel operation states + if (r->scissor) { + D3D1X_(RECT) s; + gdraw->scissor_state = 1; + if (gdraw->cur == gdraw->frame) { + s.left = r->scissor_rect.x0 + gdraw->vx - gdraw->tx0; + s.top = r->scissor_rect.y0 + gdraw->vy - gdraw->ty0; + s.right = r->scissor_rect.x1 + gdraw->vx - gdraw->tx0; + s.bottom = r->scissor_rect.y1 + gdraw->vy - gdraw->ty0; + } else { + s.left = r->scissor_rect.x0 - gdraw->tx0p; + s.top = r->scissor_rect.y0 - gdraw->ty0p; + s.right = r->scissor_rect.x1 - gdraw->tx0p; + s.bottom = r->scissor_rect.y1 - gdraw->ty0p; + } + d3d->RSSetScissorRects(1, &s); + } else if (r->scissor != gdraw->scissor_state) + disable_scissor(0); + + if (r->stencil_set | r->stencil_test) + d3d->OMSetDepthStencilState(stencil_state_cache_lookup(r->set_id, r->test_id, r->stencil_test, r->stencil_set), 255); + else + d3d->OMSetDepthStencilState(gdraw->depth_state[r->set_id][r->test_id], 0); + + return 1; +} + +static RADINLINE int set_renderstate(S32 vertex_format, GDrawRenderState *r, GDrawStats *stats) +{ + static const F32 unit_rescale[4] = { 1.0f, 1.0f, 0.0f, 0.0f }; + if (r->identical_state) { + // fast path: only need to change vertex shader, other state is the same + set_vertex_shader(gdraw->d3d_context, gdraw->vert[vertex_format].vshader); + return 1; + } else + return set_renderstate_full(vertex_format, r, stats, unit_rescale); +} + +//////////////////////////////////////////////////////////////////////// +// +// Vertex formats +// + +static D3D1X_(INPUT_ELEMENT_DESC) vformat_v2[] = { + { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D1X_(INPUT_PER_VERTEX_DATA), 0 }, +}; + +static D3D1X_(INPUT_ELEMENT_DESC) vformat_v2aa[] = { + { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D1X_(INPUT_PER_VERTEX_DATA), 0 }, + { "TEXCOORD", 0, DXGI_FORMAT_R16G16B16A16_SINT, 0, 8, D3D1X_(INPUT_PER_VERTEX_DATA), 0 }, +}; + +static D3D1X_(INPUT_ELEMENT_DESC) vformat_v2tc2[] = { + { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D1X_(INPUT_PER_VERTEX_DATA), 0 }, + { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 8, D3D1X_(INPUT_PER_VERTEX_DATA), 0 }, +}; + +static struct gdraw_vertex_format_desc { + D3D1X_(INPUT_ELEMENT_DESC) *desc; + U32 nelem; +} vformats[ASSERT_COUNT(GDRAW_vformat__basic_count, 3)] = { + vformat_v2, 1, // GDRAW_vformat_v2 + vformat_v2aa, 2, // GDRAW_vformat_v2aa + vformat_v2tc2, 2, // GDRAW_vforamt_v2tc2 +}; + +static int vertsize[GDRAW_vformat__basic_count] = { + 8, // GDRAW_vformat_v2 + 16, // GDRAW_vformat_v2aa + 16, // GDRAW_vformat_v2tc2 +}; + +//////////////////////////////////////////////////////////////////////// +// +// Draw triangles with a given renderstate +// + +static void tag_resources(void *r1, void *r2=NULL, void *r3=NULL, void *r4=NULL) +{ + U64 now = gdraw->frame_counter; + if (r1) ((GDrawHandle *) r1)->fence.value = now; + if (r2) ((GDrawHandle *) r2)->fence.value = now; + if (r3) ((GDrawHandle *) r3)->fence.value = now; + if (r4) ((GDrawHandle *) r4)->fence.value = now; +} + +static void RADLINK gdraw_DrawIndexedTriangles(GDrawRenderState *r, GDrawPrimitive *p, GDrawVertexBuffer *buf, GDrawStats *stats) +{ + ID3D1XContext *d3d = gdraw->d3d_context; + GDrawHandle *vb = (GDrawHandle *) buf; + int vfmt = p->vertex_format; + assert(vfmt >= 0 && vfmt < GDRAW_vformat__count); + + if (!set_renderstate(vfmt, r, stats)) + return; + + UINT stride = vertsize[vfmt]; + d3d->IASetInputLayout(gdraw->inlayout[vfmt]); + + if (vb) { + UINT offs = (UINT) (UINTa) p->vertices; + + d3d->IASetVertexBuffers(0, 1, &vb->handle.vbuf.verts, &stride, &offs); + d3d->IASetIndexBuffer(vb->handle.vbuf.inds, DXGI_FORMAT_R16_UINT, (UINT) (UINTa) p->indices); + d3d->DrawIndexed(p->num_indices, 0, 0); + } else if (p->indices) { + U32 vbytes = p->num_vertices * stride; + U32 ibytes = p->num_indices * 2; + + if (void *vbptr = start_write_dyn(&gdraw->dyn_vb, vbytes)) { + memcpy(vbptr, p->vertices, vbytes); + UINT vboffs = end_write_dyn(&gdraw->dyn_vb); + + if (void *ibptr = start_write_dyn(&gdraw->dyn_ib, ibytes)) { + memcpy(ibptr, p->indices, ibytes); + UINT iboffs = end_write_dyn(&gdraw->dyn_ib); + + d3d->IASetVertexBuffers(0, 1, &gdraw->dyn_vb.buffer, &stride, &vboffs); + d3d->IASetIndexBuffer(gdraw->dyn_ib.buffer, DXGI_FORMAT_R16_UINT, iboffs); + d3d->DrawIndexed(p->num_indices, 0, 0); + } + } + } else { // dynamic quads + assert(p->num_vertices % 4 == 0); + d3d->IASetIndexBuffer(gdraw->quad_ib, DXGI_FORMAT_R16_UINT, 0); + + if (gdraw->max_quad_vert_count) { + S32 pos = 0; + while (pos < p->num_vertices) { + S32 vert_count = RR_MIN(p->num_vertices - pos, gdraw->max_quad_vert_count); + UINT chunk_bytes = vert_count * stride; + + if (void *vbptr = start_write_dyn(&gdraw->dyn_vb, chunk_bytes)) { + memcpy(vbptr, (U8 *)p->vertices + pos*stride, chunk_bytes); + UINT offs = end_write_dyn(&gdraw->dyn_vb); + + d3d->IASetVertexBuffers(0, 1, &gdraw->dyn_vb.buffer, &stride, &offs); + d3d->DrawIndexed((vert_count >> 2) * 6, 0, 0); + } + pos += vert_count; + } + } + } + + tag_resources(vb, r->tex[0], r->tex[1]); + + stats->nonzero_flags |= GDRAW_STATS_batches; + stats->num_batches += 1; + stats->drawn_indices += p->num_indices; + stats->drawn_vertices += p->num_vertices; +} + +/////////////////////////////////////////////////////////////////////// +// +// Flash 8 filter effects +// + +static void *start_ps_constants(ID3D1X(Buffer) *buffer) +{ + return map_buffer(gdraw->d3d_context, buffer, true); +} + +static void end_ps_constants(ID3D1X(Buffer) *buffer) +{ + unmap_buffer(gdraw->d3d_context, buffer); + gdraw->d3d_context->PSSetConstantBuffers(1, 1, &buffer); +} + +static void set_pixel_constant(F32 *constant, F32 x, F32 y, F32 z, F32 w) +{ + constant[0] = x; + constant[1] = y; + constant[2] = z; + constant[3] = w; +} + +// caller sets up texture coordinates +static void do_screen_quad(gswf_recti *s, const F32 *tc, GDrawStats *stats) +{ + ID3D1XContext *d3d = gdraw->d3d_context; + F32 px0 = (F32) s->x0, py0 = (F32) s->y0, px1 = (F32) s->x1, py1 = (F32) s->y1; + + // generate vertex data + gswf_vertex_xyst *vert = (gswf_vertex_xyst *) start_write_dyn(&gdraw->dyn_vb, 4 * sizeof(gswf_vertex_xyst)); + if (!vert) + return; + + vert[0].x = px0; vert[0].y = py0; vert[0].s = tc[0]; vert[0].t = tc[1]; + vert[1].x = px1; vert[1].y = py0; vert[1].s = tc[2]; vert[1].t = tc[1]; + vert[2].x = px0; vert[2].y = py1; vert[2].s = tc[0]; vert[2].t = tc[3]; + vert[3].x = px1; vert[3].y = py1; vert[3].s = tc[2]; vert[3].t = tc[3]; + UINT offs = end_write_dyn(&gdraw->dyn_vb); + UINT stride = sizeof(gswf_vertex_xyst); + + if (VertexVars *vvars = (VertexVars *) map_buffer(gdraw->d3d_context, gdraw->cb_vertex, true)) { + gdraw_PixelSpace(vvars->world[0]); + memcpy(vvars->x3d, gdraw->projmat, 12*sizeof(F32)); + unmap_buffer(gdraw->d3d_context, gdraw->cb_vertex); + d3d->VSSetConstantBuffers(0, 1, &gdraw->cb_vertex); + + set_vertex_shader(d3d, gdraw->vert[GDRAW_vformat_v2tc2].vshader); + + d3d->IASetInputLayout(gdraw->inlayout[GDRAW_vformat_v2tc2]); + d3d->IASetVertexBuffers(0, 1, &gdraw->dyn_vb.buffer, &stride, &offs); + d3d->IASetPrimitiveTopology(D3D1X_(PRIMITIVE_TOPOLOGY_TRIANGLESTRIP)); + d3d->Draw(4, 0); + d3d->IASetPrimitiveTopology(D3D1X_(PRIMITIVE_TOPOLOGY_TRIANGLELIST)); + + stats->nonzero_flags |= GDRAW_STATS_batches; + stats->num_batches += 1; + stats->drawn_indices += 6; + stats->drawn_vertices += 4; + } +} + +static void manual_clear(gswf_recti *r, GDrawStats *stats) +{ + ID3D1XContext *d3d = gdraw->d3d_context; + + // go to known render state + d3d->OMSetBlendState(gdraw->blend_state[GDRAW_BLEND_none], four_zeros, ~0u); + d3d->OMSetDepthStencilState(gdraw->depth_state[0][0], 0); + gdraw->blend_mode = GDRAW_BLEND_none; + + set_viewport_raw(0, 0, gdraw->frametex_width, gdraw->frametex_height); + set_projection_raw(0, gdraw->frametex_width, gdraw->frametex_height, 0); + set_pixel_shader(d3d, gdraw->clear_ps.pshader); + + if (PixelCommonVars *pvars = (PixelCommonVars *) map_buffer(gdraw->d3d_context, gdraw->cb_ps_common, true)) { + memset(pvars, 0, sizeof(*pvars)); + unmap_buffer(gdraw->d3d_context, gdraw->cb_ps_common); + d3d->PSSetConstantBuffers(0, 1, &gdraw->cb_ps_common); + + do_screen_quad(r, four_zeros, stats); + } +} + +static void gdraw_DriverBlurPass(GDrawRenderState *r, int taps, float *data, gswf_recti *s, float *tc, float /*height_max*/, float *clamp, GDrawStats *gstats) +{ + set_texture(0, r->tex[0], false, GDRAW_WRAP_clamp); + + set_pixel_shader(gdraw->d3d_context, gdraw->blur_prog[taps].pshader); + PixelParaBlur *para = (PixelParaBlur *) start_ps_constants(gdraw->cb_blur); + memcpy(para->clamp, clamp, 4 * sizeof(float)); + memcpy(para->tap, data, taps * 4 * sizeof(float)); + end_ps_constants(gdraw->cb_blur); + + do_screen_quad(s, tc, gstats); + tag_resources(r->tex[0]); +} + +static void gdraw_Colormatrix(GDrawRenderState *r, gswf_recti *s, float *tc, GDrawStats *stats) +{ + if (!gdraw_TextureDrawBufferBegin(s, GDRAW_TEXTURE_FORMAT_rgba32, GDRAW_TEXTUREDRAWBUFFER_FLAGS_needs_color | GDRAW_TEXTUREDRAWBUFFER_FLAGS_needs_alpha, 0, stats)) + return; + + set_texture(0, r->tex[0], false, GDRAW_WRAP_clamp); + set_pixel_shader(gdraw->d3d_context, gdraw->colormatrix.pshader); + + PixelParaColorMatrix *para = (PixelParaColorMatrix *) start_ps_constants(gdraw->cb_colormatrix); + memcpy(para->data, r->shader_data, 5 * 4 * sizeof(float)); + end_ps_constants(gdraw->cb_colormatrix); + + do_screen_quad(s, tc, stats); + tag_resources(r->tex[0]); + r->tex[0] = gdraw_TextureDrawBufferEnd(stats); +} + +static gswf_recti *get_valid_rect(GDrawTexture *tex) +{ + GDrawHandle *h = (GDrawHandle *) tex; + S32 n = (S32) (h - gdraw->rendertargets.handle); + assert(n >= 0 && n <= MAX_RENDER_STACK_DEPTH+1); + return &gdraw->rt_valid[n]; +} + +static void set_clamp_constant(F32 *constant, GDrawTexture *tex) +{ + gswf_recti *s = get_valid_rect(tex); + // when we make the valid data, we make sure there is an extra empty pixel at the border + set_pixel_constant(constant, + (s->x0-0.5f) / gdraw->frametex_width, + (s->y0-0.5f) / gdraw->frametex_height, + (s->x1+0.5f) / gdraw->frametex_width, + (s->y1+0.5f) / gdraw->frametex_height); +} + +static void gdraw_Filter(GDrawRenderState *r, gswf_recti *s, float *tc, int isbevel, GDrawStats *stats) +{ + if (!gdraw_TextureDrawBufferBegin(s, GDRAW_TEXTURE_FORMAT_rgba32, GDRAW_TEXTUREDRAWBUFFER_FLAGS_needs_color | GDRAW_TEXTUREDRAWBUFFER_FLAGS_needs_alpha, NULL, stats)) + return; + + set_texture(0, r->tex[0], false, GDRAW_WRAP_clamp); + set_texture(1, r->tex[1], false, GDRAW_WRAP_clamp); + set_texture(2, r->tex[2], false, GDRAW_WRAP_clamp); + set_pixel_shader(gdraw->d3d_context, gdraw->filter_prog[isbevel][r->filter_mode].pshader); + + PixelParaFilter *para = (PixelParaFilter *) start_ps_constants(gdraw->cb_filter); + set_clamp_constant(para->clamp0, r->tex[0]); + set_clamp_constant(para->clamp1, r->tex[1]); + set_pixel_constant(para->color, r->shader_data[0], r->shader_data[1], r->shader_data[2], r->shader_data[3]); + set_pixel_constant(para->color2, r->shader_data[8], r->shader_data[9], r->shader_data[10], r->shader_data[11]); + set_pixel_constant(para->tc_off, -r->shader_data[4] / (F32)gdraw->frametex_width, -r->shader_data[5] / (F32)gdraw->frametex_height, r->shader_data[6], 0); + end_ps_constants(gdraw->cb_filter); + + do_screen_quad(s, tc, stats); + tag_resources(r->tex[0], r->tex[1], r->tex[2]); + r->tex[0] = gdraw_TextureDrawBufferEnd(stats); +} + +static void RADLINK gdraw_FilterQuad(GDrawRenderState *r, S32 x0, S32 y0, S32 x1, S32 y1, GDrawStats *stats) +{ + ID3D1XContext *d3d = gdraw->d3d_context; + F32 tc[4]; + gswf_recti s; + + // clip to tile boundaries + s.x0 = RR_MAX(x0, gdraw->tx0p); + s.y0 = RR_MAX(y0, gdraw->ty0p); + s.x1 = RR_MIN(x1, gdraw->tx0p + gdraw->tpw); + s.y1 = RR_MIN(y1, gdraw->ty0p + gdraw->tph); + if (s.x1 < s.x0 || s.y1 < s.y0) + return; + + tc[0] = (s.x0 - gdraw->tx0p) / (F32) gdraw->frametex_width; + tc[1] = (s.y0 - gdraw->ty0p) / (F32) gdraw->frametex_height; + tc[2] = (s.x1 - gdraw->tx0p) / (F32) gdraw->frametex_width; + tc[3] = (s.y1 - gdraw->ty0p) / (F32) gdraw->frametex_height; + + // clear to known render state + d3d->OMSetBlendState(gdraw->blend_state[GDRAW_BLEND_none], four_zeros, ~0u); + d3d->OMSetDepthStencilState(gdraw->depth_state[0][0], 0); + disable_scissor(0); + gdraw->blend_mode = GDRAW_BLEND_none; + + if (r->blend_mode == GDRAW_BLEND_filter) { + switch (r->filter) { + case GDRAW_FILTER_blur: { + GDrawBlurInfo b; + gswf_recti bounds = *get_valid_rect(r->tex[0]); + gdraw_ShiftRect(&s, &s, -gdraw->tx0p, -gdraw->ty0p); // blur uses physical rendertarget coordinates + + b.BlurPass = gdraw_DriverBlurPass; + b.w = gdraw->tpw; + b.h = gdraw->tph; + b.frametex_width = gdraw->frametex_width; + b.frametex_height = gdraw->frametex_height; + + // blur needs to draw with multiple passes, so set up special state + gdraw->in_blur = true; + + // do the blur + gdraw_Blur(&gdraw_funcs, &b, r, &s, &bounds, stats); + + // restore the normal state + gdraw->in_blur = false; + set_viewport(); + set_projection(); + break; + } + + case GDRAW_FILTER_colormatrix: + gdraw_Colormatrix(r, &s, tc, stats); + break; + + case GDRAW_FILTER_dropshadow: + gdraw_Filter(r, &s, tc, 0, stats); + break; + + case GDRAW_FILTER_bevel: + gdraw_Filter(r, &s, tc, 1, stats); + break; + + default: + assert(0); + } + } else { + GDrawHandle *blend_tex = NULL; + + // for crazy blend modes, we need to read back from the framebuffer + // and do the blending in the pixel shader. we do this with copies + // rather than trying to render-to-texture-all-along, because we want + // to be able to render over the user's existing framebuffer, which might + // not be a texture. note that this isn't optimal when MSAA is on! + F32 rescale1[4] = { 1.0f, 1.0f, 0.0f, 0.0f }; + if (r->blend_mode == GDRAW_BLEND_special) { + ID3D1XContext *d3d = gdraw->d3d_context; + ID3D1X(Resource) *cur_rt_rsrc; + get_active_render_target()->GetResource(&cur_rt_rsrc); + + if (gdraw->cur == gdraw->frame && gdraw->main_msaa) { + // source surface is main framebuffer and it uses MSAA. just resolve it first. + D3D1X_(SHADER_RESOURCE_VIEW_DESC) desc; + D3D1X_(TEXTURE2D_DESC) texdesc; + ID3D1X(Texture2D) *resolve_tex; + + gdraw->main_resolve_target->GetDesc(&desc); + gdraw->main_resolve_target->GetResource((ID3D1X(Resource) **) &resolve_tex); + resolve_tex->GetDesc(&texdesc); + d3d->ResolveSubresource(resolve_tex, 0, cur_rt_rsrc, 0, desc.Format); + resolve_tex->Release(); + + stats->nonzero_flags |= GDRAW_STATS_blits; + stats->num_blits += 1; + stats->num_blit_pixels += texdesc.Width * texdesc.Height; + + d3d->PSSetShaderResources(1, 1, &gdraw->main_resolve_target); + d3d->PSSetSamplers(1, 1, &gdraw->sampler_state[0][GDRAW_WRAP_clamp]); + + // calculate texture coordinate remapping + rescale1[0] = gdraw->frametex_width / (F32) texdesc.Width; + rescale1[1] = gdraw->frametex_height / (F32) texdesc.Height; + rescale1[2] = (gdraw->vx - gdraw->tx0 + gdraw->tx0p) / (F32) texdesc.Width; + rescale1[3] = (gdraw->vy - gdraw->ty0 + gdraw->ty0p) / (F32) texdesc.Height; + } else { + D3D1X_(BOX) box = { 0,0,0,0,0,1 }; + S32 dx = 0, dy = 0; + blend_tex = get_color_rendertarget(stats); + + if (gdraw->cur != gdraw->frame) + box.right=gdraw->tpw, box.bottom=gdraw->tph; + else { + box.left=gdraw->vx, box.top=gdraw->vy, box.right=gdraw->vx+gdraw->tw, box.bottom=gdraw->vy+gdraw->th; + dx = gdraw->tx0 - gdraw->tx0p; + dy = gdraw->ty0 - gdraw->ty0p; + } + + d3d->CopySubresourceRegion(blend_tex->handle.tex.d3d, 0, dx, dy, 0, + cur_rt_rsrc, 0, &box); + + stats->nonzero_flags |= GDRAW_STATS_blits; + stats->num_blits += 1; + stats->num_blit_pixels += (box.right - box.left) * (box.bottom - box.top); + + set_texture(1, (GDrawTexture *) blend_tex, false, GDRAW_WRAP_clamp); + } + + cur_rt_rsrc->Release(); + } + + if (!set_renderstate_full(GDRAW_vformat_v2tc2, r, stats, rescale1)) + return; + + do_screen_quad(&s, tc, stats); + tag_resources(r->tex[0], r->tex[1]); + if (blend_tex) + gdraw_FreeTexture((GDrawTexture *) blend_tex, 0, stats); + } +} + +/////////////////////////////////////////////////////////////////////// +// +// Shaders and state +// + +#include GDRAW_SHADER_FILE + +static void destroy_shader(ProgramWithCachedVariableLocations *p) +{ + if (p->pshader) { + p->pshader->Release(); + p->pshader = NULL; + } +} + +static ID3D1X(Buffer) *create_dynamic_buffer(U32 size, U32 bind) +{ + D3D1X_(BUFFER_DESC) desc = { size, D3D1X_(USAGE_DYNAMIC), bind, D3D1X_(CPU_ACCESS_WRITE), 0 }; + ID3D1X(Buffer) *buf = NULL; + HRESULT hr = gdraw->d3d_device->CreateBuffer(&desc, NULL, &buf); + if (FAILED(hr)) { + report_d3d_error(hr, "CreateBuffer", " creating dynamic vertex buffer"); + buf = NULL; + } + return buf; +} + +static void init_dyn_buffer(DynBuffer *buf, U32 size, U32 bind) +{ + buf->buffer = create_dynamic_buffer(size, bind); + buf->size = size; + buf->write_pos = 0; + buf->alloc_pos = 0; +} + +// These two functions are implemented by the D3D10- respectively D3D11-specific part. +static void create_pixel_shader(ProgramWithCachedVariableLocations *p, ProgramWithCachedVariableLocations *src); +static void create_vertex_shader(ProgramWithCachedVariableLocations *p, ProgramWithCachedVariableLocations *src); + +static void create_all_shaders_and_state(void) +{ + ID3D1X(Device) *d3d = gdraw->d3d_device; + HRESULT hr; + S32 i, j; + + for (i=0; i < GDRAW_TEXTURE__count*3; ++i) create_pixel_shader(&gdraw->fprog[0][i], pshader_basic_arr + i); + for (i=0; i < GDRAW_BLENDSPECIAL__count; ++i) create_pixel_shader(&gdraw->exceptional_blend[i], pshader_exceptional_blend_arr + i); + for (i=0; i < 32; ++i) create_pixel_shader(&gdraw->filter_prog[0][i], pshader_filter_arr + i); + for (i=0; i < MAX_TAPS+1; ++i) create_pixel_shader(&gdraw->blur_prog[i], pshader_blur_arr + i); + create_pixel_shader(&gdraw->colormatrix, pshader_color_matrix_arr); + create_pixel_shader(&gdraw->clear_ps, pshader_manual_clear_arr); + + for (i=0; i < GDRAW_vformat__basic_count; i++) { + ProgramWithCachedVariableLocations *vsh = vshader_vsd3d10_arr + i; + + create_vertex_shader(&gdraw->vert[i], vsh); + HRESULT hr = d3d->CreateInputLayout(vformats[i].desc, vformats[i].nelem, vsh->bytecode, vsh->size, &gdraw->inlayout[i]); + if (FAILED(hr)) { + report_d3d_error(hr, "CreateInputLayout", ""); + gdraw->inlayout[i] = NULL; + } + } + + // create rasterizer state setups + for (i=0; i < 2; ++i) { + D3D1X_(RASTERIZER_DESC) raster_desc = { D3D1X_(FILL_SOLID), D3D1X_(CULL_NONE), FALSE, 0, 0.0f, 0.0f, TRUE, TRUE, FALSE, FALSE }; + raster_desc.MultisampleEnable = i; + hr = d3d->CreateRasterizerState(&raster_desc, &gdraw->raster_state[i]); + if (FAILED(hr)) { + report_d3d_error(hr, "CreateRasterizerState", ""); + return; + } + } + + // create sampler state setups + static const D3D1X_(TEXTURE_ADDRESS_MODE) addrmode[ASSERT_COUNT(GDRAW_WRAP__count, 4)] = { + D3D1X_(TEXTURE_ADDRESS_CLAMP), // GDRAW_WRAP_clamp + D3D1X_(TEXTURE_ADDRESS_WRAP), // GDRAW_WRAP_repeat + D3D1X_(TEXTURE_ADDRESS_MIRROR), // GDRAW_WRAP_mirror + D3D1X_(TEXTURE_ADDRESS_CLAMP), // GDRAW_WRAP_clamp_to_border (unused for this renderer) + }; + + for (i=0; i < 2; ++i) { + for (j=0; j < GDRAW_WRAP__count; ++j) { + D3D1X_(SAMPLER_DESC) sampler_desc; + memset(&sampler_desc, 0, sizeof(sampler_desc)); + sampler_desc.Filter = i ? D3D1X_(FILTER_MIN_LINEAR_MAG_MIP_POINT) : D3D1X_(FILTER_MIN_MAG_MIP_LINEAR); + sampler_desc.AddressU = addrmode[j]; + sampler_desc.AddressV = addrmode[j]; + sampler_desc.AddressW = D3D1X_(TEXTURE_ADDRESS_CLAMP); + sampler_desc.MaxAnisotropy = 1; + sampler_desc.MaxLOD = D3D1X_(FLOAT32_MAX); + hr = d3d->CreateSamplerState(&sampler_desc, &gdraw->sampler_state[i][j]); + if (FAILED(hr)) { + report_d3d_error(hr, "CreateSamplerState", ""); + return; + } + } + } + + // create blend stage setups + static struct blendspec { + BOOL blend; + D3D1X_(BLEND) src; + D3D1X_(BLEND) dst; + } blends[ASSERT_COUNT(GDRAW_BLEND__count, 6)] = { + FALSE, D3D1X_(BLEND_ONE), D3D1X_(BLEND_ZERO), // GDRAW_BLEND_none + TRUE, D3D1X_(BLEND_ONE), D3D1X_(BLEND_INV_SRC_ALPHA), // GDRAW_BLEND_alpha + TRUE, D3D1X_(BLEND_DEST_COLOR), D3D1X_(BLEND_INV_SRC_ALPHA), // GDRAW_BLEND_multiply + TRUE, D3D1X_(BLEND_ONE), D3D1X_(BLEND_ONE), // GDRAW_BLEND_add + + FALSE, D3D1X_(BLEND_ONE), D3D1X_(BLEND_ZERO), // GDRAW_BLEND_filter + FALSE, D3D1X_(BLEND_ONE), D3D1X_(BLEND_ZERO), // GDRAW_BLEND_special + }; + + for (i=0; i < GDRAW_BLEND__count; ++i) { + gdraw->blend_state[i] = create_blend_state(d3d, blends[i].blend, blends[i].src, blends[i].dst); + if (!gdraw->blend_state[i]) + return; + } + + D3D1X_(BLEND_DESC) blend_desc; + memset(&blend_desc, 0, sizeof(blend_desc)); + hr = d3d->CreateBlendState(&blend_desc, &gdraw->blend_no_color_write); + if (FAILED(hr)) { + report_d3d_error(hr, "CreateBlendState", ""); + return; + } + + // create depth/stencil setups + for (i=0; i < 2; ++i) { + for (j=0; j < 2; ++j) { + D3D1X_(DEPTH_STENCIL_DESC) depth_desc; + memset(&depth_desc, 0, sizeof(depth_desc)); + + depth_desc.DepthEnable = (i || j); + depth_desc.DepthWriteMask = i ? D3D1X_(DEPTH_WRITE_MASK_ALL) : D3D1X_(DEPTH_WRITE_MASK_ZERO); + depth_desc.DepthFunc = j ? D3D1X_(COMPARISON_LESS) : D3D1X_(COMPARISON_ALWAYS); + depth_desc.StencilEnable = FALSE; + + hr = d3d->CreateDepthStencilState(&depth_desc, &gdraw->depth_state[i][j]); + if (FAILED(hr)) { + report_d3d_error(hr, "CreateDepthStencilState", ""); + return; + } + } + } + + // constant buffers + gdraw->cb_vertex = create_dynamic_buffer(sizeof(VertexVars), D3D1X_(BIND_CONSTANT_BUFFER)); + gdraw->cb_ps_common = create_dynamic_buffer(sizeof(PixelCommonVars), D3D1X_(BIND_CONSTANT_BUFFER)); + gdraw->cb_filter = create_dynamic_buffer(sizeof(PixelParaFilter), D3D1X_(BIND_CONSTANT_BUFFER)); + gdraw->cb_colormatrix = create_dynamic_buffer(sizeof(PixelParaColorMatrix), D3D1X_(BIND_CONSTANT_BUFFER)); + gdraw->cb_blur = create_dynamic_buffer(sizeof(PixelParaBlur), D3D1X_(BIND_CONSTANT_BUFFER)); + + // quad index buffer + assert(QUAD_IB_COUNT * 4 < 65535); // can't use more; we have 16-bit index buffers and 0xffff = primitive cut index + U16 *inds = (U16 *) IggyGDrawMalloc(QUAD_IB_COUNT * 6 * sizeof(U16)); + if (inds) { + D3D1X_(BUFFER_DESC) bufdesc = { }; + D3D1X_(SUBRESOURCE_DATA) data = { inds, 0, 0 }; + + bufdesc.ByteWidth = QUAD_IB_COUNT * 6 * sizeof(U16); + bufdesc.Usage = D3D1X_(USAGE_IMMUTABLE); + bufdesc.BindFlags = D3D1X_(BIND_INDEX_BUFFER); + + for (U16 i=0; i < QUAD_IB_COUNT; i++) { + inds[i*6 + 0] = i*4 + 0; + inds[i*6 + 1] = i*4 + 1; + inds[i*6 + 2] = i*4 + 2; + inds[i*6 + 3] = i*4 + 0; + inds[i*6 + 4] = i*4 + 2; + inds[i*6 + 5] = i*4 + 3; + } + + hr = gdraw->d3d_device->CreateBuffer(&bufdesc, &data, &gdraw->quad_ib); + if (FAILED(hr)) { + report_d3d_error(hr, "CreateBuffer", " for constants"); + gdraw->quad_ib = NULL; + } + IggyGDrawFree(inds); + } else + gdraw->quad_ib = NULL; +} + +static void destroy_all_shaders_and_state() +{ + S32 i; + + for (i=0; i < GDRAW_TEXTURE__count*3; ++i) destroy_shader(&gdraw->fprog[0][i]); + for (i=0; i < GDRAW_BLENDSPECIAL__count; ++i) destroy_shader(&gdraw->exceptional_blend[i]); + for (i=0; i < 32; ++i) destroy_shader(&gdraw->filter_prog[0][i]); + for (i=0; i < MAX_TAPS+1; ++i) destroy_shader(&gdraw->blur_prog[i]); + destroy_shader(&gdraw->colormatrix); + destroy_shader(&gdraw->clear_ps); + + for (i=0; i < GDRAW_vformat__basic_count; i++) { + safe_release(gdraw->inlayout[i]); + destroy_shader(&gdraw->vert[i]); + } + + for (i=0; i < 2; ++i) safe_release(gdraw->raster_state[i]); + for (i=0; i < GDRAW_WRAP__count*2; ++i) safe_release(gdraw->sampler_state[0][i]); + for (i=0; i < GDRAW_BLEND__count; ++i) safe_release(gdraw->blend_state[i]); + for (i=0; i < 2*2; ++i) safe_release(gdraw->depth_state[0][i]); + + safe_release(gdraw->blend_no_color_write); + + safe_release(gdraw->cb_vertex); + safe_release(gdraw->cb_ps_common); + safe_release(gdraw->cb_filter); + safe_release(gdraw->cb_colormatrix); + safe_release(gdraw->cb_blur); + + safe_release(gdraw->quad_ib); +} + +//////////////////////////////////////////////////////////////////////// +// +// Create and tear-down the state +// + +typedef struct +{ + S32 num_handles; + S32 num_bytes; +} GDrawResourceLimit; + +// These are the defaults limits used by GDraw unless the user specifies something else. +static GDrawResourceLimit gdraw_limits[GDRAW_D3D1X_(RESOURCE__count)] = { + MAX_RENDER_STACK_DEPTH + 1, 16*1024*1024, // RESOURCE_rendertarget + 500, 16*1024*1024, // RESOURCE_texture + 1000, 2*1024*1024, // RESOURCE_vertexbuffer + 0, 256*1024, // RESOURCE_dynbuffer +}; + +static GDrawHandleCache *make_handle_cache(gdraw_resourcetype type) +{ + S32 num_handles = gdraw_limits[type].num_handles; + S32 num_bytes = gdraw_limits[type].num_bytes; + GDrawHandleCache *cache = (GDrawHandleCache *) IggyGDrawMalloc(sizeof(GDrawHandleCache) + (num_handles - 1) * sizeof(GDrawHandle)); + if (cache) { + gdraw_HandleCacheInit(cache, num_handles, num_bytes); + cache->is_vertex = (type == GDRAW_D3D1X_(RESOURCE_vertexbuffer)); + } + + return cache; +} + +static void free_gdraw() +{ + if (!gdraw) return; + if (gdraw->texturecache) IggyGDrawFree(gdraw->texturecache); + if (gdraw->vbufcache) IggyGDrawFree(gdraw->vbufcache); + IggyGDrawFree(gdraw); + gdraw = NULL; +} + +static bool alloc_dynbuffer(U32 size) +{ + // specified input size is vertex buffer size. determine sensible size for the + // corresponding index buffer. iggy always uses 16-bit indices and has three + // primary types of geometry it sends: + // + // 1. filled polygons. these are triangulated simple polygons and thus have + // roughly as many triangles as they have vertices. they use either 8- or + // 16-byte vertex formats; this makes a worst case of 6 bytes of indices + // for every 8 bytes of vertex data. + // 2. strokes and edge antialiasing. they use a 16-byte vertex format and + // worst-case write a "double quadstrip" which has 4 triangles for every + // 3 vertices, which means 24 bytes of index data for every 48 bytes + // of vertex data. + // 3. textured quads. they use a 16-byte vertex format, have exactly 2 + // triangles for every 4 vertices, and use either a static index buffer + // (quad_ib) or a single triangle strip, so for our purposes they need no + // space to store indices at all. + // + // 1) argues for allocating index buffers at 3/4 the size of the corresponding + // vertex buffer, while 2) and 3) need 1/2 the size of the vertex buffer or less. + // 2) and 3) are the most common types of vertex data, while 1) is used only for + // morphed shapes and in certain cases when the RESOURCE_vertexbuffer pool is full. + // we just play it safe anyway and make sure we size the IB large enough to cover + // the worst case for 1). this is conservative, but it probably doesn't matter much. + U32 ibsize = (size * 3) / 4; + + init_dyn_buffer(&gdraw->dyn_vb, size, D3D1X_(BIND_VERTEX_BUFFER)); + init_dyn_buffer(&gdraw->dyn_ib, ibsize, D3D1X_(BIND_INDEX_BUFFER)); + + gdraw->max_quad_vert_count = RR_MIN(size / sizeof(gswf_vertex_xyst), QUAD_IB_COUNT * 4); + gdraw->max_quad_vert_count &= ~3; // must be multiple of four + + return gdraw->dyn_vb.buffer != NULL && gdraw->dyn_ib.buffer != NULL; +} + +int gdraw_D3D1X_(SetResourceLimits)(gdraw_resourcetype type, S32 num_handles, S32 num_bytes) +{ + GDrawStats stats={0}; + + if (type == GDRAW_D3D1X_(RESOURCE_rendertarget)) // RT count is small and space is preallocated + num_handles = MAX_RENDER_STACK_DEPTH + 1; + + assert(type >= GDRAW_D3D1X_(RESOURCE_rendertarget) && type < GDRAW_D3D1X_(RESOURCE__count)); + assert(num_handles >= 0); + assert(num_bytes >= 0); + + // nothing to do if the values are unchanged + if (gdraw_limits[type].num_handles == num_handles && + gdraw_limits[type].num_bytes == num_bytes) + return 1; + + gdraw_limits[type].num_handles = num_handles; + gdraw_limits[type].num_bytes = num_bytes; + + // if no gdraw context created, there's nothing to worry about + if (!gdraw) + return 1; + + // resize the appropriate pool + switch (type) { + case GDRAW_D3D1X_(RESOURCE_rendertarget): + flush_rendertargets(&stats); + gdraw_HandleCacheInit(&gdraw->rendertargets, num_handles, num_bytes); + return 1; + + case GDRAW_D3D1X_(RESOURCE_texture): + if (gdraw->texturecache) { + gdraw_res_flush(gdraw->texturecache, &stats); + IggyGDrawFree(gdraw->texturecache); + } + gdraw->texturecache = make_handle_cache(GDRAW_D3D1X_(RESOURCE_texture)); + return gdraw->texturecache != NULL; + + case GDRAW_D3D1X_(RESOURCE_vertexbuffer): + if (gdraw->vbufcache) { + gdraw_res_flush(gdraw->vbufcache, &stats); + IggyGDrawFree(gdraw->vbufcache); + } + gdraw->vbufcache = make_handle_cache(GDRAW_D3D1X_(RESOURCE_vertexbuffer)); + return gdraw->vbufcache != NULL; + + case GDRAW_D3D1X_(RESOURCE_dynbuffer): + unbind_resources(); + safe_release(gdraw->dyn_vb.buffer); + safe_release(gdraw->dyn_ib.buffer); + return alloc_dynbuffer(num_bytes); + + default: + return 0; + } +} + +static GDrawFunctions *create_context(ID3D1XDevice *dev, ID3D1XContext *ctx, S32 w, S32 h) +{ + gdraw = (GDraw *) IggyGDrawMalloc(sizeof(*gdraw)); + if (!gdraw) return NULL; + + memset(gdraw, 0, sizeof(*gdraw)); + + gdraw->frametex_width = w; + gdraw->frametex_height = h; + gdraw->d3d_device = dev; + gdraw->d3d_context = ctx; + + gdraw->texturecache = make_handle_cache(GDRAW_D3D1X_(RESOURCE_texture)); + gdraw->vbufcache = make_handle_cache(GDRAW_D3D1X_(RESOURCE_vertexbuffer)); + gdraw_HandleCacheInit(&gdraw->rendertargets, gdraw_limits[GDRAW_D3D1X_(RESOURCE_rendertarget)].num_handles, gdraw_limits[GDRAW_D3D1X_(RESOURCE_rendertarget)].num_bytes); + + if (!gdraw->texturecache || !gdraw->vbufcache || !alloc_dynbuffer(gdraw_limits[GDRAW_D3D1X_(RESOURCE_dynbuffer)].num_bytes)) { + free_gdraw(); + return NULL; + } + + create_all_shaders_and_state(); + + gdraw_funcs.SetViewSizeAndWorldScale = gdraw_SetViewSizeAndWorldScale; + gdraw_funcs.GetInfo = gdraw_GetInfo; + + gdraw_funcs.DescribeTexture = gdraw_DescribeTexture; + gdraw_funcs.DescribeVertexBuffer = gdraw_DescribeVertexBuffer; + + gdraw_funcs.RenderingBegin = gdraw_RenderingBegin; + gdraw_funcs.RenderingEnd = gdraw_RenderingEnd; + gdraw_funcs.RenderTileBegin = gdraw_RenderTileBegin; + gdraw_funcs.RenderTileEnd = gdraw_RenderTileEnd; + + gdraw_funcs.TextureDrawBufferBegin = gdraw_TextureDrawBufferBegin; + gdraw_funcs.TextureDrawBufferEnd = gdraw_TextureDrawBufferEnd; + + gdraw_funcs.DrawIndexedTriangles = gdraw_DrawIndexedTriangles; + gdraw_funcs.FilterQuad = gdraw_FilterQuad; + + gdraw_funcs.SetAntialiasTexture = gdraw_SetAntialiasTexture; + + gdraw_funcs.ClearStencilBits = gdraw_ClearStencilBits; + gdraw_funcs.ClearID = gdraw_ClearID; + + gdraw_funcs.MakeTextureBegin = gdraw_MakeTextureBegin; + gdraw_funcs.MakeTextureMore = gdraw_MakeTextureMore; + gdraw_funcs.MakeTextureEnd = gdraw_MakeTextureEnd; + + gdraw_funcs.UpdateTextureBegin = gdraw_UpdateTextureBegin; + gdraw_funcs.UpdateTextureRect = gdraw_UpdateTextureRect; + gdraw_funcs.UpdateTextureEnd = gdraw_UpdateTextureEnd; + + gdraw_funcs.FreeTexture = gdraw_FreeTexture; + gdraw_funcs.TryToLockTexture = gdraw_TryToLockTexture; + + gdraw_funcs.MakeTextureFromResource = (gdraw_make_texture_from_resource *) gdraw_D3D1X_(MakeTextureFromResource); + gdraw_funcs.FreeTextureFromResource = gdraw_D3D1X_(DestroyTextureFromResource); + + gdraw_funcs.MakeVertexBufferBegin = gdraw_MakeVertexBufferBegin; + gdraw_funcs.MakeVertexBufferMore = gdraw_MakeVertexBufferMore; + gdraw_funcs.MakeVertexBufferEnd = gdraw_MakeVertexBufferEnd; + gdraw_funcs.TryToLockVertexBuffer = gdraw_TryLockVertexBuffer; + gdraw_funcs.FreeVertexBuffer = gdraw_FreeVertexBuffer; + + gdraw_funcs.UnlockHandles = gdraw_UnlockHandles; + gdraw_funcs.SetTextureUniqueID = gdraw_SetTextureUniqueID; + + gdraw_funcs.Set3DTransform = gdraw_Set3DTransform; + + return &gdraw_funcs; +} + +void gdraw_D3D1X_(DestroyContext)(void) +{ + if (gdraw && gdraw->d3d_device) { + GDrawStats stats={0}; + clear_renderstate(); + stencil_state_cache_clear(); + destroy_all_shaders_and_state(); + safe_release(gdraw->aa_tex); + safe_release(gdraw->aa_tex_view); + safe_release(gdraw->dyn_vb.buffer); + safe_release(gdraw->dyn_ib.buffer); + + flush_rendertargets(&stats); + if (gdraw->texturecache) gdraw_res_flush(gdraw->texturecache, &stats); + if (gdraw->vbufcache) gdraw_res_flush(gdraw->vbufcache, &stats); + + gdraw->d3d_device = NULL; + } + + free_gdraw(); +} + +void gdraw_D3D1X_(SetErrorHandler)(void (__cdecl *error_handler)(HRESULT hr)) +{ + if (gdraw) + gdraw->error_handler = error_handler; +} + +void gdraw_D3D1X_(PreReset)(void) +{ + if (!gdraw) return; + + GDrawStats stats={0}; + flush_rendertargets(&stats); + + // we may end up resizing the frame buffer + gdraw->frametex_width = 0; + gdraw->frametex_height = 0; +} + +void gdraw_D3D1X_(PostReset)(void) +{ + // maybe re-create rendertargets right now? +} + +void RADLINK gdraw_D3D1X_(BeginCustomDraw)(IggyCustomDrawCallbackRegion * region, F32 mat[4][4]) +{ + clear_renderstate(); + gdraw_GetObjectSpaceMatrix(mat[0], region->o2w, gdraw->projection, 0, 0); +} + +void RADLINK gdraw_D3D1X_(BeginCustomDraw_4J)(IggyCustomDrawCallbackRegion * region, F32 mat[16]) +{ + clear_renderstate(); + gdraw_GetObjectSpaceMatrix(mat, region->o2w, gdraw->projection, 0, 0); +} + +void RADLINK gdraw_D3D1X_(CalculateCustomDraw_4J)(IggyCustomDrawCallbackRegion * region, F32 mat[16]) +{ + gdraw_GetObjectSpaceMatrix(mat, region->o2w, gdraw->projection, 0, 0); +} + +void RADLINK gdraw_D3D1X_(EndCustomDraw)(IggyCustomDrawCallbackRegion * /*region*/) +{ + GDrawStats stats={}; + set_common_renderstate(); + set_viewport(); + set_render_target(&stats); +} + +void RADLINK gdraw_D3D1X_(GetResourceUsageStats)(gdraw_resourcetype type, S32 *handles_used, S32 *bytes_used) +{ + GDrawHandleCache *cache; + + switch (type) { + case GDRAW_D3D1X_(RESOURCE_rendertarget): cache = &gdraw->rendertargets; break; + case GDRAW_D3D1X_(RESOURCE_texture): cache = gdraw->texturecache; break; + case GDRAW_D3D1X_(RESOURCE_vertexbuffer): cache = gdraw->vbufcache; break; + case GDRAW_D3D1X_(RESOURCE_dynbuffer): *handles_used = 0; *bytes_used = gdraw->last_dyn_maxalloc; return; + default: cache = NULL; break; + } + + *handles_used = *bytes_used = 0; + + if (cache) { + S32 i; + U64 frame = gdraw->frame_counter; + + for (i=0; i < cache->max_handles; ++i) + if (cache->handle[i].bytes && cache->handle[i].owner && cache->handle[i].fence.value == frame) { + *handles_used += 1; + *bytes_used += cache->handle[i].bytes; + } + } +} + +static S32 num_pixels(S32 w, S32 h, S32 mipmaps) +{ + S32 k, pixels=0; + for (k=0; k < mipmaps; ++k) { + pixels += w*h*2; + w = (w>>1); w += !w; + h = (h>>1); h += !h; + } + return pixels; +} + +GDrawTexture * RADLINK gdraw_D3D1X_(MakeTextureFromResource)(U8 *resource_file, S32 /*len*/, IggyFileTextureRaw *texture) +{ + char *failed_call=""; + U8 *free_data = 0; + GDrawTexture *t=0; + S32 width, height, mipmaps, size, blk; + ID3D1X(Texture2D) *tex=0; + ID3D1X(ShaderResourceView) *view=0; + + DXGI_FORMAT d3dfmt; + D3D1X_(SUBRESOURCE_DATA) mipdata[24] = { 0 }; + S32 k; + + HRESULT hr = S_OK; + + width = texture->w; + height = texture->h; + mipmaps = texture->mipmaps; + blk = 1; + + D3D1X_(TEXTURE2D_DESC) desc = { width, height, mipmaps, 1, DXGI_FORMAT_UNKNOWN, { 1, 0 }, + D3D1X_(USAGE_IMMUTABLE), D3D1X_(BIND_SHADER_RESOURCE), 0, 0 }; + + switch (texture->format) { + case IFT_FORMAT_rgba_8888 : size= 4; d3dfmt = DXGI_FORMAT_R8G8B8A8_UNORM; break; + case IFT_FORMAT_DXT1 : size= 8; d3dfmt = DXGI_FORMAT_BC1_UNORM; blk = 4; break; + case IFT_FORMAT_DXT3 : size=16; d3dfmt = DXGI_FORMAT_BC2_UNORM; blk = 4; break; + case IFT_FORMAT_DXT5 : size=16; d3dfmt = DXGI_FORMAT_BC3_UNORM; blk = 4; break; + default: { + IggyGDrawSendWarning(NULL, "GDraw .iggytex raw texture format %d not supported by hardware", texture->format); + goto done; + } + } + + desc.Format = d3dfmt; + + U8 *data = resource_file + texture->file_offset; + + if (texture->format == IFT_FORMAT_i_8 || texture->format == IFT_FORMAT_i_4) { + // convert from intensity to luma+alpha + S32 i; + S32 total_size = 2 * num_pixels(width,height,mipmaps); + + free_data = (U8 *) IggyGDrawMalloc(total_size); + if (!free_data) { + IggyGDrawSendWarning(NULL, "GDraw out of memory to store texture data to pass to D3D for %d x %d texture", width, height); + goto done; + } + + U8 *cur = free_data; + + for (k=0; k < mipmaps; ++k) { + S32 w = RR_MAX(width >> k, 1); + S32 h = RR_MAX(height >> k, 1); + for (i=0; i < w*h; ++i) { + cur[0] = cur[1] = *data++; + cur += 2; + } + } + data = free_data; + } + + for (k=0; k < mipmaps; ++k) { + S32 w = RR_MAX(width >> k, 1); + S32 h = RR_MAX(height >> k, 1); + S32 blkw = (w + blk-1) / blk; + S32 blkh = (h + blk-1) / blk; + + mipdata[k].pSysMem = data; + mipdata[k].SysMemPitch = blkw * size; + data += blkw * blkh * size; + } + + failed_call = "CreateTexture2D"; + hr = gdraw->d3d_device->CreateTexture2D(&desc, mipdata, &tex); + if (FAILED(hr)) goto done; + + failed_call = "CreateShaderResourceView for texture creation"; + hr = gdraw->d3d_device->CreateShaderResourceView(tex, NULL, &view); + if (FAILED(hr)) goto done; + + t = gdraw_D3D1X_(WrappedTextureCreate)(view); + +done: + if (FAILED(hr)) { + report_d3d_error(hr, failed_call, ""); + } + + if (free_data) + IggyGDrawFree(free_data); + + if (!t) { + if (view) + view->Release(); + if (tex) + tex->Release(); + } else { + ((GDrawHandle *) t)->handle.tex.d3d = tex; + } + return t; +} + +void RADLINK gdraw_D3D1X_(DestroyTextureFromResource)(GDrawTexture *tex) +{ + GDrawHandle *h = (GDrawHandle *) tex; + safe_release(h->handle.tex.d3d_view); + safe_release(h->handle.tex.d3d); + gdraw_D3D1X_(WrappedTextureDestroy)(tex); +} + diff --git a/Minecraft.Client/Windows64/Iggy/gdraw/gdraw_d3d9_shaders.inl b/Minecraft.Client/Windows64/Iggy/gdraw/gdraw_d3d9_shaders.inl new file mode 100644 index 00000000..ce13993b --- /dev/null +++ b/Minecraft.Client/Windows64/Iggy/gdraw/gdraw_d3d9_shaders.inl @@ -0,0 +1,1075 @@ +// This file was automatically generated by shadergen. Do not edit by hand! + +static DWORD pshader_basic_0[36] = { + 0xffff0200, 0x0200001f, 0x80000000, 0xb00f0000, 0x0200001f, 0x90000000, 0xa00f0807, 0x02000006, + 0x80080000, 0xb0ff0000, 0x03000005, 0x80010000, 0x80ff0000, 0xb0aa0000, 0x02000001, 0x80020000, + 0xb0ff0000, 0x03000042, 0x800f0000, 0x80e40000, 0xa0e40807, 0x03000005, 0x80070001, 0xa0ff0000, + 0xa0e40000, 0x02000001, 0x80080001, 0xa0ff0000, 0x03000005, 0x800f0000, 0x80e40000, 0x80e40001, + 0x02000001, 0x800f0800, 0x80e40000, 0x0000ffff, +}; + +static DWORD pshader_basic_1[48] = { + 0xffff0200, 0x0200001f, 0x80000000, 0xb00f0000, 0x0200001f, 0x90000000, 0xa00f0807, 0x02000006, + 0x80080000, 0xb0ff0000, 0x03000005, 0x80010000, 0x80ff0000, 0xb0aa0000, 0x02000001, 0x80020000, + 0xb0ff0000, 0x03000042, 0x800f0000, 0x80e40000, 0xa0e40807, 0x03000005, 0x80070001, 0xa0ff0000, + 0xa0e40000, 0x02000001, 0x80080001, 0xa0ff0000, 0x03000005, 0x800f0000, 0x80e40000, 0x80e40001, + 0x04000004, 0x80070000, 0xa0e40001, 0x80ff0000, 0x80e40000, 0x0300000a, 0x80070001, 0x80ff0000, + 0x80e40000, 0x02000001, 0x80080001, 0x80ff0000, 0x02000001, 0x800f0800, 0x80e40001, 0x0000ffff, +}; + +static DWORD pshader_basic_2[41] = { + 0xffff0200, 0x0200001f, 0x80000000, 0xb00f0000, 0x0200001f, 0x90000000, 0xa00f0807, 0x02000006, + 0x80080000, 0xb0ff0000, 0x03000005, 0x80010000, 0x80ff0000, 0xb0aa0000, 0x02000001, 0x80020000, + 0xb0ff0000, 0x03000042, 0x800f0000, 0x80e40000, 0xa0e40807, 0x02000001, 0x800f0001, 0xa0e40000, + 0x04000004, 0x80080000, 0x80ff0001, 0x80ff0000, 0xa0ff0001, 0x03000002, 0x80070001, 0x80e40001, + 0xa0e40001, 0x03000005, 0x80070000, 0x80ff0000, 0x80e40001, 0x02000001, 0x800f0800, 0x80e40000, + 0x0000ffff, +}; + +static DWORD pshader_basic_3[51] = { + 0xffff0200, 0x0200001f, 0x80000000, 0xb00f0000, 0x0200001f, 0x90000000, 0xa00f0800, 0x0200001f, + 0x90000000, 0xa00f0807, 0x02000006, 0x80080000, 0xb0ff0000, 0x03000005, 0x80030000, 0x80ff0000, + 0xb0e40000, 0x03000005, 0x80010001, 0x80ff0000, 0xb0aa0000, 0x02000001, 0x80020001, 0xb0ff0000, + 0x03000042, 0x800f0000, 0x80e40000, 0xa0e40800, 0x03000042, 0x800f0001, 0x80e40001, 0xa0e40807, + 0x03000005, 0x80070002, 0xa0ff0000, 0xa0e40000, 0x02000001, 0x80080002, 0xa0ff0000, 0x03000005, + 0x800f0000, 0x80e40000, 0x80e40002, 0x03000005, 0x800f0000, 0x80e40001, 0x80e40000, 0x02000001, + 0x800f0800, 0x80e40000, 0x0000ffff, +}; + +static DWORD pshader_basic_4[63] = { + 0xffff0200, 0x0200001f, 0x80000000, 0xb00f0000, 0x0200001f, 0x90000000, 0xa00f0800, 0x0200001f, + 0x90000000, 0xa00f0807, 0x02000006, 0x80080000, 0xb0ff0000, 0x03000005, 0x80030000, 0x80ff0000, + 0xb0e40000, 0x03000005, 0x80010001, 0x80ff0000, 0xb0aa0000, 0x02000001, 0x80020001, 0xb0ff0000, + 0x03000042, 0x800f0000, 0x80e40000, 0xa0e40800, 0x03000042, 0x800f0001, 0x80e40001, 0xa0e40807, + 0x03000005, 0x80070002, 0xa0ff0000, 0xa0e40000, 0x02000001, 0x80080002, 0xa0ff0000, 0x03000005, + 0x800f0000, 0x80e40000, 0x80e40002, 0x03000005, 0x800f0000, 0x80e40001, 0x80e40000, 0x04000004, + 0x80070000, 0xa0e40001, 0x80ff0000, 0x80e40000, 0x0300000a, 0x80070001, 0x80ff0000, 0x80e40000, + 0x02000001, 0x80080001, 0x80ff0000, 0x02000001, 0x800f0800, 0x80e40001, 0x0000ffff, +}; + +static DWORD pshader_basic_5[68] = { + 0xffff0200, 0x0200001f, 0x80000000, 0xb00f0000, 0x0200001f, 0x90000000, 0xa00f0800, 0x0200001f, + 0x90000000, 0xa00f0807, 0x02000006, 0x80080000, 0xb0ff0000, 0x03000005, 0x80030000, 0x80ff0000, + 0xb0e40000, 0x03000005, 0x80010001, 0x80ff0000, 0xb0aa0000, 0x02000001, 0x80020001, 0xb0ff0000, + 0x03000042, 0x800f0000, 0x80e40000, 0xa0e40800, 0x03000042, 0x800f0001, 0x80e40001, 0xa0e40807, + 0x02000006, 0x80010001, 0x80ff0000, 0x03000005, 0x80070001, 0x80e40000, 0x80000001, 0x03000005, + 0x80080002, 0x80ff0000, 0x80ff0000, 0x04000058, 0x80070000, 0x81ff0002, 0x80e40000, 0x80e40001, + 0x03000005, 0x800f0000, 0x80e40000, 0xa0e40000, 0x03000005, 0x80080000, 0x80ff0001, 0x80ff0000, + 0x03000002, 0x800f0000, 0x80e40000, 0xa0e40001, 0x03000005, 0x80070000, 0x80ff0000, 0x80e40000, + 0x02000001, 0x800f0800, 0x80e40000, 0x0000ffff, +}; + +static DWORD pshader_basic_6[51] = { + 0xffff0200, 0x0200001f, 0x80000000, 0xb00f0000, 0x0200001f, 0x90000000, 0xa00f0800, 0x0200001f, + 0x90000000, 0xa00f0807, 0x02000006, 0x80080000, 0xb0ff0000, 0x03000005, 0x80030000, 0x80ff0000, + 0xb0e40000, 0x03000005, 0x80010001, 0x80ff0000, 0xb0aa0000, 0x02000001, 0x80020001, 0xb0ff0000, + 0x03000042, 0x800f0000, 0x80e40000, 0xa0e40800, 0x03000042, 0x800f0001, 0x80e40001, 0xa0e40807, + 0x03000005, 0x80070002, 0xa0ff0000, 0xa0e40000, 0x02000001, 0x80080002, 0xa0ff0000, 0x03000005, + 0x800f0000, 0x80ff0000, 0x80e40002, 0x03000005, 0x800f0000, 0x80e40001, 0x80e40000, 0x02000001, + 0x800f0800, 0x80e40000, 0x0000ffff, +}; + +static DWORD pshader_basic_7[63] = { + 0xffff0200, 0x0200001f, 0x80000000, 0xb00f0000, 0x0200001f, 0x90000000, 0xa00f0800, 0x0200001f, + 0x90000000, 0xa00f0807, 0x02000006, 0x80080000, 0xb0ff0000, 0x03000005, 0x80030000, 0x80ff0000, + 0xb0e40000, 0x03000005, 0x80010001, 0x80ff0000, 0xb0aa0000, 0x02000001, 0x80020001, 0xb0ff0000, + 0x03000042, 0x800f0000, 0x80e40000, 0xa0e40800, 0x03000042, 0x800f0001, 0x80e40001, 0xa0e40807, + 0x03000005, 0x80070002, 0xa0ff0000, 0xa0e40000, 0x02000001, 0x80080002, 0xa0ff0000, 0x03000005, + 0x800f0000, 0x80ff0000, 0x80e40002, 0x03000005, 0x800f0000, 0x80e40001, 0x80e40000, 0x04000004, + 0x80070000, 0xa0e40001, 0x80ff0000, 0x80e40000, 0x0300000a, 0x80070001, 0x80ff0000, 0x80e40000, + 0x02000001, 0x80080001, 0x80ff0000, 0x02000001, 0x800f0800, 0x80e40001, 0x0000ffff, +}; + +static DWORD pshader_basic_8[56] = { + 0xffff0200, 0x0200001f, 0x80000000, 0xb00f0000, 0x0200001f, 0x90000000, 0xa00f0800, 0x0200001f, + 0x90000000, 0xa00f0807, 0x02000006, 0x80080000, 0xb0ff0000, 0x03000005, 0x80030000, 0x80ff0000, + 0xb0e40000, 0x03000005, 0x80010001, 0x80ff0000, 0xb0aa0000, 0x02000001, 0x80020001, 0xb0ff0000, + 0x03000042, 0x800f0000, 0x80e40000, 0xa0e40800, 0x03000042, 0x800f0001, 0x80e40001, 0xa0e40807, + 0x03000005, 0x80010000, 0x80ff0000, 0xa0ff0000, 0x04000004, 0x80080000, 0x80000000, 0x80ff0001, + 0xa0ff0001, 0x02000001, 0x80070001, 0xa0e40000, 0x03000002, 0x80070001, 0x80e40001, 0xa0e40001, + 0x03000005, 0x80070000, 0x80ff0000, 0x80e40001, 0x02000001, 0x800f0800, 0x80e40000, 0x0000ffff, +}; + +static DWORD pshader_basic_9[68] = { + 0xffff0200, 0x05000051, 0xa00f0001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0200001f, + 0x80000000, 0xb00f0000, 0x0200001f, 0x90000000, 0xa00f0800, 0x0200001f, 0x90000000, 0xa00f0807, + 0x02000006, 0x80080000, 0xb0ff0000, 0x03000005, 0x80030000, 0x80ff0000, 0xb0e40000, 0x03000005, + 0x80010001, 0x80ff0000, 0xb0aa0000, 0x0400005a, 0x80010000, 0x80e40000, 0x80e40000, 0xa0000001, + 0x02000007, 0x80010000, 0x80000000, 0x02000006, 0x80030000, 0x80000000, 0x02000001, 0x80020001, + 0xb0ff0000, 0x03000042, 0x800f0000, 0x80e40000, 0xa0e40800, 0x03000042, 0x800f0001, 0x80e40001, + 0xa0e40807, 0x03000005, 0x80070002, 0xa0ff0000, 0xa0e40000, 0x02000001, 0x80080002, 0xa0ff0000, + 0x03000005, 0x800f0000, 0x80e40000, 0x80e40002, 0x03000005, 0x800f0000, 0x80e40001, 0x80e40000, + 0x02000001, 0x800f0800, 0x80e40000, 0x0000ffff, +}; + +static DWORD pshader_basic_10[80] = { + 0xffff0200, 0x05000051, 0xa00f0002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0200001f, + 0x80000000, 0xb00f0000, 0x0200001f, 0x90000000, 0xa00f0800, 0x0200001f, 0x90000000, 0xa00f0807, + 0x02000006, 0x80080000, 0xb0ff0000, 0x03000005, 0x80030000, 0x80ff0000, 0xb0e40000, 0x03000005, + 0x80010001, 0x80ff0000, 0xb0aa0000, 0x0400005a, 0x80010000, 0x80e40000, 0x80e40000, 0xa0000002, + 0x02000007, 0x80010000, 0x80000000, 0x02000006, 0x80030000, 0x80000000, 0x02000001, 0x80020001, + 0xb0ff0000, 0x03000042, 0x800f0000, 0x80e40000, 0xa0e40800, 0x03000042, 0x800f0001, 0x80e40001, + 0xa0e40807, 0x03000005, 0x80070002, 0xa0ff0000, 0xa0e40000, 0x02000001, 0x80080002, 0xa0ff0000, + 0x03000005, 0x800f0000, 0x80e40000, 0x80e40002, 0x03000005, 0x800f0000, 0x80e40001, 0x80e40000, + 0x04000004, 0x80070000, 0xa0e40001, 0x80ff0000, 0x80e40000, 0x0300000a, 0x80070001, 0x80ff0000, + 0x80e40000, 0x02000001, 0x80080001, 0x80ff0000, 0x02000001, 0x800f0800, 0x80e40001, 0x0000ffff, +}; + +static DWORD pshader_basic_11[85] = { + 0xffff0200, 0x05000051, 0xa00f0002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0200001f, + 0x80000000, 0xb00f0000, 0x0200001f, 0x90000000, 0xa00f0800, 0x0200001f, 0x90000000, 0xa00f0807, + 0x02000006, 0x80080000, 0xb0ff0000, 0x03000005, 0x80030000, 0x80ff0000, 0xb0e40000, 0x03000005, + 0x80010001, 0x80ff0000, 0xb0aa0000, 0x0400005a, 0x80010000, 0x80e40000, 0x80e40000, 0xa0000002, + 0x02000007, 0x80010000, 0x80000000, 0x02000006, 0x80030000, 0x80000000, 0x02000001, 0x80020001, + 0xb0ff0000, 0x03000042, 0x800f0000, 0x80e40000, 0xa0e40800, 0x03000042, 0x800f0001, 0x80e40001, + 0xa0e40807, 0x02000006, 0x80010001, 0x80ff0000, 0x03000005, 0x80070001, 0x80e40000, 0x80000001, + 0x03000005, 0x80080002, 0x80ff0000, 0x80ff0000, 0x04000058, 0x80070000, 0x81ff0002, 0x80e40000, + 0x80e40001, 0x03000005, 0x800f0000, 0x80e40000, 0xa0e40000, 0x03000005, 0x80080000, 0x80ff0001, + 0x80ff0000, 0x03000002, 0x800f0000, 0x80e40000, 0xa0e40001, 0x03000005, 0x80070000, 0x80ff0000, + 0x80e40000, 0x02000001, 0x800f0800, 0x80e40000, 0x0000ffff, +}; + +static DWORD pshader_basic_12[89] = { + 0xffff0200, 0x0200001f, 0x80000000, 0xb00f0000, 0x0200001f, 0x90000000, 0xa00f0800, 0x0200001f, + 0x90000000, 0xa00f0807, 0x02000006, 0x80080000, 0xb0ff0000, 0x03000005, 0x80010000, 0x80ff0000, + 0xb0550000, 0x03000005, 0x80010000, 0x80000000, 0x80000000, 0x04000004, 0x80020000, 0xb0000000, + 0x80ff0000, 0xa0000002, 0x03000005, 0x80010001, 0x80ff0000, 0xb0aa0000, 0x04000004, 0x80010000, + 0x80550000, 0x80550000, 0x80000000, 0x03000005, 0x80040000, 0x80550000, 0xa0550002, 0x03000005, + 0x80040000, 0x80aa0000, 0x80aa0000, 0x04000004, 0x80010000, 0x80000000, 0xa0aa0002, 0x80aa0000, + 0x02000007, 0x80010000, 0x80000000, 0x02000006, 0x80010000, 0x80000000, 0x04000004, 0x80030000, + 0x80550000, 0xa1550002, 0x80000000, 0x02000001, 0x80020001, 0xb0ff0000, 0x03000042, 0x800f0000, + 0x80e40000, 0xa0e40800, 0x03000042, 0x800f0001, 0x80e40001, 0xa0e40807, 0x03000005, 0x80070002, + 0xa0ff0000, 0xa0e40000, 0x02000001, 0x80080002, 0xa0ff0000, 0x03000005, 0x800f0000, 0x80e40000, + 0x80e40002, 0x03000005, 0x800f0000, 0x80e40001, 0x80e40000, 0x02000001, 0x800f0800, 0x80e40000, + 0x0000ffff, +}; + +static DWORD pshader_basic_13[101] = { + 0xffff0200, 0x0200001f, 0x80000000, 0xb00f0000, 0x0200001f, 0x90000000, 0xa00f0800, 0x0200001f, + 0x90000000, 0xa00f0807, 0x02000006, 0x80080000, 0xb0ff0000, 0x03000005, 0x80010000, 0x80ff0000, + 0xb0550000, 0x03000005, 0x80010000, 0x80000000, 0x80000000, 0x04000004, 0x80020000, 0xb0000000, + 0x80ff0000, 0xa0000002, 0x03000005, 0x80010001, 0x80ff0000, 0xb0aa0000, 0x04000004, 0x80010000, + 0x80550000, 0x80550000, 0x80000000, 0x03000005, 0x80040000, 0x80550000, 0xa0550002, 0x03000005, + 0x80040000, 0x80aa0000, 0x80aa0000, 0x04000004, 0x80010000, 0x80000000, 0xa0aa0002, 0x80aa0000, + 0x02000007, 0x80010000, 0x80000000, 0x02000006, 0x80010000, 0x80000000, 0x04000004, 0x80030000, + 0x80550000, 0xa1550002, 0x80000000, 0x02000001, 0x80020001, 0xb0ff0000, 0x03000042, 0x800f0000, + 0x80e40000, 0xa0e40800, 0x03000042, 0x800f0001, 0x80e40001, 0xa0e40807, 0x03000005, 0x80070002, + 0xa0ff0000, 0xa0e40000, 0x02000001, 0x80080002, 0xa0ff0000, 0x03000005, 0x800f0000, 0x80e40000, + 0x80e40002, 0x03000005, 0x800f0000, 0x80e40001, 0x80e40000, 0x04000004, 0x80070000, 0xa0e40001, + 0x80ff0000, 0x80e40000, 0x0300000a, 0x80070001, 0x80ff0000, 0x80e40000, 0x02000001, 0x80080001, + 0x80ff0000, 0x02000001, 0x800f0800, 0x80e40001, 0x0000ffff, +}; + +static DWORD pshader_basic_14[106] = { + 0xffff0200, 0x0200001f, 0x80000000, 0xb00f0000, 0x0200001f, 0x90000000, 0xa00f0800, 0x0200001f, + 0x90000000, 0xa00f0807, 0x02000006, 0x80080000, 0xb0ff0000, 0x03000005, 0x80010000, 0x80ff0000, + 0xb0550000, 0x03000005, 0x80010000, 0x80000000, 0x80000000, 0x04000004, 0x80020000, 0xb0000000, + 0x80ff0000, 0xa0000002, 0x03000005, 0x80010001, 0x80ff0000, 0xb0aa0000, 0x04000004, 0x80010000, + 0x80550000, 0x80550000, 0x80000000, 0x03000005, 0x80040000, 0x80550000, 0xa0550002, 0x03000005, + 0x80040000, 0x80aa0000, 0x80aa0000, 0x04000004, 0x80010000, 0x80000000, 0xa0aa0002, 0x80aa0000, + 0x02000007, 0x80010000, 0x80000000, 0x02000006, 0x80010000, 0x80000000, 0x04000004, 0x80030000, + 0x80550000, 0xa1550002, 0x80000000, 0x02000001, 0x80020001, 0xb0ff0000, 0x03000042, 0x800f0000, + 0x80e40000, 0xa0e40800, 0x03000042, 0x800f0001, 0x80e40001, 0xa0e40807, 0x02000006, 0x80010001, + 0x80ff0000, 0x03000005, 0x80070001, 0x80e40000, 0x80000001, 0x03000005, 0x80080002, 0x80ff0000, + 0x80ff0000, 0x04000058, 0x80070000, 0x81ff0002, 0x80e40000, 0x80e40001, 0x03000005, 0x800f0000, + 0x80e40000, 0xa0e40000, 0x03000005, 0x80080000, 0x80ff0001, 0x80ff0000, 0x03000002, 0x800f0000, + 0x80e40000, 0xa0e40001, 0x03000005, 0x80070000, 0x80ff0000, 0x80e40000, 0x02000001, 0x800f0800, + 0x80e40000, 0x0000ffff, +}; + +static DWORD pshader_basic_15[64] = { + 0xffff0200, 0x05000051, 0xa00f0001, 0xbf000000, 0x00000000, 0x00000000, 0x00000000, 0x0200001f, + 0x80000000, 0xb00f0000, 0x0200001f, 0x90000000, 0xa00f0800, 0x0200001f, 0x90000000, 0xa00f0807, + 0x02000006, 0x80080000, 0xb0ff0000, 0x03000005, 0x80030000, 0x80ff0000, 0xb0e40000, 0x03000005, + 0x80010001, 0x80ff0000, 0xb0aa0000, 0x02000001, 0x80020001, 0xb0ff0000, 0x03000042, 0x800f0000, + 0x80e40000, 0xa0e40800, 0x03000042, 0x800f0001, 0x80e40001, 0xa0e40807, 0x03000005, 0x80070002, + 0xa0ff0000, 0xa0e40000, 0x02000001, 0x80080002, 0xa0ff0000, 0x03000005, 0x800f0000, 0x80ff0000, + 0x80e40002, 0x04000004, 0x800f0002, 0x80ff0000, 0x80ff0001, 0xa0000001, 0x03000005, 0x800f0000, + 0x80e40001, 0x80e40000, 0x02000001, 0x800f0800, 0x80e40000, 0x01000041, 0x800f0002, 0x0000ffff, +}; + +static DWORD pshader_basic_16[76] = { + 0xffff0200, 0x05000051, 0xa00f0002, 0xbf000000, 0x00000000, 0x00000000, 0x00000000, 0x0200001f, + 0x80000000, 0xb00f0000, 0x0200001f, 0x90000000, 0xa00f0800, 0x0200001f, 0x90000000, 0xa00f0807, + 0x02000006, 0x80080000, 0xb0ff0000, 0x03000005, 0x80030000, 0x80ff0000, 0xb0e40000, 0x03000005, + 0x80010001, 0x80ff0000, 0xb0aa0000, 0x02000001, 0x80020001, 0xb0ff0000, 0x03000042, 0x800f0000, + 0x80e40000, 0xa0e40800, 0x03000042, 0x800f0001, 0x80e40001, 0xa0e40807, 0x03000005, 0x80070002, + 0xa0ff0000, 0xa0e40000, 0x02000001, 0x80080002, 0xa0ff0000, 0x03000005, 0x800f0000, 0x80ff0000, + 0x80e40002, 0x04000004, 0x800f0002, 0x80ff0000, 0x80ff0001, 0xa0000002, 0x03000005, 0x800f0000, + 0x80e40001, 0x80e40000, 0x01000041, 0x800f0002, 0x04000004, 0x80070000, 0xa0e40001, 0x80ff0000, + 0x80e40000, 0x0300000a, 0x80070001, 0x80ff0000, 0x80e40000, 0x02000001, 0x80080001, 0x80ff0000, + 0x02000001, 0x800f0800, 0x80e40001, 0x0000ffff, +}; + +static DWORD pshader_basic_17[68] = { + 0xffff0200, 0x05000051, 0xa00f0002, 0xbf000000, 0x00000000, 0x00000000, 0x00000000, 0x0200001f, + 0x80000000, 0xb00f0000, 0x0200001f, 0x90000000, 0xa00f0800, 0x0200001f, 0x90000000, 0xa00f0807, + 0x02000006, 0x80080000, 0xb0ff0000, 0x03000005, 0x80030000, 0x80ff0000, 0xb0e40000, 0x03000005, + 0x80010001, 0x80ff0000, 0xb0aa0000, 0x02000001, 0x80020001, 0xb0ff0000, 0x03000042, 0x800f0000, + 0x80e40000, 0xa0e40800, 0x03000042, 0x800f0001, 0x80e40001, 0xa0e40807, 0x03000005, 0x80010000, + 0x80ff0000, 0xa0ff0000, 0x04000004, 0x80080000, 0x80000000, 0x80ff0001, 0xa0ff0001, 0x03000002, + 0x800f0001, 0x80ff0000, 0xa0000002, 0x01000041, 0x800f0001, 0x02000001, 0x80070001, 0xa0e40000, + 0x03000002, 0x80070001, 0x80e40001, 0xa0e40001, 0x03000005, 0x80070000, 0x80ff0000, 0x80e40001, + 0x02000001, 0x800f0800, 0x80e40000, 0x0000ffff, +}; + +static ProgramWithCachedVariableLocations pshader_basic_arr[18] = { + { pshader_basic_0, NULL, { -1, 7, 0, -1, -1, } }, + { pshader_basic_1, NULL, { -1, 7, 0, 1, -1, } }, + { pshader_basic_2, NULL, { -1, 7, 0, 1, -1, } }, + { pshader_basic_3, NULL, { 0, 7, 0, -1, -1, } }, + { pshader_basic_4, NULL, { 0, 7, 0, 1, -1, } }, + { pshader_basic_5, NULL, { 0, 7, 0, 1, -1, } }, + { pshader_basic_6, NULL, { 0, 7, 0, -1, -1, } }, + { pshader_basic_7, NULL, { 0, 7, 0, 1, -1, } }, + { pshader_basic_8, NULL, { 0, 7, 0, 1, -1, } }, + { pshader_basic_9, NULL, { 0, 7, 0, -1, -1, } }, + { pshader_basic_10, NULL, { 0, 7, 0, 1, -1, } }, + { pshader_basic_11, NULL, { 0, 7, 0, 1, -1, } }, + { pshader_basic_12, NULL, { 0, 7, 0, -1, 2, } }, + { pshader_basic_13, NULL, { 0, 7, 0, 1, 2, } }, + { pshader_basic_14, NULL, { 0, 7, 0, 1, 2, } }, + { pshader_basic_15, NULL, { 0, 7, 0, -1, -1, } }, + { pshader_basic_16, NULL, { 0, 7, 0, 1, -1, } }, + { pshader_basic_17, NULL, { 0, 7, 0, 1, -1, } }, +}; + +static DWORD pshader_exceptional_blend_1[72] = { + 0xffff0200, 0x05000051, 0xa00f0002, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x0200001f, + 0x80000000, 0xb0030000, 0x0200001f, 0x90000000, 0xa00f0800, 0x0200001f, 0x90000000, 0xa00f0801, + 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, 0x03000042, 0x800f0001, 0xb0e40000, 0xa0e40801, + 0x03000005, 0x80070000, 0x80e40000, 0xa0e40000, 0x03000005, 0x800f0002, 0x80ff0000, 0xa0e40001, + 0x04000004, 0x801f0000, 0x80e40000, 0xa0ff0000, 0x80e40002, 0x03000002, 0x80010002, 0x81ff0000, + 0xa0000002, 0x03000005, 0x80070003, 0x80e40001, 0x80e40000, 0x04000004, 0x80070001, 0x80000002, + 0x80e40001, 0x80e40003, 0x03000002, 0x80010002, 0x81ff0001, 0xa0000002, 0x04000004, 0x80070002, + 0x80000002, 0x80e40000, 0x80e40001, 0x03000002, 0x80010000, 0x80ff0001, 0x80ff0000, 0x04000004, + 0x80080002, 0x80ff0000, 0x81ff0001, 0x80000000, 0x02000001, 0x800f0800, 0x80e40002, 0x0000ffff, +}; + +static DWORD pshader_exceptional_blend_2[111] = { + 0xffff0200, 0x05000051, 0xa00f0002, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x0200001f, + 0x80000000, 0xb0030000, 0x0200001f, 0x90000000, 0xa00f0800, 0x0200001f, 0x90000000, 0xa00f0801, + 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, 0x03000042, 0x800f0001, 0xb0e40000, 0xa0e40801, + 0x03000005, 0x80070000, 0x80e40000, 0xa0e40000, 0x03000005, 0x800f0002, 0x80ff0000, 0xa0e40001, + 0x04000004, 0x801f0000, 0x80e40000, 0xa0ff0000, 0x80e40002, 0x03000002, 0x80010002, 0x81ff0000, + 0xa0000002, 0x03000002, 0x80020002, 0x81000000, 0x80ff0000, 0x03000005, 0x80040002, 0x80ff0001, + 0x80ff0000, 0x03000002, 0x80080002, 0x81000001, 0x80ff0001, 0x04000004, 0x80010003, 0x80ff0002, + 0x81550002, 0x80aa0002, 0x03000002, 0x80080003, 0x81550000, 0x80ff0000, 0x03000002, 0x80020002, + 0x81550001, 0x80ff0001, 0x04000004, 0x80020003, 0x80550002, 0x81ff0003, 0x80aa0002, 0x03000002, + 0x80080003, 0x81aa0000, 0x80ff0000, 0x03000002, 0x80020002, 0x81aa0001, 0x80ff0001, 0x04000004, + 0x80040003, 0x80550002, 0x81ff0003, 0x80aa0002, 0x04000004, 0x80070001, 0x80000002, 0x80e40001, + 0x80e40003, 0x03000002, 0x80010002, 0x81ff0001, 0xa0000002, 0x04000004, 0x80070002, 0x80000002, + 0x80e40000, 0x80e40001, 0x03000002, 0x80010000, 0x80ff0001, 0x80ff0000, 0x04000004, 0x80080002, + 0x80ff0000, 0x81ff0001, 0x80000000, 0x02000001, 0x800f0800, 0x80e40002, 0x0000ffff, +}; + +static DWORD pshader_exceptional_blend_3[104] = { + 0xffff0200, 0x05000051, 0xa00f0002, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x0200001f, + 0x80000000, 0xb0030000, 0x0200001f, 0x90000000, 0xa00f0800, 0x0200001f, 0x90000000, 0xa00f0801, + 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, 0x03000042, 0x800f0001, 0xb0e40000, 0xa0e40801, + 0x03000005, 0x80070000, 0x80e40000, 0xa0e40000, 0x03000005, 0x800f0002, 0x80ff0000, 0xa0e40001, + 0x04000004, 0x801f0000, 0x80e40000, 0xa0ff0000, 0x80e40002, 0x03000002, 0x80010002, 0x81ff0000, + 0xa0000002, 0x03000005, 0x80020002, 0x80000001, 0x80ff0000, 0x03000005, 0x80040002, 0x80ff0001, + 0x80000000, 0x0300000b, 0x80010003, 0x80550002, 0x80aa0002, 0x03000005, 0x80020002, 0x80550001, + 0x80ff0000, 0x03000005, 0x80040002, 0x80ff0001, 0x80550000, 0x0300000b, 0x80020003, 0x80550002, + 0x80aa0002, 0x03000005, 0x80020002, 0x80aa0001, 0x80ff0000, 0x03000005, 0x80040002, 0x80ff0001, + 0x80aa0000, 0x0300000b, 0x80040003, 0x80550002, 0x80aa0002, 0x04000004, 0x80070001, 0x80000002, + 0x80e40001, 0x80e40003, 0x03000002, 0x80010002, 0x81ff0001, 0xa0000002, 0x04000004, 0x80070002, + 0x80000002, 0x80e40000, 0x80e40001, 0x03000002, 0x80010000, 0x80ff0001, 0x80ff0000, 0x04000004, + 0x80080002, 0x80ff0000, 0x81ff0001, 0x80000000, 0x02000001, 0x800f0800, 0x80e40002, 0x0000ffff, +}; + +static DWORD pshader_exceptional_blend_4[104] = { + 0xffff0200, 0x05000051, 0xa00f0002, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x0200001f, + 0x80000000, 0xb0030000, 0x0200001f, 0x90000000, 0xa00f0800, 0x0200001f, 0x90000000, 0xa00f0801, + 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, 0x03000042, 0x800f0001, 0xb0e40000, 0xa0e40801, + 0x03000005, 0x80070000, 0x80e40000, 0xa0e40000, 0x03000005, 0x800f0002, 0x80ff0000, 0xa0e40001, + 0x04000004, 0x801f0000, 0x80e40000, 0xa0ff0000, 0x80e40002, 0x03000002, 0x80010002, 0x81ff0000, + 0xa0000002, 0x03000005, 0x80020002, 0x80000001, 0x80ff0000, 0x03000005, 0x80040002, 0x80ff0001, + 0x80000000, 0x0300000a, 0x80010003, 0x80aa0002, 0x80550002, 0x03000005, 0x80020002, 0x80550001, + 0x80ff0000, 0x03000005, 0x80040002, 0x80ff0001, 0x80550000, 0x0300000a, 0x80020003, 0x80aa0002, + 0x80550002, 0x03000005, 0x80020002, 0x80aa0001, 0x80ff0000, 0x03000005, 0x80040002, 0x80ff0001, + 0x80aa0000, 0x0300000a, 0x80040003, 0x80aa0002, 0x80550002, 0x04000004, 0x80070001, 0x80000002, + 0x80e40001, 0x80e40003, 0x03000002, 0x80010002, 0x81ff0001, 0xa0000002, 0x04000004, 0x80070002, + 0x80000002, 0x80e40000, 0x80e40001, 0x03000002, 0x80010000, 0x80ff0001, 0x80ff0000, 0x04000004, + 0x80080002, 0x80ff0000, 0x81ff0001, 0x80000000, 0x02000001, 0x800f0800, 0x80e40002, 0x0000ffff, +}; + +static DWORD pshader_exceptional_blend_5[73] = { + 0xffff0200, 0x05000051, 0xa00f0002, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x0200001f, + 0x80000000, 0xb0030000, 0x0200001f, 0x90000000, 0xa00f0800, 0x0200001f, 0x90000000, 0xa00f0801, + 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, 0x03000042, 0x800f0001, 0xb0e40000, 0xa0e40801, + 0x03000005, 0x80070000, 0x80e40000, 0xa0e40000, 0x03000005, 0x800f0002, 0x80ff0000, 0xa0e40001, + 0x04000004, 0x801f0000, 0x80e40000, 0xa0ff0000, 0x80e40002, 0x03000002, 0x80010000, 0x80000000, + 0x80000001, 0x0300000a, 0x80010002, 0x80000000, 0xa0000002, 0x03000002, 0x80010000, 0x80550000, + 0x80550001, 0x0300000a, 0x80020002, 0x80000000, 0xa0000002, 0x03000002, 0x80010000, 0x80aa0000, + 0x80aa0001, 0x03000002, 0x80020000, 0x80ff0001, 0x80ff0000, 0x0300000a, 0x80080002, 0x80550000, + 0xa0000002, 0x0300000a, 0x80040002, 0x80000000, 0xa0000002, 0x02000001, 0x800f0800, 0x80e40002, + 0x0000ffff, +}; + +static DWORD pshader_exceptional_blend_6[73] = { + 0xffff0200, 0x05000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, 0x0200001f, + 0x80000000, 0xb0030000, 0x0200001f, 0x90000000, 0xa00f0800, 0x0200001f, 0x90000000, 0xa00f0801, + 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, 0x03000042, 0x800f0001, 0xb0e40000, 0xa0e40801, + 0x03000005, 0x80070000, 0x80e40000, 0xa0e40000, 0x03000005, 0x800f0002, 0x80ff0000, 0xa0e40001, + 0x04000004, 0x801f0000, 0x80e40000, 0xa0ff0000, 0x80e40002, 0x03000002, 0x80010000, 0x81000000, + 0x80000001, 0x0300000b, 0x80010002, 0x80000000, 0xa0000002, 0x03000002, 0x80010000, 0x81550000, + 0x80550001, 0x0300000b, 0x80020002, 0x80000000, 0xa0000002, 0x03000002, 0x80010000, 0x81aa0000, + 0x80aa0001, 0x03000002, 0x80020000, 0x80ff0001, 0x80ff0000, 0x0300000a, 0x80080002, 0x80550000, + 0xa0550002, 0x0300000b, 0x80040002, 0x80000000, 0xa0000002, 0x02000001, 0x800f0800, 0x80e40002, + 0x0000ffff, +}; + +static DWORD pshader_exceptional_blend_7[104] = { + 0xffff0200, 0x05000051, 0xa00f0002, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x0200001f, + 0x80000000, 0xb0030000, 0x0200001f, 0x90000000, 0xa00f0800, 0x0200001f, 0x90000000, 0xa00f0801, + 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, 0x03000042, 0x800f0001, 0xb0e40000, 0xa0e40801, + 0x03000005, 0x80070000, 0x80e40000, 0xa0e40000, 0x03000005, 0x800f0002, 0x80ff0000, 0xa0e40001, + 0x04000004, 0x801f0000, 0x80e40000, 0xa0ff0000, 0x80e40002, 0x03000002, 0x80010002, 0x81ff0000, + 0xa0000002, 0x03000005, 0x80020002, 0x80ff0001, 0x80000000, 0x04000004, 0x80020002, 0x80ff0000, + 0x80000001, 0x81550002, 0x02000023, 0x80010003, 0x80550002, 0x03000005, 0x80080003, 0x80ff0001, + 0x80550000, 0x04000004, 0x80080003, 0x80ff0000, 0x80550001, 0x81ff0003, 0x02000023, 0x80020003, + 0x80ff0003, 0x03000005, 0x80080003, 0x80ff0001, 0x80aa0000, 0x04000004, 0x80080003, 0x80ff0000, + 0x80aa0001, 0x81ff0003, 0x02000023, 0x80040003, 0x80ff0003, 0x04000004, 0x80070001, 0x80000002, + 0x80e40001, 0x80e40003, 0x03000002, 0x80010002, 0x81ff0001, 0xa0000002, 0x04000004, 0x80070002, + 0x80000002, 0x80e40000, 0x80e40001, 0x03000002, 0x80010000, 0x80ff0001, 0x80ff0000, 0x04000004, + 0x80080002, 0x80ff0000, 0x81ff0001, 0x80000000, 0x02000001, 0x800f0800, 0x80e40002, 0x0000ffff, +}; + +static DWORD pshader_exceptional_blend_8[92] = { + 0xffff0200, 0x05000051, 0xa00f0002, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x0200001f, + 0x80000000, 0xb0030000, 0x0200001f, 0x90000000, 0xa00f0800, 0x0200001f, 0x90000000, 0xa00f0801, + 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, 0x03000042, 0x800f0001, 0xb0e40000, 0xa0e40801, + 0x03000005, 0x80070000, 0x80e40000, 0xa0e40000, 0x03000005, 0x800f0002, 0x80ff0000, 0xa0e40001, + 0x04000004, 0x801f0000, 0x80e40000, 0xa0ff0000, 0x80e40002, 0x03000002, 0x80010002, 0x81ff0000, + 0xa0000002, 0x03000002, 0x80020002, 0x81000001, 0x80ff0001, 0x03000005, 0x80010003, 0x80ff0000, + 0x80550002, 0x03000002, 0x80080003, 0x81550001, 0x80ff0001, 0x03000005, 0x80020003, 0x80ff0000, + 0x80ff0003, 0x03000002, 0x80080003, 0x81aa0001, 0x80ff0001, 0x03000005, 0x80040003, 0x80ff0000, + 0x80ff0003, 0x04000004, 0x80070001, 0x80000002, 0x80e40001, 0x80e40003, 0x03000002, 0x80010002, + 0x81ff0001, 0xa0000002, 0x04000004, 0x80070002, 0x80000002, 0x80e40000, 0x80e40001, 0x03000002, + 0x80010000, 0x80ff0001, 0x80ff0000, 0x04000004, 0x80080002, 0x80ff0000, 0x81ff0001, 0x80000000, + 0x02000001, 0x800f0800, 0x80e40002, 0x0000ffff, +}; + +static DWORD pshader_exceptional_blend_9[177] = { + 0xffff0200, 0x05000051, 0xa00f0002, 0x3f000000, 0x3f800000, 0x00000000, 0x00000000, 0x0200001f, + 0x80000000, 0xb0030000, 0x0200001f, 0x90000000, 0xa00f0800, 0x0200001f, 0x90000000, 0xa00f0801, + 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, 0x03000042, 0x800f0001, 0xb0e40000, 0xa0e40801, + 0x03000005, 0x80070000, 0x80e40000, 0xa0e40000, 0x03000005, 0x800f0002, 0x80ff0000, 0xa0e40001, + 0x04000004, 0x801f0000, 0x80e40000, 0xa0ff0000, 0x80e40002, 0x03000002, 0x80010002, 0x81000000, + 0x80ff0000, 0x03000005, 0x80020002, 0x80ff0001, 0x80ff0000, 0x03000002, 0x80040002, 0x81000001, + 0x80ff0001, 0x03000002, 0x80040002, 0x80aa0002, 0x80aa0002, 0x04000004, 0x80010002, 0x80aa0002, + 0x81000002, 0x80550002, 0x03000005, 0x80040002, 0x80000000, 0x80000001, 0x03000002, 0x80040002, + 0x80aa0002, 0x80aa0002, 0x04000004, 0x80080002, 0x80ff0001, 0xa1000002, 0x80000001, 0x04000058, + 0x80010003, 0x80ff0002, 0x80000002, 0x80aa0002, 0x03000002, 0x80080003, 0x81550000, 0x80ff0000, + 0x03000002, 0x80010002, 0x81550001, 0x80ff0001, 0x03000002, 0x80010002, 0x80000002, 0x80000002, + 0x04000004, 0x80080003, 0x80000002, 0x81ff0003, 0x80550002, 0x03000005, 0x80010002, 0x80550000, + 0x80550001, 0x03000002, 0x80010002, 0x80000002, 0x80000002, 0x04000004, 0x80040002, 0x80ff0001, + 0xa1000002, 0x80550001, 0x04000058, 0x80020003, 0x80aa0002, 0x80ff0003, 0x80000002, 0x03000002, + 0x80080003, 0x81aa0000, 0x80ff0000, 0x03000002, 0x80010002, 0x81aa0001, 0x80ff0001, 0x03000002, + 0x80010002, 0x80000002, 0x80000002, 0x04000004, 0x80080003, 0x80000002, 0x81ff0003, 0x80550002, + 0x03000005, 0x80010002, 0x80aa0000, 0x80aa0001, 0x03000002, 0x80010002, 0x80000002, 0x80000002, + 0x04000004, 0x80020002, 0x80ff0001, 0xa1000002, 0x80aa0001, 0x04000058, 0x80040003, 0x80550002, + 0x80ff0003, 0x80000002, 0x03000002, 0x80080003, 0x81ff0000, 0xa0550002, 0x04000004, 0x80070001, + 0x80ff0003, 0x80e40001, 0x80e40003, 0x03000002, 0x80010002, 0x81ff0001, 0xa0550002, 0x04000004, + 0x80070002, 0x80000002, 0x80e40000, 0x80e40001, 0x03000002, 0x80010000, 0x80ff0001, 0x80ff0000, + 0x04000004, 0x80080002, 0x80ff0000, 0x81ff0001, 0x80000000, 0x02000001, 0x800f0800, 0x80e40002, + 0x0000ffff, +}; + +static DWORD pshader_exceptional_blend_10[177] = { + 0xffff0200, 0x05000051, 0xa00f0002, 0x3f000000, 0x3f800000, 0x00000000, 0x00000000, 0x0200001f, + 0x80000000, 0xb0030000, 0x0200001f, 0x90000000, 0xa00f0800, 0x0200001f, 0x90000000, 0xa00f0801, + 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, 0x03000042, 0x800f0001, 0xb0e40000, 0xa0e40801, + 0x03000005, 0x80070000, 0x80e40000, 0xa0e40000, 0x03000005, 0x800f0002, 0x80ff0000, 0xa0e40001, + 0x04000004, 0x801f0000, 0x80e40000, 0xa0ff0000, 0x80e40002, 0x04000004, 0x80010002, 0x80ff0000, + 0xa1000002, 0x80000000, 0x03000002, 0x80020002, 0x81000000, 0x80ff0000, 0x03000002, 0x80040002, + 0x81000001, 0x80ff0001, 0x03000002, 0x80040002, 0x80aa0002, 0x80aa0002, 0x03000005, 0x80080002, + 0x80ff0001, 0x80ff0000, 0x04000004, 0x80020002, 0x80aa0002, 0x81550002, 0x80ff0002, 0x03000005, + 0x80040002, 0x80000000, 0x80000001, 0x03000002, 0x80040002, 0x80aa0002, 0x80aa0002, 0x04000058, + 0x80010002, 0x80000002, 0x80550002, 0x80aa0002, 0x03000002, 0x80080003, 0x81550000, 0x80ff0000, + 0x03000002, 0x80010003, 0x81550001, 0x80ff0001, 0x03000002, 0x80010003, 0x80000003, 0x80000003, + 0x04000004, 0x80010003, 0x80000003, 0x81ff0003, 0x80ff0002, 0x04000004, 0x80020003, 0x80ff0000, + 0xa1000002, 0x80550000, 0x03000005, 0x80040003, 0x80550000, 0x80550001, 0x03000002, 0x80040003, + 0x80aa0003, 0x80aa0003, 0x04000058, 0x80020002, 0x80550003, 0x80000003, 0x80aa0003, 0x03000002, + 0x80010003, 0x81aa0000, 0x80ff0000, 0x03000002, 0x80020003, 0x81aa0001, 0x80ff0001, 0x03000002, + 0x80020003, 0x80550003, 0x80550003, 0x04000004, 0x80080002, 0x80550003, 0x81000003, 0x80ff0002, + 0x04000004, 0x80010003, 0x80ff0000, 0xa1000002, 0x80aa0000, 0x03000005, 0x80020003, 0x80aa0000, + 0x80aa0001, 0x03000002, 0x80020003, 0x80550003, 0x80550003, 0x04000058, 0x80040002, 0x80000003, + 0x80ff0002, 0x80550003, 0x03000002, 0x80080002, 0x81ff0000, 0xa0550002, 0x04000004, 0x80070001, + 0x80ff0002, 0x80e40001, 0x80e40002, 0x03000002, 0x80010002, 0x81ff0001, 0xa0550002, 0x04000004, + 0x80070002, 0x80000002, 0x80e40000, 0x80e40001, 0x03000002, 0x80010000, 0x80ff0001, 0x80ff0000, + 0x04000004, 0x80080002, 0x80ff0000, 0x81ff0001, 0x80000000, 0x02000001, 0x800f0800, 0x80e40002, + 0x0000ffff, +}; + +static DWORD pshader_exceptional_blend_11[49] = { + 0xffff0200, 0x05000051, 0xa00f0002, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x0200001f, + 0x80000000, 0xb0030000, 0x0200001f, 0x90000000, 0xa00f0800, 0x0200001f, 0x90000000, 0xa00f0801, + 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, 0x03000042, 0x800f0001, 0xb0e40000, 0xa0e40801, + 0x03000005, 0x80010000, 0x80ff0000, 0xa0ff0001, 0x04000004, 0x80110000, 0x80ff0000, 0xa0ff0000, + 0x80000000, 0x03000002, 0x80010000, 0x81000000, 0xa0000002, 0x03000005, 0x80070002, 0x80000000, + 0x80e40001, 0x03000005, 0x80080002, 0x80ff0001, 0x80000000, 0x02000001, 0x800f0800, 0x80e40002, + 0x0000ffff, +}; + +static DWORD pshader_exceptional_blend_12[39] = { + 0xffff0200, 0x0200001f, 0x80000000, 0xb0030000, 0x0200001f, 0x90000000, 0xa00f0800, 0x0200001f, + 0x90000000, 0xa00f0801, 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, 0x03000042, 0x800f0001, + 0xb0e40000, 0xa0e40801, 0x03000005, 0x80010000, 0x80ff0000, 0xa0ff0001, 0x04000004, 0x80110000, + 0x80ff0000, 0xa0ff0000, 0x80000000, 0x03000005, 0x80070002, 0x80000000, 0x80e40001, 0x03000005, + 0x80080002, 0x80ff0001, 0x80000000, 0x02000001, 0x800f0800, 0x80e40002, 0x0000ffff, +}; + +static ProgramWithCachedVariableLocations pshader_exceptional_blend_arr[13] = { + { NULL, NULL, { -1, -1, -1, -1, } }, + { pshader_exceptional_blend_1, NULL, { 0, 1, 0, 1, } }, + { pshader_exceptional_blend_2, NULL, { 0, 1, 0, 1, } }, + { pshader_exceptional_blend_3, NULL, { 0, 1, 0, 1, } }, + { pshader_exceptional_blend_4, NULL, { 0, 1, 0, 1, } }, + { pshader_exceptional_blend_5, NULL, { 0, 1, 0, 1, } }, + { pshader_exceptional_blend_6, NULL, { 0, 1, 0, 1, } }, + { pshader_exceptional_blend_7, NULL, { 0, 1, 0, 1, } }, + { pshader_exceptional_blend_8, NULL, { 0, 1, 0, 1, } }, + { pshader_exceptional_blend_9, NULL, { 0, 1, 0, 1, } }, + { pshader_exceptional_blend_10, NULL, { 0, 1, 0, 1, } }, + { pshader_exceptional_blend_11, NULL, { 0, 1, 0, 1, } }, + { pshader_exceptional_blend_12, NULL, { 0, 1, 0, 1, } }, +}; + +static DWORD pshader_filter_0[77] = { + 0xffff0200, 0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x0200001f, + 0x80000000, 0xb0030000, 0x0200001f, 0x90000000, 0xa00f0800, 0x0200001f, 0x90000000, 0xa00f0801, + 0x03000002, 0x80030000, 0xb0e40000, 0xa0e40007, 0x0300000b, 0x80030001, 0x80e40000, 0xa0e40004, + 0x0300000a, 0x80010000, 0xa0aa0004, 0x80000001, 0x0300000a, 0x80020000, 0xa0ff0004, 0x80550001, + 0x0300000b, 0x800c0000, 0xb01b0000, 0xa01b0005, 0x0300000a, 0x80010001, 0xa0aa0005, 0x80ff0000, + 0x0300000a, 0x80020001, 0xa0ff0005, 0x80aa0000, 0x03000042, 0x800f0000, 0x80e40000, 0xa0e40800, + 0x03000042, 0x800f0001, 0x80e40001, 0xa0e40801, 0x03000005, 0x80010000, 0x80ff0000, 0xa0aa0007, + 0x0300000a, 0x80080002, 0x80000000, 0xa0000000, 0x03000005, 0x800f0000, 0x80ff0002, 0xa0e40006, + 0x03000002, 0x80010002, 0x81ff0001, 0xa0000000, 0x04000004, 0x800f0000, 0x80e40000, 0x80000002, + 0x80e40001, 0x02000001, 0x800f0800, 0x80e40000, 0x0000ffff, +}; + +static DWORD pshader_filter_1[76] = { + 0xffff0200, 0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x0200001f, + 0x80000000, 0xb0030000, 0x0200001f, 0x90000000, 0xa00f0800, 0x0200001f, 0x90000000, 0xa00f0801, + 0x03000002, 0x80030000, 0xb0e40000, 0xa0e40007, 0x0300000b, 0x80030001, 0x80e40000, 0xa0e40004, + 0x0300000a, 0x80010000, 0xa0aa0004, 0x80000001, 0x0300000a, 0x80020000, 0xa0ff0004, 0x80550001, + 0x0300000b, 0x800c0000, 0xb01b0000, 0xa01b0005, 0x0300000a, 0x80010001, 0xa0aa0005, 0x80ff0000, + 0x0300000a, 0x80020001, 0xa0ff0005, 0x80aa0000, 0x03000042, 0x800f0000, 0x80e40000, 0xa0e40800, + 0x03000042, 0x800f0001, 0x80e40001, 0xa0e40801, 0x03000005, 0x80010000, 0x80ff0000, 0xa0aa0007, + 0x0300000a, 0x80010001, 0x80000000, 0xa0000000, 0x03000002, 0x80010000, 0x81ff0001, 0xa0000000, + 0x03000005, 0x800f0000, 0x80000000, 0xa0e40006, 0x03000005, 0x800f0000, 0x80000001, 0x80e40000, + 0x02000001, 0x800f0800, 0x80e40000, 0x0000ffff, +}; + +static DWORD pshader_filter_2[83] = { + 0xffff0200, 0x05000051, 0xa00f0000, 0x3f800000, 0x3f000000, 0x00000000, 0x00000000, 0x0200001f, + 0x80000000, 0xb0030000, 0x0200001f, 0x90000000, 0xa00f0800, 0x0200001f, 0x90000000, 0xa00f0801, + 0x0200001f, 0x90000000, 0xa00f0802, 0x03000002, 0x80030000, 0xb0e40000, 0xa0e40006, 0x0300000b, + 0x80030001, 0x80e40000, 0xa0e40004, 0x0300000a, 0x80010000, 0xa0aa0004, 0x80000001, 0x0300000a, + 0x80020000, 0xa0ff0004, 0x80550001, 0x03000042, 0x800f0000, 0x80e40000, 0xa0e40800, 0x03000005, + 0x80010000, 0x80ff0000, 0xa0aa0006, 0x0300000a, 0x80010001, 0x80000000, 0xa0000000, 0x02000001, + 0x80020001, 0xa0550000, 0x0300000b, 0x80030000, 0xb0e40000, 0xa0e40005, 0x0300000a, 0x80010002, + 0xa0aa0005, 0x80000000, 0x0300000a, 0x80020002, 0xa0ff0005, 0x80550000, 0x03000042, 0x800f0000, + 0x80e40001, 0xa0e40802, 0x03000042, 0x800f0001, 0x80e40002, 0xa0e40801, 0x03000002, 0x80010002, + 0x81ff0001, 0xa0000000, 0x04000004, 0x800f0000, 0x80e40000, 0x80000002, 0x80e40001, 0x02000001, + 0x800f0800, 0x80e40000, 0x0000ffff, +}; + +static DWORD pshader_filter_3[82] = { + 0xffff0200, 0x05000051, 0xa00f0000, 0x3f800000, 0x3f000000, 0x00000000, 0x00000000, 0x0200001f, + 0x80000000, 0xb0030000, 0x0200001f, 0x90000000, 0xa00f0800, 0x0200001f, 0x90000000, 0xa00f0801, + 0x0200001f, 0x90000000, 0xa00f0802, 0x03000002, 0x80030000, 0xb0e40000, 0xa0e40006, 0x0300000b, + 0x80030001, 0x80e40000, 0xa0e40004, 0x0300000a, 0x80010000, 0xa0aa0004, 0x80000001, 0x0300000a, + 0x80020000, 0xa0ff0004, 0x80550001, 0x03000042, 0x800f0000, 0x80e40000, 0xa0e40800, 0x03000005, + 0x80010000, 0x80ff0000, 0xa0aa0006, 0x0300000a, 0x80010001, 0x80000000, 0xa0000000, 0x02000001, + 0x80020001, 0xa0550000, 0x0300000b, 0x80030000, 0xb0e40000, 0xa0e40005, 0x0300000a, 0x80010002, + 0xa0aa0005, 0x80000000, 0x0300000a, 0x80020002, 0xa0ff0005, 0x80550000, 0x03000042, 0x800f0000, + 0x80e40001, 0xa0e40802, 0x03000042, 0x800f0001, 0x80e40002, 0xa0e40801, 0x03000002, 0x80010001, + 0x81ff0001, 0xa0000000, 0x03000005, 0x800f0000, 0x80e40000, 0x80000001, 0x02000001, 0x800f0800, + 0x80e40000, 0x0000ffff, +}; + +static DWORD pshader_filter_4[89] = { + 0xffff0200, 0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x0200001f, + 0x80000000, 0xb0030000, 0x0200001f, 0x90000000, 0xa00f0800, 0x0200001f, 0x90000000, 0xa00f0801, + 0x03000002, 0x80030000, 0xb0e40000, 0xa0e40007, 0x0300000b, 0x80030001, 0x80e40000, 0xa0e40004, + 0x0300000a, 0x80010000, 0xa0aa0004, 0x80000001, 0x0300000a, 0x80020000, 0xa0ff0004, 0x80550001, + 0x0300000b, 0x800c0000, 0xb01b0000, 0xa01b0005, 0x0300000a, 0x80010001, 0xa0aa0005, 0x80ff0000, + 0x0300000a, 0x80020001, 0xa0ff0005, 0x80aa0000, 0x03000042, 0x800f0000, 0x80e40000, 0xa0e40800, + 0x03000042, 0x800f0001, 0x80e40001, 0xa0e40801, 0x03000002, 0x80010000, 0x81ff0000, 0xa0000000, + 0x03000005, 0x80010000, 0x80000000, 0xa0aa0007, 0x0300000a, 0x80080002, 0x80000000, 0xa0000000, + 0x03000005, 0x80070000, 0x80ff0002, 0xa0e40006, 0x02000001, 0x80080000, 0xa0ff0006, 0x04000004, + 0x80080000, 0x80ff0000, 0x81ff0002, 0xa0000000, 0x03000005, 0x80070002, 0x80ff0000, 0x80e40001, + 0x04000004, 0x80070001, 0x80e40000, 0x80ff0001, 0x80e40002, 0x02000001, 0x800f0800, 0x80e40001, + 0x0000ffff, +}; + +static DWORD pshader_filter_5[76] = { + 0xffff0200, 0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x0200001f, + 0x80000000, 0xb0030000, 0x0200001f, 0x90000000, 0xa00f0800, 0x0200001f, 0x90000000, 0xa00f0801, + 0x03000002, 0x80030000, 0xb0e40000, 0xa0e40007, 0x0300000b, 0x80030001, 0x80e40000, 0xa0e40004, + 0x0300000a, 0x80010000, 0xa0aa0004, 0x80000001, 0x0300000a, 0x80020000, 0xa0ff0004, 0x80550001, + 0x0300000b, 0x800c0000, 0xb01b0000, 0xa01b0005, 0x0300000a, 0x80010001, 0xa0aa0005, 0x80ff0000, + 0x0300000a, 0x80020001, 0xa0ff0005, 0x80aa0000, 0x03000042, 0x800f0000, 0x80e40000, 0xa0e40800, + 0x03000042, 0x800f0001, 0x80e40001, 0xa0e40801, 0x03000002, 0x80010000, 0x81ff0000, 0xa0000000, + 0x03000005, 0x80010000, 0x80000000, 0xa0aa0007, 0x0300000a, 0x80010001, 0x80000000, 0xa0000000, + 0x03000005, 0x800f0000, 0x80ff0001, 0xa0e40006, 0x03000005, 0x800f0000, 0x80000001, 0x80e40000, + 0x02000001, 0x800f0800, 0x80e40000, 0x0000ffff, +}; + +static DWORD pshader_filter_6[87] = { + 0xffff0200, 0x05000051, 0xa00f0000, 0x3f800000, 0x3f000000, 0x00000000, 0x00000000, 0x0200001f, + 0x80000000, 0xb0030000, 0x0200001f, 0x90000000, 0xa00f0800, 0x0200001f, 0x90000000, 0xa00f0801, + 0x0200001f, 0x90000000, 0xa00f0802, 0x03000002, 0x80030000, 0xb0e40000, 0xa0e40006, 0x0300000b, + 0x80030001, 0x80e40000, 0xa0e40004, 0x0300000a, 0x80010000, 0xa0aa0004, 0x80000001, 0x0300000a, + 0x80020000, 0xa0ff0004, 0x80550001, 0x03000042, 0x800f0000, 0x80e40000, 0xa0e40800, 0x03000005, + 0x80010000, 0x80ff0000, 0xa0aa0006, 0x0300000a, 0x80010001, 0x80000000, 0xa0000000, 0x02000001, + 0x80020001, 0xa0550000, 0x0300000b, 0x80030000, 0xb0e40000, 0xa0e40005, 0x0300000a, 0x80010002, + 0xa0aa0005, 0x80000000, 0x0300000a, 0x80020002, 0xa0ff0005, 0x80550000, 0x03000042, 0x800f0000, + 0x80e40001, 0xa0e40802, 0x03000042, 0x800f0001, 0x80e40002, 0xa0e40801, 0x03000002, 0x80080000, + 0x81ff0000, 0xa0000000, 0x03000005, 0x80070002, 0x80ff0000, 0x80e40001, 0x04000004, 0x80070001, + 0x80e40000, 0x80ff0001, 0x80e40002, 0x02000001, 0x800f0800, 0x80e40001, 0x0000ffff, +}; + +static DWORD pshader_filter_7[78] = { + 0xffff0200, 0x05000051, 0xa00f0000, 0x3f800000, 0x3f000000, 0x00000000, 0x00000000, 0x0200001f, + 0x80000000, 0xb0030000, 0x0200001f, 0x90000000, 0xa00f0800, 0x0200001f, 0x90000000, 0xa00f0801, + 0x0200001f, 0x90000000, 0xa00f0802, 0x03000002, 0x80030000, 0xb0e40000, 0xa0e40006, 0x0300000b, + 0x80030001, 0x80e40000, 0xa0e40004, 0x0300000a, 0x80010000, 0xa0aa0004, 0x80000001, 0x0300000a, + 0x80020000, 0xa0ff0004, 0x80550001, 0x03000042, 0x800f0000, 0x80e40000, 0xa0e40800, 0x03000005, + 0x80010000, 0x80ff0000, 0xa0aa0006, 0x0300000a, 0x80010001, 0x80000000, 0xa0000000, 0x02000001, + 0x80020001, 0xa0550000, 0x0300000b, 0x80030000, 0xb0e40000, 0xa0e40005, 0x0300000a, 0x80010002, + 0xa0aa0005, 0x80000000, 0x0300000a, 0x80020002, 0xa0ff0005, 0x80550000, 0x03000042, 0x800f0000, + 0x80e40001, 0xa0e40802, 0x03000042, 0x800f0001, 0x80e40002, 0xa0e40801, 0x03000005, 0x800f0000, + 0x80e40000, 0x80ff0001, 0x02000001, 0x800f0800, 0x80e40000, 0x0000ffff, +}; + +static DWORD pshader_filter_8[45] = { + 0xffff0200, 0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x0200001f, + 0x80000000, 0xb0030000, 0x0200001f, 0x90000000, 0xa00f0801, 0x0300000b, 0x80030000, 0xb0e40000, + 0xa0e40004, 0x0300000a, 0x80010001, 0xa0aa0004, 0x80000000, 0x0300000a, 0x80020001, 0xa0ff0004, + 0x80550000, 0x03000042, 0x800f0000, 0x80e40001, 0xa0e40801, 0x02000001, 0x80080001, 0xa0ff0005, + 0x03000002, 0x80010001, 0x81ff0001, 0xa0000000, 0x04000004, 0x800f0000, 0x80e40000, 0x80000001, + 0xa0e40005, 0x02000001, 0x800f0800, 0x80e40000, 0x0000ffff, +}; + +static DWORD pshader_filter_9[5] = { + 0xffff0200, 0x02000001, 0x800f0800, 0xa0e40004, 0x0000ffff, +}; + +static DWORD pshader_filter_10[83] = { + 0xffff0200, 0x05000051, 0xa00f0000, 0x3f800000, 0x3f000000, 0x00000000, 0x00000000, 0x0200001f, + 0x80000000, 0xb0030000, 0x0200001f, 0x90000000, 0xa00f0800, 0x0200001f, 0x90000000, 0xa00f0801, + 0x0200001f, 0x90000000, 0xa00f0802, 0x03000002, 0x80030000, 0xb0e40000, 0xa0e40006, 0x0300000b, + 0x80030001, 0x80e40000, 0xa0e40004, 0x0300000a, 0x80010000, 0xa0aa0004, 0x80000001, 0x0300000a, + 0x80020000, 0xa0ff0004, 0x80550001, 0x03000042, 0x800f0000, 0x80e40000, 0xa0e40800, 0x03000005, + 0x80010000, 0x80ff0000, 0xa0aa0006, 0x0300000a, 0x80010001, 0x80000000, 0xa0000000, 0x02000001, + 0x80020001, 0xa0550000, 0x0300000b, 0x80030000, 0xb0e40000, 0xa0e40005, 0x0300000a, 0x80010002, + 0xa0aa0005, 0x80000000, 0x0300000a, 0x80020002, 0xa0ff0005, 0x80550000, 0x03000042, 0x800f0000, + 0x80e40001, 0xa0e40802, 0x03000042, 0x800f0001, 0x80e40002, 0xa0e40801, 0x03000002, 0x80010002, + 0x81ff0000, 0xa0000000, 0x04000004, 0x800f0000, 0x80e40001, 0x80000002, 0x80e40000, 0x02000001, + 0x800f0800, 0x80e40000, 0x0000ffff, +}; + +static DWORD pshader_filter_11[55] = { + 0xffff0200, 0x05000051, 0xa00f0000, 0x3f800000, 0x3f000000, 0x00000000, 0x00000000, 0x0200001f, + 0x80000000, 0xb0030000, 0x0200001f, 0x90000000, 0xa00f0800, 0x0200001f, 0x90000000, 0xa00f0802, + 0x03000002, 0x80030000, 0xb0e40000, 0xa0e40005, 0x0300000b, 0x80030001, 0x80e40000, 0xa0e40004, + 0x0300000a, 0x80010000, 0xa0aa0004, 0x80000001, 0x0300000a, 0x80020000, 0xa0ff0004, 0x80550001, + 0x03000042, 0x800f0000, 0x80e40000, 0xa0e40800, 0x03000005, 0x80010000, 0x80ff0000, 0xa0aa0005, + 0x0300000a, 0x80010001, 0x80000000, 0xa0000000, 0x02000001, 0x80020001, 0xa0550000, 0x03000042, + 0x800f0000, 0x80e40001, 0xa0e40802, 0x02000001, 0x800f0800, 0x80e40000, 0x0000ffff, +}; + +static DWORD pshader_filter_16[108] = { + 0xffff0200, 0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x0200001f, + 0x80000000, 0xb0030000, 0x0200001f, 0x90000000, 0xa00f0800, 0x0200001f, 0x90000000, 0xa00f0801, + 0x03000002, 0x80030000, 0xb0e40000, 0xa0e40008, 0x0300000b, 0x80030001, 0x80e40000, 0xa0e40004, + 0x0300000a, 0x80010000, 0xa0aa0004, 0x80000001, 0x0300000a, 0x80020000, 0xa0ff0004, 0x80550001, + 0x03000002, 0x800c0000, 0xb01b0000, 0xa11b0008, 0x0300000b, 0x80030001, 0x801b0000, 0xa0e40004, + 0x0300000a, 0x80010002, 0xa0aa0004, 0x80000001, 0x0300000a, 0x80020002, 0xa0ff0004, 0x80550001, + 0x0300000b, 0x800c0000, 0xb01b0000, 0xa01b0005, 0x0300000a, 0x80010001, 0xa0aa0005, 0x80ff0000, + 0x0300000a, 0x80020001, 0xa0ff0005, 0x80aa0000, 0x03000042, 0x800f0000, 0x80e40000, 0xa0e40800, + 0x03000042, 0x800f0002, 0x80e40002, 0xa0e40800, 0x03000042, 0x800f0001, 0x80e40001, 0xa0e40801, + 0x03000002, 0x80010000, 0x81ff0000, 0x80ff0002, 0x03000005, 0x80010000, 0x80000000, 0xa0aa0008, + 0x02000001, 0x80120000, 0x80000000, 0x02000001, 0x80110000, 0x81000000, 0x03000005, 0x800f0002, + 0x80550000, 0xa0e40007, 0x04000004, 0x800f0000, 0x80000000, 0xa0e40006, 0x80e40002, 0x03000002, + 0x80010002, 0x81ff0001, 0xa0000000, 0x04000004, 0x800f0000, 0x80e40000, 0x80000002, 0x80e40001, + 0x02000001, 0x800f0800, 0x80e40000, 0x0000ffff, +}; + +static DWORD pshader_filter_17[107] = { + 0xffff0200, 0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x0200001f, + 0x80000000, 0xb0030000, 0x0200001f, 0x90000000, 0xa00f0800, 0x0200001f, 0x90000000, 0xa00f0801, + 0x03000002, 0x80030000, 0xb0e40000, 0xa0e40008, 0x0300000b, 0x80030001, 0x80e40000, 0xa0e40004, + 0x0300000a, 0x80010000, 0xa0aa0004, 0x80000001, 0x0300000a, 0x80020000, 0xa0ff0004, 0x80550001, + 0x03000002, 0x800c0000, 0xb01b0000, 0xa11b0008, 0x0300000b, 0x80030001, 0x801b0000, 0xa0e40004, + 0x0300000a, 0x80010002, 0xa0aa0004, 0x80000001, 0x0300000a, 0x80020002, 0xa0ff0004, 0x80550001, + 0x0300000b, 0x800c0000, 0xb01b0000, 0xa01b0005, 0x0300000a, 0x80010001, 0xa0aa0005, 0x80ff0000, + 0x0300000a, 0x80020001, 0xa0ff0005, 0x80aa0000, 0x03000042, 0x800f0000, 0x80e40000, 0xa0e40800, + 0x03000042, 0x800f0002, 0x80e40002, 0xa0e40800, 0x03000042, 0x800f0001, 0x80e40001, 0xa0e40801, + 0x03000002, 0x80010000, 0x81ff0000, 0x80ff0002, 0x03000005, 0x80010000, 0x80000000, 0xa0aa0008, + 0x02000001, 0x80120000, 0x80000000, 0x02000001, 0x80110000, 0x81000000, 0x03000005, 0x800f0002, + 0x80550000, 0xa0e40007, 0x04000004, 0x800f0000, 0x80000000, 0xa0e40006, 0x80e40002, 0x03000002, + 0x80010001, 0x81ff0001, 0xa0000000, 0x03000005, 0x800f0000, 0x80e40000, 0x80000001, 0x02000001, + 0x800f0800, 0x80e40000, 0x0000ffff, +}; + +static DWORD pshader_filter_18[108] = { + 0xffff0200, 0x05000051, 0xa00f0000, 0x3f000000, 0x3f800000, 0x00000000, 0x00000000, 0x0200001f, + 0x80000000, 0xb0030000, 0x0200001f, 0x90000000, 0xa00f0800, 0x0200001f, 0x90000000, 0xa00f0801, + 0x0200001f, 0x90000000, 0xa00f0802, 0x03000002, 0x80030000, 0xb0e40000, 0xa0e40006, 0x0300000b, + 0x80030001, 0x80e40000, 0xa0e40004, 0x0300000a, 0x80010000, 0xa0aa0004, 0x80000001, 0x0300000a, + 0x80020000, 0xa0ff0004, 0x80550001, 0x03000002, 0x800c0000, 0xb01b0000, 0xa11b0006, 0x0300000b, + 0x80030001, 0x801b0000, 0xa0e40004, 0x0300000a, 0x80010002, 0xa0aa0004, 0x80000001, 0x0300000a, + 0x80020002, 0xa0ff0004, 0x80550001, 0x03000042, 0x800f0000, 0x80e40000, 0xa0e40800, 0x03000042, + 0x800f0001, 0x80e40002, 0xa0e40800, 0x03000002, 0x80010000, 0x81ff0000, 0x80ff0001, 0x03000005, + 0x80010000, 0x80000000, 0xa0aa0006, 0x04000004, 0x80110000, 0x80000000, 0xa0000000, 0xa0000000, + 0x02000001, 0x80020000, 0xa0000000, 0x0300000b, 0x800c0000, 0xb01b0000, 0xa01b0005, 0x0300000a, + 0x80010001, 0xa0aa0005, 0x80ff0000, 0x0300000a, 0x80020001, 0xa0ff0005, 0x80aa0000, 0x03000042, + 0x800f0000, 0x80e40000, 0xa0e40802, 0x03000042, 0x800f0001, 0x80e40001, 0xa0e40801, 0x03000002, + 0x80010002, 0x81ff0001, 0xa0550000, 0x04000004, 0x800f0000, 0x80e40000, 0x80000002, 0x80e40001, + 0x02000001, 0x800f0800, 0x80e40000, 0x0000ffff, +}; + +static DWORD pshader_filter_19[107] = { + 0xffff0200, 0x05000051, 0xa00f0000, 0x3f000000, 0x3f800000, 0x00000000, 0x00000000, 0x0200001f, + 0x80000000, 0xb0030000, 0x0200001f, 0x90000000, 0xa00f0800, 0x0200001f, 0x90000000, 0xa00f0801, + 0x0200001f, 0x90000000, 0xa00f0802, 0x03000002, 0x80030000, 0xb0e40000, 0xa0e40006, 0x0300000b, + 0x80030001, 0x80e40000, 0xa0e40004, 0x0300000a, 0x80010000, 0xa0aa0004, 0x80000001, 0x0300000a, + 0x80020000, 0xa0ff0004, 0x80550001, 0x03000002, 0x800c0000, 0xb01b0000, 0xa11b0006, 0x0300000b, + 0x80030001, 0x801b0000, 0xa0e40004, 0x0300000a, 0x80010002, 0xa0aa0004, 0x80000001, 0x0300000a, + 0x80020002, 0xa0ff0004, 0x80550001, 0x03000042, 0x800f0000, 0x80e40000, 0xa0e40800, 0x03000042, + 0x800f0001, 0x80e40002, 0xa0e40800, 0x03000002, 0x80010000, 0x81ff0000, 0x80ff0001, 0x03000005, + 0x80010000, 0x80000000, 0xa0aa0006, 0x04000004, 0x80110000, 0x80000000, 0xa0000000, 0xa0000000, + 0x02000001, 0x80020000, 0xa0000000, 0x0300000b, 0x800c0000, 0xb01b0000, 0xa01b0005, 0x0300000a, + 0x80010001, 0xa0aa0005, 0x80ff0000, 0x0300000a, 0x80020001, 0xa0ff0005, 0x80aa0000, 0x03000042, + 0x800f0000, 0x80e40000, 0xa0e40802, 0x03000042, 0x800f0001, 0x80e40001, 0xa0e40801, 0x03000002, + 0x80010001, 0x81ff0001, 0xa0550000, 0x03000005, 0x800f0000, 0x80e40000, 0x80000001, 0x02000001, + 0x800f0800, 0x80e40000, 0x0000ffff, +}; + +static DWORD pshader_filter_20[112] = { + 0xffff0200, 0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x0200001f, + 0x80000000, 0xb0030000, 0x0200001f, 0x90000000, 0xa00f0800, 0x0200001f, 0x90000000, 0xa00f0801, + 0x03000002, 0x80030000, 0xb0e40000, 0xa0e40008, 0x0300000b, 0x80030001, 0x80e40000, 0xa0e40004, + 0x0300000a, 0x80010000, 0xa0aa0004, 0x80000001, 0x0300000a, 0x80020000, 0xa0ff0004, 0x80550001, + 0x03000002, 0x800c0000, 0xb01b0000, 0xa11b0008, 0x0300000b, 0x80030001, 0x801b0000, 0xa0e40004, + 0x0300000a, 0x80010002, 0xa0aa0004, 0x80000001, 0x0300000a, 0x80020002, 0xa0ff0004, 0x80550001, + 0x0300000b, 0x800c0000, 0xb01b0000, 0xa01b0005, 0x0300000a, 0x80010001, 0xa0aa0005, 0x80ff0000, + 0x0300000a, 0x80020001, 0xa0ff0005, 0x80aa0000, 0x03000042, 0x800f0000, 0x80e40000, 0xa0e40800, + 0x03000042, 0x800f0002, 0x80e40002, 0xa0e40800, 0x03000042, 0x800f0001, 0x80e40001, 0xa0e40801, + 0x03000002, 0x80010000, 0x81ff0000, 0x80ff0002, 0x03000005, 0x80010000, 0x80000000, 0xa0aa0008, + 0x02000001, 0x80120000, 0x80000000, 0x02000001, 0x80110000, 0x81000000, 0x03000005, 0x800f0002, + 0x80550000, 0xa0e40007, 0x04000004, 0x800f0000, 0x80000000, 0xa0e40006, 0x80e40002, 0x03000002, + 0x80080000, 0x81ff0000, 0xa0000000, 0x03000005, 0x80070002, 0x80ff0000, 0x80e40001, 0x04000004, + 0x80070001, 0x80e40000, 0x80ff0001, 0x80e40002, 0x02000001, 0x800f0800, 0x80e40001, 0x0000ffff, +}; + +static DWORD pshader_filter_21[97] = { + 0xffff0200, 0x0200001f, 0x80000000, 0xb0030000, 0x0200001f, 0x90000000, 0xa00f0800, 0x0200001f, + 0x90000000, 0xa00f0801, 0x03000002, 0x80030000, 0xb0e40000, 0xa0e40008, 0x0300000b, 0x80030001, + 0x80e40000, 0xa0e40004, 0x0300000a, 0x80010000, 0xa0aa0004, 0x80000001, 0x0300000a, 0x80020000, + 0xa0ff0004, 0x80550001, 0x03000002, 0x800c0000, 0xb01b0000, 0xa11b0008, 0x0300000b, 0x80030001, + 0x801b0000, 0xa0e40004, 0x0300000a, 0x80010002, 0xa0aa0004, 0x80000001, 0x0300000a, 0x80020002, + 0xa0ff0004, 0x80550001, 0x0300000b, 0x800c0000, 0xb01b0000, 0xa01b0005, 0x0300000a, 0x80010001, + 0xa0aa0005, 0x80ff0000, 0x0300000a, 0x80020001, 0xa0ff0005, 0x80aa0000, 0x03000042, 0x800f0000, + 0x80e40000, 0xa0e40800, 0x03000042, 0x800f0002, 0x80e40002, 0xa0e40800, 0x03000042, 0x800f0001, + 0x80e40001, 0xa0e40801, 0x03000002, 0x80010000, 0x81ff0000, 0x80ff0002, 0x03000005, 0x80010000, + 0x80000000, 0xa0aa0008, 0x02000001, 0x80120000, 0x80000000, 0x02000001, 0x80110000, 0x81000000, + 0x03000005, 0x800f0002, 0x80550000, 0xa0e40007, 0x04000004, 0x800f0000, 0x80000000, 0xa0e40006, + 0x80e40002, 0x03000005, 0x800f0000, 0x80ff0001, 0x80e40000, 0x02000001, 0x800f0800, 0x80e40000, + 0x0000ffff, +}; + +static DWORD pshader_filter_22[112] = { + 0xffff0200, 0x05000051, 0xa00f0000, 0x3f000000, 0x3f800000, 0x00000000, 0x00000000, 0x0200001f, + 0x80000000, 0xb0030000, 0x0200001f, 0x90000000, 0xa00f0800, 0x0200001f, 0x90000000, 0xa00f0801, + 0x0200001f, 0x90000000, 0xa00f0802, 0x03000002, 0x80030000, 0xb0e40000, 0xa0e40006, 0x0300000b, + 0x80030001, 0x80e40000, 0xa0e40004, 0x0300000a, 0x80010000, 0xa0aa0004, 0x80000001, 0x0300000a, + 0x80020000, 0xa0ff0004, 0x80550001, 0x03000002, 0x800c0000, 0xb01b0000, 0xa11b0006, 0x0300000b, + 0x80030001, 0x801b0000, 0xa0e40004, 0x0300000a, 0x80010002, 0xa0aa0004, 0x80000001, 0x0300000a, + 0x80020002, 0xa0ff0004, 0x80550001, 0x03000042, 0x800f0000, 0x80e40000, 0xa0e40800, 0x03000042, + 0x800f0001, 0x80e40002, 0xa0e40800, 0x03000002, 0x80010000, 0x81ff0000, 0x80ff0001, 0x03000005, + 0x80010000, 0x80000000, 0xa0aa0006, 0x04000004, 0x80110000, 0x80000000, 0xa0000000, 0xa0000000, + 0x02000001, 0x80020000, 0xa0000000, 0x0300000b, 0x800c0000, 0xb01b0000, 0xa01b0005, 0x0300000a, + 0x80010001, 0xa0aa0005, 0x80ff0000, 0x0300000a, 0x80020001, 0xa0ff0005, 0x80aa0000, 0x03000042, + 0x800f0000, 0x80e40000, 0xa0e40802, 0x03000042, 0x800f0001, 0x80e40001, 0xa0e40801, 0x03000002, + 0x80080000, 0x81ff0000, 0xa0550000, 0x03000005, 0x80070002, 0x80ff0000, 0x80e40001, 0x04000004, + 0x80070001, 0x80e40000, 0x80ff0001, 0x80e40002, 0x02000001, 0x800f0800, 0x80e40001, 0x0000ffff, +}; + +static DWORD pshader_filter_23[103] = { + 0xffff0200, 0x05000051, 0xa00f0000, 0x3f000000, 0x00000000, 0x00000000, 0x00000000, 0x0200001f, + 0x80000000, 0xb0030000, 0x0200001f, 0x90000000, 0xa00f0800, 0x0200001f, 0x90000000, 0xa00f0801, + 0x0200001f, 0x90000000, 0xa00f0802, 0x03000002, 0x80030000, 0xb0e40000, 0xa0e40006, 0x0300000b, + 0x80030001, 0x80e40000, 0xa0e40004, 0x0300000a, 0x80010000, 0xa0aa0004, 0x80000001, 0x0300000a, + 0x80020000, 0xa0ff0004, 0x80550001, 0x03000002, 0x800c0000, 0xb01b0000, 0xa11b0006, 0x0300000b, + 0x80030001, 0x801b0000, 0xa0e40004, 0x0300000a, 0x80010002, 0xa0aa0004, 0x80000001, 0x0300000a, + 0x80020002, 0xa0ff0004, 0x80550001, 0x03000042, 0x800f0000, 0x80e40000, 0xa0e40800, 0x03000042, + 0x800f0001, 0x80e40002, 0xa0e40800, 0x03000002, 0x80010000, 0x81ff0000, 0x80ff0001, 0x03000005, + 0x80010000, 0x80000000, 0xa0aa0006, 0x04000004, 0x80110000, 0x80000000, 0xa0000000, 0xa0000000, + 0x02000001, 0x80020000, 0xa0000000, 0x0300000b, 0x800c0000, 0xb01b0000, 0xa01b0005, 0x0300000a, + 0x80010001, 0xa0aa0005, 0x80ff0000, 0x0300000a, 0x80020001, 0xa0ff0005, 0x80aa0000, 0x03000042, + 0x800f0000, 0x80e40000, 0xa0e40802, 0x03000042, 0x800f0001, 0x80e40001, 0xa0e40801, 0x03000005, + 0x800f0000, 0x80e40000, 0x80ff0001, 0x02000001, 0x800f0800, 0x80e40000, 0x0000ffff, +}; + +static DWORD pshader_filter_24[108] = { + 0xffff0200, 0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x0200001f, + 0x80000000, 0xb0030000, 0x0200001f, 0x90000000, 0xa00f0800, 0x0200001f, 0x90000000, 0xa00f0801, + 0x03000002, 0x80030000, 0xb0e40000, 0xa0e40008, 0x0300000b, 0x80030001, 0x80e40000, 0xa0e40004, + 0x0300000a, 0x80010000, 0xa0aa0004, 0x80000001, 0x0300000a, 0x80020000, 0xa0ff0004, 0x80550001, + 0x03000002, 0x800c0000, 0xb01b0000, 0xa11b0008, 0x0300000b, 0x80030001, 0x801b0000, 0xa0e40004, + 0x0300000a, 0x80010002, 0xa0aa0004, 0x80000001, 0x0300000a, 0x80020002, 0xa0ff0004, 0x80550001, + 0x0300000b, 0x800c0000, 0xb01b0000, 0xa01b0005, 0x0300000a, 0x80010001, 0xa0aa0005, 0x80ff0000, + 0x0300000a, 0x80020001, 0xa0ff0005, 0x80aa0000, 0x03000042, 0x800f0000, 0x80e40000, 0xa0e40800, + 0x03000042, 0x800f0002, 0x80e40002, 0xa0e40800, 0x03000042, 0x800f0001, 0x80e40001, 0xa0e40801, + 0x03000002, 0x80010000, 0x81ff0000, 0x80ff0002, 0x03000005, 0x80010000, 0x80000000, 0xa0aa0008, + 0x02000001, 0x80120000, 0x80000000, 0x02000001, 0x80110000, 0x81000000, 0x03000005, 0x800f0002, + 0x80550000, 0xa0e40007, 0x04000004, 0x800f0000, 0x80000000, 0xa0e40006, 0x80e40002, 0x03000002, + 0x80010002, 0x81ff0000, 0xa0000000, 0x04000004, 0x800f0000, 0x80e40001, 0x80000002, 0x80e40000, + 0x02000001, 0x800f0800, 0x80e40000, 0x0000ffff, +}; + +static DWORD pshader_filter_25[74] = { + 0xffff0200, 0x0200001f, 0x80000000, 0xb0030000, 0x0200001f, 0x90000000, 0xa00f0800, 0x03000002, + 0x80030000, 0xb0e40000, 0xa0e40007, 0x0300000b, 0x80030001, 0x80e40000, 0xa0e40004, 0x0300000a, + 0x80010000, 0xa0aa0004, 0x80000001, 0x0300000a, 0x80020000, 0xa0ff0004, 0x80550001, 0x03000002, + 0x800c0000, 0xb01b0000, 0xa11b0007, 0x0300000b, 0x80030001, 0x801b0000, 0xa0e40004, 0x0300000a, + 0x80010002, 0xa0aa0004, 0x80000001, 0x0300000a, 0x80020002, 0xa0ff0004, 0x80550001, 0x03000042, + 0x800f0000, 0x80e40000, 0xa0e40800, 0x03000042, 0x800f0001, 0x80e40002, 0xa0e40800, 0x03000002, + 0x80010000, 0x81ff0000, 0x80ff0001, 0x03000005, 0x80010000, 0x80000000, 0xa0aa0007, 0x02000001, + 0x80120000, 0x80000000, 0x02000001, 0x80110000, 0x81000000, 0x03000005, 0x800f0001, 0x80550000, + 0xa0e40006, 0x04000004, 0x800f0000, 0x80000000, 0xa0e40005, 0x80e40001, 0x02000001, 0x800f0800, + 0x80e40000, 0x0000ffff, +}; + +static DWORD pshader_filter_26[108] = { + 0xffff0200, 0x05000051, 0xa00f0000, 0x3f000000, 0x3f800000, 0x00000000, 0x00000000, 0x0200001f, + 0x80000000, 0xb0030000, 0x0200001f, 0x90000000, 0xa00f0800, 0x0200001f, 0x90000000, 0xa00f0801, + 0x0200001f, 0x90000000, 0xa00f0802, 0x03000002, 0x80030000, 0xb0e40000, 0xa0e40006, 0x0300000b, + 0x80030001, 0x80e40000, 0xa0e40004, 0x0300000a, 0x80010000, 0xa0aa0004, 0x80000001, 0x0300000a, + 0x80020000, 0xa0ff0004, 0x80550001, 0x03000002, 0x800c0000, 0xb01b0000, 0xa11b0006, 0x0300000b, + 0x80030001, 0x801b0000, 0xa0e40004, 0x0300000a, 0x80010002, 0xa0aa0004, 0x80000001, 0x0300000a, + 0x80020002, 0xa0ff0004, 0x80550001, 0x03000042, 0x800f0000, 0x80e40000, 0xa0e40800, 0x03000042, + 0x800f0001, 0x80e40002, 0xa0e40800, 0x03000002, 0x80010000, 0x81ff0000, 0x80ff0001, 0x03000005, + 0x80010000, 0x80000000, 0xa0aa0006, 0x04000004, 0x80110000, 0x80000000, 0xa0000000, 0xa0000000, + 0x02000001, 0x80020000, 0xa0000000, 0x0300000b, 0x800c0000, 0xb01b0000, 0xa01b0005, 0x0300000a, + 0x80010001, 0xa0aa0005, 0x80ff0000, 0x0300000a, 0x80020001, 0xa0ff0005, 0x80aa0000, 0x03000042, + 0x800f0000, 0x80e40000, 0xa0e40802, 0x03000042, 0x800f0001, 0x80e40001, 0xa0e40801, 0x03000002, + 0x80010002, 0x81ff0000, 0xa0550000, 0x04000004, 0x800f0000, 0x80e40001, 0x80000002, 0x80e40000, + 0x02000001, 0x800f0800, 0x80e40000, 0x0000ffff, +}; + +static DWORD pshader_filter_27[80] = { + 0xffff0200, 0x05000051, 0xa00f0000, 0x3f000000, 0x00000000, 0x00000000, 0x00000000, 0x0200001f, + 0x80000000, 0xb0030000, 0x0200001f, 0x90000000, 0xa00f0800, 0x0200001f, 0x90000000, 0xa00f0802, + 0x03000002, 0x80030000, 0xb0e40000, 0xa0e40005, 0x0300000b, 0x80030001, 0x80e40000, 0xa0e40004, + 0x0300000a, 0x80010000, 0xa0aa0004, 0x80000001, 0x0300000a, 0x80020000, 0xa0ff0004, 0x80550001, + 0x03000002, 0x800c0000, 0xb01b0000, 0xa11b0005, 0x0300000b, 0x80030001, 0x801b0000, 0xa0e40004, + 0x0300000a, 0x80010002, 0xa0aa0004, 0x80000001, 0x0300000a, 0x80020002, 0xa0ff0004, 0x80550001, + 0x03000042, 0x800f0000, 0x80e40000, 0xa0e40800, 0x03000042, 0x800f0001, 0x80e40002, 0xa0e40800, + 0x03000002, 0x80010000, 0x81ff0000, 0x80ff0001, 0x03000005, 0x80010000, 0x80000000, 0xa0aa0005, + 0x04000004, 0x80110000, 0x80000000, 0xa0000000, 0xa0000000, 0x02000001, 0x80020000, 0xa0000000, + 0x03000042, 0x800f0000, 0x80e40000, 0xa0e40802, 0x02000001, 0x800f0800, 0x80e40000, 0x0000ffff, +}; + +static ProgramWithCachedVariableLocations pshader_filter_arr[32] = { + { pshader_filter_0, NULL, { 0, 1, 6, 7, -1, 4, 5, -1, } }, + { pshader_filter_1, NULL, { 0, 1, 6, 7, -1, 4, 5, -1, } }, + { pshader_filter_2, NULL, { 0, 1, -1, 6, 2, 4, 5, -1, } }, + { pshader_filter_3, NULL, { 0, 1, -1, 6, 2, 4, 5, -1, } }, + { pshader_filter_4, NULL, { 0, 1, 6, 7, -1, 4, 5, -1, } }, + { pshader_filter_5, NULL, { 0, 1, 6, 7, -1, 4, 5, -1, } }, + { pshader_filter_6, NULL, { 0, 1, -1, 6, 2, 4, 5, -1, } }, + { pshader_filter_7, NULL, { 0, 1, -1, 6, 2, 4, 5, -1, } }, + { pshader_filter_8, NULL, { -1, 1, 5, -1, -1, -1, 4, -1, } }, + { pshader_filter_9, NULL, { -1, -1, 4, -1, -1, -1, -1, -1, } }, + { pshader_filter_10, NULL, { 0, 1, -1, 6, 2, 4, 5, -1, } }, + { pshader_filter_11, NULL, { 0, -1, -1, 5, 2, 4, -1, -1, } }, + { NULL, NULL, { -1, -1, -1, -1, -1, -1, -1, -1, } }, + { NULL, NULL, { -1, -1, -1, -1, -1, -1, -1, -1, } }, + { NULL, NULL, { -1, -1, -1, -1, -1, -1, -1, -1, } }, + { NULL, NULL, { -1, -1, -1, -1, -1, -1, -1, -1, } }, + { pshader_filter_16, NULL, { 0, 1, 6, 8, -1, 4, 5, 7, } }, + { pshader_filter_17, NULL, { 0, 1, 6, 8, -1, 4, 5, 7, } }, + { pshader_filter_18, NULL, { 0, 1, -1, 6, 2, 4, 5, -1, } }, + { pshader_filter_19, NULL, { 0, 1, -1, 6, 2, 4, 5, -1, } }, + { pshader_filter_20, NULL, { 0, 1, 6, 8, -1, 4, 5, 7, } }, + { pshader_filter_21, NULL, { 0, 1, 6, 8, -1, 4, 5, 7, } }, + { pshader_filter_22, NULL, { 0, 1, -1, 6, 2, 4, 5, -1, } }, + { pshader_filter_23, NULL, { 0, 1, -1, 6, 2, 4, 5, -1, } }, + { pshader_filter_24, NULL, { 0, 1, 6, 8, -1, 4, 5, 7, } }, + { pshader_filter_25, NULL, { 0, -1, 5, 7, -1, 4, -1, 6, } }, + { pshader_filter_26, NULL, { 0, 1, -1, 6, 2, 4, 5, -1, } }, + { pshader_filter_27, NULL, { 0, -1, -1, 5, 2, 4, -1, -1, } }, + { NULL, NULL, { -1, -1, -1, -1, -1, -1, -1, -1, } }, + { NULL, NULL, { -1, -1, -1, -1, -1, -1, -1, -1, } }, + { NULL, NULL, { -1, -1, -1, -1, -1, -1, -1, -1, } }, + { NULL, NULL, { -1, -1, -1, -1, -1, -1, -1, -1, } }, +}; + +static DWORD pshader_blur_2[60] = { + 0xffff0200, 0x0200001f, 0x80000000, 0xb0030000, 0x0200001f, 0x90000000, 0xa00f0800, 0x03000002, + 0x80030000, 0xb0e40000, 0xa0e40005, 0x0300000b, 0x80030001, 0x80e40000, 0xa0e40006, 0x0300000a, + 0x80010000, 0xa0aa0006, 0x80000001, 0x0300000a, 0x80020000, 0xa0ff0006, 0x80550001, 0x03000002, + 0x800c0000, 0xb01b0000, 0xa01b0004, 0x0300000b, 0x80030001, 0x801b0000, 0xa0e40006, 0x0300000a, + 0x80010002, 0xa0aa0006, 0x80000001, 0x0300000a, 0x80020002, 0xa0ff0006, 0x80550001, 0x03000042, + 0x800f0000, 0x80e40000, 0xa0e40800, 0x03000042, 0x800f0001, 0x80e40002, 0xa0e40800, 0x03000005, + 0x800f0000, 0x80e40000, 0xa0aa0005, 0x04000004, 0x800f0000, 0x80e40001, 0xa0aa0004, 0x80e40000, + 0x02000001, 0x800f0800, 0x80e40000, 0x0000ffff, +}; + +static DWORD pshader_blur_3[85] = { + 0xffff0200, 0x0200001f, 0x80000000, 0xb0030000, 0x0200001f, 0x90000000, 0xa00f0800, 0x03000002, + 0x80030000, 0xb0e40000, 0xa0e40005, 0x0300000b, 0x80030001, 0x80e40000, 0xa0e40007, 0x0300000a, + 0x80010000, 0xa0aa0007, 0x80000001, 0x0300000a, 0x80020000, 0xa0ff0007, 0x80550001, 0x03000002, + 0x800c0000, 0xb01b0000, 0xa01b0004, 0x0300000b, 0x80030001, 0x801b0000, 0xa0e40007, 0x0300000a, + 0x80010002, 0xa0aa0007, 0x80000001, 0x0300000a, 0x80020002, 0xa0ff0007, 0x80550001, 0x03000002, + 0x800c0000, 0xb01b0000, 0xa01b0006, 0x0300000b, 0x80030001, 0x801b0000, 0xa0e40007, 0x0300000a, + 0x80010003, 0xa0aa0007, 0x80000001, 0x0300000a, 0x80020003, 0xa0ff0007, 0x80550001, 0x03000042, + 0x800f0000, 0x80e40000, 0xa0e40800, 0x03000042, 0x800f0001, 0x80e40002, 0xa0e40800, 0x03000042, + 0x800f0002, 0x80e40003, 0xa0e40800, 0x03000005, 0x800f0000, 0x80e40000, 0xa0aa0005, 0x04000004, + 0x800f0000, 0x80e40001, 0xa0aa0004, 0x80e40000, 0x04000004, 0x800f0000, 0x80e40002, 0xa0aa0006, + 0x80e40000, 0x02000001, 0x800f0800, 0x80e40000, 0x0000ffff, +}; + +static DWORD pshader_blur_4[110] = { + 0xffff0200, 0x0200001f, 0x80000000, 0xb0030000, 0x0200001f, 0x90000000, 0xa00f0800, 0x03000002, + 0x80030000, 0xb0e40000, 0xa0e40005, 0x0300000b, 0x80030001, 0x80e40000, 0xa0e40008, 0x0300000a, + 0x80010000, 0xa0aa0008, 0x80000001, 0x0300000a, 0x80020000, 0xa0ff0008, 0x80550001, 0x03000002, + 0x800c0000, 0xb01b0000, 0xa01b0004, 0x0300000b, 0x80030001, 0x801b0000, 0xa0e40008, 0x0300000a, + 0x80010002, 0xa0aa0008, 0x80000001, 0x0300000a, 0x80020002, 0xa0ff0008, 0x80550001, 0x03000002, + 0x800c0000, 0xb01b0000, 0xa01b0006, 0x0300000b, 0x80030001, 0x801b0000, 0xa0e40008, 0x0300000a, + 0x80010003, 0xa0aa0008, 0x80000001, 0x0300000a, 0x80020003, 0xa0ff0008, 0x80550001, 0x03000002, + 0x800c0000, 0xb01b0000, 0xa01b0007, 0x0300000b, 0x80030001, 0x801b0000, 0xa0e40008, 0x0300000a, + 0x80010004, 0xa0aa0008, 0x80000001, 0x0300000a, 0x80020004, 0xa0ff0008, 0x80550001, 0x03000042, + 0x800f0000, 0x80e40000, 0xa0e40800, 0x03000042, 0x800f0001, 0x80e40002, 0xa0e40800, 0x03000042, + 0x800f0002, 0x80e40003, 0xa0e40800, 0x03000042, 0x800f0003, 0x80e40004, 0xa0e40800, 0x03000005, + 0x800f0000, 0x80e40000, 0xa0aa0005, 0x04000004, 0x800f0000, 0x80e40001, 0xa0aa0004, 0x80e40000, + 0x04000004, 0x800f0000, 0x80e40002, 0xa0aa0006, 0x80e40000, 0x04000004, 0x800f0000, 0x80e40003, + 0xa0aa0007, 0x80e40000, 0x02000001, 0x800f0800, 0x80e40000, 0x0000ffff, +}; + +static DWORD pshader_blur_5[135] = { + 0xffff0200, 0x0200001f, 0x80000000, 0xb0030000, 0x0200001f, 0x90000000, 0xa00f0800, 0x03000002, + 0x80030000, 0xb0e40000, 0xa0e40005, 0x0300000b, 0x80030001, 0x80e40000, 0xa0e40009, 0x0300000a, + 0x80010000, 0xa0aa0009, 0x80000001, 0x0300000a, 0x80020000, 0xa0ff0009, 0x80550001, 0x03000002, + 0x800c0000, 0xb01b0000, 0xa01b0004, 0x0300000b, 0x80030001, 0x801b0000, 0xa0e40009, 0x0300000a, + 0x80010002, 0xa0aa0009, 0x80000001, 0x0300000a, 0x80020002, 0xa0ff0009, 0x80550001, 0x03000002, + 0x800c0000, 0xb01b0000, 0xa01b0006, 0x0300000b, 0x80030001, 0x801b0000, 0xa0e40009, 0x0300000a, + 0x80010003, 0xa0aa0009, 0x80000001, 0x0300000a, 0x80020003, 0xa0ff0009, 0x80550001, 0x03000002, + 0x800c0000, 0xb01b0000, 0xa01b0007, 0x0300000b, 0x80030001, 0x801b0000, 0xa0e40009, 0x0300000a, + 0x80010004, 0xa0aa0009, 0x80000001, 0x0300000a, 0x80020004, 0xa0ff0009, 0x80550001, 0x03000002, + 0x800c0000, 0xb01b0000, 0xa01b0008, 0x0300000b, 0x80030001, 0x801b0000, 0xa0e40009, 0x0300000a, + 0x80010005, 0xa0aa0009, 0x80000001, 0x0300000a, 0x80020005, 0xa0ff0009, 0x80550001, 0x03000042, + 0x800f0000, 0x80e40000, 0xa0e40800, 0x03000042, 0x800f0001, 0x80e40002, 0xa0e40800, 0x03000042, + 0x800f0002, 0x80e40003, 0xa0e40800, 0x03000042, 0x800f0003, 0x80e40004, 0xa0e40800, 0x03000042, + 0x800f0004, 0x80e40005, 0xa0e40800, 0x03000005, 0x800f0000, 0x80e40000, 0xa0aa0005, 0x04000004, + 0x800f0000, 0x80e40001, 0xa0aa0004, 0x80e40000, 0x04000004, 0x800f0000, 0x80e40002, 0xa0aa0006, + 0x80e40000, 0x04000004, 0x800f0000, 0x80e40003, 0xa0aa0007, 0x80e40000, 0x04000004, 0x800f0000, + 0x80e40004, 0xa0aa0008, 0x80e40000, 0x02000001, 0x800f0800, 0x80e40000, 0x0000ffff, +}; + +static DWORD pshader_blur_6[160] = { + 0xffff0200, 0x0200001f, 0x80000000, 0xb0030000, 0x0200001f, 0x90000000, 0xa00f0800, 0x03000002, + 0x80030000, 0xb0e40000, 0xa0e40005, 0x0300000b, 0x80030001, 0x80e40000, 0xa0e4000a, 0x0300000a, + 0x80010000, 0xa0aa000a, 0x80000001, 0x0300000a, 0x80020000, 0xa0ff000a, 0x80550001, 0x03000002, + 0x800c0000, 0xb01b0000, 0xa01b0004, 0x0300000b, 0x80030001, 0x801b0000, 0xa0e4000a, 0x0300000a, + 0x80010002, 0xa0aa000a, 0x80000001, 0x0300000a, 0x80020002, 0xa0ff000a, 0x80550001, 0x03000002, + 0x800c0000, 0xb01b0000, 0xa01b0006, 0x0300000b, 0x80030001, 0x801b0000, 0xa0e4000a, 0x0300000a, + 0x80010003, 0xa0aa000a, 0x80000001, 0x0300000a, 0x80020003, 0xa0ff000a, 0x80550001, 0x03000002, + 0x800c0000, 0xb01b0000, 0xa01b0007, 0x0300000b, 0x80030001, 0x801b0000, 0xa0e4000a, 0x0300000a, + 0x80010004, 0xa0aa000a, 0x80000001, 0x0300000a, 0x80020004, 0xa0ff000a, 0x80550001, 0x03000002, + 0x800c0000, 0xb01b0000, 0xa01b0008, 0x0300000b, 0x80030001, 0x801b0000, 0xa0e4000a, 0x0300000a, + 0x80010005, 0xa0aa000a, 0x80000001, 0x0300000a, 0x80020005, 0xa0ff000a, 0x80550001, 0x03000002, + 0x800c0000, 0xb01b0000, 0xa01b0009, 0x0300000b, 0x80030001, 0x801b0000, 0xa0e4000a, 0x0300000a, + 0x80010006, 0xa0aa000a, 0x80000001, 0x0300000a, 0x80020006, 0xa0ff000a, 0x80550001, 0x03000042, + 0x800f0000, 0x80e40000, 0xa0e40800, 0x03000042, 0x800f0001, 0x80e40002, 0xa0e40800, 0x03000042, + 0x800f0002, 0x80e40003, 0xa0e40800, 0x03000042, 0x800f0003, 0x80e40004, 0xa0e40800, 0x03000042, + 0x800f0004, 0x80e40005, 0xa0e40800, 0x03000042, 0x800f0005, 0x80e40006, 0xa0e40800, 0x03000005, + 0x800f0000, 0x80e40000, 0xa0aa0005, 0x04000004, 0x800f0000, 0x80e40001, 0xa0aa0004, 0x80e40000, + 0x04000004, 0x800f0000, 0x80e40002, 0xa0aa0006, 0x80e40000, 0x04000004, 0x800f0000, 0x80e40003, + 0xa0aa0007, 0x80e40000, 0x04000004, 0x800f0000, 0x80e40004, 0xa0aa0008, 0x80e40000, 0x04000004, + 0x800f0000, 0x80e40005, 0xa0aa0009, 0x80e40000, 0x02000001, 0x800f0800, 0x80e40000, 0x0000ffff, +}; + +static DWORD pshader_blur_7[185] = { + 0xffff0200, 0x0200001f, 0x80000000, 0xb0030000, 0x0200001f, 0x90000000, 0xa00f0800, 0x03000002, + 0x80030000, 0xb0e40000, 0xa0e40005, 0x0300000b, 0x80030001, 0x80e40000, 0xa0e4000b, 0x0300000a, + 0x80010000, 0xa0aa000b, 0x80000001, 0x0300000a, 0x80020000, 0xa0ff000b, 0x80550001, 0x03000002, + 0x800c0000, 0xb01b0000, 0xa01b0004, 0x0300000b, 0x80030001, 0x801b0000, 0xa0e4000b, 0x0300000a, + 0x80010002, 0xa0aa000b, 0x80000001, 0x0300000a, 0x80020002, 0xa0ff000b, 0x80550001, 0x03000002, + 0x800c0000, 0xb01b0000, 0xa01b0006, 0x0300000b, 0x80030001, 0x801b0000, 0xa0e4000b, 0x0300000a, + 0x80010003, 0xa0aa000b, 0x80000001, 0x0300000a, 0x80020003, 0xa0ff000b, 0x80550001, 0x03000002, + 0x800c0000, 0xb01b0000, 0xa01b0007, 0x0300000b, 0x80030001, 0x801b0000, 0xa0e4000b, 0x0300000a, + 0x80010004, 0xa0aa000b, 0x80000001, 0x0300000a, 0x80020004, 0xa0ff000b, 0x80550001, 0x03000002, + 0x800c0000, 0xb01b0000, 0xa01b0008, 0x0300000b, 0x80030001, 0x801b0000, 0xa0e4000b, 0x0300000a, + 0x80010005, 0xa0aa000b, 0x80000001, 0x0300000a, 0x80020005, 0xa0ff000b, 0x80550001, 0x03000002, + 0x800c0000, 0xb01b0000, 0xa01b0009, 0x0300000b, 0x80030001, 0x801b0000, 0xa0e4000b, 0x0300000a, + 0x80010006, 0xa0aa000b, 0x80000001, 0x0300000a, 0x80020006, 0xa0ff000b, 0x80550001, 0x03000002, + 0x800c0000, 0xb01b0000, 0xa01b000a, 0x0300000b, 0x80030001, 0x801b0000, 0xa0e4000b, 0x0300000a, + 0x80010007, 0xa0aa000b, 0x80000001, 0x0300000a, 0x80020007, 0xa0ff000b, 0x80550001, 0x03000042, + 0x800f0000, 0x80e40000, 0xa0e40800, 0x03000042, 0x800f0001, 0x80e40002, 0xa0e40800, 0x03000042, + 0x800f0002, 0x80e40003, 0xa0e40800, 0x03000042, 0x800f0003, 0x80e40004, 0xa0e40800, 0x03000042, + 0x800f0004, 0x80e40005, 0xa0e40800, 0x03000042, 0x800f0005, 0x80e40006, 0xa0e40800, 0x03000042, + 0x800f0006, 0x80e40007, 0xa0e40800, 0x03000005, 0x800f0000, 0x80e40000, 0xa0aa0005, 0x04000004, + 0x800f0000, 0x80e40001, 0xa0aa0004, 0x80e40000, 0x04000004, 0x800f0000, 0x80e40002, 0xa0aa0006, + 0x80e40000, 0x04000004, 0x800f0000, 0x80e40003, 0xa0aa0007, 0x80e40000, 0x04000004, 0x800f0000, + 0x80e40004, 0xa0aa0008, 0x80e40000, 0x04000004, 0x800f0000, 0x80e40005, 0xa0aa0009, 0x80e40000, + 0x04000004, 0x800f0000, 0x80e40006, 0xa0aa000a, 0x80e40000, 0x02000001, 0x800f0800, 0x80e40000, + 0x0000ffff, +}; + +static DWORD pshader_blur_8[210] = { + 0xffff0200, 0x0200001f, 0x80000000, 0xb0030000, 0x0200001f, 0x90000000, 0xa00f0800, 0x03000002, + 0x80030000, 0xb0e40000, 0xa0e40005, 0x0300000b, 0x80030001, 0x80e40000, 0xa0e4000c, 0x0300000a, + 0x80010000, 0xa0aa000c, 0x80000001, 0x0300000a, 0x80020000, 0xa0ff000c, 0x80550001, 0x03000002, + 0x800c0000, 0xb01b0000, 0xa01b0004, 0x0300000b, 0x80030001, 0x801b0000, 0xa0e4000c, 0x0300000a, + 0x80010002, 0xa0aa000c, 0x80000001, 0x0300000a, 0x80020002, 0xa0ff000c, 0x80550001, 0x03000002, + 0x800c0000, 0xb01b0000, 0xa01b0006, 0x0300000b, 0x80030001, 0x801b0000, 0xa0e4000c, 0x0300000a, + 0x80010003, 0xa0aa000c, 0x80000001, 0x0300000a, 0x80020003, 0xa0ff000c, 0x80550001, 0x03000002, + 0x800c0000, 0xb01b0000, 0xa01b0007, 0x0300000b, 0x80030001, 0x801b0000, 0xa0e4000c, 0x0300000a, + 0x80010004, 0xa0aa000c, 0x80000001, 0x0300000a, 0x80020004, 0xa0ff000c, 0x80550001, 0x03000002, + 0x800c0000, 0xb01b0000, 0xa01b0008, 0x0300000b, 0x80030001, 0x801b0000, 0xa0e4000c, 0x0300000a, + 0x80010005, 0xa0aa000c, 0x80000001, 0x0300000a, 0x80020005, 0xa0ff000c, 0x80550001, 0x03000002, + 0x800c0000, 0xb01b0000, 0xa01b0009, 0x0300000b, 0x80030001, 0x801b0000, 0xa0e4000c, 0x0300000a, + 0x80010006, 0xa0aa000c, 0x80000001, 0x0300000a, 0x80020006, 0xa0ff000c, 0x80550001, 0x03000002, + 0x800c0000, 0xb01b0000, 0xa01b000a, 0x0300000b, 0x80030001, 0x801b0000, 0xa0e4000c, 0x0300000a, + 0x80010007, 0xa0aa000c, 0x80000001, 0x0300000a, 0x80020007, 0xa0ff000c, 0x80550001, 0x03000002, + 0x800c0000, 0xb01b0000, 0xa01b000b, 0x0300000b, 0x80030001, 0x801b0000, 0xa0e4000c, 0x0300000a, + 0x80010008, 0xa0aa000c, 0x80000001, 0x0300000a, 0x80020008, 0xa0ff000c, 0x80550001, 0x03000042, + 0x800f0000, 0x80e40000, 0xa0e40800, 0x03000042, 0x800f0001, 0x80e40002, 0xa0e40800, 0x03000042, + 0x800f0002, 0x80e40003, 0xa0e40800, 0x03000042, 0x800f0003, 0x80e40004, 0xa0e40800, 0x03000042, + 0x800f0004, 0x80e40005, 0xa0e40800, 0x03000042, 0x800f0005, 0x80e40006, 0xa0e40800, 0x03000042, + 0x800f0006, 0x80e40007, 0xa0e40800, 0x03000042, 0x800f0007, 0x80e40008, 0xa0e40800, 0x03000005, + 0x800f0000, 0x80e40000, 0xa0aa0005, 0x04000004, 0x800f0000, 0x80e40001, 0xa0aa0004, 0x80e40000, + 0x04000004, 0x800f0000, 0x80e40002, 0xa0aa0006, 0x80e40000, 0x04000004, 0x800f0000, 0x80e40003, + 0xa0aa0007, 0x80e40000, 0x04000004, 0x800f0000, 0x80e40004, 0xa0aa0008, 0x80e40000, 0x04000004, + 0x800f0000, 0x80e40005, 0xa0aa0009, 0x80e40000, 0x04000004, 0x800f0000, 0x80e40006, 0xa0aa000a, + 0x80e40000, 0x04000004, 0x800f0000, 0x80e40007, 0xa0aa000b, 0x80e40000, 0x02000001, 0x800f0800, + 0x80e40000, 0x0000ffff, +}; + +static DWORD pshader_blur_9[235] = { + 0xffff0200, 0x0200001f, 0x80000000, 0xb0030000, 0x0200001f, 0x90000000, 0xa00f0800, 0x03000002, + 0x80030000, 0xb0e40000, 0xa0e40005, 0x0300000b, 0x80030001, 0x80e40000, 0xa0e4000d, 0x0300000a, + 0x80010000, 0xa0aa000d, 0x80000001, 0x0300000a, 0x80020000, 0xa0ff000d, 0x80550001, 0x03000002, + 0x800c0000, 0xb01b0000, 0xa01b0004, 0x0300000b, 0x80030001, 0x801b0000, 0xa0e4000d, 0x0300000a, + 0x80010002, 0xa0aa000d, 0x80000001, 0x0300000a, 0x80020002, 0xa0ff000d, 0x80550001, 0x03000002, + 0x800c0000, 0xb01b0000, 0xa01b0006, 0x0300000b, 0x80030001, 0x801b0000, 0xa0e4000d, 0x0300000a, + 0x80010003, 0xa0aa000d, 0x80000001, 0x0300000a, 0x80020003, 0xa0ff000d, 0x80550001, 0x03000002, + 0x800c0000, 0xb01b0000, 0xa01b0007, 0x0300000b, 0x80030001, 0x801b0000, 0xa0e4000d, 0x0300000a, + 0x80010004, 0xa0aa000d, 0x80000001, 0x0300000a, 0x80020004, 0xa0ff000d, 0x80550001, 0x03000002, + 0x800c0000, 0xb01b0000, 0xa01b0008, 0x0300000b, 0x80030001, 0x801b0000, 0xa0e4000d, 0x0300000a, + 0x80010005, 0xa0aa000d, 0x80000001, 0x0300000a, 0x80020005, 0xa0ff000d, 0x80550001, 0x03000002, + 0x800c0000, 0xb01b0000, 0xa01b0009, 0x0300000b, 0x80030001, 0x801b0000, 0xa0e4000d, 0x0300000a, + 0x80010006, 0xa0aa000d, 0x80000001, 0x0300000a, 0x80020006, 0xa0ff000d, 0x80550001, 0x03000002, + 0x800c0000, 0xb01b0000, 0xa01b000a, 0x0300000b, 0x80030001, 0x801b0000, 0xa0e4000d, 0x0300000a, + 0x80010007, 0xa0aa000d, 0x80000001, 0x0300000a, 0x80020007, 0xa0ff000d, 0x80550001, 0x03000002, + 0x800c0000, 0xb01b0000, 0xa01b000b, 0x0300000b, 0x80030001, 0x801b0000, 0xa0e4000d, 0x0300000a, + 0x80010008, 0xa0aa000d, 0x80000001, 0x0300000a, 0x80020008, 0xa0ff000d, 0x80550001, 0x03000002, + 0x800c0000, 0xb01b0000, 0xa01b000c, 0x0300000b, 0x80030001, 0x801b0000, 0xa0e4000d, 0x0300000a, + 0x80010009, 0xa0aa000d, 0x80000001, 0x0300000a, 0x80020009, 0xa0ff000d, 0x80550001, 0x03000042, + 0x800f0000, 0x80e40000, 0xa0e40800, 0x03000042, 0x800f0001, 0x80e40002, 0xa0e40800, 0x03000042, + 0x800f0002, 0x80e40003, 0xa0e40800, 0x03000042, 0x800f0003, 0x80e40004, 0xa0e40800, 0x03000042, + 0x800f0004, 0x80e40005, 0xa0e40800, 0x03000042, 0x800f0005, 0x80e40006, 0xa0e40800, 0x03000042, + 0x800f0006, 0x80e40007, 0xa0e40800, 0x03000042, 0x800f0007, 0x80e40008, 0xa0e40800, 0x03000042, + 0x800f0008, 0x80e40009, 0xa0e40800, 0x03000005, 0x800f0000, 0x80e40000, 0xa0aa0005, 0x04000004, + 0x800f0000, 0x80e40001, 0xa0aa0004, 0x80e40000, 0x04000004, 0x800f0000, 0x80e40002, 0xa0aa0006, + 0x80e40000, 0x04000004, 0x800f0000, 0x80e40003, 0xa0aa0007, 0x80e40000, 0x04000004, 0x800f0000, + 0x80e40004, 0xa0aa0008, 0x80e40000, 0x04000004, 0x800f0000, 0x80e40005, 0xa0aa0009, 0x80e40000, + 0x04000004, 0x800f0000, 0x80e40006, 0xa0aa000a, 0x80e40000, 0x04000004, 0x800f0000, 0x80e40007, + 0xa0aa000b, 0x80e40000, 0x04000004, 0x800f0000, 0x80e40008, 0xa0aa000c, 0x80e40000, 0x02000001, + 0x800f0800, 0x80e40000, 0x0000ffff, +}; + +static ProgramWithCachedVariableLocations pshader_blur_arr[10] = { + { NULL, NULL, { -1, -1, -1, } }, + { NULL, NULL, { -1, -1, -1, } }, + { pshader_blur_2, NULL, { 0, 4, 6, } }, + { pshader_blur_3, NULL, { 0, 4, 7, } }, + { pshader_blur_4, NULL, { 0, 4, 8, } }, + { pshader_blur_5, NULL, { 0, 4, 9, } }, + { pshader_blur_6, NULL, { 0, 4, 10, } }, + { pshader_blur_7, NULL, { 0, 4, 11, } }, + { pshader_blur_8, NULL, { 0, 4, 12, } }, + { pshader_blur_9, NULL, { 0, 4, 13, } }, +}; + +static DWORD pshader_color_matrix_0[50] = { + 0xffff0200, 0x0200001f, 0x80000000, 0xb0030000, 0x0200001f, 0x90000000, 0xa00f0800, 0x03000042, + 0x800f0000, 0xb0e40000, 0xa0e40800, 0x03000009, 0x80080001, 0xa0e40004, 0x80e40000, 0x04000004, + 0x80010001, 0xa0000008, 0x80ff0000, 0x80ff0001, 0x03000009, 0x80080001, 0xa0e40005, 0x80e40000, + 0x04000004, 0x80020001, 0xa0550008, 0x80ff0000, 0x80ff0001, 0x03000009, 0x80080001, 0xa0e40006, + 0x80e40000, 0x04000004, 0x80040001, 0xa0aa0008, 0x80ff0000, 0x80ff0001, 0x03000005, 0x80080000, + 0x80ff0000, 0xa0ff0007, 0x03000005, 0x80070000, 0x80e40001, 0xa0ff0007, 0x02000001, 0x800f0800, + 0x80e40000, 0x0000ffff, +}; + +static ProgramWithCachedVariableLocations pshader_color_matrix_arr[1] = { + { pshader_color_matrix_0, NULL, { 0, 4, } }, +}; + +static DWORD pshader_manual_clear_0[5] = { + 0xffff0200, 0x02000001, 0x800f0800, 0xa0e40000, 0x0000ffff, +}; + +static ProgramWithCachedVariableLocations pshader_manual_clear_arr[1] = { + { pshader_manual_clear_0, NULL, { 0, } }, +}; + +static DWORD vshader_vsd3d9_0[65] = { + 0xfffe0200, 0x05000051, 0xa00f0002, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x0200001f, + 0x80000000, 0x900f0000, 0x03000009, 0x80010000, 0x90e40000, 0xa0e40001, 0x03000005, 0x80070000, + 0x80000000, 0xa0e40006, 0x03000009, 0x80080000, 0x90e40000, 0xa0e40000, 0x04000004, 0x80070000, + 0x80ff0000, 0xa0e40005, 0x80e40000, 0x03000002, 0x80070000, 0x80e40000, 0xa0e40007, 0x02000006, + 0x80040000, 0x80aa0000, 0x03000005, 0xc0030000, 0x80aa0000, 0x80e40000, 0x03000009, 0x80010000, + 0xa0e40003, 0x90e40000, 0x03000009, 0x80020000, 0xa0e40004, 0x90e40000, 0x03000005, 0xe0030000, + 0x80aa0000, 0x80e40000, 0x02000001, 0xe0080000, 0x80aa0000, 0x02000001, 0x80040000, 0xa0aa0000, + 0x04000004, 0xc00c0000, 0x80aa0000, 0xa0440002, 0xa0140002, 0x02000001, 0xe0040000, 0xa0000002, + 0x0000ffff, +}; + +static DWORD vshader_vsd3d9_1[143] = { + 0xfffe0200, 0x05000051, 0xa00f0008, 0x3c800000, 0x3d000000, 0x00000000, 0xbf800000, 0x05000051, + 0xa00f0009, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x0200001f, 0x80000000, 0x900f0000, + 0x0200001f, 0x80000005, 0x900f0001, 0x03000005, 0x80070000, 0x90c90001, 0xa0d00008, 0x03000005, + 0x800f0001, 0x80440000, 0xa0e40002, 0x03000002, 0x80030001, 0x80ed0001, 0x80e80001, 0x02000001, + 0x800c0001, 0xa0aa0008, 0x03000009, 0x80010002, 0x80f40001, 0xa0e40000, 0x03000009, 0x80020002, + 0x80e40001, 0xa0e40001, 0x03000005, 0x80030001, 0x80e40002, 0x80e40002, 0x03000002, 0x80080000, + 0x80550001, 0x80000001, 0x02000007, 0x80080000, 0x80ff0000, 0x02000006, 0x80080000, 0x80ff0000, + 0x0300000c, 0x80010001, 0x81ff0000, 0x80ff0000, 0x04000012, 0x80040002, 0x80000001, 0x80ff0000, + 0xa1ff0008, 0x02000006, 0x80080000, 0x80aa0002, 0x03000005, 0x80030000, 0x80e40000, 0x80e40000, + 0x03000002, 0x80010000, 0x80550000, 0x80000000, 0x02000007, 0x80010000, 0x80000000, 0x02000006, + 0x80010000, 0x80000000, 0x03000005, 0x80010000, 0x80ff0000, 0x80000000, 0x03000009, 0x80010001, + 0x90e40000, 0xa0e40000, 0x03000009, 0x80020001, 0x90e40000, 0xa0e40001, 0x04000004, 0x80030000, + 0x80e40002, 0x80000000, 0x80e40001, 0x03000005, 0x80070001, 0x80550000, 0xa0e40006, 0x04000004, + 0x800b0000, 0x80000000, 0xa0a40005, 0x80a40001, 0x03000002, 0x800b0000, 0x80e40000, 0xa0a40007, + 0x02000006, 0x80080000, 0x80ff0000, 0x03000005, 0xc0030000, 0x80ff0000, 0x80e40000, 0x03000009, + 0x80010000, 0xa0e40003, 0x90e40000, 0x03000009, 0x80020000, 0xa0e40004, 0x90e40000, 0x03000005, + 0xe0070000, 0x80ff0000, 0x80e40000, 0x02000001, 0xe0080000, 0x80ff0000, 0x02000001, 0x80040000, + 0xa0aa0000, 0x04000004, 0xc00c0000, 0x80aa0000, 0xa0440009, 0xa0140009, 0x0000ffff, +}; + +static DWORD vshader_vsd3d9_2[60] = { + 0xfffe0200, 0x05000051, 0xa00f0002, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x0200001f, + 0x80000000, 0x900f0000, 0x0200001f, 0x80000005, 0x900f0001, 0x03000009, 0x80010000, 0x90e40000, + 0xa0e40001, 0x03000005, 0x80070000, 0x80000000, 0xa0e40006, 0x03000009, 0x80080000, 0x90e40000, + 0xa0e40000, 0x04000004, 0x80070000, 0x80ff0000, 0xa0e40005, 0x80e40000, 0x03000002, 0x80070000, + 0x80e40000, 0xa0e40007, 0x02000006, 0x80040000, 0x80aa0000, 0x03000005, 0xc0030000, 0x80aa0000, + 0x80e40000, 0x03000005, 0xe0030000, 0x80aa0000, 0x90e40001, 0x02000001, 0xe0080000, 0x80aa0000, + 0x02000001, 0x80040000, 0xa0aa0000, 0x04000004, 0xc00c0000, 0x80aa0000, 0xa0440002, 0xa0140002, + 0x02000001, 0xe0040000, 0xa0000002, 0x0000ffff, +}; + +static ProgramWithCachedVariableLocations vshader_vsd3d9_arr[3] = { + { vshader_vsd3d9_0, NULL, { 0 } }, + { vshader_vsd3d9_1, NULL, { 0 } }, + { vshader_vsd3d9_2, NULL, { 0 } }, +}; + diff --git a/Minecraft.Client/Windows64/Iggy/gdraw/gdraw_gl_shaders.inl b/Minecraft.Client/Windows64/Iggy/gdraw/gdraw_gl_shaders.inl new file mode 100644 index 00000000..dc8a0484 --- /dev/null +++ b/Minecraft.Client/Windows64/Iggy/gdraw/gdraw_gl_shaders.inl @@ -0,0 +1,1084 @@ +// This file was automatically generated by shadergen. Do not edit by hand! + +static char pshader_basic_frag0[] = + "#version 110 // only need 100, but 110 works around a driver issue\n" + "#define MAIN(x) void main()\n" + "#define ARGS\n" + "#define ARGS2\n" + "#define DECLARE_SAMPLER(type, name, reg) uniform type name\n" + "#define DECLARE_CONST(type, name, reg) uniform type name\n" + "#define DECLARE_CONST_EXTRA(type, name, reg) uniform type name\n" + "#define SAMPLER sampler2D\n" + "#define TEX2D texture2D\n" + "#define VEC4 vec4\n" + "#define VEC3 vec3\n" + "#define VEC2 vec2\n" + "#define LOWP\n" + "#define MEDIUMP\n" + "#define HIGHP\n" + "#define TC0 tex_coord.xy\n" + "#define TC1 tex_coord.zw\n" + "#define OUTPUT(x) gl_FragColor = x\n" + "\n" + "#define SHADER_ALPHATEST(x) if (x < 0.5) discard\n" + "\n" + "#define COMMON_PSCONSTANTS DECLARE_CONST(VEC4, color_mul, 0); DECLARE_CONST(VEC4, color_add, 1); DECLARE_CONST(VEC4, focal, 2); varying VEC4 tex_coord\n" + "#define COMMON_PCONSTANTS2 varying VEC4 tex_coord; varying VEC4 color_mul; varying VEC4 color_add; varying VEC4 clip_rect;\n" + "#define BEGIN_CONSTANTS\n" + "#define END_CONSTANTS\n" + "\n" + "#define saturate(x) clamp(x,0.0,1.0)\n"; +static char pshader_basic_frag1[] = ""; +static char pshader_basic_frag2[] = + "COMMON_PSCONSTANTS;\n" + "\n" + "#ifdef TEX0\n" + "DECLARE_SAMPLER(LOWP SAMPLER, tex0, 0);\n" + "#endif\n" + "\n" + "#ifndef READ_ALPHA_TEX\n" + "#define READ_ALPHA_TEX(x) ((x).a)\n" + "#endif\n" + "\n" + "#ifndef AATEX_USE_SAMPLER1\n" + "DECLARE_SAMPLER(LOWP SAMPLER, tex1, 7);\n" + "#else\n" + "DECLARE_SAMPLER(LOWP SAMPLER, tex1, 1);\n" + "#endif\n" + "\n" + "MAIN((ARGS))\n" + "{\n" + " LOWP VEC4 z;\n" + " MEDIUMP VEC4 t;\n" + " \n" + " z = color_mul;\n" + " \n" + " #ifndef ADDITIVE_ALPHA\n" + " z.rgb *= z.a; // premultiply; could do outside\n" + " #endif\n" + " \n" + " #ifdef TEX0\n" + " MEDIUMP VEC2 c,tc0;\n" + " tc0 = TC0;\n" + "\n" + " #ifdef EXPLICIT_PROJECTION\n" + " float one_over_w = 1.0 / TC1.y;\n" + " tc0.x *= one_over_w;\n" + " tc0.y *= one_over_w;\n" + " #endif\n" + " \n" + " #ifdef TEX0_RADIAL\n" + " tc0.x = sqrt(dot(tc0.xy,tc0.xy));\n" + " tc0.y = tc0.x; // necessary on some OpenGL devices\n" + " #else\n" + " #ifdef TEX0_FOCAL\n" + " c.x = tc0.x + focal.x;\n" + " c.y = tc0.y;\n" + " t.x = c.x * focal.y;\n" + " t.y = (c.x*c.x + c.y*c.y) * focal.z;\n" + " tc0.x = sqrt(t.y + t.x*t.x) - t.x;\n" + " tc0.y = tc0.x;\n" + " #endif\n" + " #endif\n" + "\n" + " #ifdef TEX0_ALPHA\n" + " t.a = READ_ALPHA_TEX(TEX2D(tex0, tc0));\n" + " #ifdef ADDITIVE_ALPHA\n" + " z.a *= t.a;\n" + " #else\n" + " z *= t.a;\n" + " #endif\n" + " #else\n" + " t = TEX2D(tex0, tc0);\n" + " #ifdef ADDITIVE_ALPHA\n" + " if (t.a != 0.0) t.rgb = t.rgb * (1.0/t.a); // unpremultiply\n" + " #endif\n" + " z *= t;\n" + " #endif\n" + " #endif\n" + "\n" + " MEDIUMP VEC2 tc1;\n" + " tc1.xy = TC1.xy;\n" + "\n" + " #ifdef EXPLICIT_PROJECTION\n" + " tc1.x /= TC1.y;\n" + " #endif\n" + "\n" + " // antialiasing blend curve\n" + " t = TEX2D(tex1, tc1.xy);\n" + " #ifdef ADDITIVE_ALPHA\n" + " z.a *= t.a;\n" + " #else\n" + " z *= t;\n" + " #endif\n" + "\n" + " #ifdef ADDITIVE_ALPHA\n" + " z += color_add;\n" + " z.rgb *= z.a; // premultiply\n" + " #else\n" + " #ifdef ADDITIVE\n" + " z.rgb += color_add.rgb * z.a; // scale addend to match premultiply\n" + " z.rgb = min(z.rgb, z.a);\n" + " #endif\n" + " #endif\n" + " \n" + " #ifdef TEX0_ALPHA_TEST\n" + " SHADER_ALPHATEST(z.a);\n" + " #endif\n" + "\n" + " OUTPUT(z);\n" + "}\n"; +static char pshader_basic_frag3[] = + "#define ADDITIVE\n"; +static char pshader_basic_frag4[] = + "#define ADDITIVE_ALPHA\n"; +static char pshader_basic_frag5[] = + "#define TEX0\n"; +static char pshader_basic_frag6[] = + "#define TEX0\n" + "#define TEX0_ALPHA\n"; +static char pshader_basic_frag7[] = + "#define TEX0\n" + "#define TEX0_RADIAL\n"; +static char pshader_basic_frag8[] = + "#define TEX0\n" + "#define TEX0_FOCAL\n"; +static char pshader_basic_frag9[] = + "#define TEX0\n" + "#define TEX0_ALPHA\n" + "#define TEX0_ALPHA_TEST\n"; + +#define NUMFRAGMENTS_pshader_basic 4 +static char *pshader_basic_arr[18][NUMFRAGMENTS_pshader_basic] = { + { pshader_basic_frag0, pshader_basic_frag1, pshader_basic_frag1, pshader_basic_frag2, }, + { pshader_basic_frag0, pshader_basic_frag1, pshader_basic_frag3, pshader_basic_frag2, }, + { pshader_basic_frag0, pshader_basic_frag1, pshader_basic_frag4, pshader_basic_frag2, }, + { pshader_basic_frag0, pshader_basic_frag5, pshader_basic_frag1, pshader_basic_frag2, }, + { pshader_basic_frag0, pshader_basic_frag5, pshader_basic_frag3, pshader_basic_frag2, }, + { pshader_basic_frag0, pshader_basic_frag5, pshader_basic_frag4, pshader_basic_frag2, }, + { pshader_basic_frag0, pshader_basic_frag6, pshader_basic_frag1, pshader_basic_frag2, }, + { pshader_basic_frag0, pshader_basic_frag6, pshader_basic_frag3, pshader_basic_frag2, }, + { pshader_basic_frag0, pshader_basic_frag6, pshader_basic_frag4, pshader_basic_frag2, }, + { pshader_basic_frag0, pshader_basic_frag7, pshader_basic_frag1, pshader_basic_frag2, }, + { pshader_basic_frag0, pshader_basic_frag7, pshader_basic_frag3, pshader_basic_frag2, }, + { pshader_basic_frag0, pshader_basic_frag7, pshader_basic_frag4, pshader_basic_frag2, }, + { pshader_basic_frag0, pshader_basic_frag8, pshader_basic_frag1, pshader_basic_frag2, }, + { pshader_basic_frag0, pshader_basic_frag8, pshader_basic_frag3, pshader_basic_frag2, }, + { pshader_basic_frag0, pshader_basic_frag8, pshader_basic_frag4, pshader_basic_frag2, }, + { pshader_basic_frag0, pshader_basic_frag9, pshader_basic_frag1, pshader_basic_frag2, }, + { pshader_basic_frag0, pshader_basic_frag9, pshader_basic_frag3, pshader_basic_frag2, }, + { pshader_basic_frag0, pshader_basic_frag9, pshader_basic_frag4, pshader_basic_frag2, }, +}; + +static char **pshader_basic(int tex0, int additive) +{ + return pshader_basic_arr[0 + tex0*3 + additive*1]; +} + +static char *pshader_basic_vars[] = { + "tex0", + "tex1", + "color_mul", + "color_add", + "focal", + NULL +}; + +static char pshader_general2_frag0[] = + "#version 110 // only need 100, but 110 works around a driver issue\n" + "#define MAIN(x) void main()\n" + "#define ARGS\n" + "#define ARGS2\n" + "#define DECLARE_SAMPLER(type, name, reg) uniform type name\n" + "#define DECLARE_CONST(type, name, reg) uniform type name\n" + "#define DECLARE_CONST_EXTRA(type, name, reg) uniform type name\n" + "#define SAMPLER sampler2D\n" + "#define TEX2D texture2D\n" + "#define VEC4 vec4\n" + "#define VEC3 vec3\n" + "#define VEC2 vec2\n" + "#define LOWP\n" + "#define MEDIUMP\n" + "#define HIGHP\n" + "#define TC0 tex_coord.xy\n" + "#define TC1 tex_coord.zw\n" + "#define OUTPUT(x) gl_FragColor = x\n" + "\n" + "#define SHADER_ALPHATEST(x) if (x < 0.5) discard\n" + "\n" + "#define COMMON_PSCONSTANTS DECLARE_CONST(VEC4, color_mul, 0); DECLARE_CONST(VEC4, color_add, 1); DECLARE_CONST(VEC4, focal, 2); varying VEC4 tex_coord\n" + "#define COMMON_PCONSTANTS2 varying VEC4 tex_coord; varying VEC4 color_mul; varying VEC4 color_add; varying VEC4 clip_rect;\n" + "#define BEGIN_CONSTANTS\n" + "#define END_CONSTANTS\n" + "\n" + "#define saturate(x) clamp(x,0.0,1.0)\n"; +static char pshader_general2_frag1[] = + "COMMON_PCONSTANTS2\n" + "DECLARE_SAMPLER(LOWP SAMPLER, tex0, 0);\n" + "MAIN((ARGS2))\n" + "{\n" + " // get t, the basic texture color\n" + "\n" + " LOWP VEC4 t;\n" + " \n" + " t = TEX2D(tex0, tex_coord.xy);\n" + "\n" + " // now color-transform t\n" + " //\n" + " // to determine optimal format for vertex shader to output the color, let's\n" + " // start by doing the math assuming the texture is premultiplied, but not\n" + " // the color transform:\n" + " //\n" + " // out.r = (tex.r * color_mul.r * color_mul.a) + (color_add.r * tex.a * color_mul.a)\n" + " // out.a = tex.a * color_mul.a * color_add.a // color_add.a is blend mode emulation\n" + " //\n" + " // now, we can see in the above we can premultiply both mul and add by color_mul.a\n" + " //\n" + " // out.r = (tex.r * color_mulp.r) + (color_addp.r * tex.a)\n" + " // out.a = tex.a * color_mulp.a // can premultiply color_add.a here as well\n" + "\n" + " \n" + " LOWP VEC4 c;\n" + " c.rgb = t.rgb * color_mul.rgb + t.a * color_add.rgb;\n" + " c.a = t.a * color_mul.a;\n" + "\n" + " // apply clip rect\n" + " //\n" + " // naive math, using panel-space coordinates\n" + " //\n" + " // panel_offset = abs(pos-center) - half_width\n" + " //\n" + " // Above function is negative where not clipped, positive\n" + " // where clipped. Now, we want to capture a one-pixel boundary,\n" + " // so we need to go to pixel coordinates:\n" + " //\n" + " // panel_offset *= pixels_per_panel_unit;\n" + " // // note this doesn't account for non-uniform scale of panel\n" + " //\n" + " // And now, with an offset in pixels, we want to compute an AA mask:\n" + " //\n" + " // saturate(1-panel_offset)\n" + " //\n" + " // Note that we can just multiply pixels_per_panel_unit into\n" + " // each of the terms in panel offset, and we're left with:\n" + " //\n" + " // saturate(1 - (abs() - k))\n" + " //\n" + " // which becomes:\n" + " //\n" + " // saturate(k+1 - abs())\n" + " //\n" + " // and the +1 is folded into k.\n" + "\n" + " LOWP VEC2 cliprect_alpha = saturate(clip_rect.zw - abs(tex_coord.zw - clip_rect.xy));\n" + "\n" + " float edge_alpha = cliprect_alpha.x * cliprect_alpha.y;\n" + " // could be min, but multiply represents coverage better in theory; @TODO check visually\n" + "\n" + " // multiply it into c's alpha, but c's already premultiplied so multiply it all\n" + " c *= edge_alpha;\n" + "\n" + " OUTPUT(c);\n" + "}\n"; + +#define NUMFRAGMENTS_pshader_general2 2 +static char *pshader_general2_arr[1][NUMFRAGMENTS_pshader_general2] = { + { pshader_general2_frag0, pshader_general2_frag1, }, +}; + +static char **pshader_general2(void) +{ + return pshader_general2_arr[0]; +} + +static char *pshader_general2_vars[] = { + "tex0", + NULL +}; + +static char pshader_exceptional_blend_frag0[] = + "#version 110 // only need 100, but 110 works around a driver issue\n" + "#define MAIN(x) void main()\n" + "#define ARGS\n" + "#define ARGS2\n" + "#define DECLARE_SAMPLER(type, name, reg) uniform type name\n" + "#define DECLARE_CONST(type, name, reg) uniform type name\n" + "#define DECLARE_CONST_EXTRA(type, name, reg) uniform type name\n" + "#define SAMPLER sampler2D\n" + "#define TEX2D texture2D\n" + "#define VEC4 vec4\n" + "#define VEC3 vec3\n" + "#define VEC2 vec2\n" + "#define LOWP\n" + "#define MEDIUMP\n" + "#define HIGHP\n" + "#define TC0 tex_coord.xy\n" + "#define TC1 tex_coord.zw\n" + "#define OUTPUT(x) gl_FragColor = x\n" + "\n" + "#define SHADER_ALPHATEST(x) if (x < 0.5) discard\n" + "\n" + "#define COMMON_PSCONSTANTS DECLARE_CONST(VEC4, color_mul, 0); DECLARE_CONST(VEC4, color_add, 1); DECLARE_CONST(VEC4, focal, 2); varying VEC4 tex_coord\n" + "#define COMMON_PCONSTANTS2 varying VEC4 tex_coord; varying VEC4 color_mul; varying VEC4 color_add; varying VEC4 clip_rect;\n" + "#define BEGIN_CONSTANTS\n" + "#define END_CONSTANTS\n" + "\n" + "#define saturate(x) clamp(x,0.0,1.0)\n"; +static char pshader_exceptional_blend_frag1[] = + "#define BLENDPROG return s*d;\n" + "#define ALPHAFUNC return sa+da-sa*da;\n"; +static char pshader_exceptional_blend_frag2[] = + "#define TEX0\n" + "\n" + "MEDIUMP float compute(MEDIUMP float s, MEDIUMP float sa, MEDIUMP float d, MEDIUMP float da)\n" + "{\n" + " BLENDPROG\n" + "}\n" + "\n" + "MEDIUMP float compute_a(MEDIUMP float sa, MEDIUMP float da)\n" + "{\n" + " ALPHAFUNC\n" + "}\n" + "\n" + "DECLARE_SAMPLER(LOWP SAMPLER, tex0, 0);\n" + "DECLARE_SAMPLER(LOWP SAMPLER, tex1, 1);\n" + "COMMON_PSCONSTANTS;\n" + "\n" + "MAIN((ARGS))\n" + "{\n" + " MEDIUMP VEC4 srcc,dstc;\n" + " MEDIUMP VEC3 mixed;\n" + " MEDIUMP VEC2 tc;\n" + " srcc = TEX2D(tex0, TC0.xy);\n" + " srcc = srcc*VEC4(color_mul.rgb, 1.0)*color_mul.a + color_add*srcc.a;\n" + " srcc = clamp(srcc,VEC4(0.0,0.0,0.0,0.0),VEC4(1.0,1.0,1.0,1.0));\n" + " tc = TC0.xy;\n" + " #ifndef EXCEPTIONAL_BLEND_LOAD\n" + " #ifndef EXCEPTIONAL_BLEND_RESCALE\n" + " dstc = TEX2D(tex1, tc).rgba;\n" + " #else\n" + " dstc = TEX2D(tex1, tc*rescale1.xy + rescale1.zw).rgba;\n" + " #endif\n" + " #else\n" + " dstc = EXCEPTIONAL_BLEND_LOAD(tex1, tc);\n" + " #endif\n" + " mixed.r = compute(srcc.r,srcc.a, dstc.r,dstc.a);\n" + " mixed.g = compute(srcc.g,srcc.a, dstc.g,dstc.a);\n" + " mixed.b = compute(srcc.b,srcc.a, dstc.b,dstc.a);\n" + " MEDIUMP VEC4 res;\n" + " #ifdef DIRECT\n" + " res.rgb = mixed;\n" + " #else\n" + " res.rgb = mixed + (1.0-srcc.a)*dstc.rgb + (1.0-dstc.a)*srcc.rgb;\n" + " #endif\n" + " res.a = compute_a(srcc.a,dstc.a);\n" + " OUTPUT(res);\n" + "}\n"; +static char pshader_exceptional_blend_frag3[] = + "#define BLENDPROG return sa*da - (da-d)*(sa-s);\n" + "#define ALPHAFUNC return sa+da-sa*da;\n"; +static char pshader_exceptional_blend_frag4[] = + "#define BLENDPROG return max(sa*d,s*da);\n" + "#define ALPHAFUNC return sa+da-sa*da;\n"; +static char pshader_exceptional_blend_frag5[] = + "#define BLENDPROG return min(sa*d,s*da);\n" + "#define ALPHAFUNC return sa+da-sa*da;\n"; +static char pshader_exceptional_blend_frag6[] = + "#define DIRECT\n" + "#define BLENDPROG return min(d+s,1.0);\n" + "#define ALPHAFUNC return min(sa+da,1.0);\n"; +static char pshader_exceptional_blend_frag7[] = + "#define DIRECT\n" + "#define BLENDPROG return max(d-s,0.0);\n" + "#define ALPHAFUNC return min(sa+da,1.0);\n"; +static char pshader_exceptional_blend_frag8[] = + "#define BLENDPROG return abs(sa*d-s*da);\n" + "#define ALPHAFUNC return sa+da-sa*da;\n"; +static char pshader_exceptional_blend_frag9[] = + "#define BLENDPROG return sa*(da-d);\n" + "#define ALPHAFUNC return sa+da-sa*da;\n"; +static char pshader_exceptional_blend_frag10[] = + "#define BLENDPROG return d < da/2.0 ? (2.0*s*d) : (sa*da - 2.0*(da-d)*(sa-s));\n" + "#define ALPHAFUNC return sa+da-sa*da;\n"; +static char pshader_exceptional_blend_frag11[] = + "#define BLENDPROG return s < sa/2.0 ? (2.0*s*d) : (sa*da - 2.0*(da-d)*(sa-s));\n" + "#define ALPHAFUNC return sa+da-sa*da;\n"; +static char pshader_exceptional_blend_frag12[] = + "#define DIRECT\n" + "#define BLENDPROG return d*(1.0-sa);\n" + "#define ALPHAFUNC return (1.0-sa)*da;\n"; +static char pshader_exceptional_blend_frag13[] = + "#define DIRECT\n" + "#define BLENDPROG return d*sa;\n" + "#define ALPHAFUNC return sa*da;\n"; + +#define NUMFRAGMENTS_pshader_exceptional_blend 3 +static char *pshader_exceptional_blend_arr[13][NUMFRAGMENTS_pshader_exceptional_blend] = { + { NULL, NULL, NULL, }, + { pshader_exceptional_blend_frag0, pshader_exceptional_blend_frag1, pshader_exceptional_blend_frag2, }, + { pshader_exceptional_blend_frag0, pshader_exceptional_blend_frag3, pshader_exceptional_blend_frag2, }, + { pshader_exceptional_blend_frag0, pshader_exceptional_blend_frag4, pshader_exceptional_blend_frag2, }, + { pshader_exceptional_blend_frag0, pshader_exceptional_blend_frag5, pshader_exceptional_blend_frag2, }, + { pshader_exceptional_blend_frag0, pshader_exceptional_blend_frag6, pshader_exceptional_blend_frag2, }, + { pshader_exceptional_blend_frag0, pshader_exceptional_blend_frag7, pshader_exceptional_blend_frag2, }, + { pshader_exceptional_blend_frag0, pshader_exceptional_blend_frag8, pshader_exceptional_blend_frag2, }, + { pshader_exceptional_blend_frag0, pshader_exceptional_blend_frag9, pshader_exceptional_blend_frag2, }, + { pshader_exceptional_blend_frag0, pshader_exceptional_blend_frag10, pshader_exceptional_blend_frag2, }, + { pshader_exceptional_blend_frag0, pshader_exceptional_blend_frag11, pshader_exceptional_blend_frag2, }, + { pshader_exceptional_blend_frag0, pshader_exceptional_blend_frag12, pshader_exceptional_blend_frag2, }, + { pshader_exceptional_blend_frag0, pshader_exceptional_blend_frag13, pshader_exceptional_blend_frag2, }, +}; + +static char **pshader_exceptional_blend(int blend_mode) +{ + return pshader_exceptional_blend_arr[0 + blend_mode*1]; +} + +static char *pshader_exceptional_blend_vars[] = { + "tex0", + "tex1", + "color_mul", + "color_add", + NULL +}; + +static char pshader_filter_frag0[] = + "#version 110 // only need 100, but 110 works around a driver issue\n" + "#define MAIN(x) void main()\n" + "#define ARGS\n" + "#define ARGS2\n" + "#define DECLARE_SAMPLER(type, name, reg) uniform type name\n" + "#define DECLARE_CONST(type, name, reg) uniform type name\n" + "#define DECLARE_CONST_EXTRA(type, name, reg) uniform type name\n" + "#define SAMPLER sampler2D\n" + "#define TEX2D texture2D\n" + "#define VEC4 vec4\n" + "#define VEC3 vec3\n" + "#define VEC2 vec2\n" + "#define LOWP\n" + "#define MEDIUMP\n" + "#define HIGHP\n" + "#define TC0 tex_coord.xy\n" + "#define TC1 tex_coord.zw\n" + "#define OUTPUT(x) gl_FragColor = x\n" + "\n" + "#define SHADER_ALPHATEST(x) if (x < 0.5) discard\n" + "\n" + "#define COMMON_PSCONSTANTS DECLARE_CONST(VEC4, color_mul, 0); DECLARE_CONST(VEC4, color_add, 1); DECLARE_CONST(VEC4, focal, 2); varying VEC4 tex_coord\n" + "#define COMMON_PCONSTANTS2 varying VEC4 tex_coord; varying VEC4 color_mul; varying VEC4 color_add; varying VEC4 clip_rect;\n" + "#define BEGIN_CONSTANTS\n" + "#define END_CONSTANTS\n" + "\n" + "#define saturate(x) clamp(x,0.0,1.0)\n"; +static char pshader_filter_frag1[] = ""; +static char pshader_filter_frag2[] = + "#define TEX0\n" + "\n" + "DECLARE_SAMPLER(LOWP SAMPLER, tex0, 0);\n" + "DECLARE_SAMPLER(LOWP SAMPLER, tex1, 1);\n" + "DECLARE_SAMPLER(LOWP SAMPLER, tex2, 2);\n" + "\n" + "COMMON_PSCONSTANTS;\n" + "\n" + "BEGIN_CONSTANTS \n" + " DECLARE_CONST_EXTRA(HIGHP VEC4, clamp0, 4);\n" + " DECLARE_CONST_EXTRA(HIGHP VEC4, clamp1, 5);\n" + " #define CLAMP(a,b) clamp(a.xy, b.xy, b.zw)\n" + "\n" + " DECLARE_CONST_EXTRA(LOWP VEC4, color, 6);\n" + " DECLARE_CONST_EXTRA(LOWP VEC4, color2, 7);\n" + " DECLARE_CONST_EXTRA(MEDIUMP VEC4, tc_off, 8);\n" + "END_CONSTANTS\n" + " \n" + "MAIN((ARGS))\n" + "{\n" + " LOWP VEC4 source;\n" + " source = TEX2D(tex1, CLAMP(TC0.xy,clamp1));\n" + " MEDIUMP float shadow_a = TEX2D(tex0, CLAMP(TC0.xy + tc_off.xy,clamp0)).a;\n" + " \n" + " #ifdef BEVEL\n" + " MEDIUMP float shadow_b = TEX2D(tex0, CLAMP(TC0.xy - tc_off.xy,clamp0)).a;\n" + " shadow_a = (shadow_b - shadow_a) * tc_off.z;\n" + " #ifdef GRADIENT\n" + " shadow_a = clamp(shadow_a*0.5 + 0.5, 0.0, 1.0);\n" + " #else\n" + " shadow_b = clamp(-shadow_a, 0.0, 1.0);\n" + " shadow_a = clamp(shadow_a, 0.0, 1.0);\n" + " #endif\n" + " #else\n" + " #ifdef INNER\n" + " #ifndef GRADIENT\n" + " shadow_a = 1.0-shadow_a;\n" + " #endif // !GRADIENT\n" + " #endif // INNER\n" + " shadow_a = min(shadow_a*tc_off.z,1.0);\n" + " #endif // BEVEL\n" + " \n" + " #ifdef GRADIENT\n" + " MEDIUMP VEC2 gtc = VEC2(shadow_a, 0.5);\n" + " MEDIUMP VEC4 ecolor = TEX2D(tex2, gtc);\n" + " shadow_a = 1.0;\n" + " #else\n" + " #ifdef BEVEL\n" + " MEDIUMP VEC4 ecolor = shadow_b*color + shadow_a*color2;\n" + " shadow_a = 1.0;\n" + " #else\n" + " MEDIUMP VEC4 ecolor = color;\n" + " #endif\n" + " #endif\n" + " \n" + " #ifdef ONTOP\n" + " #ifdef KNOCKOUT\n" + " OUTPUT(ecolor);\n" + " #else\n" + " OUTPUT(ecolor + source * (1.0-ecolor.a));\n" + " #endif\n" + " #else\n" + " \n" + " #ifdef KNOCKOUT\n" + " #ifdef INNER\n" + " // KNOCKOUT & INNER\n" + " OUTPUT(ecolor * source.a * shadow_a);\n" + " #else\n" + " // KNOCKOUT & !INNER\n" + " OUTPUT(ecolor * (1.0-source.a) * shadow_a);\n" + " #endif\n" + " #else // !KNOCKOUT\n" + " \n" + " #ifdef INNER\n" + " // !KNOCKOUT & INNER\n" + " /* this is particularly subtle; effectively computes\n" + " invert shadow\n" + " unpremultiply source\n" + " shadow*color over source.rgb (treat as opaque)\n" + " multiply through by source alpha (i.e. make premultiplied again)\n" + " but expressed without *actually* unpremultiplying\n" + " */\n" + " LOWP VEC4 shadow = ecolor * shadow_a;\n" + " LOWP VEC4 res;\n" + " res.rgb = shadow.rgb*source.a + source.rgb*(1.0-shadow.a);\n" + " res.a = source.a;\n" + " OUTPUT(res);\n" + " #else\n" + " // !KNOCKOUT & !INNER\n" + " LOWP VEC4 shadow = ecolor * shadow_a;\n" + " OUTPUT(shadow * (1.0-source.a) + source);\n" + " #endif // INNER\n" + "\n" + " #endif // KNOCKOUT\n" + " #endif // ONTOP\n" + "}\n"; +static char pshader_filter_frag3[] = + "#define KNOCKOUT\n"; +static char pshader_filter_frag4[] = + "#define GRADIENT\n"; +static char pshader_filter_frag5[] = + "#define INNER\n"; +static char pshader_filter_frag6[] = + "#define ONTOP\n"; +static char pshader_filter_frag7[] = + "#define BEVEL\n"; + +#define NUMFRAGMENTS_pshader_filter 7 +static char *pshader_filter_arr[32][NUMFRAGMENTS_pshader_filter] = { + { pshader_filter_frag0, pshader_filter_frag1, pshader_filter_frag1, pshader_filter_frag1, pshader_filter_frag1, pshader_filter_frag1, pshader_filter_frag2, }, + { pshader_filter_frag0, pshader_filter_frag1, pshader_filter_frag1, pshader_filter_frag1, pshader_filter_frag1, pshader_filter_frag3, pshader_filter_frag2, }, + { pshader_filter_frag0, pshader_filter_frag1, pshader_filter_frag1, pshader_filter_frag1, pshader_filter_frag4, pshader_filter_frag1, pshader_filter_frag2, }, + { pshader_filter_frag0, pshader_filter_frag1, pshader_filter_frag1, pshader_filter_frag1, pshader_filter_frag4, pshader_filter_frag3, pshader_filter_frag2, }, + { pshader_filter_frag0, pshader_filter_frag1, pshader_filter_frag1, pshader_filter_frag5, pshader_filter_frag1, pshader_filter_frag1, pshader_filter_frag2, }, + { pshader_filter_frag0, pshader_filter_frag1, pshader_filter_frag1, pshader_filter_frag5, pshader_filter_frag1, pshader_filter_frag3, pshader_filter_frag2, }, + { pshader_filter_frag0, pshader_filter_frag1, pshader_filter_frag1, pshader_filter_frag5, pshader_filter_frag4, pshader_filter_frag1, pshader_filter_frag2, }, + { pshader_filter_frag0, pshader_filter_frag1, pshader_filter_frag1, pshader_filter_frag5, pshader_filter_frag4, pshader_filter_frag3, pshader_filter_frag2, }, + { pshader_filter_frag0, pshader_filter_frag1, pshader_filter_frag6, pshader_filter_frag1, pshader_filter_frag1, pshader_filter_frag1, pshader_filter_frag2, }, + { pshader_filter_frag0, pshader_filter_frag1, pshader_filter_frag6, pshader_filter_frag1, pshader_filter_frag1, pshader_filter_frag3, pshader_filter_frag2, }, + { pshader_filter_frag0, pshader_filter_frag1, pshader_filter_frag6, pshader_filter_frag1, pshader_filter_frag4, pshader_filter_frag1, pshader_filter_frag2, }, + { pshader_filter_frag0, pshader_filter_frag1, pshader_filter_frag6, pshader_filter_frag1, pshader_filter_frag4, pshader_filter_frag3, pshader_filter_frag2, }, + { NULL, NULL, NULL, NULL, NULL, NULL, NULL, }, + { NULL, NULL, NULL, NULL, NULL, NULL, NULL, }, + { NULL, NULL, NULL, NULL, NULL, NULL, NULL, }, + { NULL, NULL, NULL, NULL, NULL, NULL, NULL, }, + { pshader_filter_frag0, pshader_filter_frag7, pshader_filter_frag1, pshader_filter_frag1, pshader_filter_frag1, pshader_filter_frag1, pshader_filter_frag2, }, + { pshader_filter_frag0, pshader_filter_frag7, pshader_filter_frag1, pshader_filter_frag1, pshader_filter_frag1, pshader_filter_frag3, pshader_filter_frag2, }, + { pshader_filter_frag0, pshader_filter_frag7, pshader_filter_frag1, pshader_filter_frag1, pshader_filter_frag4, pshader_filter_frag1, pshader_filter_frag2, }, + { pshader_filter_frag0, pshader_filter_frag7, pshader_filter_frag1, pshader_filter_frag1, pshader_filter_frag4, pshader_filter_frag3, pshader_filter_frag2, }, + { pshader_filter_frag0, pshader_filter_frag7, pshader_filter_frag1, pshader_filter_frag5, pshader_filter_frag1, pshader_filter_frag1, pshader_filter_frag2, }, + { pshader_filter_frag0, pshader_filter_frag7, pshader_filter_frag1, pshader_filter_frag5, pshader_filter_frag1, pshader_filter_frag3, pshader_filter_frag2, }, + { pshader_filter_frag0, pshader_filter_frag7, pshader_filter_frag1, pshader_filter_frag5, pshader_filter_frag4, pshader_filter_frag1, pshader_filter_frag2, }, + { pshader_filter_frag0, pshader_filter_frag7, pshader_filter_frag1, pshader_filter_frag5, pshader_filter_frag4, pshader_filter_frag3, pshader_filter_frag2, }, + { pshader_filter_frag0, pshader_filter_frag7, pshader_filter_frag6, pshader_filter_frag1, pshader_filter_frag1, pshader_filter_frag1, pshader_filter_frag2, }, + { pshader_filter_frag0, pshader_filter_frag7, pshader_filter_frag6, pshader_filter_frag1, pshader_filter_frag1, pshader_filter_frag3, pshader_filter_frag2, }, + { pshader_filter_frag0, pshader_filter_frag7, pshader_filter_frag6, pshader_filter_frag1, pshader_filter_frag4, pshader_filter_frag1, pshader_filter_frag2, }, + { pshader_filter_frag0, pshader_filter_frag7, pshader_filter_frag6, pshader_filter_frag1, pshader_filter_frag4, pshader_filter_frag3, pshader_filter_frag2, }, + { NULL, NULL, NULL, NULL, NULL, NULL, NULL, }, + { NULL, NULL, NULL, NULL, NULL, NULL, NULL, }, + { NULL, NULL, NULL, NULL, NULL, NULL, NULL, }, + { NULL, NULL, NULL, NULL, NULL, NULL, NULL, }, +}; + +static char **pshader_filter(int bevel, int ontop, int inner, int gradient, int knockout) +{ + return pshader_filter_arr[0 + bevel*16 + ontop*8 + inner*4 + gradient*2 + knockout*1]; +} + +static char *pshader_filter_vars[] = { + "tex0", + "tex1", + "color", + "tc_off", + "tex2", + "clamp0", + "clamp1", + "color2", + NULL +}; + +static char pshader_blur_frag0[] = + "#version 110 // only need 100, but 110 works around a driver issue\n" + "#define MAIN(x) void main()\n" + "#define ARGS\n" + "#define ARGS2\n" + "#define DECLARE_SAMPLER(type, name, reg) uniform type name\n" + "#define DECLARE_CONST(type, name, reg) uniform type name\n" + "#define DECLARE_CONST_EXTRA(type, name, reg) uniform type name\n" + "#define SAMPLER sampler2D\n" + "#define TEX2D texture2D\n" + "#define VEC4 vec4\n" + "#define VEC3 vec3\n" + "#define VEC2 vec2\n" + "#define LOWP\n" + "#define MEDIUMP\n" + "#define HIGHP\n" + "#define TC0 tex_coord.xy\n" + "#define TC1 tex_coord.zw\n" + "#define OUTPUT(x) gl_FragColor = x\n" + "\n" + "#define SHADER_ALPHATEST(x) if (x < 0.5) discard\n" + "\n" + "#define COMMON_PSCONSTANTS DECLARE_CONST(VEC4, color_mul, 0); DECLARE_CONST(VEC4, color_add, 1); DECLARE_CONST(VEC4, focal, 2); varying VEC4 tex_coord\n" + "#define COMMON_PCONSTANTS2 varying VEC4 tex_coord; varying VEC4 color_mul; varying VEC4 color_add; varying VEC4 clip_rect;\n" + "#define BEGIN_CONSTANTS\n" + "#define END_CONSTANTS\n" + "\n" + "#define saturate(x) clamp(x,0.0,1.0)\n"; +static char pshader_blur_frag1[] = + "#define TAPS TAP(0); TAP(1);\n"; +static char pshader_blur_frag2[] = + "#define TEX0\n" + "\n" + "DECLARE_SAMPLER(LOWP SAMPLER, tex0, 0);\n" + "COMMON_PSCONSTANTS;\n" + "\n" + "BEGIN_CONSTANTS\n" + " DECLARE_CONST_EXTRA(HIGHP VEC4, clampv, 4);\n" + " #define CLAMP(t) clamp(t, clampv.xy, clampv.zw)\n" + " \n" + " DECLARE_CONST_EXTRA(MEDIUMP VEC4, tap[9], 5);\n" + "END_CONSTANTS\n" + "\n" + "MAIN((ARGS))\n" + "{\n" + " MEDIUMP VEC4 s = VEC4(0,0,0,0);\n" + " \n" + " #define TAP(i) s += TEX2D(tex0, CLAMP(TC0.xy + tap[i].xy)) * tap[i].z\n" + " TAPS\n" + " \n" + " OUTPUT(s);\n" + "}\n"; +static char pshader_blur_frag3[] = + "#define TAPS TAP(0); TAP(1); TAP(2);\n"; +static char pshader_blur_frag4[] = + "#define TAPS TAP(0); TAP(1); TAP(2); TAP(3);\n"; +static char pshader_blur_frag5[] = + "#define TAPS TAP(0); TAP(1); TAP(2); TAP(3); TAP(4);\n"; +static char pshader_blur_frag6[] = + "#define TAPS TAP(0); TAP(1); TAP(2); TAP(3); TAP(4); TAP(5);\n"; +static char pshader_blur_frag7[] = + "#define TAPS TAP(0); TAP(1); TAP(2); TAP(3); TAP(4); TAP(5); TAP(6);\n"; +static char pshader_blur_frag8[] = + "#define TAPS TAP(0); TAP(1); TAP(2); TAP(3); TAP(4); TAP(5); TAP(6); TAP(7);\n"; +static char pshader_blur_frag9[] = + "#define TAPS TAP(0); TAP(1); TAP(2); TAP(3); TAP(4); TAP(5); TAP(6); TAP(7); TAP(8);\n"; + +#define NUMFRAGMENTS_pshader_blur 3 +static char *pshader_blur_arr[10][NUMFRAGMENTS_pshader_blur] = { + { NULL, NULL, NULL, }, + { NULL, NULL, NULL, }, + { pshader_blur_frag0, pshader_blur_frag1, pshader_blur_frag2, }, + { pshader_blur_frag0, pshader_blur_frag3, pshader_blur_frag2, }, + { pshader_blur_frag0, pshader_blur_frag4, pshader_blur_frag2, }, + { pshader_blur_frag0, pshader_blur_frag5, pshader_blur_frag2, }, + { pshader_blur_frag0, pshader_blur_frag6, pshader_blur_frag2, }, + { pshader_blur_frag0, pshader_blur_frag7, pshader_blur_frag2, }, + { pshader_blur_frag0, pshader_blur_frag8, pshader_blur_frag2, }, + { pshader_blur_frag0, pshader_blur_frag9, pshader_blur_frag2, }, +}; + +static char **pshader_blur(int numtaps) +{ + return pshader_blur_arr[0 + numtaps*1]; +} + +static char *pshader_blur_vars[] = { + "tex0", + "tap", + "clampv", + NULL +}; + +static char pshader_color_matrix_frag0[] = + "#version 110 // only need 100, but 110 works around a driver issue\n" + "#define MAIN(x) void main()\n" + "#define ARGS\n" + "#define ARGS2\n" + "#define DECLARE_SAMPLER(type, name, reg) uniform type name\n" + "#define DECLARE_CONST(type, name, reg) uniform type name\n" + "#define DECLARE_CONST_EXTRA(type, name, reg) uniform type name\n" + "#define SAMPLER sampler2D\n" + "#define TEX2D texture2D\n" + "#define VEC4 vec4\n" + "#define VEC3 vec3\n" + "#define VEC2 vec2\n" + "#define LOWP\n" + "#define MEDIUMP\n" + "#define HIGHP\n" + "#define TC0 tex_coord.xy\n" + "#define TC1 tex_coord.zw\n" + "#define OUTPUT(x) gl_FragColor = x\n" + "\n" + "#define SHADER_ALPHATEST(x) if (x < 0.5) discard\n" + "\n" + "#define COMMON_PSCONSTANTS DECLARE_CONST(VEC4, color_mul, 0); DECLARE_CONST(VEC4, color_add, 1); DECLARE_CONST(VEC4, focal, 2); varying VEC4 tex_coord\n" + "#define COMMON_PCONSTANTS2 varying VEC4 tex_coord; varying VEC4 color_mul; varying VEC4 color_add; varying VEC4 clip_rect;\n" + "#define BEGIN_CONSTANTS\n" + "#define END_CONSTANTS\n" + "\n" + "#define saturate(x) clamp(x,0.0,1.0)\n"; +static char pshader_color_matrix_frag1[] = + "#define TEX0\n" + "\n" + "DECLARE_SAMPLER(LOWP SAMPLER, tex0, 0);\n" + "COMMON_PSCONSTANTS;\n" + "\n" + "BEGIN_CONSTANTS\n" + " DECLARE_CONST_EXTRA(MEDIUMP VEC4, data[5], 4);\n" + "END_CONSTANTS\n" + "\n" + "MAIN((ARGS))\n" + "{\n" + " MEDIUMP VEC4 t,color;\n" + " t = TEX2D(tex0, TC0.xy);\n" + " \n" + "#ifndef COLORMATRIX_HAS_ALPHA_EFFECTS\n" + " // version of colormatrix assuming no additive alpha in matrix,\n" + " // which is all CS3 seems to be able to output\n" + " color.r = dot(data[0], t) + data[4].r*t.a;\n" + " color.g = dot(data[1], t) + data[4].g*t.a;\n" + " color.b = dot(data[2], t) + data[4].b*t.a;\n" + " color.a = data[3].a * t.a;\n" + " color.rgb = color.rgb * data[3].a;\n" + "#else\n" + " // version of colormatrix that matches spec \n" + " if (t.a == 0.0)\n" + " t.rgb = VEC3(0.0);\n" + " else\n" + " t.rgb /= t.a;\n" + " color.r = dot(data[0], t) + data[4].r;\n" + " color.g = dot(data[1], t) + data[4].g;\n" + " color.b = dot(data[2], t) + data[4].b;\n" + " color.a = dot(data[3], t) + data[4].a;\n" + " color.rgb = color.rgb * color.a;\n" + "#endif\n" + " OUTPUT(color);\n" + "}\n"; + +#define NUMFRAGMENTS_pshader_color_matrix 2 +static char *pshader_color_matrix_arr[1][NUMFRAGMENTS_pshader_color_matrix] = { + { pshader_color_matrix_frag0, pshader_color_matrix_frag1, }, +}; + +static char **pshader_color_matrix(void) +{ + return pshader_color_matrix_arr[0]; +} + +static char *pshader_color_matrix_vars[] = { + "tex0", + "data", + NULL +}; + +static char pshader_manual_clear_frag0[] = + "#version 110 // only need 100, but 110 works around a driver issue\n" + "#define MAIN(x) void main()\n" + "#define ARGS\n" + "#define ARGS2\n" + "#define DECLARE_SAMPLER(type, name, reg) uniform type name\n" + "#define DECLARE_CONST(type, name, reg) uniform type name\n" + "#define DECLARE_CONST_EXTRA(type, name, reg) uniform type name\n" + "#define SAMPLER sampler2D\n" + "#define TEX2D texture2D\n" + "#define VEC4 vec4\n" + "#define VEC3 vec3\n" + "#define VEC2 vec2\n" + "#define LOWP\n" + "#define MEDIUMP\n" + "#define HIGHP\n" + "#define TC0 tex_coord.xy\n" + "#define TC1 tex_coord.zw\n" + "#define OUTPUT(x) gl_FragColor = x\n" + "\n" + "#define SHADER_ALPHATEST(x) if (x < 0.5) discard\n" + "\n" + "#define COMMON_PSCONSTANTS DECLARE_CONST(VEC4, color_mul, 0); DECLARE_CONST(VEC4, color_add, 1); DECLARE_CONST(VEC4, focal, 2); varying VEC4 tex_coord\n" + "#define COMMON_PCONSTANTS2 varying VEC4 tex_coord; varying VEC4 color_mul; varying VEC4 color_add; varying VEC4 clip_rect;\n" + "#define BEGIN_CONSTANTS\n" + "#define END_CONSTANTS\n" + "\n" + "#define saturate(x) clamp(x,0.0,1.0)\n"; +static char pshader_manual_clear_frag1[] = + "COMMON_PSCONSTANTS;\n" + "\n" + "MAIN((ARGS))\n" + "{\n" + " OUTPUT(color_mul);\n" + "}\n"; + +#define NUMFRAGMENTS_pshader_manual_clear 2 +static char *pshader_manual_clear_arr[1][NUMFRAGMENTS_pshader_manual_clear] = { + { pshader_manual_clear_frag0, pshader_manual_clear_frag1, }, +}; + +static char **pshader_manual_clear(void) +{ + return pshader_manual_clear_arr[0]; +} + +static char *pshader_manual_clear_vars[] = { + "color_mul", + NULL +}; + +static char vshader_vsgl_frag0[] = + "#version 110 // only need 100, but 110 works around a driver issue\n" + "#define MAIN(x) void main()\n" + "#define ARGS\n" + "#define ARGS2\n" + "#define DECLARE_SAMPLER(type, name, reg) uniform type name\n" + "#define DECLARE_CONST(type, name, reg) uniform type name\n" + "#define DECLARE_CONST_EXTRA(type, name, reg) uniform type name\n" + "#define SAMPLER sampler2D\n" + "#define TEX2D texture2D\n" + "#define VEC4 vec4\n" + "#define VEC3 vec3\n" + "#define VEC2 vec2\n" + "#define LOWP\n" + "#define MEDIUMP\n" + "#define HIGHP\n" + "#define TC0 tex_coord.xy\n" + "#define TC1 tex_coord.zw\n" + "#define OUTPUT(x) gl_FragColor = x\n" + "\n" + "#define SHADER_ALPHATEST(x) if (x < 0.5) discard\n" + "\n" + "#define COMMON_PSCONSTANTS DECLARE_CONST(VEC4, color_mul, 0); DECLARE_CONST(VEC4, color_add, 1); DECLARE_CONST(VEC4, focal, 2); varying VEC4 tex_coord\n" + "#define COMMON_PCONSTANTS2 varying VEC4 tex_coord; varying VEC4 color_mul; varying VEC4 color_add; varying VEC4 clip_rect;\n" + "#define BEGIN_CONSTANTS\n" + "#define END_CONSTANTS\n" + "\n" + "#define saturate(x) clamp(x,0.0,1.0)\n"; +static char vshader_vsgl_frag1[] = + "#define FORMAT_V2\n"; +static char vshader_vsgl_frag2[] = + " uniform vec4 world0;\n" + " uniform vec4 world1;\n" + " uniform vec4 x_off;\n" + " uniform vec4 texgen_s;\n" + " uniform vec4 texgen_t;\n" + "#ifdef FLASH_10\n" + " uniform vec4 x3d;\n" + " uniform vec4 y3d;\n" + " uniform vec4 w3d;\n" + "#else\n" + " uniform vec4 viewproj;\n" + "#endif\n" + "\n" + " attribute vec4 position;\n" + " attribute vec4 in_attr;\n" + "\n" + " varying vec4 tex_coord;\n" + " \n" + " void main() {\n" + " // world transform\n" + " HIGHP vec4 wpos = vec4(dot(world0, position), dot(world1, position), world0.z, 1.0);\n" + " \n" + " // texture coordinates\n" + " tex_coord = vec4(dot(texgen_s, position), dot(texgen_t, position), 1.0, 0.0);\n" + " #ifdef FORMAT_V2TC2\n" + " tex_coord.xy = in_attr.xy;\n" + " #endif\n" + " \n" + " // antialias processing\n" + " #ifdef FORMAT_V2C4\n" + " HIGHP vec4 q,p;\n" + " HIGHP float len,newlen;\n" + " q.xy = in_attr.yz / 64.0;\n" + " len = length(q.xy);\n" + " p.x = q.x*x_off.x + q.y*x_off.y;\n" + " p.y = q.x*x_off.z + q.y*x_off.w;\n" + " p.z = 0.0; p.w = 0.0;\n" + " p.xy = vec2(dot(world0, p), dot(world1, p));\n" + " newlen = length(p.xy);\n" + " p *= (newlen!=0.0) ? len / newlen : 0.0;\n" + " wpos.xy += p.xy;\n" + " tex_coord.z = in_attr.x / 32.0;\n" + " #endif\n" + " \n" + " // view/projection transform\n" + " gl_Position = vec4(wpos.xy * viewproj.xy + viewproj.zw, wpos.zw);\n" + "\n" + " #ifdef FLASH_10\n" + " gl_Position = wpos.x * x3d + wpos.y * y3d + w3d; // z is ignored!\n" + " gl_Position.w = gl_Position.z;\n" + " gl_Position.z = wpos.z * gl_Position.w;\n" + " #endif\n" + " } \n"; +static char vshader_vsgl_frag3[] = + "#define FORMAT_V2C4\n"; +static char vshader_vsgl_frag4[] = + "#define FORMAT_V2TC2\n"; + +#define NUMFRAGMENTS_vshader_vsgl 3 +static char *vshader_vsgl_arr[3][NUMFRAGMENTS_vshader_vsgl] = { + { vshader_vsgl_frag0, vshader_vsgl_frag1, vshader_vsgl_frag2, }, + { vshader_vsgl_frag0, vshader_vsgl_frag3, vshader_vsgl_frag2, }, + { vshader_vsgl_frag0, vshader_vsgl_frag4, vshader_vsgl_frag2, }, +}; + +static char **vshader_vsgl(int vformat) +{ + return vshader_vsgl_arr[0 + vformat*1]; +} + +static char *vshader_vsgl_vars[] = { + "world0", + "world1", + "x_off", + "texgen_s", + "texgen_t", + "viewproj", + NULL +}; + +static char vshader_vsglihud_frag0[] = + "#version 110 // only need 100, but 110 works around a driver issue\n" + "#define MAIN(x) void main()\n" + "#define ARGS\n" + "#define ARGS2\n" + "#define DECLARE_SAMPLER(type, name, reg) uniform type name\n" + "#define DECLARE_CONST(type, name, reg) uniform type name\n" + "#define DECLARE_CONST_EXTRA(type, name, reg) uniform type name\n" + "#define SAMPLER sampler2D\n" + "#define TEX2D texture2D\n" + "#define VEC4 vec4\n" + "#define VEC3 vec3\n" + "#define VEC2 vec2\n" + "#define LOWP\n" + "#define MEDIUMP\n" + "#define HIGHP\n" + "#define TC0 tex_coord.xy\n" + "#define TC1 tex_coord.zw\n" + "#define OUTPUT(x) gl_FragColor = x\n" + "\n" + "#define SHADER_ALPHATEST(x) if (x < 0.5) discard\n" + "\n" + "#define COMMON_PSCONSTANTS DECLARE_CONST(VEC4, color_mul, 0); DECLARE_CONST(VEC4, color_add, 1); DECLARE_CONST(VEC4, focal, 2); varying VEC4 tex_coord\n" + "#define COMMON_PCONSTANTS2 varying VEC4 tex_coord; varying VEC4 color_mul; varying VEC4 color_add; varying VEC4 clip_rect;\n" + "#define BEGIN_CONSTANTS\n" + "#define END_CONSTANTS\n" + "\n" + "#define saturate(x) clamp(x,0.0,1.0)\n"; +static char vshader_vsglihud_frag1[] = + "uniform vec4 worldview[2];\n" + "uniform vec4 material[96];\n" + "uniform float textmode;\n" + "\n" + "#define pixels_per_panel_unit 1.0\n" + "\n" + "attribute vec2 position;\n" + "attribute vec2 texcoord;\n" + "attribute vec4 material_index; \n" + "\n" + "varying vec4 tex_coord;\n" + "varying vec4 color_mul;\n" + "varying vec4 color_add;\n" + "varying vec4 clip_rect;\n" + "\n" + "void main() {\n" + " // view/projection transform\n" + " gl_Position = vec4(worldview[0].w + dot(worldview[0].xy, position),\n" + " worldview[1].w + dot(worldview[1].xy, position),\n" + " 0.0,\n" + " 1.0);\n" + "\n" + " LOWP VEC4 c1_mul,c1_add,c2_mul,c2_add, c_mul,c_add;\n" + " HIGHP VEC4 clip;\n" + "\n" + " // convert 8-bit material_info loaded as float back to integers\n" + " LOWP VEC3 mat = floor(255.0*material_index.xyz + 0.5);\n" + "\n" + " // @TODO: flatten these into a single array\n" + " c1_mul = material[int(mat.r )];\n" + " c1_add = material[int(mat.r+1.0)];\n" + " c2_mul = material[int(mat.g )];\n" + " c2_add = material[int(mat.g+1.0)];\n" + " clip = material[int(mat.b )];\n" + "\n" + " // if textmode is 0, suppress c2_add.rgba\n" + "\n" + " // combine hierarchical and local colors\n" + " color_add.rgb = c1_mul.rgb * (c2_add.rgb * textmode) + c1_add.rgb;\n" + " color_mul = c1_mul * c2_mul;\n" + " color_mul.a *= material_index.w;\n" + "\n" + " // compute premultiplied alpha\n" + " color_mul.rgb *= color_mul.a;\n" + " color_add.rgb *= color_mul.a;\n" + "\n" + " // pass additive blending flag stored in c1_add.a and c2_add.a to pixel shader\n" + " color_add.a = clamp(c1_add.a + c2_add.a * textmode,0.0,1.0);\n" + "\n" + " // except actually we'll premultiply that into color_mul.a\n" + " color_mul.a *= (1.0-color_add.a);\n" + "\n" + " // compute premultiplied cliprect\n" + " // for now cliprect comes in as x0,y0,x1,y1, not center/offset\n" + " \n" + " // coordinates come in already rotated into panel space, which is also where cliprect is defined\n" + " HIGHP VEC2 center = (clip.xy + clip.zw) / 2.0;\n" + " HIGHP VEC2 offset = (clip.zw - clip.xy) / 2.0;\n" + "\n" + " // use of pixels_per_panel_unit here ignores effect of non-uniform scaling\n" + " clip_rect.xy = center * pixels_per_panel_unit;\n" + " clip_rect.zw = offset * pixels_per_panel_unit + 1.0; // offset is location where alpha goes to 0, so it's 1 pixel out\n" + "\n" + " tex_coord.zw = position * pixels_per_panel_unit;\n" + " tex_coord.xy = texcoord;\n" + "} \n"; + +#define NUMFRAGMENTS_vshader_vsglihud 2 +static char *vshader_vsglihud_arr[1][NUMFRAGMENTS_vshader_vsglihud] = { + { vshader_vsglihud_frag0, vshader_vsglihud_frag1, }, +}; + +static char **vshader_vsglihud(void) +{ + return vshader_vsglihud_arr[0]; +} + +static char *vshader_vsglihud_vars[] = { + "worldview", + "material", + "textmode", + NULL +}; + diff --git a/Minecraft.Client/Windows64/Iggy/gdraw/gdraw_gl_shared.inl b/Minecraft.Client/Windows64/Iggy/gdraw/gdraw_gl_shared.inl new file mode 100644 index 00000000..9916096a --- /dev/null +++ b/Minecraft.Client/Windows64/Iggy/gdraw/gdraw_gl_shared.inl @@ -0,0 +1,2428 @@ +// gdraw_gl_shared.inl - copyright 2012 RAD Game Tools +// +// This file implements the part of the Iggy graphics driver layer shared between +// GL and GL ES 2 (which is most of it). It heavily depends on a bunch of typedefs, +// #defines and some utility functions that need to be set up correctly for the GL +// version being targeted. It also targets a kind of pseudo-GL 2.0; the platform +// implementation has to set up some #defines and perform extra initialization +// work if we go through extensions instead. This is all a bit ugly, but much +// easier to maintain than the original solution, where we just kept two almost +// identical versions of this code. + +///////////////////////////////////////////////////////////// +// +// common code shared by all GDraw implemetations +// + +// The native handle type holds resource handles and a coarse description. +typedef union { + // handle that is a texture + struct { + GLuint gl; + GLuint gl_renderbuf; + U32 w:24; + U32 nonpow2:8; + U32 h:24; + U32 reserved:8; + } tex; + + // handle that is a vertex buffer + struct { + GLuint base; + GLuint indices; + } vbuf; +} GDrawNativeHandle; + +#include "gdraw_shared.inl" + +// max rendertarget stack depth. this depends on the extent to which you +// use filters and non-standard blend modes, and how nested they are. +#define MAX_RENDER_STACK_DEPTH 8 // Iggy is hardcoded to a limit of 16... probably 1-3 is realistic +#define AATEX_SAMPLER 3 // sampler that aa_tex gets set in +#define QUAD_IB_COUNT 4096 // quad index buffer has indices for this many quads + +#define ASSERT_COUNT(a,b) ((a) == (b) ? (b) : -1) + +/////////////////////////////////////////////////////////////////////////////// +// +// debugging/validation +// + +static RADINLINE void break_on_err(GLint e) +{ +#ifdef _DEBUG + if (e) { + RR_BREAK(); + } +#endif +} + +static void report_err(GLint e) +{ + break_on_err(e); + IggyGDrawSendWarning(NULL, "OpenGL glGetError error"); +} + +static void compilation_err(const char *msg) +{ + error_msg_platform_specific(msg); + report_err(GL_INVALID_VALUE); +} + +static void eat_gl_err(void) +{ + while (glGetError() != GL_NO_ERROR); +} + +static void opengl_check(void) +{ +#ifdef _DEBUG + GLint e = glGetError(); + if (e != GL_NO_ERROR) { + report_err(e); + eat_gl_err(); + } +#endif +} + +static U32 is_pow2(S32 n) +{ + return ((U32) n & (U32) (n-1)) == 0; +} + +/////////////////////////////////////////////////////////////////////////////// +// +// GDraw +// +// This data structure stores all the data for the GDraw, just to keep +// it a bit cleaner instead of storing in globals, even though GDraw is +// a singleton. + +// fragment and vertex program + +// The mac doesn't use extensions for the functions dealing with programs, and the non-extension versions +// take GLuint instead of GLhandle. The mac defines GDrawGLProgram to GLuint before including gdraw_gl_shared.inl +// to account for this. +#ifndef GDrawGLProgram +#define GDrawGLProgram GLhandle +#endif + +typedef struct ProgramWithCachedVariableLocations +{ + GDrawGLProgram program; + GLint vars[2][MAX_VARS]; +} ProgramWithCachedVariableLocations; + +// render-stack state +typedef struct +{ + GDrawHandle *color_buffer; + GDrawHandle *stencil_depth; + S32 base_x, base_y, width, height; + rrbool cached; +} GDrawFramebufferState; + +// texture format description +typedef struct { + U8 iggyfmt; // IFT_FORMAT_* + U8 blkx, blky; // compressed block size in pixels (for compressed formats) + U8 blkbytes; // block bytes + GLenum intfmt; // GL internal format + GLenum fmt; // GL_TEXTURE_COMPRESSED for compressed formats! + GLenum type; +} TextureFormatDesc; + +static GDrawFunctions gdraw_funcs; + +/////////////////////////////////////////////////////////////////////////////// +// +// GDraw data structure +// +// +// This is the primary rendering abstraction, which hides all +// the platform-specific rendering behavior from /G/. It is +// full of platform-specific graphics state, and also general +// graphics state so that it doesn't have to callback into /G/ +// to get at that graphics state. + +static struct +{ + S32 multisampling; // number of samples if multisampling (always 0 if no GDRAW_MULTISAMPLING) + + S32 vx,vy; // viewport width/height in pixels + S32 fw,fh; // full width/height of bound rendertarget + S32 tw,th; // actual width/height of current tile + S32 tpw,tph; // width/height of padded version of tile + + // tile origin location (without and with padding) + rrbool tile_enabled; + S32 tx0,ty0; + S32 tx0p,ty0p; + + // if we're in the middle of rendering a blur, certain viewport-related + // functions have to behave differently, so they check this flag + rrbool in_blur; + + F32 projection[4]; // scalex, scaley, transx, transy + + // conversion from worldspace to viewspace <0,0>.. -- no translation or rotation + F32 world_to_pixel[2]; + + // 3d transformation + F32 xform_3d[3][4]; + rrbool use_3d; + + // render-state stack for 'temporary' rendering + GDrawFramebufferState frame[MAX_RENDER_STACK_DEPTH]; + GDrawFramebufferState *cur; + + // texture and vertex buffer pools + GDrawHandleCache *texturecache; + GDrawHandleCache *vbufcache; + + // GL_EXT_separate_shader_objects isn't sufficiently standard, + // so we have to bind every vertex shader to every fragment shader + + // raw vertex shaders + GLuint vert[GDRAW_vformat__count]; + + // fragment shaders with vertex shaders + ProgramWithCachedVariableLocations fprog[GDRAW_TEXTURE__count][3][3]; // [tex0mode][additive][vformat] + ProgramWithCachedVariableLocations ihud[2]; + + // fragment shaders with fixed-function + ProgramWithCachedVariableLocations exceptional_blend[GDRAW_BLENDSPECIAL__count]; + ProgramWithCachedVariableLocations filter_prog[2][16]; + ProgramWithCachedVariableLocations blur_prog[MAX_TAPS+1]; + ProgramWithCachedVariableLocations colormatrix; + ProgramWithCachedVariableLocations manual_clear; + + // render targets + + // these two lines must be adjacent because of how rendertargets works + GDrawHandleCache rendertargets; + GDrawHandle rendertarget_handles[MAX_RENDER_STACK_DEPTH]; // not -1, because we use +1 to initialize + + gswf_recti rt_valid[MAX_RENDER_STACK_DEPTH + 1]; + GDrawHandle stencil_depth; + + // size of our render targets + S32 frametex_width, frametex_height; + + // framebuffer object used for render-to-texture + GLuint framebuffer_stack_object; + + // framebuffer object used to copy from MSAA renderbuffer to texture + GLuint framebuffer_copy_to_texture; + + // framebuffer object used for main screen (set to non-0 to do render to texture) + GLuint main_framebuffer; + + // antialias texture + GLuint aa_tex; + + // canned quad indices + GLuint quad_ib; + + // texture formats + const TextureFormatDesc *tex_formats; + + // caps + U32 has_conditional_non_power_of_two : 1; // non-power-of-2 supported, but only CLAMP_TO_EDGE and can't have mipmaps + U32 has_packed_depth_stencil : 1; + U32 has_depth24 : 1; + U32 has_mapbuffer : 1; + U32 has_texture_max_level : 1; + + // fake fence tracking for thrashing detection + U64 frame_counter; +} *gdraw; + +//////////////////////////////////////////////////////////////////////// +// +// General resource management for both textures and vertex buffers +// + +// make a texture with reasonable default state +static void make_texture(GLuint tex) +{ + glBindTexture(GL_TEXTURE_2D, tex); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); +} + +static void make_rendertarget(GDrawHandle *t, GLuint tex, GLenum int_type, GLenum ext_type, GLenum data_type, S32 w, S32 h, S32 size) +{ + glBindTexture(GL_TEXTURE_2D, tex); + glTexImage2D(GL_TEXTURE_2D, 0, int_type, w, h, 0, ext_type, data_type, NULL); + make_texture(tex); + glBindTexture(GL_TEXTURE_2D, 0); +} + +static void api_free_resource(GDrawHandle *r) +{ + if (r->state == GDRAW_HANDLE_STATE_user_owned) + return; + + if (!r->cache->is_vertex) { + glDeleteTextures(1, &r->handle.tex.gl); + if (r->handle.tex.gl_renderbuf && r->handle.tex.gl_renderbuf != r->handle.tex.gl) + glDeleteRenderbuffers(1, &r->handle.tex.gl_renderbuf); + } else { + glDeleteBuffers(1, &r->handle.vbuf.base); + glDeleteBuffers(1, &r->handle.vbuf.indices); + } + opengl_check(); +} + +static void RADLINK gdraw_UnlockHandles(GDrawStats *gstats) +{ + // since we're not using fences for this implementation, move all textures off the active list + // if you're using fences, this is when the fence needs to actually occur + gdraw_HandleCacheUnlockAll(gdraw->texturecache); + gdraw_HandleCacheUnlockAll(gdraw->vbufcache); +} + +//////////////////////////////////////////////////////////////////////// +// +// Texture creation/updating +// + +extern GDrawTexture *gdraw_GLx_(WrappedTextureCreate)(S32 gl_texture_handle, S32 width, S32 height, rrbool has_mipmaps) +{ + GDrawStats stats={0}; + GDrawHandle *p = gdraw_res_alloc_begin(gdraw->texturecache, 0, &stats); // it may need to free one item to give us a handle + GLint old; + + glGetIntegerv(GL_TEXTURE_BINDING_2D, &old); + glBindTexture(GL_TEXTURE_2D, gl_texture_handle); + if (has_mipmaps) + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + else + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glBindTexture(GL_TEXTURE_2D, old); + + p->bytes = 0; + p->handle.tex.gl = gl_texture_handle; + p->handle.tex.w = width; + p->handle.tex.h = height; + p->handle.tex.nonpow2 = !(is_pow2(width) && is_pow2(height)); + gdraw_HandleCacheAllocateEnd(p, 0, NULL, GDRAW_HANDLE_STATE_user_owned); + return (GDrawTexture *) p; +} + +extern void gdraw_GLx_(WrappedTextureChange)(GDrawTexture *tex, S32 new_gl_texture_handle, S32 new_width, S32 new_height, rrbool has_mipmaps) +{ + GDrawHandle *p = (GDrawHandle *) tex; + GLint old; + + glGetIntegerv(GL_TEXTURE_BINDING_2D, &old); + glBindTexture(GL_TEXTURE_2D, new_gl_texture_handle); + if (has_mipmaps) + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + else + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glBindTexture(GL_TEXTURE_2D, old); + + p->handle.tex.gl = new_gl_texture_handle; + p->handle.tex.w = new_width; + p->handle.tex.h = new_height; + p->handle.tex.nonpow2 = !(is_pow2(new_width) && is_pow2(new_height)); +} + +extern void gdraw_GLx_(WrappedTextureDestroy)(GDrawTexture *tex) +{ + GDrawStats stats={0}; + gdraw_res_free((GDrawHandle *) tex, &stats); +} + +static void RADLINK gdraw_SetTextureUniqueID(GDrawTexture *tex, void *old_id, void *new_id) +{ + GDrawHandle *p = (GDrawHandle *) tex; + // if this is still the handle it's thought to be, change the owner; + // if the owner *doesn't* match, then they're changing a stale handle, so ignore + if (p->owner == old_id) + p->owner = new_id; +} + +static rrbool RADLINK gdraw_MakeTextureBegin(void *owner, S32 width, S32 height, gdraw_texture_format format, U32 flags, GDraw_MakeTexture_ProcessingInfo *p, GDrawStats *gstats) +{ + S32 size=0, asize, stride; + GDrawHandle *t = NULL; + opengl_check(); + + stride = width; + if (format == GDRAW_TEXTURE_FORMAT_rgba32) stride *= 4; + size = stride*height; + + asize = size; + if (flags & GDRAW_MAKETEXTURE_FLAGS_mipmap) asize = asize*4/3; + + t = gdraw_res_alloc_begin(gdraw->texturecache, asize, gstats); + if (!t) + return IGGY_RESULT_Error_GDraw; + + glGenTextures(1, &t->handle.tex.gl); + + p->texture_data = IggyGDrawMalloc(size); + if (!p->texture_data) { + gdraw_HandleCacheAllocateFail(t); + IggyGDrawSendWarning(NULL, "GDraw malloc for texture data failed"); + return false; + } + + t->handle.tex.w = width; + t->handle.tex.h = height; + t->handle.tex.nonpow2 = !(is_pow2(width) && is_pow2(height)); + + p->num_rows = height; + p->p0 = t; + p->p1 = owner; + p->stride_in_bytes = stride; + p->texture_type = GDRAW_TEXTURE_TYPE_rgba; + p->i0 = format; + p->i1 = flags; + p->i2 = width; + p->i3 = height; + p->i4 = asize; + opengl_check(); + return true; +} + +static GDrawTexture * RADLINK gdraw_MakeTextureEnd(GDraw_MakeTexture_ProcessingInfo *p, GDrawStats *stats) +{ + gdraw_texture_format format = (gdraw_texture_format) p->i0; + S32 flags = p->i1; + rrbool mipmap = (flags & GDRAW_MAKETEXTURE_FLAGS_mipmap) != 0; + S32 width = p->i2, height = p->i3; + GLuint z,e; + GDrawHandle *t = (GDrawHandle *) p->p0; + + z = t->handle.tex.gl; + assert(z != 0); + + make_texture(z); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + + if (format == GDRAW_TEXTURE_FORMAT_font) + glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, p->texture_data); + else + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, p->texture_data); + e = glGetError(); + break_on_err(e); + + if (mipmap) + glGenerateMipmap(GL_TEXTURE_2D); + if (!e) e = glGetError(); + + if (e != 0) { + gdraw_HandleCacheAllocateFail(t); + IggyGDrawSendWarning(NULL, "GDraw OpenGL error creating texture"); + eat_gl_err(); + return NULL; + } else { + gdraw_HandleCacheAllocateEnd(t, p->i4, p->p1, (flags & GDRAW_MAKETEXTURE_FLAGS_never_flush) ? GDRAW_HANDLE_STATE_pinned : GDRAW_HANDLE_STATE_locked); + stats->nonzero_flags |= GDRAW_STATS_alloc_tex; + stats->alloc_tex += 1; + stats->alloc_tex_bytes += p->i4; + } + + // default wrap mode is clamp to edge + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + if (mipmap) + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + else + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + + IggyGDrawFree(p->texture_data); + + opengl_check(); + return (GDrawTexture *) t; +} + +static rrbool RADLINK gdraw_UpdateTextureBegin(GDrawTexture *tex, void *unique_id, GDrawStats *stats) +{ + RR_UNUSED_VARIABLE(stats); + return gdraw_HandleCacheLock((GDrawHandle *) tex, unique_id); +} + +static void RADLINK gdraw_UpdateTextureRect(GDrawTexture *tex, void *unique_id, S32 x, S32 y, S32 stride, S32 w, S32 h, U8 *data, gdraw_texture_format format) +{ + glBindTexture(GL_TEXTURE_2D, ((GDrawHandle *) tex)->handle.tex.gl); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + // @TODO: use 'stride' + glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, (format == GDRAW_TEXTURE_FORMAT_font) ? GL_ALPHA : GL_RGBA, GL_UNSIGNED_BYTE, data); + opengl_check(); +} + +static void RADLINK gdraw_UpdateTextureEnd(GDrawTexture *tex, void *unique_id, GDrawStats *stats) +{ + gdraw_HandleCacheUnlock((GDrawHandle *) tex); +} + +static void RADLINK gdraw_FreeTexture(GDrawTexture *tt, void *unique_id, GDrawStats *gstats) +{ + GDrawHandle *t = (GDrawHandle *) tt; + assert(t != NULL); + if (t->owner == unique_id || unique_id == NULL) { + if (t->cache == &gdraw->rendertargets) { + gdraw_HandleCacheUnlock(t); + // cache it by simply not freeing it + return; + } + + gdraw_res_free(t, gstats); + } +} + +static rrbool RADLINK gdraw_TryToLockTexture(GDrawTexture *t, void *unique_id, GDrawStats *gstats) +{ + RR_UNUSED_VARIABLE(gstats); + return gdraw_HandleCacheLock((GDrawHandle *) t, unique_id); +} + +static void RADLINK gdraw_DescribeTexture(GDrawTexture *tex, GDraw_Texture_Description *desc) +{ + GDrawHandle *p = (GDrawHandle *) tex; + desc->width = p->handle.tex.w; + desc->height = p->handle.tex.h; + desc->size_in_bytes = p->bytes; +} + +static void RADLINK gdraw_SetAntialiasTexture(S32 width, U8 *rgba) +{ + if (!gdraw->aa_tex) + glGenTextures(1, &gdraw->aa_tex); + + make_texture(gdraw->aa_tex); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, rgba); + opengl_check(); +} + +//////////////////////////////////////////////////////////////////////// +// +// Vertex buffer creation/deletion +// + +static rrbool RADLINK gdraw_MakeVertexBufferBegin(void *unique_id, gdraw_vformat vformat, S32 vbuf_size, S32 ibuf_size, GDraw_MakeVertexBuffer_ProcessingInfo *p, GDrawStats *gstats) +{ + GLuint e; + GDrawHandle *vb; + opengl_check(); + vb = gdraw_res_alloc_begin(gdraw->vbufcache, vbuf_size + ibuf_size, gstats); + if (!vb) { + IggyGDrawSendWarning(NULL, "GDraw out of vertex buffer memory"); + return false; + } + + e = glGetError(); + vb->handle.vbuf.base = 0; + vb->handle.vbuf.indices = 0; + glGenBuffers(1, &vb->handle.vbuf.base); + glGenBuffers(1, &vb->handle.vbuf.indices); + glBindBuffer(GL_ARRAY_BUFFER, vb->handle.vbuf.base); + glBufferData(GL_ARRAY_BUFFER, vbuf_size, NULL, GL_STATIC_DRAW); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vb->handle.vbuf.indices); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, ibuf_size, NULL, GL_STATIC_DRAW); + if (!e) e = glGetError(); + if (e != GL_NO_ERROR) { + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + glDeleteBuffers(1, &vb->handle.vbuf.base); + glDeleteBuffers(1, &vb->handle.vbuf.indices); + gdraw_HandleCacheAllocateFail(vb); + eat_gl_err(); + IggyGDrawSendWarning(NULL, "GDraw OpenGL vertex buffer creation failed"); + return false; + } + + p->i0 = vbuf_size; + p->i1 = ibuf_size; + p->p0 = vb; + p->p1 = unique_id; + + if (!gdraw->has_mapbuffer) { + p->vertex_data = IggyGDrawMalloc(vbuf_size); + p->vertex_data_length = vbuf_size; + p->index_data = IggyGDrawMalloc(ibuf_size); + p->index_data_length = ibuf_size; + + // check for out of memory conditions + if (!p->vertex_data || !p->index_data) { + if (p->vertex_data) IggyGDrawFree(p->vertex_data); + if (p->index_data) IggyGDrawFree(p->index_data); + IggyGDrawSendWarning(NULL, "GDraw malloc for vertex buffer temporary memory failed"); + return false; + } + } else { + p->vertex_data = (U8 *)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); + p->vertex_data_length = vbuf_size; + + p->index_data = (U8 *)glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY); + p->index_data_length = ibuf_size; + } + + opengl_check(); + return true; +} + +static rrbool RADLINK gdraw_MakeVertexBufferMore(GDraw_MakeVertexBuffer_ProcessingInfo *p) +{ + assert(0); + return false; +} + +static GDrawVertexBuffer * RADLINK gdraw_MakeVertexBufferEnd(GDraw_MakeVertexBuffer_ProcessingInfo *p, GDrawStats *stats) +{ + GDrawHandle *vb = (GDrawHandle *) p->p0; + rrbool ok = true; + GLuint e; + + if (!gdraw->has_mapbuffer) { + glBufferData(GL_ARRAY_BUFFER, p->i0, p->vertex_data, GL_STATIC_DRAW); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, p->i1, p->index_data, GL_STATIC_DRAW); + IggyGDrawFree(p->vertex_data); + IggyGDrawFree(p->index_data); + } else { + if (!glUnmapBuffer(GL_ARRAY_BUFFER)) ok = false; + if (!glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER)) ok = false; + } + + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + + e = glGetError(); + if (!ok || e != GL_NO_ERROR) { + glDeleteBuffers(1, &vb->handle.vbuf.base); + glDeleteBuffers(1, &vb->handle.vbuf.indices); + gdraw_HandleCacheAllocateFail(vb); + eat_gl_err(); + return NULL; + } else + gdraw_HandleCacheAllocateEnd(vb, p->i0 + p->i1, p->p1, GDRAW_HANDLE_STATE_locked); + + opengl_check(); + return (GDrawVertexBuffer *) vb; +} + +static rrbool RADLINK gdraw_TryToLockVertexBuffer(GDrawVertexBuffer *vb, void *unique_id, GDrawStats *stats) +{ + RR_UNUSED_VARIABLE(stats); + return gdraw_HandleCacheLock((GDrawHandle *) vb, unique_id); +} + +static void RADLINK gdraw_FreeVertexBuffer(GDrawVertexBuffer *vb, void *unique_id, GDrawStats *stats) +{ + GDrawHandle *h = (GDrawHandle *) vb; + assert(h != NULL); + if (h->owner == unique_id) + gdraw_res_free(h, stats); +} + +static void RADLINK gdraw_DescribeVertexBuffer(GDrawVertexBuffer *vbuf, GDraw_VertexBuffer_Description *desc) +{ + GDrawHandle *p = (GDrawHandle *) vbuf; + desc->size_in_bytes = p->bytes; +} + +//////////////////////////////////////////////////////////////////////// +// +// Create/free (or cache) render targets +// + +static GDrawHandle *get_rendertarget_texture(int width, int height, void *owner, GDrawStats *gstats) +{ + S32 size; + GDrawHandle *t; + opengl_check(); + t = gdraw_HandleCacheGetLRU(&gdraw->rendertargets); + if (t) { + gdraw_HandleCacheLock(t, (void *) (UINTa) 1); + return t; + } + + size = gdraw->frametex_width * gdraw->frametex_height * 4; + t = gdraw_res_alloc_begin(gdraw->texturecache, size, gstats); + if (!t) return t; + + glGenTextures(1, &t->handle.tex.gl); + make_rendertarget(t, t->handle.tex.gl, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, width, height, 4); + t->handle.tex.w = gdraw->frametex_width; + t->handle.tex.h = gdraw->frametex_height; + t->handle.tex.nonpow2 = 1; // assume all rendertargets are non-pow2 for consistency + gstats->nonzero_flags |= GDRAW_STATS_alloc_tex; + gstats->alloc_tex += 1; + gstats->alloc_tex_bytes += size; + opengl_check(); + gdraw_HandleCacheAllocateEnd(t, size, owner, GDRAW_HANDLE_STATE_locked); + + return t; +} + +static GDrawHandle *get_color_rendertarget(GDrawStats *gstats) +{ + S32 size; + GDrawHandle *t; + opengl_check(); + t = gdraw_HandleCacheGetLRU(&gdraw->rendertargets); + if (t) { + gdraw_HandleCacheLock(t, (void *) (UINTa) 1); + return t; + } + + // ran out of RTs, allocate a new one + size = gdraw->frametex_width * gdraw->frametex_height * 4; + if (gdraw->rendertargets.bytes_free < size) { + IggyGDrawSendWarning(NULL, "GDraw exceeded available rendertarget memory"); + return NULL; + } + + t = gdraw_HandleCacheAllocateBegin(&gdraw->rendertargets); + if (!t) { + IggyGDrawSendWarning(NULL, "GDraw exceeded available rendertarget handles"); + return t; + } + + glGenTextures(1, &t->handle.tex.gl); + make_rendertarget(t, t->handle.tex.gl, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, gdraw->frametex_width,gdraw->frametex_height, 4); + t->handle.tex.w = gdraw->frametex_width; + t->handle.tex.h = gdraw->frametex_height; + t->handle.tex.nonpow2 = 1; // assume all rendertargets are non-pow2 for consistency + +#ifdef GDRAW_MULTISAMPLING + if (gdraw->multisampling) { + glGenRenderbuffers(1, &t->handle.tex.gl_renderbuf); + glBindRenderbuffer(GL_RENDERBUFFER, t->handle.tex.gl_renderbuf); + glRenderbufferStorageMultisample(GL_RENDERBUFFER, gdraw->multisampling, GL_RGBA, gdraw->frametex_width, gdraw->frametex_height); + glBindRenderbuffer(GL_RENDERBUFFER, 0); + } +#endif + opengl_check(); + + gdraw_HandleCacheAllocateEnd(t, size, (void *) (UINTa) 1, GDRAW_HANDLE_STATE_locked); + gstats->nonzero_flags |= GDRAW_STATS_alloc_tex; + gstats->alloc_tex += gdraw->multisampling ? 2 : 1; + gstats->alloc_tex_bytes += (1 + gdraw->multisampling) * size; + + return t; +} + +static GDrawHandle *get_depthstencil_renderbuffer(GDrawStats *gstats) +{ + if (!gdraw->stencil_depth.handle.tex.gl) { + gstats->nonzero_flags |= GDRAW_STATS_alloc_tex; + gstats->alloc_tex += 1; + +#ifdef GDRAW_MULTISAMPLING + if (gdraw->multisampling) { + glGenRenderbuffers(1, &gdraw->stencil_depth.handle.tex.gl); + glBindRenderbuffer(GL_RENDERBUFFER, gdraw->stencil_depth.handle.tex.gl); + glRenderbufferStorageMultisample(GL_RENDERBUFFER, gdraw->multisampling, GL_DEPTH24_STENCIL8, gdraw->frametex_width, gdraw->frametex_height); + + gstats->alloc_tex_bytes += gdraw->multisampling * 4 * gdraw->frametex_width * gdraw->frametex_height; + } else { +#endif + if (gdraw->has_packed_depth_stencil) { + glGenRenderbuffers(1, &gdraw->stencil_depth.handle.tex.gl); + glBindRenderbuffer(GL_RENDERBUFFER, gdraw->stencil_depth.handle.tex.gl); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, gdraw->frametex_width, gdraw->frametex_height); + + gdraw->stencil_depth.handle.tex.gl_renderbuf = gdraw->stencil_depth.handle.tex.gl; + } else { + // this path is mainly for the iOS simulator + glGenRenderbuffers(1, &gdraw->stencil_depth.handle.tex.gl); + glBindRenderbuffer(GL_RENDERBUFFER, gdraw->stencil_depth.handle.tex.gl); + glRenderbufferStorage(GL_RENDERBUFFER, gdraw->has_depth24 ? GL_DEPTH_COMPONENT24 : GL_DEPTH_COMPONENT16, gdraw->frametex_width, gdraw->frametex_height); + + glGenRenderbuffers(1, &gdraw->stencil_depth.handle.tex.gl_renderbuf); + glBindRenderbuffer(GL_RENDERBUFFER, gdraw->stencil_depth.handle.tex.gl_renderbuf); + glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, gdraw->frametex_width, gdraw->frametex_height); + } + + gstats->alloc_tex_bytes += 4 * gdraw->frametex_width * gdraw->frametex_height; +#ifdef GDRAW_MULTISAMPLING + } +#endif + + glBindRenderbuffer(GL_RENDERBUFFER, 0); + opengl_check(); + } + return &gdraw->stencil_depth; +} + +static void flush_rendertargets(GDrawStats *stats) +{ + gdraw_res_flush(&gdraw->rendertargets, stats); + + if (gdraw->stencil_depth.handle.tex.gl_renderbuf && + gdraw->stencil_depth.handle.tex.gl_renderbuf != gdraw->stencil_depth.handle.tex.gl) { + glDeleteRenderbuffers(1, &gdraw->stencil_depth.handle.tex.gl_renderbuf); + gdraw->stencil_depth.handle.tex.gl_renderbuf = 0; + } + + if (gdraw->stencil_depth.handle.tex.gl) { + glDeleteRenderbuffers(1, &gdraw->stencil_depth.handle.tex.gl); + gdraw->stencil_depth.handle.tex.gl = 0; + } + opengl_check(); +} + +//////////////////////////////////////////////////////////////////////// +// +// Begin rendering for a frame +// + +static void lazy_shader(ProgramWithCachedVariableLocations *ptr); + +static RADINLINE void use_lazy_shader(ProgramWithCachedVariableLocations *prg) +{ + if (!prg->program) + lazy_shader(prg); // already does a glUseProgram! + else + glUseProgram(prg->program); +} + +static void set_viewport(void) +{ + if (gdraw->in_blur) { + glViewport(0, 0, gdraw->tpw, gdraw->tph); + } else if (gdraw->cur == gdraw->frame) { + glViewport(gdraw->vx, gdraw->vy, gdraw->tw, gdraw->th); + } else if (gdraw->cur->cached) { + glViewport(0, 0, gdraw->cur->width, gdraw->cur->height); + } else { + glViewport(0, 0, gdraw->tpw, gdraw->tph); + // we need to translate from naive pixel space to align a tile + } + opengl_check(); +} + +static void set_projection_raw(S32 x0, S32 x1, S32 y0, S32 y1) +{ + gdraw->projection[0] = 2.0f / (x1-x0); + gdraw->projection[1] = 2.0f / (y1-y0); + gdraw->projection[2] = (x1+x0)/(F32)(x0-x1); + gdraw->projection[3] = (y1+y0)/(F32)(y0-y1); +} + +static void set_projection(void) +{ + if (gdraw->in_blur) + set_projection_raw(0, gdraw->tpw, gdraw->tph, 0); + else if (gdraw->cur == gdraw->frame) + set_projection_raw(gdraw->tx0, gdraw->tx0 + gdraw->tw, gdraw->ty0 + gdraw->th, gdraw->ty0); + else if (gdraw->cur->cached) + set_projection_raw(gdraw->cur->base_x, gdraw->cur->base_x + gdraw->cur->width, gdraw->cur->base_y, gdraw->cur->base_y + gdraw->cur->height); + else + set_projection_raw(gdraw->tx0p, gdraw->tx0p + gdraw->tpw, gdraw->ty0p + gdraw->tph, gdraw->ty0p); +} + +static void clear_renderstate(void) +{ + clear_renderstate_platform_specific(); + + // deactivate aa_tex + glActiveTexture(GL_TEXTURE0 + AATEX_SAMPLER); + glBindTexture(GL_TEXTURE_2D, 0); + + glColorMask(1,1,1,1); + glDepthMask(GL_TRUE); + + glDisable(GL_CULL_FACE); + glDisable(GL_BLEND); + glDisable(GL_DEPTH_TEST); + glDisable(GL_STENCIL_TEST); + glDisable(GL_SCISSOR_TEST); + glActiveTexture(GL_TEXTURE0); + + glUseProgram(0); + opengl_check(); +} + +static void set_common_renderstate(void) +{ + clear_renderstate(); + + // activate aa_tex + glActiveTexture(GL_TEXTURE0 + AATEX_SAMPLER); + glBindTexture(GL_TEXTURE_2D, gdraw->aa_tex); + glActiveTexture(GL_TEXTURE0); +} + +void gdraw_GLx_(SetTileOrigin)(S32 x, S32 y, U32 framebuffer) +{ + gdraw->vx = x; + gdraw->vy = y; + gdraw->main_framebuffer = framebuffer; +} + +static void RADLINK gdraw_SetViewSizeAndWorldScale(S32 w, S32 h, F32 scalex, F32 scaley) +{ + memset(gdraw->frame, 0, sizeof(gdraw->frame)); + gdraw->cur = gdraw->frame; + gdraw->fw = w; + gdraw->fh = h; + gdraw->world_to_pixel[0] = scalex; + gdraw->world_to_pixel[1] = scaley; +} + +static void RADLINK gdraw_Set3DTransform(F32 *mat) +{ + if (mat == NULL) + gdraw->use_3d = 0; + else { + gdraw->use_3d = 1; + memcpy(gdraw->xform_3d, mat, sizeof(gdraw->xform_3d)); + } +} + +// must include anything necessary for texture creation/update +static void RADLINK gdraw_RenderingBegin(void) +{ +} +static void RADLINK gdraw_RenderingEnd(void) +{ +} + +static void RADLINK gdraw_RenderTileBegin(S32 x0, S32 y0, S32 x1, S32 y1, S32 pad, GDrawStats *gstats) +{ + opengl_check(); + + if (x0 == 0 && y0 == 0 && x1 == gdraw->fw && y1 == gdraw->fh) { + pad = 0; + gdraw->tile_enabled = false; + } else { + gdraw->tile_enabled = true; + } + + gdraw->tx0 = x0; + gdraw->ty0 = y0; + gdraw->tw = x1-x0; + gdraw->th = y1-y0; + gdraw->tpw = gdraw->tw + pad*2; + gdraw->tph = gdraw->th + pad*2; + // origin of padded region + gdraw->tx0p = x0 - pad; + gdraw->ty0p = y0 - pad; + + if (gdraw->tpw > gdraw->frametex_width || gdraw->tph > gdraw->frametex_height) { + gdraw->frametex_width = RR_MAX(gdraw->tpw, gdraw->frametex_width); + gdraw->frametex_height = RR_MAX(gdraw->tph, gdraw->frametex_height); + + flush_rendertargets(gstats); + } + + set_viewport(); + set_projection(); + set_common_renderstate(); + + glBindFramebuffer(GL_FRAMEBUFFER, gdraw->main_framebuffer); + opengl_check(); +} + +static void RADLINK gdraw_RenderTileEnd(GDrawStats *stats) +{ + clear_renderstate(); +} + +#define MAX_DEPTH_VALUE (1 << 13) + +static void RADLINK gdraw_GetInfo(GDrawInfo *d) +{ + GLint maxtex; + + opengl_check(); + glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxtex); + + d->num_stencil_bits = 8; + d->max_id = MAX_DEPTH_VALUE-2; + // for floating point depth, just use mantissa, e.g. 16-20 bits + d->max_texture_size = maxtex; + d->buffer_format = GDRAW_BFORMAT_vbib; + d->shared_depth_stencil = 0; + d->always_mipmap = 0; + d->conditional_nonpow2 = gdraw->has_conditional_non_power_of_two; + opengl_check(); +} + + +//////////////////////////////////////////////////////////////////////// +// +// Enable/disable rendertargets in stack fashion +// + +static void clear_with_rect(gswf_recti *region, rrbool clear_depth, GDrawStats *stats); + +static void set_render_target_state(void) +{ + GLint h; +#ifdef GDRAW_MULTISAMPLING + if (gdraw->multisampling) { + glGetIntegerv(GL_FRAMEBUFFER_BINDING, &h); + h = gdraw->cur->color_buffer ? gdraw->cur->color_buffer->handle.tex.gl_renderbuf : 0; + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 , GL_RENDERBUFFER, h); + h = gdraw->cur->stencil_depth ? gdraw->cur->stencil_depth->handle.tex.gl : 0; + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT , GL_RENDERBUFFER, h); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, h); + } else { +#endif + h = gdraw->cur->color_buffer ? gdraw->cur->color_buffer->handle.tex.gl : 0; + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 , GL_TEXTURE_2D, h, 0); + if (gdraw->cur->stencil_depth) { + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, gdraw->cur->stencil_depth->handle.tex.gl); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, gdraw->cur->stencil_depth->handle.tex.gl_renderbuf); + } else { + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0); + } +#ifdef GDRAW_MULTISAMPLING + } +#endif + opengl_check(); +} + +static rrbool RADLINK gdraw_TextureDrawBufferBegin(gswf_recti *region, gdraw_texture_format format, U32 flags, void *owner, GDrawStats *gstats) +{ + GDrawFramebufferState *n = gdraw->cur+1; + GDrawHandle *t; + int k; + if (gdraw->tw == 0 || gdraw->th == 0) { + IggyGDrawSendWarning(NULL, "GDraw got a request for an empty rendertarget"); + return false; + } + + if (n >= &gdraw->frame[MAX_RENDER_STACK_DEPTH]) { + IggyGDrawSendWarning(NULL, "GDraw rendertarget nesting exceeded MAX_RENDER_STACK_DEPTH"); + return false; + } + + if (owner) { + t = get_rendertarget_texture(region->x1 - region->x0, region->y1 - region->y0, owner, gstats); + if (!t) { + IggyGDrawSendWarning(NULL, "GDraw ran out of rendertargets for cacheAsBItmap"); + return false; + } + } else { + t = get_color_rendertarget(gstats); + if (!t) { + IggyGDrawSendWarning(NULL, "GDraw ran out of rendertargets"); + return false; + } + } + n->color_buffer = t; + assert(n->color_buffer != NULL); + + if (n == gdraw->frame+1) + n->stencil_depth = get_depthstencil_renderbuffer(gstats); + else + n->stencil_depth = (n-1)->stencil_depth; + ++gdraw->cur; + + gdraw->cur->cached = owner != NULL; + if (owner) { + gdraw->cur->base_x = region->x0; + gdraw->cur->base_y = region->y0; + gdraw->cur->width = region->x1 - region->x0; + gdraw->cur->height = region->y1 - region->y0; + } + + gstats->nonzero_flags |= GDRAW_STATS_rendtarg; + + glBindFramebuffer(GL_FRAMEBUFFER, gdraw->framebuffer_stack_object); + set_render_target_state(); + + assert(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE); + + // viewport for clear (make sure scissor is inside viewport just in case) + glViewport(0, 0, gdraw->frametex_width, gdraw->frametex_height); + + k = (int) (n->color_buffer - gdraw->rendertargets.handle); + if (region) { + S32 ox, oy; + + // in a perfect world, we'd only need 1 pixel of border on all sides for + // bilinear filtering, which would mean pad = 1. however, texture interpolator + // precision is not that high even on PC parts, and if we only use 1 pixel of + // padding we will often get some un-filled pixels "creeping in" from the sides. + // pad = 2 is fine on recent PC parts, but not old PC parts or even fairly new + // mobile parts, so we play it safe and use 3 pixels which so far gives good + // results everywhere. + S32 pad = 3; + + // region.x0,y0 are the top left of the rectangle in display space + // x,y are the *bottom* left of the rectangle in window space + S32 h = gdraw->tph; + S32 xt0, yt0, xt1, yt1; + S32 x0, y0, x1, y1; + + if (gdraw->in_blur || !gdraw->tile_enabled) + ox = oy = 0; + else + ox = gdraw->tx0, oy = gdraw->ty0; + + // clamp region to tile (in gdraw coords) + xt0 = RR_MAX(region->x0 - ox, 0); + yt0 = RR_MAX(region->y0 - oy, 0); + xt1 = RR_MIN(region->x1 - ox, gdraw->tpw); + yt1 = RR_MIN(region->y1 - oy, gdraw->tph); + + // but the padding gets clamped to framebuffer coords! also transfer to window space here. + x0 = RR_MAX( xt0 - pad, 0); + y0 = RR_MAX(h - yt1 - pad, 0); + x1 = RR_MIN( xt1 + pad, gdraw->frametex_width); + y1 = RR_MIN(h - yt0 + pad, gdraw->frametex_height); + + if (x1 <= x0 || y1 <= y0) { // region doesn't intersect with current tile + --gdraw->cur; + + // remove color and stencil buffers + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 , GL_TEXTURE_2D, 0, 0); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT , GL_TEXTURE_2D, 0, 0); + + // switch render target back + if (gdraw->cur == gdraw->frame) + glBindFramebuffer(GL_FRAMEBUFFER, gdraw->main_framebuffer); + else + set_render_target_state(); + + set_viewport(); + set_projection(); + opengl_check(); + + // free our render target + gdraw_FreeTexture((GDrawTexture *) n->color_buffer, 0, gstats); + + // note: don't send a warning since this will happen during regular tiled rendering + return false; + } + + glEnable(GL_SCISSOR_TEST); + glScissor(x0, y0, x1 - x0, y1 - y0); + gdraw->rt_valid[k].x0 = xt0; + gdraw->rt_valid[k].y0 = yt0; + gdraw->rt_valid[k].x1 = xt1; + gdraw->rt_valid[k].y1 = yt1; + gstats->cleared_pixels += (x1 - x0) * (y1 - y0); + } else { + glDisable(GL_SCISSOR_TEST); + gdraw->rt_valid[k].x0 = 0; + gdraw->rt_valid[k].y0 = 0; + gdraw->rt_valid[k].x1 = gdraw->frametex_width; + gdraw->rt_valid[k].y1 = gdraw->frametex_height; + gstats->cleared_pixels += gdraw->frametex_width * gdraw->frametex_height; + } + + gstats->nonzero_flags |= GDRAW_STATS_clears; + gstats->num_clears += 1; + +#ifdef GDRAW_FEWER_CLEARS + if (region) { + clear_with_rect(region, n==gdraw->frame+1, gstats); + } else +#endif // GDRAW_FEWER_CLEARS + { + glClearColor(0,0,0,0); // must clear destination alpha + glClearStencil(0); + glClearDepth(1); + glStencilMask(255); + glDepthMask(GL_TRUE); + glColorMask(1,1,1,1); + glDisable(GL_STENCIL_TEST); + if (n == gdraw->frame+1) + glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + else + glClear(GL_COLOR_BUFFER_BIT); + } + + set_viewport(); + set_projection(); + + opengl_check(); + + return true; +} + + +static GDrawTexture *RADLINK gdraw_TextureDrawBufferEnd(GDrawStats *gstats) +{ + GDrawFramebufferState *n = gdraw->cur; + GDrawFramebufferState *m = --gdraw->cur; + if (gdraw->fw == 0 || gdraw->fh == 0) return 0; + + if (n >= &gdraw->frame[MAX_RENDER_STACK_DEPTH]) + return 0; // already returned a warning in Start...() + + assert(m >= gdraw->frame); // bug in Iggy -- unbalanced + + if (m != gdraw->frame) + assert(m->color_buffer != NULL); + assert(n->color_buffer != NULL); + + // remove color and stencil buffers + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 , GL_RENDERBUFFER, 0); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT , GL_RENDERBUFFER, 0); + +#ifdef GDRAW_MULTISAMPLING + if (gdraw->multisampling) { + // blit from multisample to texture + if (n->color_buffer->handle.tex.gl_renderbuf) { + GLuint res; + glBindFramebuffer(GL_READ_FRAMEBUFFER, gdraw->framebuffer_copy_to_texture); + glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0); + glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0); + glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0); + glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0); + glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, n->color_buffer->handle.tex.gl_renderbuf); + glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, n->color_buffer->handle.tex.gl, 0); + res = glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER); + glBlitFramebuffer(0,0,gdraw->tpw,gdraw->tph,0,0,gdraw->tpw,gdraw->tph, GL_COLOR_BUFFER_BIT, GL_NEAREST); + gstats->nonzero_flags |= GDRAW_STATS_blits; + gstats->num_blits += 1; + gstats->num_blit_pixels += (gdraw->tpw * gdraw->tph); + + glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, 0); + glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, 0); + glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); + } + } +#endif + + gstats->nonzero_flags |= GDRAW_STATS_rendtarg; + gstats->rendertarget_changes += 1; + + // set the new state + if (m == gdraw->frame) // back to initial framebuffer + glBindFramebuffer(GL_FRAMEBUFFER, gdraw->main_framebuffer); + else + set_render_target_state(); + + // reset the viewport if we've reached the root scope + set_viewport(); + set_projection(); + + opengl_check(); + + return (GDrawTexture *) n->color_buffer; +} + + +//////////////////////////////////////////////////////////////////////// +// +// Clear stencil/depth buffers +// +// Open question whether we'd be better off finding bounding boxes +// and only clearing those; it depends exactly how fast clearing works. +// + +static void RADLINK gdraw_ClearStencilBits(U32 bits) +{ + glDisable(GL_SCISSOR_TEST); + glStencilMask(bits); + glClearStencil(0); + glClear(GL_STENCIL_BUFFER_BIT); + opengl_check(); +} + +// this only happens rarely (hopefully never) if we use the depth buffer, +// so we can just clear the whole thing +static void RADLINK gdraw_ClearID(void) +{ + glDisable(GL_SCISSOR_TEST); + glClearDepth(1); + glDepthMask(GL_TRUE); + glClear(GL_DEPTH_BUFFER_BIT); + opengl_check(); +} + + +//////////////////////////////////////////////////////////////////////// +// +// Set all the render state from GDrawRenderState +// +// This also is responsible for getting the framebuffer into a texture +// if the read-modify-write blend operation can't be expressed with +// the native blend operators. (E.g. "screen") +// + +enum +{ + VVAR_world0 = 0, + VVAR_world1 = 1, + VVAR_xoff = 2, + VVAR_texgen_s = 3, + VVAR_texgen_t = 4, + VVAR_viewproj = 5, + VVAR_x3d = 5, + VVAR_y3d = 6, + VVAR_z3d = 7, +}; + +// convert an ID request to a value suitable for the depth buffer, +// in homogeneous clip space with w=1 (depth from -1..1) +static float depth_from_id(S32 id) +{ + return 1.0f - 2.0f*(id+1) / (F32) MAX_DEPTH_VALUE; +} + +static void set_texture(U32 texunit, GDrawTexture *tex) +{ + glActiveTexture(GL_TEXTURE0 + texunit); + if (tex == NULL) + glBindTexture(GL_TEXTURE_2D, 0); + else + glBindTexture(GL_TEXTURE_2D, ((GDrawHandle *) tex)->handle.tex.gl); +} + +static void set_world_projection(const int *vvars, const F32 world[2*4]) +{ + assert(vvars[VVAR_world0] >= 0 && vvars[VVAR_world1] >= 0 && vvars[VVAR_viewproj] >= 0); + glUniform4fv(vvars[VVAR_world0], 1, world + 0); + glUniform4fv(vvars[VVAR_world1], 1, world + 4); + glUniform4fv(vvars[VVAR_viewproj], 1, gdraw->projection); +} + +static void set_3d_projection(const int *vvars, const F32 world[2*4], const F32 xform[3][4]) +{ + assert(vvars[VVAR_world0] >= 0 && vvars[VVAR_world1] >= 0); + glUniform4fv(vvars[VVAR_world0], 1, world + 0); + glUniform4fv(vvars[VVAR_world1], 1, world + 4); + + assert(vvars[VVAR_x3d] >= 0 && vvars[VVAR_y3d] >= 0 && vvars[VVAR_z3d] >= 0); + glUniform4fv(vvars[VVAR_x3d], 1, xform[0]); + glUniform4fv(vvars[VVAR_y3d], 1, xform[1]); + glUniform4fv(vvars[VVAR_z3d], 1, xform[2]); +} + + +static int set_render_state(GDrawRenderState *r, S32 vformat, const int **ovvars, GDrawPrimitive *p, GDrawStats *gstats) +{ + static struct gdraw_gl_blendspec { + GLboolean enable; + GLenum src; + GLenum dst; + } blends[ASSERT_COUNT(GDRAW_BLEND__count, 6)] = { + { GL_FALSE, GL_ONE, GL_ZERO }, // GDRAW_BLEND_none + { GL_TRUE, GL_ONE, GL_ONE_MINUS_SRC_ALPHA }, // GDRAW_BLEND_alpha + { GL_TRUE, GL_DST_COLOR, GL_ONE_MINUS_SRC_ALPHA }, // GDRAW_BLEND_multiply + { GL_TRUE, GL_ONE, GL_ONE }, // GDRAW_BLEND_add + + { GL_FALSE, GL_ONE, GL_ZERO }, // GDRAW_BLEND_filter + { GL_FALSE, GL_ONE, GL_ZERO }, // GDRAW_BLEND_special + }; + + F32 world[2*4]; + ProgramWithCachedVariableLocations *prg; + int *fvars, *vvars; + int blend_mode; + + opengl_check(); + assert((vformat >= 0 && vformat < GDRAW_vformat__basic_count) || vformat == GDRAW_vformat_ihud1); + + if (vformat == GDRAW_vformat_ihud1) { + glEnable(GL_BLEND); + glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); // premultiplied alpha blend mode + prg = &gdraw->ihud[0]; + } else { + // apply the major blend mode + blend_mode = r->blend_mode; + assert(blend_mode >= 0 && blend_mode < sizeof(blends)/sizeof(*blends)); + if (blends[blend_mode].enable) { + glEnable(GL_BLEND); + glBlendFunc(blends[blend_mode].src, blends[blend_mode].dst); + } else + glDisable(GL_BLEND); + + // set the fragment program if it wasn't set above + if (r->blend_mode != GDRAW_BLEND_special) { + // make sure data has been initialized + int which = r->tex0_mode, additive = 0; + + if (r->cxf_add) { + additive = 1; + if (r->cxf_add[3]) additive = 2; + } + + prg = &gdraw->fprog[which][additive][vformat]; + } else + prg = &gdraw->exceptional_blend[r->special_blend]; + } + + use_lazy_shader(prg); + opengl_check(); + fvars = prg->vars[0]; + vvars = prg->vars[1]; + + if (vformat == GDRAW_vformat_ihud1) { + F32 wv[2][4] = { 1.0f/960,0,0,-1.0, 0,-1.0f/540,0,+1.0 }; + glUniform4fv(vvars[VAR_ihudv_worldview], 2, wv[0]); + opengl_check(); + glUniform4fv(vvars[VAR_ihudv_material], p->uniform_count, p->uniforms); + opengl_check(); + glUniform1f(vvars[VAR_ihudv_textmode], p->drawprim_mode ? 0.0f : 1.0f); + opengl_check(); + } else { + + // set vertex shader constants + if (!r->use_world_space) + gdraw_ObjectSpace(world, r->o2w, depth_from_id(r->id), 0.0f); + else + gdraw_WorldSpace(world, gdraw->world_to_pixel, depth_from_id(r->id), 0.0f); + + #ifdef FLASH_10 + set_3d_projection(vvars, world, gdraw->xform_3d); + #else + set_world_projection(vvars, world); + #endif + + if (vvars[VVAR_xoff] >= 0) + glUniform4fv(vvars[VVAR_xoff], 1, r->edge_matrix); + + if (r->texgen0_enabled) { + assert(vvars[VVAR_texgen_s] >= 0 && vvars[VVAR_texgen_t] >= 0); + glUniform4fv(vvars[VVAR_texgen_s], 1, r->s0_texgen); + glUniform4fv(vvars[VVAR_texgen_t], 1, r->t0_texgen); + } + } + + // texture stuff + set_texture(0, r->tex[0]); + opengl_check(); + + if (r->tex[0] && gdraw->has_conditional_non_power_of_two && ((GDrawHandle*) r->tex[0])->handle.tex.nonpow2) { + // only wrap mode allowed in conditional nonpow2 is clamp; this should + // have been set when the texture was created, but to be on the safe side... + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + } else switch (r->wrap0) { + case GDRAW_WRAP_repeat: + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + break; + case GDRAW_WRAP_clamp: + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + break; + case GDRAW_WRAP_mirror: + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT); + break; + } + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, r->nearest0 ? GL_NEAREST : GL_LINEAR); + + // fragment shader constants + + if (fvars[VAR_cmul] >= 0) + glUniform4f(fvars[VAR_cmul], r->color[0], r->color[1], r->color[2], r->color[3]); + if (fvars[VAR_cadd] >= 0) + if (r->cxf_add) + glUniform4f(fvars[VAR_cadd], r->cxf_add[0]/255.0f, r->cxf_add[1]/255.0f, r->cxf_add[2]/255.0f, r->cxf_add[3]/255.0f); + else + glUniform4f(fvars[VAR_cadd], 0,0,0,0); + if (fvars[VAR_focal] >= 0) + glUniform4fv(fvars[VAR_focal], 1, r->focal_point); + + glActiveTexture(GL_TEXTURE0); + + // Set pixel operation states + + if (r->scissor) { + S32 x0,y0,x1,y1; + // scissor.x0,y0 are the top left of the rectangle in display space + // x,y are the *bottom* left of the rectangle in window space + x0 = r->scissor_rect.x0; + y0 = r->scissor_rect.y1; + x1 = r->scissor_rect.x1; + y1 = r->scissor_rect.y0; + // convert into tile-relative coordinates + if (gdraw->tile_enabled) { + x0 -= gdraw->tx0; + y0 -= gdraw->ty0; + x1 -= gdraw->tx0; + y1 -= gdraw->ty0; + } + // convert bottom-most edge to bottom-relative + y0 = (gdraw->th) - y0; + y1 = (gdraw->th) - y1; + if (gdraw->cur == gdraw->frame) { + // move into viewport space + x0 += gdraw->vx; + y0 += gdraw->vy; + x1 += gdraw->vx; + y1 += gdraw->vy; + } + glScissor(x0,y0,x1-x0,y1-y0); + glEnable(GL_SCISSOR_TEST); + } else + glDisable(GL_SCISSOR_TEST); + + glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); + glStencilMask(r->stencil_set); + glStencilFunc(GL_EQUAL, 255, r->stencil_test); + if (r->stencil_set | r->stencil_test) + glEnable(GL_STENCIL_TEST); + else + glDisable(GL_STENCIL_TEST); + + if (r->stencil_set) + glColorMask(0,0,0,0); + else + glColorMask(1,1,1,1); + + if (r->test_id) { + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_LESS); + } else { + glDisable(GL_DEPTH_TEST); + glDepthFunc(GL_LESS); + } + + if (r->set_id) + glDepthMask(GL_TRUE); + else + glDepthMask(GL_FALSE); + + opengl_check(); + if (ovvars) + *ovvars = vvars; + + return 1; +} + +//////////////////////////////////////////////////////////////////////// +// +// Vertex formats +// + +static void set_vertex_format(S32 format, F32 *vertices) +{ + switch (format) { + case GDRAW_vformat_v2: + glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, vertices); + glEnableVertexAttribArray(0); + break; + + case GDRAW_vformat_v2aa: + glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 16, vertices); + glVertexAttribPointer(1, 4, GL_SHORT, GL_FALSE, 16, vertices+2); + glEnableVertexAttribArray(0); + glEnableVertexAttribArray(1); + break; + + case GDRAW_vformat_v2tc2: + glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 16, vertices); + glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 16, vertices+2); + glEnableVertexAttribArray(0); + glEnableVertexAttribArray(1); + break; + + case GDRAW_vformat_ihud1: + glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 20, vertices); + glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 20, vertices+2); + glVertexAttribPointer(2, 4, GL_UNSIGNED_BYTE, GL_TRUE, 20, vertices+4); + glEnableVertexAttribArray(0); + glEnableVertexAttribArray(1); + glEnableVertexAttribArray(2); + break; + + default: + assert(0); + } +} + +static void reset_vertex_format(S32 format) +{ + // we don't use attrib #1 for all formats, but doesn't seem worthwhile to check + format = format; + glDisableVertexAttribArray(0); + glDisableVertexAttribArray(1); + glDisableVertexAttribArray(2); +} + +//////////////////////////////////////////////////////////////////////// +// +// Draw triangles with a given renderstate +// + +static void tag_resources(void *r1, void *r2, void *r3) +{ + U64 now = gdraw->frame_counter; + if (r1) ((GDrawHandle *) r1)->fence.value = now; + if (r2) ((GDrawHandle *) r2)->fence.value = now; + if (r3) ((GDrawHandle *) r3)->fence.value = now; +} + +static int vformat_stride[] = +{ + 2,4,4,5 +}; + +static void RADLINK gdraw_DrawIndexedTriangles(GDrawRenderState *r, GDrawPrimitive *p, GDrawVertexBuffer *buf, GDrawStats *gstats) +{ + GDrawHandle *vb = (GDrawHandle *) buf; + if (vb) { + glBindBuffer(GL_ARRAY_BUFFER, vb->handle.vbuf.base); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vb->handle.vbuf.indices); + } else { + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + } + + if (!set_render_state(r,p->vertex_format, NULL, p, gstats)) return; + gstats->nonzero_flags |= GDRAW_STATS_batches; + gstats->num_batches += 1; + gstats->drawn_indices += p->num_indices; + gstats->drawn_vertices += p->num_vertices; + + if (vb || p->indices) { // regular path + set_vertex_format(p->vertex_format, p->vertices); + glDrawElements(GL_TRIANGLES, p->num_indices, GL_UNSIGNED_SHORT, p->indices); + } else { // dynamic quads + S32 pos = 0; + U32 stride = vformat_stride[p->vertex_format]; // in units of sizeof(F32) + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, gdraw->quad_ib); + assert(p->num_vertices % 4 == 0); + + while (pos < p->num_vertices) { + S32 vert_count = RR_MIN(p->num_vertices - pos, QUAD_IB_COUNT * 4); + set_vertex_format(p->vertex_format, p->vertices + pos*stride); + glDrawElements(GL_TRIANGLES, (vert_count >> 2) * 6, GL_UNSIGNED_SHORT, NULL); + pos += vert_count; + } + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + } + reset_vertex_format(p->vertex_format); + + if (vb) { + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + } + + opengl_check(); + tag_resources(vb, r->tex[0], r->tex[1]); +} + +/////////////////////////////////////////////////////////////////////// +// +// Flash 8 filter effects +// + +// caller sets up texture coordinates +static void do_screen_quad(gswf_recti *s, F32 *tc, const int *vvars, GDrawStats *gstats, F32 depth) +{ + F32 px0 = (F32) s->x0, py0 = (F32) s->y0, px1 = (F32) s->x1, py1 = (F32) s->y1; + F32 s0 = tc[0], t0 = tc[1], s1 = tc[2], t1 = tc[3]; + F32 vert[4][4]; + F32 world[2*4]; + + opengl_check(); + + vert[0][0] = px0; vert[0][1] = py0; vert[0][2] = s0; vert[0][3] = t0; + vert[1][0] = px1; vert[1][1] = py0; vert[1][2] = s1; vert[1][3] = t0; + vert[2][0] = px1; vert[2][1] = py1; vert[2][2] = s1; vert[2][3] = t1; + vert[3][0] = px0; vert[3][1] = py1; vert[3][2] = s0; vert[3][3] = t1; + + opengl_check(); + gdraw_PixelSpace(world); + world[2] = depth; + set_world_projection(vvars, world); + opengl_check(); + + set_vertex_format(GDRAW_vformat_v2tc2, vert[0]); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + opengl_check(); + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + reset_vertex_format(GDRAW_vformat_v2tc2); + opengl_check(); + + gstats->nonzero_flags |= GDRAW_STATS_batches; + gstats->num_batches += 1; + gstats->drawn_vertices += 4; + gstats->drawn_indices += 6; + + opengl_check(); +} + +#ifdef GDRAW_FEWER_CLEARS +static void clear_with_rect(gswf_recti *region, rrbool clear_depth, GDrawStats *gstats) +{ + F32 tc[4] = { 0,0,0,0 }; + + use_lazy_shader(&gdraw->manual_clear); + glUniform4f(gdraw->manual_clear.vars[0][0], 0.0, 0,0,0); + + glDisable(GL_BLEND); + + if (clear_depth) { + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_ALWAYS); + glDepthMask(GL_TRUE); + + glEnable(GL_STENCIL_TEST); + glStencilMask(255); + glStencilOp(GL_REPLACE,GL_REPLACE,GL_REPLACE); + glStencilFunc(GL_ALWAYS,0,255); + } else { + glDisable(GL_DEPTH_TEST); + glDisable(GL_STENCIL_TEST); + } + + glColorMask(1,1,1,1); + glColor4f(0,0,0,0); + + { + // coordinate system doesn't match, so just draw whole screen, rely on scissor to clip it properly + gswf_recti foo = { -10000,-10000,10000,10000 }; + do_screen_quad(&foo, tc, gdraw->manual_clear.vars[1], gstats, 1.0f); + } +} +#endif + +static void gdraw_DriverBlurPass(GDrawRenderState *r, int taps, F32 *data, gswf_recti *s, F32 *tc, F32 height_max, F32 *clamp, GDrawStats *gstats) +{ + ProgramWithCachedVariableLocations *prg = &gdraw->blur_prog[taps]; + F32 clampv[4]; + + // fix OpenGL t values for rendertargets are from bottom, not top + tc[1] = height_max - tc[1]; + tc[3] = height_max - tc[3]; + + clampv[0] = clamp[0]; + clampv[1] = height_max - clamp[3]; + clampv[2] = clamp[2]; + clampv[3] = height_max - clamp[1]; + + use_lazy_shader(prg); + set_texture(0, r->tex[0]); + + glColorMask(1,1,1,1); + glDisable(GL_BLEND); + glDisable(GL_SCISSOR_TEST); + + assert(prg->vars[0][VAR_blur_tap] >= 0); + glUniform4fv(prg->vars[0][VAR_blur_tap], taps, data); + glUniform4fv(prg->vars[0][VAR_blur_clampv], 1, clampv); + + do_screen_quad(s, tc, prg->vars[1], gstats, 0); + tag_resources(r->tex[0],0,0); +} + +static void gdraw_Colormatrix(GDrawRenderState *r, gswf_recti *s, float *tc, GDrawStats *gstats) +{ + ProgramWithCachedVariableLocations *prg = &gdraw->colormatrix; + if (!gdraw_TextureDrawBufferBegin(s, GDRAW_TEXTURE_FORMAT_rgba32, GDRAW_TEXTUREDRAWBUFFER_FLAGS_needs_color | GDRAW_TEXTUREDRAWBUFFER_FLAGS_needs_alpha, NULL, gstats)) + return; + use_lazy_shader(prg); + set_texture(0, r->tex[0]); + glUniform4fv(prg->vars[0][VAR_colormatrix_data], 5, r->shader_data); + do_screen_quad(s, tc, gdraw->colormatrix.vars[1], gstats, 0); + tag_resources(r->tex[0],0,0); + r->tex[0] = gdraw_TextureDrawBufferEnd(gstats); +} + +static gswf_recti *get_valid_rect(GDrawTexture *tex) +{ + GDrawHandle *h = (GDrawHandle *) tex; + S32 n = (S32) (h - gdraw->rendertargets.handle); + assert(n >= 0 && n <= MAX_RENDER_STACK_DEPTH+1); + return &gdraw->rt_valid[n]; +} + +static void set_clamp_constant(GLint constant, GDrawTexture *tex) +{ + gswf_recti *s = get_valid_rect(tex); + // when we make the valid data, we make sure there is an extra empty pixel at the border + // we also have to convert from GDraw coords to GL coords here. + glUniform4f(constant, + ( s->x0-0.5f) / gdraw->frametex_width, + (gdraw->tph-s->y1-0.5f) / gdraw->frametex_height, + ( s->x1+0.5f) / gdraw->frametex_width, + (gdraw->tph-s->y0+0.5f) / gdraw->frametex_height); +} + +static void gdraw_Filter(GDrawRenderState *r, gswf_recti *s, float *tc, int isbevel, GDrawStats *gstats) +{ + ProgramWithCachedVariableLocations *prg = &gdraw->filter_prog[isbevel][r->filter_mode]; + if (!gdraw_TextureDrawBufferBegin(s, GDRAW_TEXTURE_FORMAT_rgba32, GDRAW_TEXTUREDRAWBUFFER_FLAGS_needs_color | GDRAW_TEXTUREDRAWBUFFER_FLAGS_needs_alpha, NULL, gstats)) + return; + use_lazy_shader(prg); + set_texture(0, r->tex[0]); + set_texture(1, r->tex[1]); + set_texture(2, r->tex[2]); + glUniform4fv(prg->vars[0][VAR_filter_color], 1, &r->shader_data[0]); + glUniform4f(prg->vars[0][VAR_filter_tc_off], -r->shader_data[4] / (F32)gdraw->frametex_width, r->shader_data[5] / (F32)gdraw->frametex_height, r->shader_data[6], 0); + if (prg->vars[0][VAR_filter_color2] >= 0) + glUniform4fv(prg->vars[0][VAR_filter_color2], 1, &r->shader_data[8]); + set_clamp_constant(prg->vars[0][VAR_filter_clamp0], r->tex[0]); + set_clamp_constant(prg->vars[0][VAR_filter_clamp1], r->tex[1]); + do_screen_quad(s, tc, prg->vars[1], gstats, 0); + tag_resources(r->tex[0],0,0); + r->tex[0] = gdraw_TextureDrawBufferEnd(gstats); +} + +static void RADLINK gdraw_FilterQuad(GDrawRenderState *r, S32 x0, S32 y0, S32 x1, S32 y1, GDrawStats *gstats) +{ + F32 tc[4]; + gswf_recti s; + + // clip to tile boundaries + s.x0 = RR_MAX(x0, gdraw->tx0p); + s.y0 = RR_MAX(y0, gdraw->ty0p); + s.x1 = RR_MIN(x1, gdraw->tx0p + gdraw->tpw); + s.y1 = RR_MIN(y1, gdraw->ty0p + gdraw->tph); + if (s.x1 <= s.x0 || s.y1 <= s.y0) + return; + + // if it's a rendertarget, it's inverted from our design because OpenGL is bottom-left 0,0 + // and we have to compensate for scaling + tc[0] = (s.x0 - gdraw->tx0p) / (F32) gdraw->frametex_width; + tc[1] = (gdraw->tph - (s.y0 + gdraw->ty0p)) / (F32) gdraw->frametex_height; + tc[2] = (s.x1 - gdraw->tx0p) / (F32) gdraw->frametex_width; + tc[3] = (gdraw->tph - (s.y1 - gdraw->ty0p)) / (F32) gdraw->frametex_height; + + glUseProgram(0); + set_texture(0, 0); + set_texture(1, 0); + set_texture(2, 0); + + glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); + glStencilMask(255); + glDisable(GL_STENCIL_TEST); + glColorMask(1,1,1,1); + glDisable(GL_BLEND); + glDisable(GL_DEPTH_TEST); + opengl_check(); + + if (r->blend_mode == GDRAW_BLEND_filter) { + switch (r->filter) { + case GDRAW_FILTER_blur: { + GDrawBlurInfo b; + gswf_recti bounds = *get_valid_rect(r->tex[0]); + gdraw_ShiftRect(&s, &s, -gdraw->tx0p, -gdraw->ty0p); // blur uses physical rendertarget coordinates + + b.BlurPass = gdraw_DriverBlurPass; + b.w = gdraw->tpw; + b.h = gdraw->tph; + b.frametex_width = gdraw->frametex_width; + b.frametex_height = gdraw->frametex_height; + + // blur passes must override the viewport/ortho projection + + gdraw->in_blur = true; // prevent viewport/projection munging in start/end texture + set_viewport(); + set_projection(); + gdraw_Blur(&gdraw_funcs, &b,r, &s, &bounds, gstats); + + gdraw->in_blur = false; + + set_viewport(); + set_projection(); + break; + } + + case GDRAW_FILTER_colormatrix: + gdraw_Colormatrix(r, &s, tc, gstats); + break; + + case GDRAW_FILTER_dropshadow: + gdraw_Filter(r, &s, tc, 0, gstats); + break; + + case GDRAW_FILTER_bevel: + gdraw_Filter(r, &s, tc, 1, gstats); + break; + + default: + assert(0); + } + } else { + GDrawTexture *blend_tex = NULL; + const int *vvars; + + // for crazy blend modes, we need to read back from the framebuffer + // and do the blending in the pixel shader. we do this with CopyTexSubImage, + // rather than trying to render-to-texture-all-along, because that's a pain. + // @TODO: propogate the rectangle down and only copy what we need, like in 360 + + if (r->blend_mode == GDRAW_BLEND_special) { + blend_tex = (GDrawTexture *) get_color_rendertarget(gstats); + glBindTexture(GL_TEXTURE_2D, ((GDrawHandle *) blend_tex)->handle.tex.gl); + if (gdraw->cur != gdraw->frame) + glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0,0, 0,0,gdraw->tpw,gdraw->tph); + else + glCopyTexSubImage2D(GL_TEXTURE_2D, 0, gdraw->tx0 - gdraw->tx0p, gdraw->ty0 - gdraw->ty0p, gdraw->vx,gdraw->vy,gdraw->tw,gdraw->th); + + set_texture(1, blend_tex); + } + + if (!set_render_state(r, GDRAW_vformat_v2tc2, &vvars, NULL, gstats)) + return; + do_screen_quad(&s, tc, vvars, gstats, 0); + tag_resources(r->tex[0],r->tex[1],0); + if (blend_tex) + gdraw_FreeTexture(blend_tex, 0, gstats); + } +} + +void gdraw_GLx_(NoMoreGDrawThisFrame)(void) +{ + clear_renderstate(); + ++gdraw->frame_counter; +} + +void gdraw_GLx_(BeginCustomDraw)(IggyCustomDrawCallbackRegion *region, F32 *matrix) +{ + clear_renderstate(); + gdraw_GetObjectSpaceMatrix(matrix, region->o2w, gdraw->projection, depth_from_id(0), 1); +} + +void gdraw_GLx_(EndCustomDraw)(IggyCustomDrawCallbackRegion *region) +{ + set_common_renderstate(); +} + + +/////////////////////////////////////////////////////////////////////// +// +// Vertex and Fragment program initialization +// + +#include GDRAW_SHADERS + +static void make_vars(GDrawGLProgram prog, S32 vars[2][8], char **varn) +{ + if (prog) { + char **varn2 = (varn == pshader_general2_vars ? vshader_vsglihud_vars : vshader_vsgl_vars); + S32 k; + for (k=0; varn[k]; ++k) + if (varn[k][0]) + vars[0][k] = glGetUniformLocation(prog, varn[k]); + else + vars[0][k] = -1; + + for (k=0; varn2[k]; ++k) + if (varn2[k][0]) + vars[1][k] = glGetUniformLocation(prog, varn2[k]); + else + vars[1][k] = -1; + + if (vars[0][0] >= 0) + assert(vars[0][0] != vars[0][1]); + } +} + +static void make_fragment_program(ProgramWithCachedVariableLocations *p, int num_strings, char **strings, char **varn) +{ + S32 i; + GLint res; + GDrawGLProgram shad; + opengl_check(); + for (i=0; i < MAX_VARS; ++i) { + p->vars[0][i] = -1; + p->vars[1][i] = -1; + } + + shad = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(shad, num_strings, (const GLchar **)strings, NULL); + glCompileShader(shad); + glGetShaderiv(shad, GL_COMPILE_STATUS, &res); + if (!res) { + char errors[512]; + glGetShaderInfoLog(shad, sizeof(errors)-2, &res, errors); + compilation_err(errors); + p->program = 0; + } else { + S32 vert = GDRAW_vformat_v2tc2; + if (p >= &gdraw->fprog[0][0][0] && p < &gdraw->fprog[GDRAW_TEXTURE__count][0][0]) { + // for basic rendering shaders, we have three versions corresponding to the + // three vertex formats we support. + S32 n = (S32) (p - gdraw->fprog[0][0]); + vert = n % 3; + } + + if (p == &gdraw->ihud[0]) + vert = GDRAW_vformat_ihud1; + + opengl_check(); + p->program = glCreateProgram(); + glAttachShader(p->program, shad); + glAttachShader(p->program, gdraw->vert[vert]); + opengl_check(); + + if (vert == GDRAW_vformat_ihud1) { + glBindAttribLocation(p->program, 0, "position"); + glBindAttribLocation(p->program, 1, "texcoord"); + glBindAttribLocation(p->program, 2, "material_index"); + } else { + glBindAttribLocation(p->program, 0, "position"); + glBindAttribLocation(p->program, 1, "in_attr"); + } + + glLinkProgram(p->program); + glGetProgramiv(p->program, GL_LINK_STATUS, &res); + if (!res) { + char errors[512]; + glGetProgramiv(p->program, GL_INFO_LOG_LENGTH, &res); + glGetProgramInfoLog(p->program, sizeof(errors)-2, &res, errors); + compilation_err(errors); + glDeleteShader(shad); + glDeleteProgram(p->program); + p->program = 0; + } else + make_vars(p->program, p->vars, varn); + } + opengl_check(); + glUseProgram(p->program); // now activate the program + opengl_check(); +} + +static void make_vertex_program(GLuint *vprog, int num_strings, char **strings) +{ + GLint res; + GDrawGLProgram shad; + opengl_check(); + + if(strings[0]) + { + shad = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(shad, num_strings, (const GLchar **)strings, NULL); + glCompileShader(shad); + glGetShaderiv(shad, GL_COMPILE_STATUS, &res); + if (!res) { + char errors[512]; + glGetShaderInfoLog(shad, sizeof(errors)-2, &res, errors); + compilation_err(errors); + glDeleteShader(shad); + shad = 0; + } + opengl_check(); + *vprog = shad; + } + else + { + *vprog = 0; + } +} + +static void bind_sampler(ProgramWithCachedVariableLocations *prog, int varidx, int sampleridx) +{ + int var = prog->vars[0][varidx]; + if (var >= 0) + glUniform1i(var, sampleridx); +} + +static void make_vertex_programs(void) +{ + int type; + for (type=0; type < GDRAW_vformat__basic_count; type++) + make_vertex_program(&gdraw->vert[type], NUMFRAGMENTS_vshader_vsgl, vshader_vsgl(type)); + type = GDRAW_vformat_ihud1; + make_vertex_program(&gdraw->vert[type], NUMFRAGMENTS_vshader_vsglihud, vshader_vsglihud()); +} + +static void lazy_shader(ProgramWithCachedVariableLocations *ptr) +{ + if (ptr >= &gdraw->fprog[0][0][0] && ptr < &gdraw->fprog[GDRAW_TEXTURE__count][0][0]) { + S32 n = (S32) (ptr - gdraw->fprog[0][0]); + n /= 3; + + make_fragment_program(ptr, NUMFRAGMENTS_pshader_basic, pshader_basic_arr[n], pshader_basic_vars); + bind_sampler(ptr, VAR_tex0, 0); + bind_sampler(ptr, VAR_tex1, AATEX_SAMPLER); + return; + } + + if (ptr >= &gdraw->exceptional_blend[0] && ptr < &gdraw->exceptional_blend[GDRAW_BLENDSPECIAL__count]) { + S32 n = (S32) (ptr - gdraw->exceptional_blend); + make_fragment_program(ptr, NUMFRAGMENTS_pshader_exceptional_blend, pshader_exceptional_blend_arr[n], pshader_exceptional_blend_vars); + bind_sampler(ptr, VAR_tex0, 0); + bind_sampler(ptr, VAR_tex1, 1); + return; + } + + if (ptr >= &gdraw->filter_prog[0][0] && ptr <= &gdraw->filter_prog[1][15]) { + S32 n = (S32) (ptr - gdraw->filter_prog[0]); + make_fragment_program(ptr, NUMFRAGMENTS_pshader_filter, pshader_filter_arr[n], pshader_filter_vars); + bind_sampler(ptr, VAR_filter_tex0, 0); + bind_sampler(ptr, VAR_filter_tex1, 1); + bind_sampler(ptr, VAR_filter_tex2, 2); + return; + } + + if (ptr >= &gdraw->blur_prog[0] && ptr <= &gdraw->blur_prog[MAX_TAPS]) { + S32 n = (S32) (ptr - gdraw->blur_prog); + make_fragment_program(ptr, NUMFRAGMENTS_pshader_blur, pshader_blur_arr[n], pshader_blur_vars); + bind_sampler(ptr, VAR_blur_tex0, 0); + return; + } + + if (ptr == &gdraw->colormatrix) { + make_fragment_program(ptr, NUMFRAGMENTS_pshader_color_matrix, pshader_color_matrix_arr[0], pshader_color_matrix_vars); + bind_sampler(ptr, VAR_colormatrix_tex0, 0); + return; + } + + if (ptr == &gdraw->manual_clear) { + make_fragment_program(ptr, NUMFRAGMENTS_pshader_manual_clear, pshader_manual_clear_arr[0], pshader_manual_clear_vars); + return; + } + + if (ptr == &gdraw->ihud[0]) { + make_fragment_program(ptr, NUMFRAGMENTS_pshader_general2, pshader_general2_arr[0], pshader_general2_vars); + bind_sampler(ptr, VAR_tex0, 0); + return; + } + + RR_BREAK(); +} + +static rrbool make_quad_indices(void) +{ + int size = QUAD_IB_COUNT * 6 * sizeof(GLushort); + GLushort *inds = IggyGDrawMalloc(size); + int i, e; + + if (!inds) + return 0; + + // make quad inds + for (i=0; i < QUAD_IB_COUNT; i++) { + inds[i*6 + 0] = (GLushort) (i*4 + 0); + inds[i*6 + 1] = (GLushort) (i*4 + 1); + inds[i*6 + 2] = (GLushort) (i*4 + 2); + inds[i*6 + 3] = (GLushort) (i*4 + 0); + inds[i*6 + 4] = (GLushort) (i*4 + 2); + inds[i*6 + 5] = (GLushort) (i*4 + 3); + } + + glGenBuffers(1, &gdraw->quad_ib); + glBindBuffer(GL_ARRAY_BUFFER, gdraw->quad_ib); + glBufferData(GL_ARRAY_BUFFER, size, inds, GL_STATIC_DRAW); + IggyGDrawFree(inds); + e = glGetError(); + if (e != GL_NO_ERROR) { + eat_gl_err(); + return 0; + } + + return 1; +} + +//////////////////////////////////////////////////////////////////////// +// +// Create and tear-down the state +// + +typedef struct +{ + S32 num_handles; + S32 num_bytes; +} GDrawResourceLimit; + +// These are the defaults limits used by GDraw unless the user specifies something else. +static GDrawResourceLimit gdraw_limits[GDRAW_GLx_(RESOURCE__count)] = { + MAX_RENDER_STACK_DEPTH + 1, 16*1024*1024, // GDRAW_GLx_RESOURCE_rendertarget + 500, 20*1024*1024, // GDRAW_GLx_RESOURCE_texture + 1000, 2*1024*1024, // GDRAW_GLx_RESOURCE_vertexbuffer +}; + +static GDrawHandleCache *make_handle_cache(gdraw_resourcetype type) +{ + S32 num_handles = gdraw_limits[type].num_handles; + S32 num_bytes = gdraw_limits[type].num_bytes; + GDrawHandleCache *cache = (GDrawHandleCache *) IggyGDrawMalloc(sizeof(GDrawHandleCache) + (num_handles - 1) * sizeof(GDrawHandle)); + if (cache) { + gdraw_HandleCacheInit(cache, num_handles, num_bytes); + cache->is_vertex = (type == GDRAW_GLx_(RESOURCE_vertexbuffer)); + } + + return cache; +} + +static void free_gdraw() +{ + if (!gdraw) return; + if (gdraw->texturecache) IggyGDrawFree(gdraw->texturecache); + if (gdraw->vbufcache) IggyGDrawFree(gdraw->vbufcache); + IggyGDrawFree(gdraw); + gdraw = NULL; +} + +int gdraw_GLx_(SetResourceLimits)(gdraw_resourcetype type, S32 num_handles, S32 num_bytes) +{ + GDrawStats stats={0}; + + if (type == GDRAW_GLx_(RESOURCE_rendertarget)) // RT count is small and space is preallocated + num_handles = MAX_RENDER_STACK_DEPTH + 1; + + assert(type >= GDRAW_GLx_(RESOURCE_rendertarget) && type < GDRAW_GLx_(RESOURCE__count)); + assert(num_handles >= 0); + assert(num_bytes >= 0); + + // nothing to do if the values are unchanged + if (gdraw_limits[type].num_handles == num_handles && + gdraw_limits[type].num_bytes == num_bytes) + return 1; + + gdraw_limits[type].num_handles = num_handles; + gdraw_limits[type].num_bytes = num_bytes; + + // if no gdraw context created, there's nothing to worry about + if (!gdraw) + return 1; + + // resize the appropriate pool + switch (type) { + case GDRAW_GLx_(RESOURCE_rendertarget): + flush_rendertargets(&stats); + gdraw_HandleCacheInit(&gdraw->rendertargets, num_handles, num_bytes); + return 1; + + case GDRAW_GLx_(RESOURCE_texture): + if (gdraw->texturecache) { + gdraw_res_flush(gdraw->texturecache, &stats); + IggyGDrawFree(gdraw->texturecache); + } + gdraw->texturecache = make_handle_cache(GDRAW_GLx_(RESOURCE_texture)); + return gdraw->texturecache != NULL; + + case GDRAW_GLx_(RESOURCE_vertexbuffer): + if (gdraw->vbufcache) { + gdraw_res_flush(gdraw->vbufcache, &stats); + IggyGDrawFree(gdraw->vbufcache); + } + gdraw->vbufcache = make_handle_cache(GDRAW_GLx_(RESOURCE_vertexbuffer)); + return gdraw->vbufcache != NULL; + + default: + return 0; + } +} + +GDrawTexture * RADLINK gdraw_GLx_(MakeTextureFromResource)(U8 *resource_file, S32 len, IggyFileTextureRaw *texture) +{ + int i, offset, mips; + const TextureFormatDesc *fmt; + GDrawTexture *tex; + GLuint gl_texture_handle; + + // look up the texture format + fmt = gdraw->tex_formats; + while (fmt->iggyfmt != texture->format && fmt->blkbytes) + fmt++; + if (!fmt->blkbytes) // end of list - i.e. format not supported + return NULL; + + // prepare texture + glGenTextures(1, &gl_texture_handle); + if (gl_texture_handle == 0) + return NULL; + + opengl_check(); + make_texture(gl_texture_handle); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + + offset = texture->file_offset; + mips = RR_MAX(texture->mipmaps, 1); + + // disable mipmaps if non-pow-2 is unsupported + if (gdraw->has_conditional_non_power_of_two) + if (!is_pow2(texture->w) || !is_pow2(texture->h)) + mips = 1; + + // disable mipmaps if chain is incomplete and GL_TEXTURE_MAX_LEVEL is unsupported + if (!gdraw->has_texture_max_level && mips > 1) { + int lastmip = mips-1; + if ((texture->w >> lastmip) > 1 || (texture->h >> lastmip) > 1) + mips = 1; + } + + for (i=0; i < mips; i++) { + U8 *data = resource_file + offset; + int w = RR_MAX(texture->w >> i, 1); + int h = RR_MAX(texture->h >> i, 1); + int j; + + if (texture->format == IFT_FORMAT_rgba_4444_LE) { + for (j=0; j < w * h; ++j) { + unsigned short x = * (unsigned short *) (data + j*2); + x = ((x>>12) & 0xf) | ((x<<4) & 0xfff0); + * (unsigned short *) (data + j*2) = x; + } + } + if (texture->format == IFT_FORMAT_rgba_5551_LE) { + for (j=0; j < w * h; ++j) { + unsigned short x = * (unsigned short *) (data + j*2); + x = (x >> 15) | (x << 1); + * (unsigned short *) (data + j*2) = x; + } + } + + if (fmt->fmt != 0) { + glTexImage2D(GL_TEXTURE_2D, i, fmt->intfmt, w, h, 0, fmt->fmt, fmt->type, data); + offset += w * h * fmt->blkbytes; + } else { + int size = ((w + fmt->blkx-1) / fmt->blkx) * ((h + fmt->blky-1) / fmt->blky) * fmt->blkbytes; + glCompressedTexImage2D(GL_TEXTURE_2D, i, fmt->intfmt, w, h, 0, size, data); + offset += size; + } + + opengl_check(); + } + + if (gdraw->has_texture_max_level) + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, mips-1); + + tex = gdraw_GLx_(WrappedTextureCreate)(gl_texture_handle, texture->w, texture->h, mips > 1); + if (tex == NULL) + glDeleteTextures(1, &gl_texture_handle); + opengl_check(); + return tex; +} + +void RADLINK gdraw_GLx_(DestroyTextureFromResource)(GDrawTexture *tex) +{ + if (tex) + gdraw_GLx_(WrappedTextureDestroy)(tex); +} + +static rrbool hasext(const char *exts, const char *which) +{ + const char *where; + size_t len; + +#ifdef GDRAW_USE_glGetStringi + if (exts == NULL) { + GLint i, num_exts; + glGetIntegerv(GL_NUM_EXTENSIONS, &num_exts); + for (i=0; i < num_exts; ++i) + if (0==strcmp(which, (char const *) glGetStringi(GL_EXTENSIONS, i))) + return 1; + return 0; + } +#endif + + where = exts; + len = strlen(which); + + for(;;) { + where = strstr(where, which); + if (where == NULL) + return false; + + if ( (where == exts || *(where - 1) == ' ') // starts with terminator + && (where[len] == ' ' || where[len] == 0)) // ends with terminator + return true; + where += len; + } +} + +static GDrawFunctions *create_context(S32 w, S32 h) +{ + gdraw = IggyGDrawMalloc(sizeof(*gdraw)); + if (!gdraw) return NULL; + + memset(gdraw, 0, sizeof(*gdraw)); + + gdraw->texturecache = make_handle_cache(GDRAW_GLx_(RESOURCE_texture)); + gdraw->vbufcache = make_handle_cache(GDRAW_GLx_(RESOURCE_vertexbuffer)); + gdraw_HandleCacheInit(&gdraw->rendertargets, gdraw_limits[GDRAW_GLx_(RESOURCE_rendertarget)].num_handles, gdraw_limits[GDRAW_GLx_(RESOURCE_rendertarget)].num_bytes); + + if (!gdraw->texturecache || !gdraw->vbufcache || !make_quad_indices()) { + free_gdraw(); + return NULL; + } + + opengl_check(); + + gdraw->frametex_width = w; + gdraw->frametex_height = h; + gdraw->frame->cached = false; + + // if the globals have already been initialized, this has no effect; + // otherwise it initializes them with no global texture storage and the + // default global rendertarget storage + + glGenFramebuffers(1, &gdraw->framebuffer_stack_object); + glGenFramebuffers(1, &gdraw->framebuffer_copy_to_texture); + opengl_check(); + + make_vertex_programs(); + // fragment shaders are created lazily + + gdraw_funcs.SetViewSizeAndWorldScale = gdraw_SetViewSizeAndWorldScale; + gdraw_funcs.RenderingBegin = gdraw_RenderingBegin; + gdraw_funcs.RenderingEnd = gdraw_RenderingEnd; + gdraw_funcs.RenderTileBegin = gdraw_RenderTileBegin; + gdraw_funcs.RenderTileEnd = gdraw_RenderTileEnd; + gdraw_funcs.GetInfo = gdraw_GetInfo; + gdraw_funcs.DescribeTexture = gdraw_DescribeTexture; + gdraw_funcs.DescribeVertexBuffer = gdraw_DescribeVertexBuffer; + + gdraw_funcs.TextureDrawBufferBegin = gdraw_TextureDrawBufferBegin; + gdraw_funcs.TextureDrawBufferEnd = gdraw_TextureDrawBufferEnd; + + gdraw_funcs.DrawIndexedTriangles = gdraw_DrawIndexedTriangles; + gdraw_funcs.FilterQuad = gdraw_FilterQuad; + + gdraw_funcs.SetAntialiasTexture = gdraw_SetAntialiasTexture; + + gdraw_funcs.ClearStencilBits = gdraw_ClearStencilBits; + gdraw_funcs.ClearID = gdraw_ClearID; + + gdraw_funcs.MakeTextureBegin = gdraw_MakeTextureBegin; + gdraw_funcs.MakeTextureMore = NULL; + gdraw_funcs.MakeTextureEnd = gdraw_MakeTextureEnd; + + gdraw_funcs.UpdateTextureRect = gdraw_UpdateTextureRect; + gdraw_funcs.UpdateTextureBegin = gdraw_UpdateTextureBegin; + gdraw_funcs.UpdateTextureEnd = gdraw_UpdateTextureEnd; + gdraw_funcs.FreeTexture = gdraw_FreeTexture; + gdraw_funcs.TryToLockTexture = gdraw_TryToLockTexture; + + gdraw_funcs.MakeVertexBufferBegin = gdraw_MakeVertexBufferBegin; + gdraw_funcs.MakeVertexBufferMore = gdraw_MakeVertexBufferMore; + gdraw_funcs.MakeVertexBufferEnd = gdraw_MakeVertexBufferEnd; + gdraw_funcs.TryToLockVertexBuffer = gdraw_TryToLockVertexBuffer; + gdraw_funcs.FreeVertexBuffer = gdraw_FreeVertexBuffer; + + gdraw_funcs.UnlockHandles = gdraw_UnlockHandles; + gdraw_funcs.SetTextureUniqueID = gdraw_SetTextureUniqueID; + + gdraw_funcs.MakeTextureFromResource = (gdraw_make_texture_from_resource *) gdraw_GLx_(MakeTextureFromResource); + gdraw_funcs.FreeTextureFromResource = gdraw_GLx_(DestroyTextureFromResource); + + gdraw_funcs.Set3DTransform = gdraw_Set3DTransform; + + return &gdraw_funcs; +} + +void gdraw_GLx_(DestroyContext)(void) +{ + if (gdraw) + { + GDrawStats stats={0}; + if (gdraw->texturecache) gdraw_res_flush(gdraw->texturecache, &stats); + if (gdraw->vbufcache) gdraw_res_flush(gdraw->vbufcache, &stats); + flush_rendertargets(&stats); + + if (gdraw->aa_tex) + glDeleteTextures(1, &gdraw->aa_tex); + + if (gdraw->quad_ib) + glDeleteBuffers(1, &gdraw->quad_ib); + } + + opengl_check(); + free_gdraw(); +} + diff --git a/Minecraft.Client/Windows64/Iggy/gdraw/gdraw_shared.inl b/Minecraft.Client/Windows64/Iggy/gdraw/gdraw_shared.inl new file mode 100644 index 00000000..a60fa520 --- /dev/null +++ b/Minecraft.Client/Windows64/Iggy/gdraw/gdraw_shared.inl @@ -0,0 +1,2595 @@ +// gdraw_shared.inl - author: Sean Barrett - copyright 2010 RAD Game Tools +// +// This file implements some common code that can be shared across +// all the sample implementations of GDraw. + +#ifdef IGGY_DISABLE_GDRAW_ASSERT +#define assert(x) +#else +#include +#endif + +#ifndef GDRAW_MAYBE_UNUSED +#define GDRAW_MAYBE_UNUSED +#endif + +/////////////////////////////////////////////////////////////// +// +// GDrawHandleCache manages resource "handles" used by Iggy +// (i.e. these handles wrap the platform resource handles, +// and this file provides those wrappers and facilities for +// LRU tracking them). Moreover, for console platforms, we +// actually implement our own managed resource pools. +// +// This is the main state machine when GDRAW_MANAGE_MEM is defined: +// (which covers all console platforms) +// +// +------+ +--------+ | +// | Live |<------->| Locked | | +// +------+ +--------+ | +// / \ ^ | +// / \ \ | +// v v \ | +// +------+ +------+ +------+ | | +// | Dead |--->| Free |<---| User | | | +// +------+ +------+ +------+ | | +// ^ ^ ^ ^ | | +// \ / \ | | | +// \ / v | | | +// +--------+ +-------+ / | +// | Pinned |<--------| Alloc |/ | +// +--------+ +-------+ | +// +// "Free" handles are not in use and available for allocation. +// "Alloc" handles have been assigned by GDraw, but do not yet +// have a system resource backing them. Resources stay in +// this state until we know that for sure that we're going +// to be able to successfully complete creation, at which +// point the resource transitions to one of the regular states. +// "Live" handles correspond to resources that may be used +// for rendering. They are kept in LRU order. Old resources +// may be evicted to make space. +// "Locked" handles cover resources that are going to be used +// in the next draw command. Once a resource is marked locked, +// it may not be evicted until it's back to "Live". +// "Dead" handles describe resources that have been freed on the +// CPU side, but are still in use by the GPU. Their memory may +// only be reclaimed once the GPU is done with them, at which +// point they are moved to the "Free" list. Items on the "Dead" +// list appear ordered by the last time they were used by the +// GPU - "most stale" first. +// "Pinned" resources can be used in any draw call without getting +// locked first. They can never be LRU-freed, but their memory +// is still managed by GDraw. Currently this is only used for +// the Iggy font cache. +// "User" (user-owned) resources are exactly that. They act much like +// pinned resources, but their memory isn't managed by GDraw. +// When a user-owned resource is freed, we really need to free +// it immediately (instead of marking it as "dead"), which might +// necessitate stalling the CPU until the GPU is finished using +// that resource. Since we don't own the memory, delayed frees +// are not an option. +// +// Without GDRAW_MANAGE_MEM, there's no "Dead" resources, and all +// frees are performed immediately. + +typedef struct GDrawHandleCache GDrawHandleCache; +typedef struct GDrawHandle GDrawHandle; + +typedef struct +{ + U64 value; +} GDrawFence; + +typedef enum +{ + GDRAW_HANDLE_STATE_free = 0, + GDRAW_HANDLE_STATE_live, + GDRAW_HANDLE_STATE_locked, + GDRAW_HANDLE_STATE_dead, + GDRAW_HANDLE_STATE_pinned, + GDRAW_HANDLE_STATE_user_owned, + GDRAW_HANDLE_STATE_alloc, + GDRAW_HANDLE_STATE__count, + + // not an actual state! + GDRAW_HANDLE_STATE_sentinel = GDRAW_HANDLE_STATE__count, +} GDrawHandleState; + +struct GDrawHandle +{ + GDrawNativeHandle handle; // platform handle to a resource (variable size) + void * owner; // 4/8 // opaque handle used to allow freeing resources without calling back to owner + + GDrawHandleCache * cache; // 4/8 // which cache this handle came from + + GDrawHandle * next,*prev; // 8/16 // doubly-linked list + + #ifdef GDRAW_MANAGE_MEM + void * raw_ptr; // 4/8 // pointer to allocation - when you're managing memory manually + #ifdef GDRAW_CORRUPTION_CHECK + U32 cached_raw_value[4]; + rrbool has_check_value; + #endif + #endif + + GDrawFence fence; // 8 // (optional) platform fence for resource + // 4 + U32 bytes:28; // estimated storage cost to allow setting a loose limit + U32 state:4; // state the handle is in +}; + +// validate alignment to make sure structure will pack correctly +#ifdef __RAD64__ +RR_COMPILER_ASSERT((sizeof(GDrawHandle) & 7) == 0); +#else +RR_COMPILER_ASSERT((sizeof(GDrawHandle) & 3) == 0); +#endif + +struct GDrawHandleCache +{ + S32 bytes_free; + S32 total_bytes; + S32 max_handles; + U32 is_vertex : 1; // vertex buffers have different warning codes and generate discard callbacks + U32 is_thrashing : 1; + U32 did_defragment : 1; + // 30 unused bits + GDrawHandle state[GDRAW_HANDLE_STATE__count]; // sentinel nodes for all of the state lists + #ifdef GDRAW_MANAGE_MEM + struct gfx_allocator *alloc; + #endif + #ifdef GDRAW_MANAGE_MEM_TWOPOOL + struct gfx_allocator *alloc_other; + #endif + GDrawFence prev_frame_start, prev_frame_end; // fence value at start/end of previous frame, for thrashing detection + GDrawHandle handle[1]; // the rest of the handles must be stored right after this in the containing structure +}; + +#ifdef GDRAW_CORRUPTION_CHECK +// values for corruption checking +#define GDRAW_CORRUPTIONCHECK_renderbegin 0x10 +#define GDRAW_CORRUPTIONCHECK_renderend 0x20 +#define GDRAW_CORRUPTIONCHECK_nomoregdraw 0x30 +#define GDRAW_CORRUPTIONCHECK_maketexbegin 0x40 +#define GDRAW_CORRUPTIONCHECK_maketexend 0x50 + +#define GDRAW_CORRUPTIONCHECK_wrappedcreateend 0x60 +#define GDRAW_CORRUPTIONCHECK_wrappedcreatebegin 0x61 +#define GDRAW_CORRUPTIONCHECK_wrappeddestroyend 0x70 +#define GDRAW_CORRUPTIONCHECK_wrappeddestroybegin 0x71 + +#define GDRAW_CORRUPTIONCHECK_allochandle 0x80 +#define GDRAW_CORRUPTIONCHECK_allochandle_begin 0x81 +#define GDRAW_CORRUPTIONCHECK_allochandle_postreap 0x82 +#define GDRAW_CORRUPTIONCHECK_allochandle_postfree1 0x83 +#define GDRAW_CORRUPTIONCHECK_allochandle_postfree2 0x84 +#define GDRAW_CORRUPTIONCHECK_allochandle_postfree3 0x85 +#define GDRAW_CORRUPTIONCHECK_allochandle_postalloc1 0x86 +#define GDRAW_CORRUPTIONCHECK_allochandle_postalloc2 0x87 +#define GDRAW_CORRUPTIONCHECK_allochandle_postalloc3 0x88 +#define GDRAW_CORRUPTIONCHECK_allochandle_defrag 0x89 + +#define GDRAW_CORRUPTIONCHECK_freetex 0x90 + +static U32 *debug_raw_address(GDrawHandle *t, int choice) +{ + static int offset_table[4] = { 0x555555, 0xaaaaaa, 0x333333, 0x6e6e6e }; + U8 *base = (U8 *) t->raw_ptr; + int offset = offset_table[choice] & (t->bytes-1) & ~3; + return (U32 *) (base + offset); +} + +static void debug_check_overlap_one(GDrawHandle *t, U8 *ptr, S32 len) +{ + assert(len >= 0); + if (t->raw_ptr && t->raw_ptr != ptr) { + assert(t->raw_ptr < ptr || t->raw_ptr >= ptr+len); + } +} + +static void debug_check_overlap(GDrawHandleCache *c, U8 *ptr, S32 len) +{ + GDrawHandle *t = c->head; + while (t) { + debug_check_overlap_one(t, ptr, len); + t = t->next; + } + t = c->active; + while (t) { + debug_check_overlap_one(t, ptr, len); + t = t->next; + } +} + +static void debug_check_raw_values(GDrawHandleCache *c) +{ + GDrawHandle *t = c->head; + while (t) { + if (t->raw_ptr && t->has_check_value) { + int i; + for (i=0; i < 4; ++i) { + if (*debug_raw_address(t, i) != t->cached_raw_value[i]) { + //zlog("!Iggy texture corruption found\n"); + //zlog("t=%p, t->raw_ptr=%p\n", t, t->raw_ptr); + //zlog("Cached values: %08x %08x %08x %08x\n", t->cached_raw_value[0], t->cached_raw_value[1], t->cached_raw_value[2], t->cached_raw_value[3]); + //zlog("Current values: %08x %08x %08x %08x\n", *debug_raw_address(t,0), *debug_raw_address(t,1), *debug_raw_address(t,2), *debug_raw_address(t,3)); + assert(0); + } + } + #if 0 + GDrawHandle *s; + check_block_alloc(c->alloc, t->raw_ptr, 1); + s = c->head; + while (s != t) { + assert(s->raw_ptr != t->raw_ptr); + s = s->next; + } + s = c->active; + while (s != NULL) { + assert(s->raw_ptr != t->raw_ptr); + s = s->next; + } + #endif + } + t = t->next; + } + t = c->active; + while (t) { + if (t->raw_ptr && t->has_check_value) { + int i; + for (i=0; i < 4; ++i) { + if (*debug_raw_address(t, i) != t->cached_raw_value[i]) { + //zlog("!Iggy texture corruption found\n"); + //zlog("t=%p, t->raw_ptr=%p\n", t, t->raw_ptr); + //zlog("Cached values: %08x %08x %08x %08x\n", t->cached_raw_value[0], t->cached_raw_value[1], t->cached_raw_value[2], t->cached_raw_value[3]); + //zlog("Current values: %08x %08x %08x %08x\n", *debug_raw_address(t,0), *debug_raw_address(t,1), *debug_raw_address(t,2), *debug_raw_address(t,3)); + assert(0); + } + } + #if 0 + GDrawHandle *s; + check_block_alloc(c->alloc, t->raw_ptr, 1); + s = c->active; + while (s != t) { + assert(s->raw_ptr != t->raw_ptr); + s = s->next; + } + #endif + } + t = t->next; + } +} + +#ifndef GDRAW_CORRUPTION_MASK +#define GDRAW_CORRUPTION_MASK 0 +#endif +#define debug_check_raw_values_if(c,v) \ + if ((GDRAW_CORRUPTION_CHECK & ~GDRAW_CORRUPTION_MASK) == ((v) & ~GDRAW_CORRUPTION_MASK)) \ + debug_check_raw_values(c); \ + else + +static void debug_set_raw_value(GDrawHandle *t) +{ + if (t->raw_ptr) { + int i; + for (i=0; i < 4; ++i) + t->cached_raw_value[i] = *debug_raw_address(t, i); + t->has_check_value = true; + } +} + +static void debug_unset_raw_value(GDrawHandle *t) +{ + t->has_check_value = false; +} + +static void debug_check_value_is_unreferenced(GDrawHandleCache *c, void *ptr) +{ + GDrawHandle *t = c->head; + while (t) { + assert(t->raw_ptr != ptr); + t = t->next; + } + t = c->active; + while (t) { + assert(t->raw_ptr != ptr); + t = t->next; + } +} + +#else + +#define debug_check_overlap(c,p,len) +#define debug_set_raw_value(t) +#define debug_check_value_is_unreferenced(c,p) +#define debug_unset_raw_value(t) +#define debug_check_raw_values(c) +#define debug_check_raw_values_if(c,v) +#endif + +#ifdef SUPERDEBUG +static void check_lists(GDrawHandleCache *c) +{ + GDrawHandle *sentinel, *t; + U32 state; + + // for all lists, verify that they are consistent and + // properly linked + for (state = 0; state < GDRAW_HANDLE_STATE__count; state++) { + S32 count = 0; + sentinel = &c->state[state]; + + assert(!sentinel->cache); + assert(sentinel->state == GDRAW_HANDLE_STATE_sentinel); + for (t = sentinel->next; t != sentinel; t = t->next) { + count++; + assert(t->cache == c); + assert(t->state == state); + assert(t->prev->next == t); + assert(t->next->prev == t); + assert(count < 50000); + } + } + + // for dead list, additionally verify that it's in the right + // order (namely, sorted by ascending fence index) + sentinel = &c->state[GDRAW_HANDLE_STATE_dead]; + for (t = sentinel->next; t != sentinel; t = t->next) { + assert(t->prev == sentinel || t->fence.value >= t->prev->fence.value); + } +} + +#include + +static const char *gdraw_StateName(U32 state) +{ + switch (state) { + case GDRAW_HANDLE_STATE_free: return "free"; + case GDRAW_HANDLE_STATE_live: return "live"; + case GDRAW_HANDLE_STATE_locked: return "locked"; + case GDRAW_HANDLE_STATE_dead: return "dead"; + case GDRAW_HANDLE_STATE_pinned: return "pinned"; + case GDRAW_HANDLE_STATE_user_owned: return "user-owned"; + case GDRAW_HANDLE_STATE_alloc: return "alloc"; + case GDRAW_HANDLE_STATE_sentinel: return ""; + default: return "???"; + } +} + +#else +static RADINLINE void check_lists(GDrawHandleCache *c) +{ + RR_UNUSED_VARIABLE(c); +} +#endif + +static void gdraw_HandleTransitionInsertBefore(GDrawHandle *t, GDrawHandleState new_state, GDrawHandle *succ) +{ + check_lists(t->cache); + assert(t->state != GDRAW_HANDLE_STATE_sentinel); // sentinels should never get here! + assert(t->state != (U32) new_state); // code should never call "transition" if it's not transitioning! + // unlink from prev state + t->prev->next = t->next; + t->next->prev = t->prev; + // add to list for new state + t->next = succ; + t->prev = succ->prev; + t->prev->next = t; + t->next->prev = t; +#ifdef SUPERDEBUG + printf("GD %chandle %p %s->%s\n", t->cache->is_vertex ? 'v' : 't', t, gdraw_StateName(t->state), gdraw_StateName(new_state)); +#endif + t->state = new_state; + check_lists(t->cache); +} + +static RADINLINE void gdraw_HandleTransitionTo(GDrawHandle *t, GDrawHandleState new_state) +{ + gdraw_HandleTransitionInsertBefore(t, new_state, &t->cache->state[new_state]); +} + +#ifdef GDRAW_MANAGE_MEM_TWOPOOL +static rrbool gdraw_MigrateResource(GDrawHandle *t, GDrawStats *stats); +static void gdraw_res_free(GDrawHandle *t, GDrawStats *stats); +#endif + +static rrbool gdraw_HandleCacheLockStats(GDrawHandle *t, void *owner, GDrawStats *stats) +{ + RR_UNUSED_VARIABLE(stats); + + // if the GPU memory is owned by the user, then we never spontaneously + // free it, and we can always report true. moreover, Iggy doesn't bother + // keeping 'owner' consistent in this case, so we must check this before + // verifying t->owner. + if (t->state == GDRAW_HANDLE_STATE_user_owned) + return true; + + // if t->owner has changed, then Iggy is trying to lock an old version + // of this handle from before (the handle has already been recycled to + // point to a new resource) + if (t->owner != owner) + return false; + + // otherwise, it's a valid resource and we should lock it until the next + // unlock call + assert(t->state == GDRAW_HANDLE_STATE_live || t->state == GDRAW_HANDLE_STATE_locked || t->state == GDRAW_HANDLE_STATE_pinned); + if (t->state == GDRAW_HANDLE_STATE_live) { +#ifdef GDRAW_MANAGE_MEM_TWOPOOL + // if we defragmented this frame, we can't just make resources live; + // we need to migrate them to their new location. (which might fail + // if we don't have enough memory left in the new pool) + if (t->cache->did_defragment) { + if (!gdraw_MigrateResource(t, stats)) { + gdraw_res_free(t, stats); + return false; + } + } +#endif + gdraw_HandleTransitionTo(t, GDRAW_HANDLE_STATE_locked); + } + return true; +} + +static rrbool gdraw_HandleCacheLock(GDrawHandle *t, void *owner) +{ + return gdraw_HandleCacheLockStats(t, owner, NULL); +} + +static void gdraw_HandleCacheUnlock(GDrawHandle *t) +{ + assert(t->state == GDRAW_HANDLE_STATE_locked || t->state == GDRAW_HANDLE_STATE_pinned || t->state == GDRAW_HANDLE_STATE_user_owned); + if (t->state == GDRAW_HANDLE_STATE_locked) + gdraw_HandleTransitionTo(t, GDRAW_HANDLE_STATE_live); +} + +static void gdraw_HandleCacheUnlockAll(GDrawHandleCache *c) +{ + GDrawHandle *sentinel = &c->state[GDRAW_HANDLE_STATE_locked]; + while (sentinel->next != sentinel) + gdraw_HandleTransitionTo(sentinel->next, GDRAW_HANDLE_STATE_live); +} + +static void gdraw_HandleCacheInit(GDrawHandleCache *c, S32 num_handles, S32 bytes) +{ + S32 i; + assert(num_handles > 0); + c->max_handles = num_handles; + c->total_bytes = bytes; + c->bytes_free = c->total_bytes; + c->is_vertex = false; + c->is_thrashing = false; + c->did_defragment = false; + for (i=0; i < GDRAW_HANDLE_STATE__count; i++) { + c->state[i].owner = NULL; + c->state[i].cache = NULL; // should never follow cache link from sentinels! + c->state[i].next = c->state[i].prev = &c->state[i]; +#ifdef GDRAW_MANAGE_MEM + c->state[i].raw_ptr = NULL; +#endif + c->state[i].fence.value = 0; + c->state[i].bytes = 0; + c->state[i].state = GDRAW_HANDLE_STATE_sentinel; + } + for (i=0; i < num_handles; ++i) { + c->handle[i].cache = c; + c->handle[i].prev = (i == 0) ? &c->state[GDRAW_HANDLE_STATE_free] : &c->handle[i-1]; + c->handle[i].next = (i == num_handles - 1) ? &c->state[GDRAW_HANDLE_STATE_free] : &c->handle[i+1]; + c->handle[i].bytes = 0; + c->handle[i].state = GDRAW_HANDLE_STATE_free; +#ifdef GDRAW_MANAGE_MEM + c->handle[i].raw_ptr = NULL; +#endif + } + c->state[GDRAW_HANDLE_STATE_free].next = &c->handle[0]; + c->state[GDRAW_HANDLE_STATE_free].prev = &c->handle[num_handles - 1]; + c->prev_frame_start.value = 0; + c->prev_frame_end.value = 0; +#ifdef GDRAW_MANAGE_MEM + c->alloc = NULL; +#endif +#ifdef GDRAW_MANAGE_MEM_TWOPOOL + c->alloc_other = NULL; +#endif + check_lists(c); +} + +static GDrawHandle *gdraw_HandleCacheAllocateBegin(GDrawHandleCache *c) +{ + GDrawHandle *free_list = &c->state[GDRAW_HANDLE_STATE_free]; + GDrawHandle *t = NULL; + if (free_list->next != free_list) { + t = free_list->next; + gdraw_HandleTransitionTo(t, GDRAW_HANDLE_STATE_alloc); + t->bytes = 0; + t->owner = 0; +#ifdef GDRAW_MANAGE_MEM + t->raw_ptr = NULL; +#endif +#ifdef GDRAW_CORRUPTION_CHECK + t->has_check_value = false; +#endif + } + return t; +} + +static void gdraw_HandleCacheAllocateEnd(GDrawHandle *t, S32 bytes, void *owner, GDrawHandleState new_state) +{ + assert(t->cache); + assert(t->bytes == 0); + assert(t->owner == 0); + assert(t->state == GDRAW_HANDLE_STATE_alloc); + if (bytes == 0) + assert(new_state == GDRAW_HANDLE_STATE_user_owned); + else + assert(new_state == GDRAW_HANDLE_STATE_locked || new_state == GDRAW_HANDLE_STATE_pinned); + t->bytes = bytes; + t->owner = owner; + t->cache->bytes_free -= bytes; + + gdraw_HandleTransitionTo(t, new_state); +} + +static void gdraw_HandleCacheFree(GDrawHandle *t) +{ + GDrawHandleCache *c = t->cache; + assert(t->state != GDRAW_HANDLE_STATE_alloc && t->state != GDRAW_HANDLE_STATE_sentinel); + c->bytes_free += t->bytes; + t->bytes = 0; + t->owner = 0; +#ifdef GDRAW_MANAGE_MEM + t->raw_ptr = 0; +#endif +#ifdef GDRAW_CORRUPTION_CHECK + t->has_check_value = false; +#endif + gdraw_HandleTransitionTo(t, GDRAW_HANDLE_STATE_free); +} + +static void gdraw_HandleCacheAllocateFail(GDrawHandle *t) +{ + assert(t->state == GDRAW_HANDLE_STATE_alloc); + gdraw_HandleTransitionTo(t, GDRAW_HANDLE_STATE_free); +} + +static GDrawHandle *gdraw_HandleCacheGetLRU(GDrawHandleCache *c) +{ + // TransitionTo always inserts at the end, which means that the resources + // at the front of the LRU list are the oldest ones, since in-use resources + // will get appended on every transition from "locked" to "live". + GDrawHandle *sentinel = &c->state[GDRAW_HANDLE_STATE_live]; + return (sentinel->next != sentinel) ? sentinel->next : NULL; +} + +static void gdraw_HandleCacheTick(GDrawHandleCache *c, GDrawFence now) +{ + c->prev_frame_start = c->prev_frame_end; + c->prev_frame_end = now; + + // reset these flags every frame + c->is_thrashing = false; + c->did_defragment = false; +} + +#ifdef GDRAW_MANAGE_MEM + +static void gdraw_HandleCacheInsertDead(GDrawHandle *t) +{ + GDrawHandle *s, *sentinel; + + assert(t->state == GDRAW_HANDLE_STATE_live || t->state == GDRAW_HANDLE_STATE_locked || t->state == GDRAW_HANDLE_STATE_pinned); + + // figure out where t belongs in the dead list in "chronological order" + // do this by finding its (chronological) successor s + sentinel = &t->cache->state[GDRAW_HANDLE_STATE_dead]; + s = sentinel->next; + while (s != sentinel && s->fence.value <= t->fence.value) + s = s->next; + + // and then insert it there + gdraw_HandleTransitionInsertBefore(t, GDRAW_HANDLE_STATE_dead, s); +} + +#endif + +//////////////////////////////////////////////////////////////////////// +// +// Set transformation matrices +// + +// Our vertex shaders use this convention: +// world: our world matrices always look like this +// m00 m01 0 t0 +// m10 m11 0 t1 +// 0 0 0 d +// 0 0 0 1 +// +// we just store the first two rows and insert d +// in the first row, third column. our input position vectors are +// always (x,y,0,1) or (x,y,0,0), so we can still just use dp4 to +// compute final x/y. after that it's a single move to set the +// correct depth value. +// +// viewproj: our view-projection matrix is always just a 2D scale+translate, +// i.e. the matrix looks like this: +// +// p[0] 0 0 p[2] +// 0 p[1] 0 p[3] +// 0 0 1 0 +// 0 0 0 1 +// +// just store (p[0],p[1],p[2],p[3]) in a 4-component vector and the projection +// transform is a single multiply-add. +// +// The output is volatile since it's often in Write-Combined memory where we +// really don't want compiler reordering. + +static RADINLINE void gdraw_PixelSpace(volatile F32 * RADRESTRICT vvec) +{ + // 1:1 pixel mapping - just identity since our "view space" is pixels + vvec[0] = 1.0f; vvec[1] = 0.0f; vvec[2] = 0.0f; vvec[3] = 0.0f; + vvec[4] = 0.0f; vvec[5] = 1.0f; vvec[6] = 0.0f; vvec[7] = 0.0f; +} + +static RADINLINE void gdraw_WorldSpace(volatile F32 * RADRESTRICT vvec, F32 * RADRESTRICT world_to_pixel, F32 depth, F32 misc) +{ + // World->pixel space transform is just a scale + vvec[0] = world_to_pixel[0]; vvec[1] = 0.0f; vvec[2] = depth; vvec[3] = 0.0f; + vvec[4] = 0.0f; vvec[5] = world_to_pixel[1]; vvec[6] = misc; vvec[7] = 0.0f; +} + +static RADINLINE void gdraw_ObjectSpace(volatile F32 * RADRESTRICT vvec, gswf_matrix * RADRESTRICT xform, F32 depth, F32 misc) +{ + // Object->pixel transform is a 2D homogeneous matrix transform + F32 m00 = xform->m00; + F32 m01 = xform->m01; + F32 m10 = xform->m10; + F32 m11 = xform->m11; + F32 trans0 = xform->trans[0]; + F32 trans1 = xform->trans[1]; + + vvec[0] = m00; vvec[1] = m01; vvec[2] = depth; vvec[3] = trans0; + vvec[4] = m10; vvec[5] = m11; vvec[6] = misc; vvec[7] = trans1; +} + +static void gdraw_GetObjectSpaceMatrix(F32 * RADRESTRICT mat, gswf_matrix * RADRESTRICT xform, F32 * RADRESTRICT proj, F32 depth, int out_col_major) +{ + int row = out_col_major ? 1 : 4; + int col = out_col_major ? 4 : 1; + + F32 xs = proj[0]; + F32 ys = proj[1]; + + mat[0*row+0*col] = xform->m00 * xs; + mat[0*row+1*col] = xform->m01 * xs; + mat[0*row+2*col] = 0.0f; + mat[0*row+3*col] = xform->trans[0] * xs + proj[2]; + + mat[1*row+0*col] = xform->m10 * ys; + mat[1*row+1*col] = xform->m11 * ys; + mat[1*row+2*col] = 0.0f; + mat[1*row+3*col] = xform->trans[1] * ys + proj[3]; + + mat[2*row+0*col] = 0.0f; + mat[2*row+1*col] = 0.0f; + mat[2*row+2*col] = 0.0f; + mat[2*row+3*col] = depth; + + mat[3*row+0*col] = 0.0f; + mat[3*row+1*col] = 0.0f; + mat[3*row+2*col] = 0.0f; + mat[3*row+3*col] = 1.0f; +} + + +//////////////////////////////////////////////////////////////////////// +// +// Blurs +// +// symmetrically expand a rectangle by ex/ey pixels on both sides, then clamp to tile bounds +static void gdraw_ExpandRect(gswf_recti *out, gswf_recti const *in, S32 ex, S32 ey, S32 w, S32 h) +{ + out->x0 = RR_MAX(in->x0 - ex, 0); + out->y0 = RR_MAX(in->y0 - ey, 0); + out->x1 = RR_MIN(in->x1 + ex, w); + out->y1 = RR_MIN(in->y1 + ey, h); +} + +static void gdraw_ShiftRect(gswf_recti *out, gswf_recti const *in, S32 dx, S32 dy) +{ + out->x0 = in->x0 + dx; + out->y0 = in->y0 + dy; + out->x1 = in->x1 + dx; + out->y1 = in->y1 + dy; +} + +#define MAX_TAPS 9 // max # of bilinear samples in one 'convolution' step + +enum +{ + // basic shader family + VAR_tex0 = 0, + VAR_tex1, + VAR_cmul, + VAR_cadd, + VAR_focal, + + // filter family + VAR_filter_tex0 = 0, + VAR_filter_tex1, + VAR_filter_color, + VAR_filter_tc_off, + VAR_filter_tex2, + VAR_filter_clamp0, + VAR_filter_clamp1, + VAR_filter_color2, + MAX_VARS, + + // blur family + VAR_blur_tex0 = 0, + VAR_blur_tap, + VAR_blur_clampv, + + // color matrix family + VAR_colormatrix_tex0 = 0, + VAR_colormatrix_data, + + // ihud family + VAR_ihudv_worldview = 0, + VAR_ihudv_material, + VAR_ihudv_textmode, +}; + +typedef struct +{ + S32 w,h, frametex_width, frametex_height; + void (*BlurPass)(GDrawRenderState *r, int taps, float *data, gswf_recti *s, float *tc, float height_max, float *clampv, GDrawStats *gstats); +} GDrawBlurInfo; + +static GDrawTexture *gdraw_BlurPass(GDrawFunctions *g, GDrawBlurInfo *c, GDrawRenderState *r, int taps, float *data, gswf_recti *draw_bounds, gswf_recti *sample_bounds, GDrawStats *gstats) +{ + F32 tc[4]; + F32 clamp[4]; + F32 t=0; + F32 texel_scale_s = 1.0f / c->frametex_width; + F32 texel_scale_t = 1.0f / c->frametex_height; + S32 i; + for (i=0; i < taps; ++i) + t += data[4*i+2]; + assert(t >= 0.99f && t <= 1.01f); + + tc[0] = texel_scale_s * draw_bounds->x0; + tc[1] = texel_scale_t * draw_bounds->y0; + tc[2] = texel_scale_s * draw_bounds->x1; + tc[3] = texel_scale_t * draw_bounds->y1; + + // sample_bounds is (x0,y0) inclusive, (x1,y1) exclusive + // texel centers are offset by 0.5 from integer coordinates and we don't want to sample outside sample_bounds + clamp[0] = texel_scale_s * (sample_bounds->x0 + 0.5f); + clamp[1] = texel_scale_t * (sample_bounds->y0 + 0.5f); + clamp[2] = texel_scale_s * (sample_bounds->x1 - 0.5f); + clamp[3] = texel_scale_t * (sample_bounds->y1 - 0.5f); + + if (!g->TextureDrawBufferBegin(draw_bounds, GDRAW_TEXTURE_FORMAT_rgba32, GDRAW_TEXTUREDRAWBUFFER_FLAGS_needs_color | GDRAW_TEXTUREDRAWBUFFER_FLAGS_needs_alpha, 0, gstats)) + return r->tex[0]; + + c->BlurPass(r, taps, data, draw_bounds, tc, (F32) c->h / c->frametex_height, clamp, gstats); + return g->TextureDrawBufferEnd(gstats); +} + +static GDrawTexture *gdraw_BlurPassDownsample(GDrawFunctions *g, GDrawBlurInfo *c, GDrawRenderState *r, int taps, float *data, gswf_recti *draw_bounds, int axis, int divisor, int tex_w, int tex_h, gswf_recti *sample_bounds, GDrawStats *gstats) +{ + S32 i; + F32 t=0; + F32 tc[4]; + F32 clamp[4]; + F32 texel_scale_s = 1.0f / tex_w; + F32 texel_scale_t = 1.0f / tex_h; + gswf_recti z; + + for (i=0; i < taps; ++i) + t += data[4*i+2]; + assert(t >= 0.99f && t <= 1.01f); + + // following must be integer divides! + if (axis == 0) { + z.x0 = draw_bounds->x0 / divisor; + z.x1 = (draw_bounds->x1-1) / divisor + 1; + z.y0 = draw_bounds->y0; + z.y1 = draw_bounds->y1; + + tc[0] = ((z.x0 - 0.5f)*divisor+0.5f)*texel_scale_s; + tc[2] = ((z.x1 - 0.5f)*divisor+0.5f)*texel_scale_s; + tc[1] = z.y0*texel_scale_t; + tc[3] = z.y1*texel_scale_t; + } else { + z.x0 = draw_bounds->x0; + z.x1 = draw_bounds->x1; + z.y0 = draw_bounds->y0 / divisor; + z.y1 = (draw_bounds->y1-1) / divisor + 1; + + tc[0] = z.x0*texel_scale_s; + tc[2] = z.x1*texel_scale_s; + tc[1] = ((z.y0 - 0.5f)*divisor+0.5f)*texel_scale_t; + tc[3] = ((z.y1 - 0.5f)*divisor+0.5f)*texel_scale_t; + } + + if (!g->TextureDrawBufferBegin(&z, GDRAW_TEXTURE_FORMAT_rgba32, GDRAW_TEXTUREDRAWBUFFER_FLAGS_needs_color | GDRAW_TEXTUREDRAWBUFFER_FLAGS_needs_alpha, 0, gstats)) + return r->tex[0]; + + clamp[0] = texel_scale_s * (sample_bounds->x0 + 0.5f); + clamp[1] = texel_scale_t * (sample_bounds->y0 + 0.5f); + clamp[2] = texel_scale_s * (sample_bounds->x1 - 0.5f); + clamp[3] = texel_scale_t * (sample_bounds->y1 - 0.5f); + + assert(clamp[0] <= clamp[2]); + assert(clamp[1] <= clamp[3]); + + c->BlurPass(r, taps, data, &z, tc, (F32) c->h / c->frametex_height, clamp, gstats); + return g->TextureDrawBufferEnd(gstats); +} + +#define unmap(t,a,b) (((t)-(a))/(F32) ((b)-(a))) +#define linear_remap(t,a,b,c,d) ((c) + unmap(t,a,b)*((d)-(c))) + +static void gdraw_BlurAxis(S32 axis, GDrawFunctions *g, GDrawBlurInfo *c, GDrawRenderState *r, F32 blur_width, F32 texel, gswf_recti *draw_bounds, gswf_recti *sample_bounds, GDrawTexture *protect, GDrawStats *gstats) +{ + GDrawTexture *t; + F32 data[MAX_TAPS][4]; + S32 off_axis = 1-axis; + S32 w = ((S32) ceil((blur_width-1)/2))*2+1; // 1.2 => 3, 2.8 => 3, 3.2 => 5 + F32 edge_weight = 1 - (w - blur_width)/2; // 3 => 0 => 1; 1.2 => 1.8 => 0.9 => 0.1 + F32 inverse_weight = 1.0f / blur_width; + + w = ((w-1) >> 1) + 1; // 3 => 2, 5 => 3, 7 => 4 (number of texture samples) + + if (!r->tex[0]) + return; + + // horizontal filter + if (w > 1) { + if (w <= MAX_TAPS) { + // we have enough taps to just do it + // use 'w' taps + S32 i, expand; + + // just go through and place all the taps in the right place + + // if w is 2 (sample from -1,0,1) + // 0 => -0.5 + // 1 => 1 + + // if w is 3: + // 0 => -1.5 samples from -2,-1 + // 1 => 0.5 samples from 0,1 + // 2 => 2 samples from 2 + + // if w is 4: + // 0 => -2.5 samples from -3,-2 + // 1 => -0.5 samples from -1,0 + // 2 => 1.5 samples from 1,2 + // 3 => 3 samples from 3 + + for (i=0; i < w; ++i) { + // first texsample samples from -w+1 and -w+2, e.g. w=2 => -1,0,1 + data[i][axis] = (-w+1.5f + i*2)*texel; + data[i][off_axis] = 0; + data[i][2] = 2*inverse_weight; // 2 full-weight samples + data[i][3] = 0; + } + // now reweight the last one + data[i-1][axis] = (w-1)*texel; + data[i-1][2] = edge_weight*inverse_weight; + // now reweight the first one + // (ew*0 + 1*1)/(1+ew) = 1/(1+ew) + data[0][axis] = (-w + 1.0f + 1/(edge_weight+1)) * texel; + data[0][2] = (edge_weight+1)*inverse_weight; + + expand = w-1; + gdraw_ExpandRect(draw_bounds, draw_bounds, axis ? 0 : expand, axis ? expand : 0, c->w, c->h); + + t = gdraw_BlurPass(g, c, r, w, data[0], draw_bounds, sample_bounds, gstats); + if (r->tex[0] != protect && r->tex[0] != t) + g->FreeTexture(r->tex[0], 0, gstats); + r->tex[0] = t; + gdraw_ExpandRect(sample_bounds, draw_bounds, 1, 1, c->w, c->h); // for next pass + } else { + // @OPTIMIZE: for symmetrical blurs we can get a 2-wide blur in the *off* axis at the same + // time we get N-wide in the on axis, which could double our max width + S32 i, expand; + // @HACK: this is really a dumb way to do it, i kind of had a brain fart, you could get + // the exact same result by just doing the downsample the naive way and then the + // final sample uses texture samples spaced by a texel rather than spaced by two + // texels -- the current method is just as inefficient, it just puts the inefficiency + // in the way the downsampled texture is self-overlapping, so the downsampled texture + // is twice as larger as it should be. + + // we COULD be exact by generating a mipmap, then sampling some number of samples + // from the mipmap and some from the original, but that would require being polyphase. + // instead we just are approximate. the mipmap weights the edge pixels by one half + // and overlaps them by one sample, so then in phase two we sample N slightly-overlapping + // mipmap samples + // + // instead we do the following. + // divide the source data up into clusters that are K samples long. + // ...K0... ...K1... ...K2... ...K3... + // + // Suppose K[i] is the average of all the items in cluster i. + // + // We compute a downsampled texture where T[i] = K[i] + K[i+1]. + // + // Now, we sample N taps from adjacent elements of T, allowing the texture unit + // to bilerp. Suppose a given sample falls at coordinate i with sub-position p. + // Then tap #j will compute: + // T[i+j]*(1-p) + T[i+j+1]*p + // But tap #j+1 will compute: + // T[i+j+1]*(1-p) + T[i+j+2]*p + // so we end up computing: + // sum(T[i+j]) except for the end samples. + // + // So, how do we create these initial clusters? That's easy, we use K taps + // to sample 2K texels. + // + // What value of k do we use? Well, we're constrained to using MAX_TAPS + // on each pass. So at the high end, we're bounded by: + // K = MAX_TAPS + // S = MAX_TAPS (S is number of samples in second pass) + // S addresses S*2-1 texels of T, and each texel adds K more samples, + // so (ignoring the edges) we basically have w = K*S + + // if w == MAX_TAPS*MAX_TAPS, then k = MAX_TAPS + // if w == MAX_TAPS+1, then k = 2 + // + // suppose we have 3 taps, then we can sample 5 samples in one pass, so then our + // max coverage is 25 samples, or a filter width of 13. with 7 taps, we sample + // 13 samples in one pass, max coverage is 13*13 samples or (13*13-1)/2 width, + // which is ((2T-1)*(2T-1)-1)/2 or (4T^2 - 4T + 1 -1)/2 or 2T^2 - 2T or 2T*(T-1) + S32 w_mip = (S32) ceil(linear_remap(w, MAX_TAPS+1, MAX_TAPS*MAX_TAPS, 2, MAX_TAPS)); + S32 downsample = w_mip; + F32 sample_spacing = texel; + if (downsample < 2) downsample = 2; + if (w_mip > MAX_TAPS) { + // if w_mip > MAX_TAPS, then we ought to use more than one mipmap pass, but + // since that's a huge filter ( > 80 pixels) let's just try subsampling and + // see if it's good enough. + sample_spacing *= w_mip / MAX_TAPS; + w_mip = MAX_TAPS; + } else { + assert(w / downsample <= MAX_TAPS); + } + inverse_weight = 1.0f / (2*w_mip); + for (i=0; i < w_mip; ++i) { + data[i][axis] = (-w_mip+1 + i*2+0.5f)*sample_spacing; + data[i][off_axis] = 0; + data[i][2] = 2*inverse_weight; + data[i][3] = 0; + } + w = w*2 / w_mip; + + // @TODO: compute the correct bboxes for this size + // the downsampled texture samples from -w_mip+1 to w_mip + // the sample from within that samples w spots within that, + // or w/2 of those, but they're overlapping by 50%. + // so if a sample is a point i, it samples from the original + // from -w_mip+1 to w_mip + i*w_mip. + // So then the minimum is: -w_mip+1 + (w/2)*w_mip, and + // the maximum is w_mip + (w/2)*w_mip + expand = (((w+1)>>1)+1)*w_mip+1; + gdraw_ExpandRect(draw_bounds, draw_bounds, axis ? 0 : expand, axis ? expand : 0, c->w, c->h); + + t = gdraw_BlurPassDownsample(g, c, r, w_mip, data[0], draw_bounds, axis, downsample, c->frametex_width, c->frametex_height, sample_bounds, gstats); + if (r->tex[0] != protect && r->tex[0] != t) + g->FreeTexture(r->tex[0], 0, gstats); + r->tex[0] = t; + gdraw_ExpandRect(sample_bounds, draw_bounds, 1, 1, c->w, c->h); + if (!r->tex[0]) + return; + + // now do a regular blur pass sampling from that + // the raw texture now contains 'downsample' samples per texel + if (w > 2*MAX_TAPS) { + sample_spacing = texel * (w-1) / (2*MAX_TAPS-1); + w = 2*MAX_TAPS; + } else { + sample_spacing = texel; + } + //sample_spacing *= 1.0f/2; + assert(w >= 2 && w <= 2*MAX_TAPS); + + if (w & 1) { + // we just want to evenly weight even-spaced samples + inverse_weight = 1.0f / w; + + // just go through and place all the taps in the right place + + w = (w+1)>>1; + for (i=0; i < w; ++i) { + data[i][axis] = (-w+1.0f + 0.5f + i*2)*sample_spacing; + data[i][off_axis] = 0; + data[i][2] = 2*inverse_weight; // 2 full-weight samples + data[i][3] = 0; + } + + // fix up the last tap + + // the following test is always true, but we're testing it here + // explicitly so as to make VS2012's static analyzer not complain + if (i > 0) { + data[i-1][axis] = (-w+1.0f+(i-1)*2)*sample_spacing; + data[i-1][2] = inverse_weight; + } + } else { + // we just want to evenly weight even-spaced samples + inverse_weight = 1.0f / w; + + // just go through and place all the taps in the right place + w >>= 1; + for (i=0; i < w; ++i) { + data[i][axis] = (-w+1.0f + i*2)*sample_spacing; + data[i][off_axis] = 0; + data[i][2] = 2*inverse_weight; // 2 full-weight samples + data[i][3] = 0; + } + } + + t = gdraw_BlurPassDownsample(g, c, r, w, data[0], draw_bounds, axis, 1, + axis==0 ? c->frametex_width*downsample : c->frametex_width, + axis==1 ? c->frametex_height*downsample : c->frametex_height, sample_bounds, gstats); + if (r->tex[0] != protect && r->tex[0] != t) + g->FreeTexture(r->tex[0], 0, gstats); + r->tex[0] = t; + gdraw_ExpandRect(sample_bounds, draw_bounds, 1, 1, c->w, c->h); + } + } +} + +static void gdraw_Blur(GDrawFunctions *g, GDrawBlurInfo *c, GDrawRenderState *r, gswf_recti *draw_bounds, gswf_recti *sample_bounds, GDrawStats *gstats) +{ + S32 p; + GDrawTexture *protect = r->tex[0]; + gswf_recti sbounds; + + // compute texel offset size + F32 dx = 1.0f / c->frametex_width; + F32 dy = 1.0f / c->frametex_height; + + // blur = 1 => 1 tap + // blur = 1.2 => 3 taps (0.1, 1, 0.1) + // blur = 2.2 => 3 taps (0.6, 1, 0.6) + // blur = 2.8 => 3 taps (0.9, 1, 0.9) + // blur = 3 => 3 taps (1 , 1, 1 ) + // blur = 3.2 => 5 taps (0.1, 1, 1, 1, 0.1) + + //S32 w = ((S32) ceil((r->blur_x-1)/2))*2+1; // 1.2 => (1.2-1)/2 => 0.1 => 1.0 => 1 => 2 => 3 + //S32 h = ((S32) ceil((r->blur_y-1)/2))*2+1; // 3 => (3-1)/2 => 1.0 => 1 => 2 => 3 + + // gdraw puts 1 border pixel around everything when producing rendertargets and we use this + // so expand the input sample bounds accordingly + gdraw_ExpandRect(&sbounds, sample_bounds, 1, 1, c->w, c->h); + + for (p=0; p < r->blur_passes; ++p) { + #if 0 // @OPTIMIZE do the filter in one pass + if (w*h <= MAX_TAPS) { + } else + #endif + { + // do the filter separably + gdraw_BlurAxis(0,g,c,r,r->blur_x,dx, draw_bounds, &sbounds, protect, gstats); + gdraw_BlurAxis(1,g,c,r,r->blur_y,dy, draw_bounds, &sbounds, protect, gstats); + } + } +} + +#ifdef GDRAW_MANAGE_MEM + +static void make_pool_aligned(void **start, S32 *num_bytes, U32 alignment) +{ + UINTa addr_orig = (UINTa) *start; + UINTa addr_aligned = (addr_orig + alignment-1) & ~((UINTa) alignment - 1); + + if (addr_aligned != addr_orig) { + S32 diff = (S32) (addr_aligned - addr_orig); + if (*num_bytes < diff) { + *start = NULL; + *num_bytes = 0; + return; + } else { + *start = (void *)addr_aligned; + *num_bytes -= diff; + } + } +} + +// Very simple arena allocator +typedef struct +{ + U8 *begin; + U8 *current; + U8 *end; +} GDrawArena; + +static void gdraw_arena_init(GDrawArena *arena, void *start, U32 size) +{ + arena->begin = (U8 *)start; + arena->current = (U8 *)start; + arena->end = (U8 *)start + size; +} + +static GDRAW_MAYBE_UNUSED void gdraw_arena_reset(GDrawArena *arena) +{ + arena->current = arena->begin; +} + +static void *gdraw_arena_alloc(GDrawArena *arena, U32 size, U32 align) +{ + UINTa start_addr = ((UINTa)arena->current + align-1) & ~((UINTa) align - 1); + U8 *ptr = (U8 *)start_addr; + UINTa remaining = arena->end - arena->current; + UINTa total_size = (ptr - arena->current) + size; + if (remaining < total_size) // doesn't fit + return NULL; + + arena->current = ptr + size; + return ptr; +} + +// Allocator for graphics memory. +// Graphics memory is assumed to be write-combined and slow to read for the +// CPU, so we keep all heap management information separately in main memory. +// +// There's a constant management of about 1k (2k for 64bit) to create a heap, +// plus a per-block overhead. The maximum number of blocks the allocator can +// ever use is bounded by 2*max_allocs+1; since GDraw manages a limited +// amount of handles, max_allocs is a known value at heap creation time. +// +// The allocator uses a best-fit heuristic to minimize fragmentation. +// Currently, there are no size classes or other auxiliary data structures to +// speed up this process, since the number of free blocks at any point in time +// is assumed to be fairly low. +// +// The allocator maintains a number of invariants: +// - The free list and physical block list are proper double-linked lists. +// (i.e. block->next->prev == block->prev->next == block) +// - All allocated blocks are also kept in a hash table, indexed by their +// pointer (to allow free to locate the corresponding block_info quickly). +// There's a single-linked, NULL-terminated list of elements in each hash +// bucket. +// - The physical block list is ordered. It always contains all currently +// active blocks and spans the whole managed memory range. There are no +// gaps between blocks, and all blocks have nonzero size. +// - There are no two adjacent free blocks; if two such blocks would be created, +// they are coalesced immediately. +// - The maximum number of blocks that could ever be necessary is allocated +// on initialization. All block_infos not currently in use are kept in a +// single-linked, NULL-terminated list of unused blocks. Every block is either +// in the physical block list or the unused list, and the total number of +// blocks is constant. +// These invariants always hold before and after an allocation/free. + +#ifndef GFXALLOC_ASSERT +#define GFXALLOC_ASSERT(x) +#endif + +typedef struct gfx_block_info +{ + U8 *ptr; + gfx_block_info *prev, *next; // for free blocks this is the free list, for allocated blocks it's a (single-linked!) list of elements in the corresponding hash bucket + gfx_block_info *prev_phys, *next_phys; + U32 is_free : 1; + U32 is_unused : 1; + U32 size : 30; +} gfx_block_info; +// 24 bytes/block on 32bit, 48 bytes/block on 64bit. + +#define GFXALLOC_HASH_SIZE 256 + +typedef struct gfx_allocator +{ + U8 *mem_base; + U8 *mem_end; + U32 max_allocs; + U32 block_align; + U32 block_shift; + S32 actual_bytes_free; + +#ifdef GFXALLOC_CHECK + int num_blocks; + int num_unused; + int num_alloc; + int num_free; +#endif + + GDrawHandleCache *cache; + + gfx_block_info *unused_list; // next unused block_info (single-linked list) + gfx_block_info *hash[GFXALLOC_HASH_SIZE]; // allocated blocks + gfx_block_info blocks[1]; // first block is head of free list AND head of physical block list (sentinel) +} gfx_allocator; +// about 1k (32bit), 2k (64bit) with 256 hash buckets (the default). dominated by hash table. + +#ifdef GFXALLOC_CHECK +#define GFXALLOC_IF_CHECK(x) x +#else +#define GFXALLOC_IF_CHECK(x) +#endif + +static U32 gfxalloc_get_hash_code(gfx_allocator *alloc, void *ptr) +{ + U32 a = (U32) (((U8 *) ptr - alloc->mem_base) >> alloc->block_shift); + + // integer hash function by Bob Jenkins (http://burtleburtle.net/bob/hash/integer.html) + // I use this function because integer mults are slow on PPC and large literal constants + // take multiple instrs to set up on all RISC CPUs. + a -= (a<<6); + a ^= (a>>17); + a -= (a<<9); + a ^= (a<<4); + a -= (a<<3); + a ^= (a<<10); + a ^= (a>>15); + + return a & (GFXALLOC_HASH_SIZE - 1); +} + +#if defined(SUPERDEBUG) || defined(COMPLETE_DEBUG) +#include +#define MAX_REGIONS 8192 +typedef struct +{ + U32 begin,end; +} gfx_region; +static gfx_region region[MAX_REGIONS]; + +static int region_sort(const void *p, const void *q) +{ + U32 a = *(U32*)p; + U32 b = *(U32*)q; + if (a < b) return -1; + if (a > b) return 1; + return 0; +} + +static void gfxalloc_check1(gfx_allocator *alloc) +{ + assert(alloc->max_allocs*2+1 < MAX_REGIONS); + int i,n=0; + for (i=0; i < GFXALLOC_HASH_SIZE; ++i) { + gfx_block_info *b = alloc->hash[i]; + while (b) { + region[n].begin = (UINTa) b->ptr; + region[n].end = region[n].begin + b->size; + ++n; + b = b->next; + } + } + gfx_block_info *b = alloc->blocks[0].next; + while (b != &alloc->blocks[0]) { + region[n].begin = (UINTa) b->ptr; + region[n].end = region[n].begin + b->size; + ++n; + b = b->next; + } + qsort(region, n, sizeof(region[0]), region_sort); + for (i=0; i+1 < n; ++i) { + assert(region[i].end == region[i+1].begin); + } +} +#else +#define gfxalloc_check1(a) +#endif + +#ifdef COMPLETE_DEBUG +static void verify_against_blocks(int num_regions, void *vptr, S32 len) +{ + U32 *ptr = (U32 *) vptr; + // binary search for ptr amongst regions + S32 s=0,e=num_regions-1; + assert(len != 0); + while (s < e) { + S32 i = (s+e+1)>>1; + // invariant: b[s] <= ptr <= b[e] + if (region[i].begin <= (UINTa) ptr) + s = i; + else + e = i-1; + + // consider cases: + // s=0,e=1: i = 0, how do we get i to be 1? + } + // at this point, s >= e + assert(s < num_regions && region[s].begin == (UINTa) ptr && (UINTa) ptr+len <= region[s].end); +} + +static void debug_complete_check(gfx_allocator *alloc, void *ptr, S32 len, void *skip) +{ + GDrawHandleCache *c = alloc->cache; + assert(alloc->max_allocs*2+1 < MAX_REGIONS); + int i,n=0; + for (i=0; i < GFXALLOC_HASH_SIZE; ++i) { + gfx_block_info *b = alloc->hash[i]; + while (b) { + region[n].begin = (UINTa) b->ptr; + region[n].end = region[n].begin + b->size; + ++n; + b = b->next; + } + } + gfx_block_info *b = alloc->blocks[0].next; + while (b != &alloc->blocks[0]) { + region[n].begin = (UINTa) b->ptr; + region[n].end = region[n].begin + b->size; + ++n; + b = b->next; + } + for (i=0; i < n; ++i) + assert(region[i].end > region[i].begin); + qsort(region, n, sizeof(region[0]), region_sort); + for (i=0; i+1 < n; ++i) { + assert(region[i].end == region[i+1].begin); + } + + if (ptr) + verify_against_blocks(n, ptr, len); + + if (c) { + GDrawHandle *t = c->head; + while (t) { + if (t->raw_ptr && t->raw_ptr != skip) + verify_against_blocks(n, t->raw_ptr, t->bytes); + t = t->next; + } + t = c->active; + while (t) { + if (t->raw_ptr && t->raw_ptr != skip) + verify_against_blocks(n, t->raw_ptr, t->bytes); + t = t->next; + } + } +} +#else +#define debug_complete_check(a,p,len,s) +#endif + +#ifdef GFXALLOC_CHECK +static void gfxalloc_check2(gfx_allocator *alloc) +{ + int n=0; + gfx_block_info *b = alloc->unused_list; + while (b) { + ++n; + b = b->next; + } + GFXALLOC_ASSERT(n == alloc->num_unused); + b = alloc->blocks->next; + n = 0; + while (b != alloc->blocks) { + ++n; + b = b->next; + } + GFXALLOC_ASSERT(n == alloc->num_free); + GFXALLOC_ASSERT(alloc->num_blocks == alloc->num_unused + alloc->num_free + alloc->num_alloc); +} +#define gfxalloc_check(a) do { gfxalloc_check1(a); gfxalloc_check2(a); } while(0) +#else +#define gfxalloc_check2(a) +#define gfxalloc_check(a) +#endif + + + +static gfx_block_info *gfxalloc_pop_unused(gfx_allocator *alloc) +{ + GFXALLOC_ASSERT(alloc->unused_list != NULL); + GFXALLOC_ASSERT(alloc->unused_list->is_unused); + GFXALLOC_IF_CHECK(GFXALLOC_ASSERT(alloc->num_unused);) + + gfx_block_info *b = alloc->unused_list; + alloc->unused_list = b->next; + GFXALLOC_ASSERT(alloc->unused_list); + b->is_unused = 0; + GFXALLOC_IF_CHECK(--alloc->num_unused;) + return b; +} + +static void gfxalloc_push_unused(gfx_allocator *alloc, gfx_block_info *b) +{ + GFXALLOC_ASSERT(!b->is_unused); + b->is_unused = 1; + b->next = alloc->unused_list; + alloc->unused_list = b; + GFXALLOC_IF_CHECK(++alloc->num_unused); +} + +static void gfxalloc_add_free(gfx_allocator *alloc, gfx_block_info *b) +{ + gfx_block_info *head = alloc->blocks; + + b->is_free = 1; + b->next = head->next; + b->prev = head; + head->next->prev = b; + head->next = b; + GFXALLOC_IF_CHECK(++alloc->num_free;) +} + +static void gfxalloc_rem_free(gfx_allocator *alloc, gfx_block_info *b) +{ + RR_UNUSED_VARIABLE(alloc); + b->is_free = 0; + b->prev->next = b->next; + b->next->prev = b->prev; + GFXALLOC_IF_CHECK(--alloc->num_free;) +} + +static void gfxalloc_split_free(gfx_allocator *alloc, gfx_block_info *b, U32 pos) +{ + gfx_block_info *n = gfxalloc_pop_unused(alloc); + + GFXALLOC_ASSERT(b->is_free); + GFXALLOC_ASSERT(pos > 0 && pos < b->size); + + // set up new free block + n->ptr = b->ptr + pos; + n->prev_phys = b; + n->next_phys = b->next_phys; + n->next_phys->prev_phys = n; + n->size = b->size - pos; + assert(n->size != 0); + gfxalloc_add_free(alloc, n); + + // fix original block + b->next_phys = n; + b->size = pos; + assert(b->size != 0); + +debug_complete_check(alloc, n->ptr, n->size,0); +debug_complete_check(alloc, b->ptr, b->size,0); +} + +static gfx_allocator *gfxalloc_create(void *mem, U32 mem_size, U32 align, U32 max_allocs) +{ + gfx_allocator *a; + U32 i, max_blocks, size; + + if (!align || (align & (align - 1)) != 0) // align must be >0 and a power of 2 + return NULL; + + // for <= max_allocs live allocs, there's <= 2*max_allocs+1 blocks. worst case: + // [free][used][free] .... [free][used][free] + max_blocks = max_allocs * 2 + 1; + size = sizeof(gfx_allocator) + max_blocks * sizeof(gfx_block_info); + a = (gfx_allocator *) IggyGDrawMalloc(size); + if (!a) + return NULL; + + memset(a, 0, size); + + GFXALLOC_IF_CHECK(a->num_blocks = max_blocks;) + GFXALLOC_IF_CHECK(a->num_alloc = 0;) + GFXALLOC_IF_CHECK(a->num_free = 1;) + GFXALLOC_IF_CHECK(a->num_unused = max_blocks-1;) + + GFXALLOC_IF_CHECK(GFXALLOC_ASSERT(a->num_blocks == a->num_alloc + a->num_free + a->num_unused);) + GFXALLOC_IF_CHECK(GFXALLOC_ASSERT(a->num_free <= a->num_blocks+1);) + + a->actual_bytes_free = mem_size; + a->mem_base = (U8 *) mem; + a->mem_end = a->mem_base + mem_size; + a->max_allocs = max_allocs; + a->block_align = align; + a->block_shift = 0; + while ((1u << a->block_shift) < a->block_align) + a->block_shift++; + + // init sentinel block + a->blocks[0].prev = a->blocks[0].next = &a->blocks[1]; // point to free block + a->blocks[0].prev_phys = a->blocks[0].next_phys = &a->blocks[1]; // same + + // init first free block + a->blocks[1].ptr = a->mem_base; + a->blocks[1].prev = a->blocks[1].next = &a->blocks[0]; + a->blocks[1].prev_phys = a->blocks[1].next_phys = &a->blocks[0]; + a->blocks[1].is_free = 1; + a->blocks[1].size = mem_size; + + // init "unused" list + a->unused_list = a->blocks + 2; + for (i=2; i < max_blocks; i++) { + a->blocks[i].is_unused = 1; + a->blocks[i].next = a->blocks + (i + 1); + } + a->blocks[i].is_unused = 1; + + gfxalloc_check(a); + debug_complete_check(a, NULL, 0,0); + return a; +} + +static void *gfxalloc_alloc(gfx_allocator *alloc, U32 size_in_bytes) +{ + gfx_block_info *cur, *best = NULL; + U32 i, best_wasted = ~0u; + U32 size = size_in_bytes; +debug_complete_check(alloc, NULL, 0,0); +gfxalloc_check(alloc); + GFXALLOC_IF_CHECK(GFXALLOC_ASSERT(alloc->num_blocks == alloc->num_alloc + alloc->num_free + alloc->num_unused);) + GFXALLOC_IF_CHECK(GFXALLOC_ASSERT(alloc->num_free <= alloc->num_blocks+1);) + + + // round up to multiple of our block alignment + size = (size + alloc->block_align-1) & ~(alloc->block_align - 1); + assert(size >= size_in_bytes); + assert(size != 0); + + // find best fit among all free blocks. this is O(N)! + for (cur = alloc->blocks[0].next; cur != alloc->blocks; cur = cur->next) { + if (cur->size >= size) { + U32 wasted = cur->size - size; + if (wasted < best_wasted) { + best_wasted = wasted; + best = cur; + if (!wasted) break; // can't get better than perfect + } + } + } + + // return the best fit, if we found any suitable block + if (best) { +debug_check_overlap(alloc->cache, best->ptr, best->size); + // split off allocated part + if (size != best->size) + gfxalloc_split_free(alloc, best, size); +debug_complete_check(alloc, best->ptr, best->size,0); + + // remove from free list and add to allocated hash table + GFXALLOC_ASSERT(best->size == size); + gfxalloc_rem_free(alloc, best); + + i = gfxalloc_get_hash_code(alloc, best->ptr); + best->next = alloc->hash[i]; + alloc->hash[i] = best; + alloc->actual_bytes_free -= size; + GFXALLOC_ASSERT(alloc->actual_bytes_free >= 0); + + GFXALLOC_IF_CHECK(++alloc->num_alloc;) + GFXALLOC_IF_CHECK(GFXALLOC_ASSERT(alloc->num_blocks == alloc->num_alloc + alloc->num_free + alloc->num_unused);) + GFXALLOC_IF_CHECK(GFXALLOC_ASSERT(alloc->num_free <= alloc->num_blocks+1);) + +debug_complete_check(alloc, best->ptr, best->size,0); +gfxalloc_check(alloc); +debug_check_overlap(alloc->cache, best->ptr, best->size); + return best->ptr; + } else + return NULL; // not enough space! +} + +static void gfxalloc_free(gfx_allocator *alloc, void *ptr) +{ + GFXALLOC_IF_CHECK(GFXALLOC_ASSERT(alloc->num_blocks == alloc->num_alloc + alloc->num_free + alloc->num_unused);) + GFXALLOC_IF_CHECK(GFXALLOC_ASSERT(alloc->num_free <= alloc->num_blocks+1);) + + // find the block in the hash table + gfx_block_info *b, *t, **prevnext; + U32 i = gfxalloc_get_hash_code(alloc, ptr); + + prevnext = &alloc->hash[i]; + b = alloc->hash[i]; + + while (b) { + if (b->ptr == ptr) break; + prevnext = &b->next; + b = b->next; + } + + if (!b) { + GFXALLOC_ASSERT(0); // trying to free a non-allocated block + return; + } + +debug_complete_check(alloc, b->ptr, b->size, 0); + GFXALLOC_IF_CHECK(--alloc->num_alloc;) + + // remove it from the hash table + *prevnext = b->next; + + alloc->actual_bytes_free += b->size; + + // merge with previous block if it's free, else add it to free list + t = b->prev_phys; + if (t->is_free) { + t->size += b->size; + t->next_phys = b->next_phys; + t->next_phys->prev_phys = t; + gfxalloc_push_unused(alloc, b); + b = t; + } else + gfxalloc_add_free(alloc, b); + + // try to merge with next block + t = b->next_phys; + if (t->is_free) { + b->size += t->size; + b->next_phys = t->next_phys; + t->next_phys->prev_phys = b; + gfxalloc_rem_free(alloc, t); + gfxalloc_push_unused(alloc, t); + } +debug_complete_check(alloc, 0, 0, ptr); +gfxalloc_check(alloc); + GFXALLOC_IF_CHECK(GFXALLOC_ASSERT(alloc->num_blocks == alloc->num_alloc + alloc->num_free + alloc->num_unused);) + GFXALLOC_IF_CHECK(GFXALLOC_ASSERT(alloc->num_free <= alloc->num_blocks+1);) +} + +#ifdef GDRAW_MANAGE_MEM_TWOPOOL + +static rrbool gfxalloc_is_empty(gfx_allocator *alloc) +{ + gfx_block_info *first_free = alloc->blocks[0].next; + + // we want to check whether there's exactly one free block that + // covers the entire pool. + if (first_free == alloc->blocks) // 0 free blocks + return false; + + if (first_free->next != alloc->blocks) // >1 free block + return false; + + return first_free->ptr == alloc->mem_base && first_free->ptr + first_free->size == alloc->mem_end; +} + +static rrbool gfxalloc_mem_contains(gfx_allocator *alloc, void *ptr) +{ + return alloc->mem_base <= (U8*)ptr && (U8*)ptr < alloc->mem_end; +} + +#endif + +#ifdef GDRAW_DEBUG + +static void gfxalloc_dump(gfx_allocator *alloc) +{ + static const char *type[] = { + "allocated", + "free", + }; + + for (gfx_block_info *b = alloc->blocks[0].next_phys; b != alloc->blocks; b=b->next_phys) { + U8 *start = b->ptr; + U8 *end = b->ptr + b->size; + printf("%p-%p: %s (%d bytes)\n", start, end, type[b->is_free], b->size); + } +} + +#endif + +#endif + +#ifdef GDRAW_DEFRAGMENT + +#define GDRAW_DEFRAGMENT_may_overlap 1 // self-overlap for individual copies is OK + +// Defragmentation code for graphics memory. +// The platform implementation must provide a GPU memcpy function and handle all necessary +// synchronization. It must also adjust its resource descriptors to match the new addresses +// after defragmentation. + +static void gdraw_gpu_memcpy(GDrawHandleCache *c, void *dst, void *src, U32 num_bytes); + +static void gdraw_Defragment_memmove(GDrawHandleCache *c, U8 *dst, U8 *src, U32 num_bytes, U32 flags, GDrawStats *stats) +{ + if (dst == src) + return; + + assert(num_bytes != 0); + + stats->nonzero_flags |= GDRAW_STATS_defrag; + stats->defrag_objects += 1; + stats->defrag_bytes += num_bytes; + + if ((flags & GDRAW_DEFRAGMENT_may_overlap) || dst + num_bytes <= src || src + num_bytes <= dst) // no problematic overlap + gdraw_gpu_memcpy(c, dst, src, num_bytes); + else { + // need to copy in multiple chunks + U32 chunk_size, pos=0; + if (dst < src) + chunk_size = (U32) (src - dst); + else + chunk_size = (U32) (dst - src); + + while (pos < num_bytes) { + U32 amount = num_bytes - pos; + if (amount > chunk_size) amount = chunk_size; + gdraw_gpu_memcpy(c, dst + pos, src + pos, amount); + pos += amount; + } + } +} + +static rrbool gdraw_CanDefragment(GDrawHandleCache *c) +{ + // we can defragment (and extract some gain from it) if and only if there's more + // than one free block. since gfxalloc coalesces free blocks immediately and keeps + // them in a circular linked list, this is very easy to detect: just check if the + // "next" pointer of the first free block points to the sentinel. (this is only + // the case if there are 0 or 1 free blocks) + gfx_allocator *alloc = c->alloc; + return alloc->blocks[0].next->next != alloc->blocks; +} + +static void gdraw_DefragmentMain(GDrawHandleCache *c, U32 flags, GDrawStats *stats) +{ + gfx_allocator *alloc = c->alloc; + gfx_block_info *b, *n; + U8 *p; + S32 i; + + GFXALLOC_IF_CHECK(GFXALLOC_ASSERT(alloc->num_blocks == alloc->num_alloc + alloc->num_free + alloc->num_unused);) + GFXALLOC_IF_CHECK(GFXALLOC_ASSERT(alloc->num_free <= alloc->num_blocks+1);) + + // go over all allocated memory blocks and clear the "prev" pointer + // (unused for allocated blocks, we'll use it to store a back-pointer to the corresponding handle) + for (b = alloc->blocks[0].next_phys; b != alloc->blocks; b=b->next_phys) + if (!b->is_free) + b->prev = NULL; + + // go through all handles and store a pointer to the handle in the corresponding memory block + for (i=0; i < c->max_handles; i++) + if (c->handle[i].raw_ptr) { + assert(c->handle[i].bytes != 0); + for (b=alloc->hash[gfxalloc_get_hash_code(alloc, c->handle[i].raw_ptr)]; b; b=b->next) + if (b->ptr == c->handle[i].raw_ptr) { + void *block = &c->handle[i]; + b->prev = (gfx_block_info *) block; + break; + } + + GFXALLOC_ASSERT(b != NULL); // didn't find this block anywhere! + } + + // clear alloc hash table (we rebuild it during defrag) + memset(alloc->hash, 0, sizeof(alloc->hash)); + + // defragmentation proper: go over all blocks again, remove all free blocks from the physical + // block list and compact the remaining blocks together. + p = alloc->mem_base; + for (b = alloc->blocks[0].next_phys; b != alloc->blocks; b=n) { + n = b->next_phys; + + if (!b->is_free) { + U32 h; + + // move block if necessary + if (p != b->ptr) { + assert(b->size != 0); + gdraw_Defragment_memmove(c, p, b->ptr, b->size, flags, stats); + b->ptr = p; + assert(b->prev); + if (b->prev) + ((GDrawHandle *) b->prev)->raw_ptr = p; + } + + // re-insert into hash table + h = gfxalloc_get_hash_code(alloc, p); + b->next = alloc->hash[h]; + alloc->hash[h] = b; + + p += b->size; + } else { + // free block: remove it from the physical block list + b->prev_phys->next_phys = b->next_phys; + b->next_phys->prev_phys = b->prev_phys; + gfxalloc_rem_free(alloc, b); + gfxalloc_push_unused(alloc, b); + } + } + // the free list should be empty now + assert(alloc->blocks[0].next == &alloc->blocks[0]); + + // unless all memory is allocated, we now need to add a new block for the free space at the end + if (p != alloc->mem_end) { + b = gfxalloc_pop_unused(alloc); + + b->ptr = p; + b->prev_phys = alloc->blocks[0].prev_phys; + b->next_phys = &alloc->blocks[0]; + b->prev_phys->next_phys = b; + b->next_phys->prev_phys = b; + b->size = alloc->mem_end - p; + gfxalloc_add_free(alloc, b); + } + + GFXALLOC_IF_CHECK(GFXALLOC_ASSERT(alloc->num_blocks == alloc->num_alloc + alloc->num_free + alloc->num_unused);) + GFXALLOC_IF_CHECK(GFXALLOC_ASSERT(alloc->num_free <= alloc->num_blocks+1);) +} + +#endif + +#ifdef GDRAW_MANAGE_MEM_TWOPOOL + +// Defragmentation code for graphics memory, using two-pool strategy. +// +// The platform implementation must provide a GPU memcpy function and handle +// all necessary synchronization. It must also adjust its resource descriptors +// to match the new addresses after defragmentation. +// +// The high concept for two-pool is that we can't update the resource pools +// mid-frame; instead, while preparing for a frame, we need to produce a memory +// configuration that is suitable for rendering a whole frame at once (in +// contrast to our normal incremental strategy, where we can decide to +// defragment mid-frame if things are getting desperate). This is for tiled +// renderers. +// +// Two-pool works like this: +// - As the name suggests, each handle cache has two memory pools and corresponding backing +// allocators. The currently used allocator, "alloc", and a second allocator, "alloc_other". +// - Any resource used in a command buffer gets locked and *stays locked* until we're done +// preparing that command buffer (i.e. no unlocking after every draw as in the normal +// incremental memory management). +// - All allocations happen from "alloc", always. We mostly do our normal LRU cache freeing +// to make space when required. +// - We can still run out of space (no surprise) and get into a configuration where we have +// to defragment. This is the only tricky part, and where the second pool comes in. To +// defragment, we switch the roles of "alloc" and "alloc_other", and allocate new backing +// storage for all currently "locked" and "pinned" resources (i.e. everything we've used +// in the currently pending frame). +// - In general, we have the invariant that all resources we're using for batches we're +// working on must be in the "alloc" (fresh) pool, not in the "other" (stale) pool. +// Therefore, after a defragment/pool switch, any "live" resource (which means it's +// present in the stale pool) has to be copied to the "fresh" pool as it's getting +// locked to maintain this invariant. +// +// What this does is give us a guarantee that any given frame either only +// references resources in one pool (the common case), or does a defragment, in +// which case it looks like this: +// +// +------------------------------+ +// | | +// | | pool A is fresh (=alloc), pool B is stale (=alloc_other) +// | | all resources referenced in here are in pool A +// | | +// | | +// | | +// +------------------------------+ <-- defragment! pools flip roles here +// | | +// | | +// | | pool B is fresh (=alloc), pool A is stale (=alloc_other) +// | | all resources referenced in here are in pool B +// | | +// +------------------------------+ +// +// Now, at the end of the frame, we need to decide what to do with the +// resources that remain "live" (i.e. they're in the old pool but weren't +// referenced in the current frame so they didn't get copied). As of this +// writing, we simply free them, to maximize the amount of free memory in the +// new pool (and hopefully minimize the chance that we'll have to defragment +// again soon). It would also be possible to copy some of them though, assuming +// there's enough space. +// +// Freeing resources is an interesting case. When the CPU side of GDraw does a +// "free", we can't immediately reclaim the resource memory, since the GPU will +// generally still have outstanding commands that reference that resource. So +// our freed resources first enter the "Dead" state and only actually get freed +// once the GPU is done with them. What this means is that the list of +// resources in the "dead" state can end up holding references to both the +// fresh and the stale pool; the free implementation needs to be aware of this +// and return the memory to the right allocator. +// +// When we defragment, it's important to make sure that the pool we're flipping +// to is actually empty. What this means is that right before a defragment, we +// need to wait for all stale "dead" resources to actually become free. If the +// last defragment was several frames ago, this is fast - we haven't generated +// any new commands referencing the stale resources in several frames, so most +// likely they're all immediately free-able. By contrast, if we just +// defragmented last frame, this will be a slow operation since we need to wait +// for the GPU pipeline to drain - but if you're triggering defragments in +// several consecutive frames, you're thrashing the resource pools badly and +// are getting really bad performance anyway. + +static void gdraw_gpu_memcpy(GDrawHandleCache *c, void *dst, void *src, U32 num_bytes); +static void gdraw_gpu_wait_for_transfer_completion(); +static void gdraw_resource_moved(GDrawHandle *t); + +static rrbool gdraw_CanDefragment(GDrawHandleCache *c) +{ + // we can defragment (and extract some gain from it) if and only if there's more + // than one free block. since gfxalloc coalesces free blocks immediately and keeps + // them in a circular linked list, this is very easy to detect: just check if the + // "next" pointer of the first free block points to the sentinel. (this is only + // the case if there are 0 or 1 free blocks) + gfx_allocator *alloc = c->alloc; + if (!c->alloc_other) // if we don't have a second pool, we can't defrag at all. + return false; + return alloc->blocks[0].next->next != alloc->blocks; +} + +static rrbool gdraw_MigrateResource(GDrawHandle *t, GDrawStats *stats) +{ + GDrawHandleCache *c = t->cache; + void *ptr = NULL; + + assert(t->state == GDRAW_HANDLE_STATE_live || t->state == GDRAW_HANDLE_STATE_locked || t->state == GDRAW_HANDLE_STATE_pinned); + // anything we migrate should be in the "other" (old) pool + assert(gfxalloc_mem_contains(c->alloc_other, t->raw_ptr)); + + ptr = gfxalloc_alloc(c->alloc, t->bytes); + if (ptr) { + // update stats + stats->nonzero_flags |= GDRAW_STATS_defrag; + stats->defrag_objects += 1; + stats->defrag_bytes += t->bytes; + + // copy contents to new storage + gdraw_gpu_memcpy(c, ptr, t->raw_ptr, t->bytes); + + // free old storage + gfxalloc_free(c->alloc_other, t->raw_ptr); + + // adjust pointers to point to new location + t->raw_ptr = ptr; + gdraw_resource_moved(t); + + return true; + } else + return false; +} + +static rrbool gdraw_MigrateAllResources(GDrawHandle *sentinel, GDrawStats *stats) +{ + GDrawHandle *h; + for (h = sentinel->next; h != sentinel; h = h->next) { + if (!gdraw_MigrateResource(h, stats)) + return false; + } + return true; +} + +static rrbool gdraw_TwoPoolDefragmentMain(GDrawHandleCache *c, GDrawStats *stats) +{ + gfx_allocator *t; + + // swap allocators + t = c->alloc; + c->alloc = c->alloc_other; + c->alloc_other = t; + + // immediately migrate all currently pinned and locked resources + rrbool ok = true; + ok = ok && gdraw_MigrateAllResources(&c->state[GDRAW_HANDLE_STATE_pinned], stats); + ok = ok && gdraw_MigrateAllResources(&c->state[GDRAW_HANDLE_STATE_locked], stats); + + return ok; +} + +static rrbool gdraw_StateListIsEmpty(GDrawHandle *head) +{ + // a list is empty when the head sentinel is the only node + return head->next == head; +} + +static void gdraw_CheckAllPointersUpdated(GDrawHandle *head) +{ +#ifdef GDRAW_DEBUG + GDrawHandle *h; + for (h = head->next; h != head; h = h->next) { + assert(gfxalloc_mem_contains(h->cache->alloc, h->raw_ptr)); + } +#endif +} + +static void gdraw_PostDefragmentCleanup(GDrawHandleCache *c, GDrawStats *stats) +{ + // if we defragmented during this scene, this is the spot where + // we need to nuke all references to resources that weren't + // carried over into the new pool. + if (c->did_defragment) { + GDrawHandle *h; + + // alloc list should be empty at this point + assert(gdraw_StateListIsEmpty(&c->state[GDRAW_HANDLE_STATE_alloc])); + + // free all remaining live resources (these are the resources we didn't + // touch this frame, hence stale) + h = &c->state[GDRAW_HANDLE_STATE_live]; + while (!gdraw_StateListIsEmpty(h)) + gdraw_res_free(h->next, stats); + + // "live" is now empty, and we already checked that "alloc" was empty + // earlier. "dead" may hold objects on the old heap still (that were freed + // before we swapped allocators). "user owned" is not managed by us. + // that leaves "locked" and "pinned" resources, both of which better be + // only pointing into the new heap now! + gdraw_CheckAllPointersUpdated(&c->state[GDRAW_HANDLE_STATE_locked]); + gdraw_CheckAllPointersUpdated(&c->state[GDRAW_HANDLE_STATE_pinned]); + + gdraw_gpu_wait_for_transfer_completion(); + } +} + +#endif + +// Image processing code + +// Compute average of 4 RGBA8888 pixels passed as U32. +// Variables are named assuming the values are stored as big-endian, but all bytes +// are treated equally, so this code will work just fine on little-endian data. +static U32 gdraw_Avg4_rgba8888(U32 p0, U32 p1, U32 p2, U32 p3) +{ + U32 mask = 0x00ff00ff; + U32 bias = 0x00020002; + + U32 gasum = ((p0 >> 0) & mask) + ((p1 >> 0) & mask) + ((p2 >> 0) & mask) + ((p3 >> 0) & mask) + bias; + U32 rbsum = ((p0 >> 8) & mask) + ((p1 >> 8) & mask) + ((p2 >> 8) & mask) + ((p3 >> 8) & mask) + bias; + + return ((gasum >> 2) & mask) | ((rbsum << 6) & ~mask); +} + +// Compute average of 2 RGBA8888 pixels passed as U32 +static U32 gdraw_Avg2_rgba8888(U32 p0, U32 p1) +{ + return (p0 | p1) - (((p0 ^ p1) >> 1) & 0x7f7f7f7f); +} + +// 2:1 downsample in both horizontal and vertical direction, for one line. +// width is width of destination line. +static void gdraw_Downsample_2x2_line(U8 *dst, U8 *line0, U8 *line1, U32 width, U32 bpp) +{ + U32 x; + if (bpp == 4) { + U32 *in0 = (U32 *) line0; + U32 *in1 = (U32 *) line1; + U32 *out = (U32 *) dst; + for (x=0; x < width; x++, in0 += 2, in1 += 2) + *out++ = gdraw_Avg4_rgba8888(in0[0], in0[1], in1[0], in1[1]); + } else if (bpp == 1) { + for (x=0; x < width; x++, line0 += 2, line1 += 2) + *dst++ = (line0[0] + line0[1] + line1[0] + line1[1] + 2) / 4; + } else + RR_BREAK(); +} + +// 2:1 downsample in horizontal but not vertical direction. +static void gdraw_Downsample_2x1_line(U8 *dst, U8 *src, U32 width, U32 bpp) +{ + U32 x; + if (bpp == 4) { + U32 *in = (U32 *) src; + U32 *out = (U32 *) dst; + for (x=0; x < width; x++, in += 2) + *out++ = gdraw_Avg2_rgba8888(in[0], in[1]); + } else if (bpp == 1) { + for (x=0; x < width; x++, src += 2) + *dst++ = (src[0] + src[1] + 1) / 2; + } else + RR_BREAK(); +} + +// 2:1 downsample in vertical but not horizontal direction. +static void gdraw_Downsample_1x2(U8 *dst, S32 dstpitch, U8 *src, S32 srcpitch, U32 height, U32 bpp) +{ + U32 y; + if (bpp == 4) { + for (y=0; y < height; y++, dst += dstpitch, src += 2*srcpitch) + *((U32 *) dst) = gdraw_Avg2_rgba8888(*((U32 *) src), *((U32 *) (src + srcpitch))); + } else if (bpp == 1) { + for (y=0; y < height; y++, dst += dstpitch, src += 2*srcpitch) + *dst = (src[0] + src[srcpitch] + 1) / 2; + } else + RR_BREAK(); +} + +// 2:1 downsample (for mipmaps) +// dst: Pointer to destination buffer +// dstpitch: Pitch for destination buffer +// width: Width of *destination* image (i.e. downsampled version) +// height: Height of *destination* image (i.e. downsampled version) +// src: Pointer to source buffer +// srcpitch: Pitch of source buffer +// bpp: Bytes per pixel for image data +// +// can be used for in-place resizing if src==dst and dstpitch <= srcpitch! +static GDRAW_MAYBE_UNUSED void gdraw_Downsample(U8 *dst, S32 dstpitch, U32 width, U32 height, U8 *src, S32 srcpitch, U32 bpp) +{ + U32 y; + assert(bpp == 1 || bpp == 4); + + // @TODO gamma? + if (!height) // non-square texture, height was reduced to 1 in a previous step + gdraw_Downsample_2x1_line(dst, src, width, bpp); + else if (!width) // non-square texture, width was reduced to 1 in a previous step + gdraw_Downsample_1x2(dst, dstpitch, src, srcpitch, height, bpp); + else { + for (y=0; y < height; y++) { + gdraw_Downsample_2x2_line(dst, src, src + srcpitch, width, bpp); + dst += dstpitch; + src += 2*srcpitch; + } + } +} + +#ifndef GDRAW_NO_STREAMING_MIPGEN + +#define GDRAW_MAXMIPS 16 // maximum number of mipmaps supported. + +typedef struct GDrawMipmapContext { + U32 width; // width of the texture being mipmapped + U32 height; // height of the texture being mipmapped + U32 mipmaps; // number of mipmaps + U32 bpp; // bytes per pixel + + U32 partial_row; // bit N: is mipmap N currently storing a partial row? + U32 bheight; // height of the buffer at miplevel 0 + U8 *pixels[GDRAW_MAXMIPS]; + U32 pitch[GDRAW_MAXMIPS]; +} GDrawMipmapContext; + +static rrbool gdraw_MipmapBegin(GDrawMipmapContext *c, U32 width, U32 height, U32 mipmaps, U32 bpp, U8 *buffer, U32 buffer_size) +{ + U32 i; + U8 *p; + + if (mipmaps > GDRAW_MAXMIPS) + return false; + + c->width = width; + c->height = height; + c->mipmaps = mipmaps; + c->bpp = bpp; + c->partial_row = 0; + + // determine how many lines to buffer + // we try to use roughly 2/3rds of the buffer for the first miplevel (less than 3/4 since with our + // partial line buffers, we have extra buffer space for lower mip levels). + c->bheight = (2 * buffer_size) / (3 * width * bpp); + + // round down to next-smaller power of 2 (in case we need to swizzle; swizzling works on pow2-sized blocks) + while (c->bheight & (c->bheight-1)) // while not a power of 2... + c->bheight &= c->bheight - 1; // clear least significant bit set + + // then keep lowering the number of buffered lines until they fit (or we reach zero, i.e. it doesn't fit) + while (c->bheight) { + p = buffer; + for (i=0; i < c->mipmaps; i++) { + U32 mw = c->width >> i; + U32 bh = c->bheight >> i; + if (!mw) mw++; + if (!bh) mw *= 2, bh++; // need space for line of previous miplevel + + c->pixels[i] = p; + c->pitch[i] = mw * bpp; + p += c->pitch[i] * bh; + } + + // if it fits, we're done + if (p <= buffer + buffer_size) { + if (c->bheight > height) // buffer doesn't need to be larger than the image! + c->bheight = height; + return true; + } + + // need to try a smaller line buffer... + c->bheight >>= 1; + } + + // can't fit even one line into our buffer. ouch! + return false; +} + +// returns true if there was data generated for this miplevel, false otherwise. +static rrbool gdraw_MipmapAddLines(GDrawMipmapContext *c, U32 level) +{ + U32 bw,bh; + + assert(level > 0); // doesn't make sense to call this on level 0 + if (level == 0 || level >= c->mipmaps) + return false; // this level doesn't exist + + bw = c->width >> level; // buffer width at this level + bh = c->bheight >> level; // buffer height at this level + + if (bh) { // we can still do regular downsampling + gdraw_Downsample(c->pixels[level], c->pitch[level], bw, bh, c->pixels[level-1], c->pitch[level-1], c->bpp); + return true; + } else if (c->height >> level) { // need to buffer partial lines, but still doing vertical 2:1 downsampling + if ((c->partial_row ^= (1 << level)) & (1 << level)) { // no buffered partial row for this miplevel yet, make one + memcpy(c->pixels[level], c->pixels[level-1], bw * 2 * c->bpp); + return false; + } else { // have one buffered row, can generate output pixels + gdraw_Downsample_2x2_line(c->pixels[level], c->pixels[level], c->pixels[level-1], bw, c->bpp); + return true; + } + } else { // finish off with a chain of Nx1 miplevels + gdraw_Downsample_2x1_line(c->pixels[level], c->pixels[level-1], bw, c->bpp); + return true; + } +} + +#endif // GDRAW_NO_STREAMING_MIPGEN + +#ifdef GDRAW_CHECK_BLOCK +static void check_block_alloc(gfx_allocator *alloc, void *ptr, rrbool allocated) +{ + int i,n=0,m=0; + for (i=0; i < GFXALLOC_HASH_SIZE; ++i) { + gfx_block_info *b = alloc->hash[i]; + while (b) { + if (b->ptr == ptr) + ++n; + b = b->next; + } + } + gfx_block_info *b = alloc->blocks[0].next; + while (b != &alloc->blocks[0]) { + if (b->ptr == ptr) + ++m; + b = b->next; + } + if (allocated) + assert(n == 1 && m == 0); + else + assert(n == 0 && m == 1); +} +#else +#define check_block_alloc(a,p,f) +#endif + +#ifdef GDRAW_BUFFER_RING + +//////////////////////////////////////////////////////////////////////// +// +// Buffer ring +// + +// Implements a dynamic buffer backed by multiple physical buffers, with +// the usual append-only, DISCARD/NOOVERWRITE semantics. +// +// This can be used for dynamic vertex buffers, constant buffers, etc. +#define GDRAW_BUFRING_MAXSEGS 4 // max number of backing segments + +typedef struct gdraw_bufring_seg { + struct gdraw_bufring_seg *next; // next segment in ring + U8 *data; // pointer to the allocation + GDrawFence fence; // fence for this segment + U32 used; // number of bytes used +} gdraw_bufring_seg; + +typedef struct gdraw_bufring { + gdraw_bufring_seg *cur; // active ring segment + U32 seg_size; // size of one segment + U32 align; // alignment of segment allocations + gdraw_bufring_seg all_segs[GDRAW_BUFRING_MAXSEGS]; +} gdraw_bufring; + +// forwards +static GDrawFence put_fence(); +static void wait_on_fence(GDrawFence fence); + +static void gdraw_bufring_init(gdraw_bufring * RADRESTRICT ring, void *ptr, U32 size, U32 nsegs, U32 align) +{ + U32 i, seg_size; + + ring->seg_size = 0; + if (!ptr || nsegs < 1 || size < nsegs * align) // bail if no ring buffer memory or too small + return; + + if (nsegs > GDRAW_BUFRING_MAXSEGS) + nsegs = GDRAW_BUFRING_MAXSEGS; + + // align needs to be a positive power of two + assert(align >= 1 && (align & (align - 1)) == 0); + + // buffer really needs to be properly aligned + assert(((UINTa)ptr & (align - 1)) == 0); + + seg_size = (size / nsegs) & ~(align - 1); + for (i=0; i < nsegs; ++i) { + ring->all_segs[i].next = &ring->all_segs[(i + 1) % nsegs]; + ring->all_segs[i].data = (U8 *) ptr + i * seg_size; + ring->all_segs[i].fence.value = 0; + ring->all_segs[i].used = 0; + } + + ring->cur = ring->all_segs; + ring->seg_size = seg_size; + ring->align = align; +} + +static void gdraw_bufring_shutdown(gdraw_bufring * RADRESTRICT ring) +{ + ring->cur = NULL; + ring->seg_size = 0; +} + +static void *gdraw_bufring_alloc(gdraw_bufring * RADRESTRICT ring, U32 size, U32 align) +{ + U32 align_up; + gdraw_bufring_seg *seg; + + if (size > ring->seg_size) + return NULL; // nope, won't fit + + assert(align <= ring->align); + + // check if it fits in the active segment first + seg = ring->cur; + align_up = (seg->used + align - 1) & -align; + + if ((align_up + size) <= ring->seg_size) { + void *ptr = seg->data + align_up; + seg->used = align_up + size; + return ptr; + } + + // doesn't fit, we have to start a new ring segment. + seg->fence = put_fence(); + + // switch to the next segment, wait till GPU is done with it + seg = ring->cur = seg->next; + wait_on_fence(seg->fence); + + // allocate from the new segment. we assume that segment offsets + // satisfy the highest alignment requirements we ever ask for! + seg->used = size; + return seg->data; +} + +#endif + +//////////////////////////////////////////////////////////////////////// +// +// General resource manager +// + +#ifndef GDRAW_FENCE_FLUSH +#define GDRAW_FENCE_FLUSH() +#endif + +#ifdef GDRAW_MANAGE_MEM +// functions the platform must implement +#ifndef GDRAW_BUFFER_RING // avoid "redundant redeclaration" warning +static void wait_on_fence(GDrawFence fence); +#endif +static rrbool is_fence_pending(GDrawFence fence); +static void gdraw_defragment_cache(GDrawHandleCache *c, GDrawStats *stats); + +// functions we implement +static void gdraw_res_reap(GDrawHandleCache *c, GDrawStats *stats); +#endif + +// If GDRAW_MANAGE_MEM is not #defined, this needs to perform the +// actual free using whatever API we're targeting. +// +// If GDRAW_MANAGE_MEM is #defined, the shared code handles the +// memory management part, but you might still need to update +// your state caching. +static void api_free_resource(GDrawHandle *r); + +// Actually frees a resource and releases all allocated resources +static void gdraw_res_free(GDrawHandle *r, GDrawStats *stats) +{ + assert(r->state == GDRAW_HANDLE_STATE_live || r->state == GDRAW_HANDLE_STATE_locked || r->state == GDRAW_HANDLE_STATE_dead || + r->state == GDRAW_HANDLE_STATE_pinned || r->state == GDRAW_HANDLE_STATE_user_owned); + +#ifdef GDRAW_MANAGE_MEM + GDRAW_FENCE_FLUSH(); + + // make sure resource isn't in use before we actually free the memory + wait_on_fence(r->fence); + if (r->raw_ptr) { +#ifndef GDRAW_MANAGE_MEM_TWOPOOL + gfxalloc_free(r->cache->alloc, r->raw_ptr); +#else + GDrawHandleCache *c = r->cache; + if (gfxalloc_mem_contains(c->alloc, r->raw_ptr)) + gfxalloc_free(c->alloc, r->raw_ptr); + else { + assert(gfxalloc_mem_contains(c->alloc_other, r->raw_ptr)); + gfxalloc_free(c->alloc_other, r->raw_ptr); + } +#endif + } +#endif + + api_free_resource(r); + + stats->nonzero_flags |= GDRAW_STATS_frees; + stats->freed_objects += 1; + stats->freed_bytes += r->bytes; + + gdraw_HandleCacheFree(r); +} + +// Frees the LRU resource in the given cache. +static rrbool gdraw_res_free_lru(GDrawHandleCache *c, GDrawStats *stats) +{ + GDrawHandle *r = gdraw_HandleCacheGetLRU(c); + if (!r) return false; + + if (c->is_vertex && r->owner) // check for r->owner since it may already be killed (if player destroyed first) + IggyDiscardVertexBufferCallback(r->owner, r); + + // was it referenced since end of previous frame (=in this frame)? + // if some, we're thrashing; report it to the user, but only once per frame. + if (c->prev_frame_end.value < r->fence.value && !c->is_thrashing) { + IggyGDrawSendWarning(NULL, c->is_vertex ? "GDraw Thrashing vertex memory" : "GDraw Thrashing texture memory"); + c->is_thrashing = true; + } + + gdraw_res_free(r, stats); + return true; +} + +static void gdraw_res_flush(GDrawHandleCache *c, GDrawStats *stats) +{ + c->is_thrashing = true; // prevents warnings being generated from free_lru + gdraw_HandleCacheUnlockAll(c); + while (gdraw_res_free_lru(c, stats)) + ; +} + +static GDrawHandle *gdraw_res_alloc_outofmem(GDrawHandleCache *c, GDrawHandle *t, char const *failed_type) +{ + if (t) + gdraw_HandleCacheAllocateFail(t); + IggyGDrawSendWarning(NULL, c->is_vertex ? "GDraw Out of static vertex buffer %s" : "GDraw Out of texture %s", failed_type); + return NULL; +} + +#ifndef GDRAW_MANAGE_MEM + +static GDrawHandle *gdraw_res_alloc_begin(GDrawHandleCache *c, S32 size, GDrawStats *stats) +{ + GDrawHandle *t; + if (size > c->total_bytes) + gdraw_res_alloc_outofmem(c, NULL, "memory (single resource larger than entire pool)"); + else { + // given how much data we're going to allocate, throw out + // data until there's "room" (this basically lets us use + // managed memory and just bound our usage, without actually + // packing it and being exact) + while (c->bytes_free < size) { + if (!gdraw_res_free_lru(c, stats)) { + gdraw_res_alloc_outofmem(c, NULL, "memory"); + break; + } + } + } + + // now try to allocate a handle + t = gdraw_HandleCacheAllocateBegin(c); + if (!t) { + // it's possible we have no free handles, because all handles + // are in use without exceeding the max storage above--in that + // case, just free one texture to give us a free handle (ideally + // we'd trade off cost of regenerating) + if (gdraw_res_free_lru(c, stats)) { + t = gdraw_HandleCacheAllocateBegin(c); + if (t == NULL) { + gdraw_res_alloc_outofmem(c, NULL, "handles"); + } + } + } + return t; +} + +#else + +// Returns whether this resource holds pointers to one of the GDraw-managed +// pools. +static rrbool gdraw_res_is_managed(GDrawHandle *r) +{ + return r->state == GDRAW_HANDLE_STATE_live || + r->state == GDRAW_HANDLE_STATE_locked || + r->state == GDRAW_HANDLE_STATE_dead || + r->state == GDRAW_HANDLE_STATE_pinned; +} + +// "Reaps" dead resources. Even if the user requests that a +// resource be freed, it might still be in use in a pending +// command buffer. So we can't free the associated memory +// immediately; instead, we flag the resource as "dead" and +// periodically check whether we can actually free the +// pending memory of dead resources ("reap" them). +static void gdraw_res_reap(GDrawHandleCache *c, GDrawStats *stats) +{ + GDrawHandle *sentinel = &c->state[GDRAW_HANDLE_STATE_dead]; + GDrawHandle *t; + GDRAW_FENCE_FLUSH(); + + // reap all dead resources that aren't in use anymore + while ((t = sentinel->next) != sentinel && !is_fence_pending(t->fence)) + gdraw_res_free(t, stats); +} + +// "Kills" a resource. This means GDraw won't use it anymore +// (it's dead), but there might still be outstanding references +// to it in a pending command buffer, so we can't physically +// free the associated memory until that's all processed. +static void gdraw_res_kill(GDrawHandle *r, GDrawStats *stats) +{ + GDRAW_FENCE_FLUSH(); // dead list is sorted by fence index - make sure all fence values are current. + + r->owner = NULL; + gdraw_HandleCacheInsertDead(r); + gdraw_res_reap(r->cache, stats); +} + +static GDrawHandle *gdraw_res_alloc_begin(GDrawHandleCache *c, S32 size, GDrawStats *stats) +{ + GDrawHandle *t; + void *ptr = NULL; + + gdraw_res_reap(c, stats); // NB this also does GDRAW_FENCE_FLUSH(); + if (size > c->total_bytes) + return gdraw_res_alloc_outofmem(c, NULL, "memory (single resource larger than entire pool)"); + + // now try to allocate a handle + t = gdraw_HandleCacheAllocateBegin(c); + if (!t) { + // it's possible we have no free handles, because all handles + // are in use without exceeding the max storage above--in that + // case, just free one texture to give us a free handle (ideally + // we'd trade off cost of regenerating) + gdraw_res_free_lru(c, stats); + t = gdraw_HandleCacheAllocateBegin(c); + if (!t) + return gdraw_res_alloc_outofmem(c, NULL, "handles"); + } + + // try to allocate first + if (size) { + ptr = gfxalloc_alloc(c->alloc, size); + if (!ptr) { + // doesn't currently fit. try to free some allocations to get space to breathe. + S32 want_free = RR_MAX(size + (size / 2), GDRAW_MIN_FREE_AMOUNT); + if (want_free > c->total_bytes) + want_free = size; // okay, *really* big resource, just try to allocate its real size + + // always keep freeing textures until want_free bytes are free. + while (c->alloc->actual_bytes_free < want_free) { + if (!gdraw_res_free_lru(c, stats)) + return gdraw_res_alloc_outofmem(c, t, "memory"); + } + + // now, keep trying to allocate and free some more memory when it still doesn't fit + while (!(ptr = gfxalloc_alloc(c->alloc, size))) { + if (c->alloc->actual_bytes_free >= 3 * size || // if we should have enough free bytes to satisfy the request by now + (c->alloc->actual_bytes_free >= size && size * 2 >= c->total_bytes)) // or the resource is very big and the alloc doesn't fit + { + // before we actually consider defragmenting, we want to free all stale resources (not + // referenced in the previous 2 frames). and if that frees up enough memory so we don't have + // to defragment, all the better! + // also, never defragment twice in a frame, just assume we're thrashing when we get in that + // situation and free up as much as possible. + if (!c->did_defragment && + c->prev_frame_start.value <= c->handle->fence.value) { + + // defragment. + defrag: + if (gdraw_CanDefragment(c)) { // only try defrag if it has a chance of helping. + gdraw_defragment_cache(c, stats); + c->did_defragment = true; + } + ptr = gfxalloc_alloc(c->alloc, size); + if (!ptr) + return gdraw_res_alloc_outofmem(c, t, "memory (fragmentation)"); + break; + } + } + + // keep trying to free some more + if (!gdraw_res_free_lru(c, stats)) { + if (c->alloc->actual_bytes_free >= size) // nothing left to free but we should be good - defrag again, even if it's the second time in a frame + goto defrag; + + return gdraw_res_alloc_outofmem(c, t, "memory"); + } + } + } + } + + t->fence.value = 0; // hasn't been used yet + t->raw_ptr = ptr; + return t; +} + +#endif diff --git a/Minecraft.Client/Windows64/Iggy/gdraw/gdraw_wgl.c b/Minecraft.Client/Windows64/Iggy/gdraw/gdraw_wgl.c new file mode 100644 index 00000000..f4f477aa --- /dev/null +++ b/Minecraft.Client/Windows64/Iggy/gdraw/gdraw_wgl.c @@ -0,0 +1,202 @@ +// gdraw_wgl.c - copyright 2011-2012 RAD Game Tools +// +// This implements the Iggy graphics driver layer for GL on Windows. + +#define GDRAW_ASSERTS + +#include "iggy.h" +#include "gdraw.h" +#include "gdraw_wgl.h" +#include +#include +#include "glext.h" +#include +#include + +#define true 1 +#define false 0 + +/////////////////////////////////////////////////////////////////////////////// +// +// Extensions (we map to GL 2.0 function names for a uniform interface +// across platforms) +// + +#define GDRAW_GL_EXTENSION_LIST \ + /* identifier import procname */ \ + /* GL_ARB_multitexture */ \ + GLE(ActiveTexture, "ActiveTextureARB", ACTIVETEXTUREARB) \ + /* GL_ARB_texture_compression */ \ + GLE(CompressedTexImage2D, "CompressedTexImage2DARB", COMPRESSEDTEXIMAGE2DARB) \ + /* GL_ARB_vertex_buffer_object */ \ + GLE(GenBuffers, "GenBuffersARB", GENBUFFERSARB) \ + GLE(DeleteBuffers, "DeleteBuffersARB", DELETEBUFFERSARB) \ + GLE(BindBuffer, "BindBufferARB", BINDBUFFERARB) \ + GLE(BufferData, "BufferDataARB", BUFFERDATAARB) \ + GLE(MapBuffer, "MapBufferARB", MAPBUFFERARB) \ + GLE(UnmapBuffer, "UnmapBufferARB", UNMAPBUFFERARB) \ + GLE(VertexAttribPointer, "VertexAttribPointerARB", VERTEXATTRIBPOINTERARB) \ + GLE(EnableVertexAttribArray, "EnableVertexAttribArrayARB", ENABLEVERTEXATTRIBARRAYARB) \ + GLE(DisableVertexAttribArray, "DisableVertexAttribArrayARB", DISABLEVERTEXATTRIBARRAYARB) \ + /* GL_ARB_shader_objects */ \ + GLE(CreateShader, "CreateShaderObjectARB", CREATESHADEROBJECTARB) \ + GLE(DeleteShader, "DeleteObjectARB", DELETEOBJECTARB) \ + GLE(ShaderSource, "ShaderSourceARB", SHADERSOURCEARB) \ + GLE(CompileShader, "CompileShaderARB", COMPILESHADERARB) \ + GLE(GetShaderiv, "GetObjectParameterivARB", GETOBJECTPARAMETERIVARB) \ + GLE(GetShaderInfoLog, "GetInfoLogARB", GETINFOLOGARB) \ + GLE(CreateProgram, "CreateProgramObjectARB", CREATEPROGRAMOBJECTARB) \ + GLE(DeleteProgram, "DeleteObjectARB", DELETEOBJECTARB) \ + GLE(AttachShader, "AttachObjectARB", ATTACHOBJECTARB) \ + GLE(LinkProgram, "LinkProgramARB", LINKPROGRAMARB) \ + GLE(GetUniformLocation, "GetUniformLocationARB", GETUNIFORMLOCATIONARB) \ + GLE(UseProgram, "UseProgramObjectARB", USEPROGRAMOBJECTARB) \ + GLE(GetProgramiv, "GetObjectParameterivARB", GETOBJECTPARAMETERIVARB) \ + GLE(GetProgramInfoLog, "GetInfoLogARB", GETINFOLOGARB) \ + GLE(Uniform1i, "Uniform1iARB", UNIFORM1IARB) \ + GLE(Uniform4f, "Uniform4fARB", UNIFORM4FARB) \ + GLE(Uniform4fv, "Uniform4fvARB", UNIFORM4FVARB) \ + /* GL_ARB_vertex_shader */ \ + GLE(BindAttribLocation, "BindAttribLocationARB", BINDATTRIBLOCATIONARB) \ + /* GL_EXT_framebuffer_object */ \ + GLE(GenRenderbuffers, "GenRenderbuffersEXT", GENRENDERBUFFERSEXT) \ + GLE(DeleteRenderbuffers, "DeleteRenderbuffersEXT", DELETERENDERBUFFERSEXT) \ + GLE(BindRenderbuffer, "BindRenderbufferEXT", BINDRENDERBUFFEREXT) \ + GLE(RenderbufferStorage, "RenderbufferStorageEXT", RENDERBUFFERSTORAGEEXT) \ + GLE(GenFramebuffers, "GenFramebuffersEXT", GENFRAMEBUFFERSEXT) \ + GLE(DeleteFramebuffers, "DeleteFramebuffersEXT", DELETEFRAMEBUFFERSEXT) \ + GLE(BindFramebuffer, "BindFramebufferEXT", BINDFRAMEBUFFEREXT) \ + GLE(CheckFramebufferStatus, "CheckFramebufferStatusEXT", CHECKFRAMEBUFFERSTATUSEXT) \ + GLE(FramebufferRenderbuffer, "FramebufferRenderbufferEXT", FRAMEBUFFERRENDERBUFFEREXT) \ + GLE(FramebufferTexture2D, "FramebufferTexture2DEXT", FRAMEBUFFERTEXTURE2DEXT) \ + GLE(GenerateMipmap, "GenerateMipmapEXT", GENERATEMIPMAPEXT) \ + /* GL_EXT_framebuffer_blit */ \ + GLE(BlitFramebuffer, "BlitFramebufferEXT", BLITFRAMEBUFFEREXT) \ + /* GL_EXT_framebuffer_multisample */ \ + GLE(RenderbufferStorageMultisample, "RenderbufferStorageMultisampleEXT",RENDERBUFFERSTORAGEMULTISAMPLEEXT) \ + /* */ + +#define gdraw_GLx_(id) gdraw_GL_##id +#define GDRAW_GLx_(id) GDRAW_GL_##id +#define GDRAW_SHADERS "gdraw_gl_shaders.inl" + +typedef GLhandleARB GLhandle; +typedef gdraw_gl_resourcetype gdraw_resourcetype; + +// Extensions +#define GLE(id, import, procname) static PFNGL##procname##PROC gl##id; +GDRAW_GL_EXTENSION_LIST +#undef GLE + +static void load_extensions(void) +{ +#define GLE(id, import, procname) gl##id = (PFNGL##procname##PROC) wglGetProcAddress("gl" import); + GDRAW_GL_EXTENSION_LIST +#undef GLE +} + +static void clear_renderstate_platform_specific(void) +{ + glDisable(GL_ALPHA_TEST); +} + +static void error_msg_platform_specific(const char *msg) +{ + OutputDebugStringA(msg); +} + +/////////////////////////////////////////////////////////////////////////////// +// +// Shared code +// + +#define GDRAW_MULTISAMPLING +#include "gdraw_gl_shared.inl" + +/////////////////////////////////////////////////////////////////////////////// +// +// Initialization and platform-specific functionality +// + +GDrawFunctions *gdraw_GL_CreateContext(S32 w, S32 h, S32 msaa_samples) +{ + static const TextureFormatDesc tex_formats[] = { + { IFT_FORMAT_rgba_8888, 1, 1, 4, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE }, + { IFT_FORMAT_rgba_4444_LE, 1, 1, 2, GL_RGBA4, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4 }, + { IFT_FORMAT_rgba_5551_LE, 1, 1, 2, GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1 }, + { IFT_FORMAT_la_88, 1, 1, 2, GL_LUMINANCE8_ALPHA8, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE }, + { IFT_FORMAT_la_44, 1, 1, 1, GL_LUMINANCE4_ALPHA4, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE }, + { IFT_FORMAT_i_8, 1, 1, 1, GL_INTENSITY8, GL_ALPHA, GL_UNSIGNED_BYTE }, + { IFT_FORMAT_i_4, 1, 1, 1, GL_INTENSITY4, GL_ALPHA, GL_UNSIGNED_BYTE }, + { IFT_FORMAT_l_8, 1, 1, 1, GL_LUMINANCE8, GL_LUMINANCE, GL_UNSIGNED_BYTE }, + { IFT_FORMAT_l_4, 1, 1, 1, GL_LUMINANCE4, GL_LUMINANCE, GL_UNSIGNED_BYTE }, + { IFT_FORMAT_DXT1, 4, 4, 8, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, 0, GL_UNSIGNED_BYTE }, + { IFT_FORMAT_DXT3, 4, 4, 16, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, 0, GL_UNSIGNED_BYTE }, + { IFT_FORMAT_DXT5, 4, 4, 16, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, 0, GL_UNSIGNED_BYTE }, + { 0, 0, 0, 0, 0, 0, 0 }, + }; + + GDrawFunctions *funcs; + const char *s; + GLint n; + + // check for the extensions we need + s = (const char *) glGetString(GL_EXTENSIONS); + if (s == NULL) { + assert(s != NULL); // if this is NULL, you're probably trying to create the device too early + return NULL; + } + + // check for the extensions we won't work without + if (!hasext(s, "GL_ARB_multitexture") || + !hasext(s, "GL_ARB_texture_compression") || + !hasext(s, "GL_ARB_texture_mirrored_repeat") || + !hasext(s, "GL_ARB_texture_non_power_of_two") || // with caveats - see below! + !hasext(s, "GL_ARB_vertex_buffer_object") || + !hasext(s, "GL_EXT_framebuffer_object") || + !hasext(s, "GL_ARB_shader_objects") || + !hasext(s, "GL_ARB_vertex_shader") || + !hasext(s, "GL_ARB_fragment_shader")) + return NULL; + + // if user requests multisampling and HW doesn't support it, bail + if (!hasext(s, "GL_EXT_framebuffer_multisample") && msaa_samples > 1) + return NULL; + + load_extensions(); + funcs = create_context(w, h); + if (!funcs) + return NULL; + + gdraw->tex_formats = tex_formats; + + // check for optional extensions + gdraw->has_mapbuffer = true; // part of core VBO extension on regular GL + gdraw->has_depth24 = true; // we just assume. + gdraw->has_texture_max_level = true; // core on regular GL + + if (hasext(s, "GL_EXT_packed_depth_stencil")) gdraw->has_packed_depth_stencil = true; + + // we require ARB_texture_non_power_of_two - on actual HW, this may either give us + // "full" non-power-of-two support, or "conditional" non-power-of-two (wrap mode must + // be CLAMP_TO_EDGE, no mipmaps). figure out which it is using this heuristic by + // Unity's Aras Pranckevicius (thanks!): + // http://www.aras-p.info/blog/2012/10/17/non-power-of-two-textures/ + // + // we use the second heuristic (texture size <8192 for cards without full NPOT support) + // since we don't otherwise use ARB_fragment_program and don't want to create a program + // just to be able to query MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB! + glGetIntegerv(GL_MAX_TEXTURE_SIZE, &n); + gdraw->has_conditional_non_power_of_two = n < 8192; + + // clamp number of multisampling levels to max supported + if (msaa_samples > 1) { + glGetIntegerv(GL_MAX_SAMPLES, &n); + gdraw->multisampling = RR_MIN(msaa_samples, n); + } + + opengl_check(); + + return funcs; +} + diff --git a/Minecraft.Client/Windows64/Iggy/gdraw/gdraw_wgl.h b/Minecraft.Client/Windows64/Iggy/gdraw/gdraw_wgl.h new file mode 100644 index 00000000..aa9db034 --- /dev/null +++ b/Minecraft.Client/Windows64/Iggy/gdraw/gdraw_wgl.h @@ -0,0 +1,38 @@ +#ifndef __RAD_INCLUDE_GDRAW_GL_H__ +#define __RAD_INCLUDE_GDRAW_GL_H__ + +#include "rrCore.h" +#include "gdraw.h" + +RADDEFSTART + +typedef enum gdraw_gl_resourcetype +{ + GDRAW_GL_RESOURCE_rendertarget, + GDRAW_GL_RESOURCE_texture, + GDRAW_GL_RESOURCE_vertexbuffer, + + GDRAW_GL_RESOURCE__count, +} gdraw_gl_resourcetype; + +struct IggyCustomDrawCallbackRegion; + +extern int gdraw_GL_SetResourceLimits(gdraw_gl_resourcetype type, S32 num_handles, S32 num_bytes); +extern GDrawFunctions * gdraw_GL_CreateContext(S32 min_w, S32 min_h, S32 msaa_samples); +extern void gdraw_GL_DestroyContext(void); +extern void gdraw_GL_SetTileOrigin(S32 vx, S32 vy, U32 framebuffer); // framebuffer=FBO handle, or 0 for main frame buffer +extern void gdraw_GL_NoMoreGDrawThisFrame(void); + +extern GDrawTexture *gdraw_GL_WrappedTextureCreate(S32 gl_texture_handle, S32 width, S32 height, rrbool has_mipmaps); +extern void gdraw_GL_WrappedTextureChange(GDrawTexture *tex, S32 new_gl_texture_handle, S32 new_width, S32 new_height, rrbool new_has_mipmaps); +extern void gdraw_GL_WrappedTextureDestroy(GDrawTexture *tex); + +extern void gdraw_GL_BeginCustomDraw(struct IggyCustomDrawCallbackRegion *region, F32 *matrix); +extern void gdraw_GL_EndCustomDraw(struct IggyCustomDrawCallbackRegion *region); + +extern GDrawTexture * RADLINK gdraw_GL_MakeTextureFromResource(U8 *resource_file, S32 resource_len, IggyFileTextureRaw *texture); +extern void RADLINK gdraw_GL_DestroyTextureFromResource(GDrawTexture *tex); + +RADDEFEND + +#endif diff --git a/Minecraft.Client/Windows64/Iggy/include/gdraw.h b/Minecraft.Client/Windows64/Iggy/include/gdraw.h new file mode 100644 index 00000000..404a2642 --- /dev/null +++ b/Minecraft.Client/Windows64/Iggy/include/gdraw.h @@ -0,0 +1,726 @@ +// gdraw.h - author: Sean Barrett - copyright 2009 RAD Game Tools +// +// This is the graphics rendering abstraction that Iggy is implemented +// on top of. + +#ifndef __RAD_INCLUDE_GDRAW_H__ +#define __RAD_INCLUDE_GDRAW_H__ + +#include "rrcore.h" + +#define IDOC + +RADDEFSTART + +//idoc(parent,GDrawAPI_Buffers) + +#ifndef IGGY_GDRAW_SHARED_TYPEDEF + + #define IGGY_GDRAW_SHARED_TYPEDEF + typedef struct GDrawFunctions GDrawFunctions; + + typedef struct GDrawTexture GDrawTexture; + +#endif//IGGY_GDRAW_SHARED_TYPEDEF + + + +IDOC typedef struct GDrawVertexBuffer GDrawVertexBuffer; +/* An opaque handle to an internal GDraw vertex buffer. */ + +//idoc(parent,GDrawAPI_Base) + +IDOC typedef struct gswf_recti +{ + S32 x0,y0; // Minimum corner of the rectangle + S32 x1,y1; // Maximum corner of the rectangle +} gswf_recti; +/* A 2D rectangle with integer coordinates specifying its minimum and maximum corners. */ + +IDOC typedef struct gswf_rectf +{ + F32 x0,y0; // Minimum corner of the rectangle + F32 x1,y1; // Maximum corner of the rectangle +} gswf_rectf; +/* A 2D rectangle with floating-point coordinates specifying its minimum and maximum corners. */ + +IDOC typedef struct gswf_matrix +{ + union { + F32 m[2][2]; // 2x2 transform matrix + struct { + F32 m00; // Alternate name for m[0][0], for coding convenience + F32 m01; // Alternate name for m[0][1], for coding convenience + F32 m10; // Alternate name for m[1][0], for coding convenience + F32 m11; // Alternate name for m[1][1], for coding convenience + }; + }; + F32 trans[2]; // 2D translation vector (the affine component of the matrix) +} gswf_matrix; +/* A 2D transform matrix plus a translation offset. */ + +#define GDRAW_STATS_batches 1 +#define GDRAW_STATS_blits 2 +#define GDRAW_STATS_alloc_tex 4 +#define GDRAW_STATS_frees 8 +#define GDRAW_STATS_defrag 16 +#define GDRAW_STATS_rendtarg 32 +#define GDRAW_STATS_clears 64 +IDOC typedef struct GDrawStats +{ + S16 nonzero_flags; // which of the fields below are non-zero + + U16 num_batches; // number of batches, e.g. DrawPrim, DrawPrimUP + U16 num_blits; // number of blit operations (resolve, msaa resolve, blend readback) + U16 freed_objects; // number of cached objects freed + U16 defrag_objects; // number of cached objects defragmented + U16 alloc_tex; // number of textures/buffers allocated + U16 rendertarget_changes; // number of rendertarget changes + U16 num_clears; + //0 mod 8 + + U32 drawn_indices; // number of indices drawn (3 times number of triangles) + U32 drawn_vertices; // number of unique vertices referenced + U32 num_blit_pixels;// number of pixels in blit operations + U32 alloc_tex_bytes;// number of bytes in textures/buffers allocated + U32 freed_bytes; // number of bytes in freed cached objects + U32 defrag_bytes; // number of bytes in defragmented cached objects + U32 cleared_pixels; // number of pixels cleared by clear operation + U32 reserved; + //0 mod 8 +} GDrawStats; +/* A structure with statistics information to show in resource browser/Telemetry */ + +//////////////////////////////////////////////////////////// +// +// Queries +// +//idoc(parent,GDrawAPI_Queries) + +IDOC typedef enum gdraw_bformat +{ + GDRAW_BFORMAT_vbib, // Platform uses vertex and index buffers + GDRAW_BFORMAT_wii_dlist, // Platform uses Wii-style display lists + GDRAW_BFORMAT_vbib_single_format, // Platform uses vertex and index buffers, but doesn't support multiple vertex formats in a single VB + + GDRAW_BFORMAT__count, +} gdraw_bformat; +/* Specifies what data format GDraw expects in MakeVertexBuffer_* and DrawIndexedTriangles. + + Most supported platforms prefer Vertex and Index buffers so that's what we use, + but this format turns out to be somewhat awkward for Wii, so we use the native + graphics processor display list format on that platform. */ + +IDOC typedef struct GDrawInfo +{ + S32 num_stencil_bits; // number of (possibly emulated) stencil buffer bits + U32 max_id; // number of unique values that can be easily encoded in zbuffer + U32 max_texture_size; // edge length of largest square texture supported by hardware + U32 buffer_format; // one of $gdraw_bformat + rrbool shared_depth_stencil; // does 0'th framebuffer share depth & stencil with others? (on GL it can't?) + rrbool always_mipmap; // if GDraw can generate mipmaps nearly for free, then set this flag + rrbool conditional_nonpow2; // non-pow2 textures supported, but only using clamp and without mipmaps + rrbool has_rendertargets; // if true, then there is no rendertarget stack support + rrbool no_nonpow2; // non-pow2 textures aren't supported at all +} GDrawInfo; // must be a multiple of 8 +/* $GDrawInfo contains the information that Iggy needs to know about + what a GDraw implementation supports and what limits it places on + certain important values. */ + +IDOC typedef void RADLINK gdraw_get_info(GDrawInfo *d); +/* Iggy queries this at the beginning of rendering to get information + about the viewport and the device capabilities. */ + +//////////////////////////////////////////////////////////// +// +// Drawing State +// +//idoc(parent,GDrawAPI_DrawingState) + +IDOC typedef enum gdraw_blend +{ + GDRAW_BLEND_none, // Directly copy + GDRAW_BLEND_alpha, // Use the source alpha channel to modulate its contribution + GDRAW_BLEND_multiply, // Multiply colors componentwise + GDRAW_BLEND_add, // Add the source and destination together + + GDRAW_BLEND_filter, // Uses a secondary $gdraw_filter specification to determine how to blend + GDRAW_BLEND_special, // Uses a secondary $gdraw_blendspecial specification to determine how to blend + + GDRAW_BLEND__count, +} gdraw_blend; +/* Identifier indicating the type of blending operation to use when rendering.*/ + +IDOC typedef enum gdraw_blendspecial +{ + GDRAW_BLENDSPECIAL_layer, // s + GDRAW_BLENDSPECIAL_multiply, // s*d + GDRAW_BLENDSPECIAL_screen, // sa*da - (da-d)*(sa-s) + GDRAW_BLENDSPECIAL_lighten, // max(sa*d,s*da) + GDRAW_BLENDSPECIAL_darken, // min(sa*d,s*da) + GDRAW_BLENDSPECIAL_add, // min(d+s,1.0) + GDRAW_BLENDSPECIAL_subtract, // max(d-s,0.0) + GDRAW_BLENDSPECIAL_difference, // abs(sa*d-s*da) + GDRAW_BLENDSPECIAL_invert, // sa*(da-d) + GDRAW_BLENDSPECIAL_overlay, // d < da/2.0 ? (2.0*s*d) : (sa*da - 2.0*(da-d)*(sa-s)) + GDRAW_BLENDSPECIAL_hardlight, // s < sa/2.0 ? (2.0*s*d) : (sa*da - 2.0*(da-d)*(sa-s)) + + // these do extra-special math on the output alpha + GDRAW_BLENDSPECIAL_erase, // d*(1.0-sa) + GDRAW_BLENDSPECIAL_alpha_special, // d*sa + + GDRAW_BLENDSPECIAL__count, +} gdraw_blendspecial; +/* Specifies a type of "special" blend mode, which is defined as one + that has to read from the framebuffer to compute its effect. + + These modes are only used with a 1-to-1 textured quad containing + the exact output data in premultiplied alpha. They all need to + read from the framebuffer to compute their effect, so a GDraw + implementation will usually need a custom path to handle that. + Users will not warn in advance whether you're going to need this + operation, so implementations either need to always render to a + texture in case it happens, or copy the framebuffer to a texture + when it does. + + Note that $(gdraw_blendspecial::GDRAW_BLENDSPECIAL_erase) and + $(gdraw_blendspecial::GDRAW_BLENDSPECIAL_alpha_special) are unique + among $gdraw_blendspecial modes in that they may not actually need + to be implemented with the destination input as a texture if + the destination buffer doesn't have an alpha channel. */ + +// (@OPTIMIZE: the last filter in each chain could be combined with +// the final blend, although only worth doing if the final blend is +// ALPHA/ADD/MULTIPLY--it's usually ALPHA though so worth doing!) +IDOC typedef enum gdraw_filter +{ + GDRAW_FILTER_blur, // Blurs the source image + GDRAW_FILTER_colormatrix, // Transform RGB pixel values by a matrix + GDRAW_FILTER_bevel, // Bevels the source image + GDRAW_FILTER_dropshadow, // Adds a dropshadow underneath the source image + + GDRAW_FILTER__count, +} gdraw_filter; +/* Specifies a type of post-processing graphics filter. + + These modes are only used to implement filter effects, and will + always be blending from a temporary buffer to another temporary + buffer with no blending, so in general they should not require + any additional input. +*/ + +IDOC typedef enum gdraw_texture +{ + GDRAW_TEXTURE_none, // No texture applied + GDRAW_TEXTURE_normal, // Texture is bitmap or linear gradient + GDRAW_TEXTURE_alpha, // Texture is an alpha-only font bitmap + GDRAW_TEXTURE_radial, // Texture is a radial gradient + GDRAW_TEXTURE_focal_gradient, // Texture is a "focal" radial gradient + GDRAW_TEXTURE_alpha_test, // Texture is an alpha-only font bitmap, alpha test for alpha >= 0.5 + + GDRAW_TEXTURE__count, +} gdraw_texture; +/* Specifies how to apply a texture while rendering. */ + +IDOC typedef enum gdraw_wrap +{ + GDRAW_WRAP_clamp, // Texture coordinates clamped to edges + GDRAW_WRAP_repeat, // Texture repeats periodically + GDRAW_WRAP_mirror, // Repeat periodically, mirror on odd repetititions + GDRAW_WRAP_clamp_to_border, // only used internally by some GDraws + + GDRAW_WRAP__count, +} gdraw_wrap; +/* Specifies what to do with texture coordinates outside [0,1]. */ + +typedef struct GDrawRenderState +{ + S32 id; // Object "identifier" used for high-quality AA mode + U32 test_id:1; // Whether to test zbuffer == id + U32 set_id:1; // Whether to set zbuffer == id + U32 use_world_space:1; // Whether primitive is defined in object space or world space + U32 scissor:1; // Whether rendering will be clipped to $(GDrawRenderState::scissor_rect) + U32 identical_state:1; // Whether state is identical to the one used for the previous draw call + U32 unused:27; + //aligned 0 mod 8 + + U8 texgen0_enabled; // Whether to use texgen for tex0 + U8 tex0_mode; // One of $gdraw_texture + U8 wrap0; // One of $gdraw_wrap + U8 nearest0; // Whether to sample texture 0 nearest neighbor + + U8 blend_mode; // One of $gdraw_blend + U8 special_blend; // One of $gdraw_blendspecial (used only if $(GDrawRenderState::blend_mode) == $(gdraw_blend::GDRAW_BLEND_special) + U8 filter; // One of $gdraw_filter (used only if $(GDrawRenderState::blend_mode) == $(gdraw_blend::GDRAW_BLEND_filter) + U8 filter_mode; // Used to select the right compositing operation for the $(gdraw_filter::GDRAW_FILTER_bevel) and $(gdraw_filter::GDRAW_FILTER_dropshadow) modes + //aligned 0 mod 8 + U8 stencil_test; // Only draw if these stencil bits are "set" + U8 stencil_set; // "Set" these stencil bits (note that actual implementation initializes stencil to 1, and "set" makes them 0) + + U8 reserved[2]; // Currently unused (used to make padding to 4/8-byte boundary for following pointer explicit) + S32 blur_passes; // For filters that include blurring, this is the number of box filter passes to run + //align 0 mod 8 + + S16 *cxf_add; // Color transform addition (discourage additive alpha!) + + GDrawTexture *tex[3]; // One or more textures to apply -- need 3 for gradient dropshadow. + //0 mod 8 + F32 *edge_matrix; // Screen to object space matrix (for edge antialiasing) + gswf_matrix *o2w; // Object-to-world matrix + + // --- Everything below this point must be manually initialized + + //0 mod 8 + F32 color[4]; // Color of the object + + //0 mod 8 + gswf_recti scissor_rect; // The rectangle to which rendering will be clipped if $(GDrawRenderState::scissor) is set + //0 mod 8 + // --- Everything below this point might be uninitialized if it's not used for this particular render state + + F32 s0_texgen[4]; // "s" (x) row of texgen matrix + F32 t0_texgen[4]; // "t" (y) row of texgen matrix + //0 mod 8 + F32 focal_point[4]; // Data used for $(gdraw_texgen_mode::GDRAW_TEXTURE_focal_gradient) + //0 mod 8 + F32 blur_x,blur_y; // The size of the box filter, where '1' is the identity and 2 adds half a pixel on each side + //0 mod 8 + F32 shader_data[20]; // Various data that depends on filter (e.g. drop shadow direction, color) +} GDrawRenderState; +/* Encapsulation of the entire drawing state that affects a rendering command. */ + +IDOC typedef void RADLINK gdraw_set_view_size_and_world_scale(S32 w, S32 h, F32 x_world_to_pixel, F32 y_world_to_pixel); +/* Sets the size of the rendering viewport and the world to pixel scaling. + + Iggy calls this function with the full size that the viewport would + be if it were rendered untiled, even if it will eventually be + rendered as a collection of smaller tiles. + + The world scale is used to compensate non-square pixel aspect ratios + when rendering wide lines. Both scale factors are 1 unless Iggy is + running on a display with non-square pixels. */ + +typedef void RADLINK gdraw_set_3d_transform(F32 *mat); /* mat[3][4] */ + +IDOC typedef void RADLINK gdraw_render_tile_begin(S32 tx0, S32 ty0, S32 tx1, S32 ty1, S32 pad, GDrawStats *stats); +/* Begins rendering of a sub-region of the rendered image. */ + +IDOC typedef void RADLINK gdraw_render_tile_end(GDrawStats *stats); +/* Ends rendering of a sub-region of the rendered image. */ + +IDOC typedef void RADLINK gdraw_rendering_begin(void); +/* Begins rendering; takes control of the graphics API. */ + +IDOC typedef void RADLINK gdraw_rendering_end(void); +/* Ends rendering; gives up control of the graphics API. */ + + +//////////////////////////////////////////////////////////// +// +// Drawing +// +//idoc(parent,GDrawAPI_Drawing) + +IDOC typedef void RADLINK gdraw_clear_stencil_bits(U32 bits); +/* Clears the 'bits' parts of the stencil value in the entire framebuffer to the default value. */ + +IDOC typedef void RADLINK gdraw_clear_id(void); +/* Clears the 'id' buffer, which is typically the z-buffer but can also be the stencil buffer. */ + +IDOC typedef void RADLINK gdraw_filter_quad(GDrawRenderState *r, S32 x0, S32 y0, S32 x1, S32 y1, GDrawStats *stats); +/* Draws a special quad in viewport-relative pixel space. + + May be normal, may be displaced by filters, etc. and require multiple passes, + may apply special blending (and require extra resolves/rendertargets) + for filter/blend., + + The x0,y0,x1,y1 always describes the "input" box. */ + +IDOC typedef struct GDrawPrimitive +{ + F32 *vertices; // Pointer to an array of $gswf_vertex_xy, $gswf_vertex_xyst, or $gswf_vertex_xyoffs + U16 *indices; // Pointer to an array of 16-bit indices into $(GDrawPrimitive::vertices) + + S32 num_vertices; // Count of elements in $(GDrawPrimitive::vertices) + S32 num_indices; // Count of elements in $(GDrawPrimitive::indices) + + S32 vertex_format; // One of $gdraw_vformat, specifying the type of element in $(GDrawPrimitive::vertices) + + U32 uniform_count; + F32 *uniforms; + + U8 drawprim_mode; +} GDrawPrimitive; +/* Specifies the vertex and index data necessary to draw a batch of graphics primitives. */ + +IDOC typedef void RADLINK gdraw_draw_indexed_triangles(GDrawRenderState *r, GDrawPrimitive *prim, GDrawVertexBuffer *buf, GDrawStats *stats); +/* Draws a collection of indexed triangles, ignoring special filters or blend modes. + + If buf is NULL, then the pointers in 'prim' are machine pointers, and + you need to make a copy of the data (note currently all triangles + implementing strokes (wide lines) go this path). + + If buf is non-NULL, then use the appropriate vertex buffer, and the + pointers in prim are actually offsets from the beginning of the + vertex buffer -- i.e. offset = (char*) prim->whatever - (char*) NULL; + (note there are separate spaces for vertices and indices; e.g. the + first mesh in a given vertex buffer will normally have a 0 offset + for the vertices and a 0 offset for the indices) +*/ + +IDOC typedef void RADLINK gdraw_set_antialias_texture(S32 width, U8 *rgba); +/* Specifies the 1D texture data to be used for the antialiasing gradients. + + 'rgba' specifies the pixel values in rgba byte order. This will only be called + once during initialization. */ + +//////////////////////////////////////////////////////////// +// +// Texture and Vertex Buffers +// +//idoc(parent,GDrawAPI_Buffers) + +IDOC typedef enum gdraw_texture_format +{ + // Platform-independent formats + GDRAW_TEXTURE_FORMAT_rgba32, // 32bpp RGBA data in platform-preferred byte order (returned by $gdraw_make_texture_begin as $gdraw_texture_type) + GDRAW_TEXTURE_FORMAT_font, // Alpha-only data with at least 4 bits/pixel. Data is submitted as 8 bits/pixel, conversion (if necessary) done by GDraw. + + // First platform-specific format index (for reference) + GDRAW_TEXTURE_FORMAT__platform = 16, + + // In the future, we will support platform-specific formats and add them to this list. +} gdraw_texture_format; +/* Describes the format of a texture submitted to GDraw. */ + +IDOC typedef enum gdraw_texture_type +{ + GDRAW_TEXTURE_TYPE_rgba, // Raw 4-channel packed texels, in OpenGL-standard order + GDRAW_TEXTURE_TYPE_bgra, // Raw 4-channel packed texels, in Direct3D-standard order + GDRAW_TEXTURE_TYPE_argb, // Raw 4-channel packed texels, in Flash native order + + GDRAW_TEXTURE_TYPE__count, +} gdraw_texture_type; +/* Describes the channel layout of a RGBA texture submitted to GDraw. */ + +IDOC typedef struct GDraw_MakeTexture_ProcessingInfo +{ + U8 *texture_data; // Pointer to the texture image bits + S32 num_rows; // Number of rows to upload in the current chunk + S32 stride_in_bytes; // Distance between a given pixel and the first pixel in the next row + S32 texture_type; // One of $gdraw_texture_type + + U32 temp_buffer_bytes; // Size of temp buffer in bytes + U8 *temp_buffer; // Temp buffer for GDraw to work in (used during mipmap creation) + + void *p0,*p1,*p2,*p3,*p4,*p5,*p6,*p7; // Pointers for GDraw to store data across "passes" (never touched by Iggy) + U32 i0, i1, i2, i3, i4, i5, i6, i7; // Integers for GDraw to store data across "passes" (never touched by Iggy) +} GDraw_MakeTexture_ProcessingInfo; +/* $GDraw_MakeTexture_ProcessingInfo is used when building a texture. */ + +IDOC typedef struct GDraw_Texture_Description { + S32 width; // Width of the texture in pixels + S32 height; // Height of the texture in pixels + U32 size_in_bytes; // Size of the texture in bytes +} GDraw_Texture_Description; +/* $GDraw_Texture_Description contains information about a texture. */ + +IDOC typedef U32 gdraw_maketexture_flags; +#define GDRAW_MAKETEXTURE_FLAGS_mipmap 1 IDOC // Generates mip-maps for the texture +#define GDRAW_MAKETEXTURE_FLAGS_updatable 2 IDOC // Set if the texture might be updated subsequent to its initial submission +#define GDRAW_MAKETEXTURE_FLAGS_never_flush 4 IDOC // Set to request that the texture never be flushed from the GDraw cache + +/* Flags that control the submission and management of GDraw textures. */ + +IDOC typedef void RADLINK gdraw_set_texture_unique_id(GDrawTexture *tex, void *old_unique_id, void *new_unique_id); +/* Changes unique id of a texture, only used for TextureSubstitution */ + +IDOC typedef rrbool RADLINK gdraw_make_texture_begin(void *unique_id, + S32 width, S32 height, gdraw_texture_format format, gdraw_maketexture_flags flags, + GDraw_MakeTexture_ProcessingInfo *output_info, GDrawStats *stats); +/* Begins specifying a new texture. + + $:unique_id Unique value specified by Iggy that you can use to identify a reference to the same texture even if its handle has been discarded + $:return Error code if there was a problem, IGGY_RESULT_OK otherwise +*/ + +IDOC typedef rrbool RADLINK gdraw_make_texture_more(GDraw_MakeTexture_ProcessingInfo *info); +/* Continues specifying a new texture. + + $:info The same handle initially passed to $gdraw_make_texture_begin + $:return True if specification can continue, false if specification must be aborted +*/ + +IDOC typedef GDrawTexture * RADLINK gdraw_make_texture_end(GDraw_MakeTexture_ProcessingInfo *info, GDrawStats *stats); +/* Ends specification of a new texture. + + $:info The same handle initially passed to $gdraw_make_texture_begin + $:return Handle for the newly created texture, or NULL if an error occured +*/ + +IDOC typedef rrbool RADLINK gdraw_update_texture_begin(GDrawTexture *tex, void *unique_id, GDrawStats *stats); +/* Begins updating a previously submitted texture. + + $:unique_id Must be the same value initially passed to $gdraw_make_texture_begin + $:return True on success, false otherwise and the texture must be recreated +*/ + +IDOC typedef void RADLINK gdraw_update_texture_rect(GDrawTexture *tex, void *unique_id, S32 x, S32 y, S32 stride, S32 w, S32 h, U8 *data, gdraw_texture_format format); +/* Updates a rectangle in a previously submitted texture. + + $:format Must be the $gdraw_texture_format that was originally passed to $gdraw_make_texture_begin for this texture. +*/ + +IDOC typedef void RADLINK gdraw_update_texture_end(GDrawTexture *tex, void *unique_id, GDrawStats *stats); +/* Ends an update to a previously submitted texture. + + $:unique_id Must be the same value initially passed to $gdraw_make_texture_begin (and hence $gdraw_update_texture_begin) +*/ + +IDOC typedef void RADLINK gdraw_describe_texture(GDrawTexture *tex, GDraw_Texture_Description *desc); +/* Returns a texture description for a given GDraw texture. */ + +IDOC typedef GDrawTexture * RADLINK gdraw_make_texture_from_resource(U8 *resource_file, S32 file_len, void *texture); +/* Loads a texture from a resource file and returns a wrapped pointer. */ + +IDOC typedef void RADLINK gdraw_free_texture_from_resource(GDrawTexture *tex); +/* Frees a texture created with gdraw_make_texture_from_resource. */ + + +IDOC typedef struct gswf_vertex_xy +{ + F32 x,y; // Position of the vertex +} gswf_vertex_xy; +/* A 2D point with floating-point position. */ + +IDOC typedef struct gswf_vertex_xyoffs +{ + F32 x,y; // Position of the vertex + + S16 aa; // Stroke/aa texcoord + S16 dx, dy; // Vector offset from the position, used for anti-aliasing (signed 11.5 fixed point) + S16 unused; +} gswf_vertex_xyoffs; +/* A 2D point with floating-point position, additional integer parameter, and integer anti-aliasing offset vector. */ + +IDOC typedef struct gswf_vertex_xyst +{ + F32 x,y; // Position of the vertex + F32 s,t; // Explicit texture coordinates for rectangles +} gswf_vertex_xyst; +/* A 2D point with floating-point position and texture coordinates. */ + +typedef int gdraw_verify_size_xy [sizeof(gswf_vertex_xy ) == 8 ? 1 : -1]; +typedef int gdraw_verify_size_xyoffs[sizeof(gswf_vertex_xyoffs) == 16 ? 1 : -1]; +typedef int gdraw_verify_size_xyst [sizeof(gswf_vertex_xyst ) == 16 ? 1 : -1]; + +IDOC typedef enum gdraw_vformat +{ + GDRAW_vformat_v2, // Indicates vertices of type $gswf_vertex_xy (8 bytes per vertex) + GDRAW_vformat_v2aa, // Indicates vertices of type $gswf_vertex_xyoffs (16 bytes per vertex) + GDRAW_vformat_v2tc2, // Indicates vertices of type $gswf_vertex_xyst (16 bytes per vertex) + + GDRAW_vformat__basic_count, + GDRAW_vformat_ihud1 = GDRAW_vformat__basic_count, // primary format for ihud, currently v2tc2mat4 (20 bytes per vertex) + + GDRAW_vformat__count, + GDRAW_vformat_mixed, // Special value that denotes a VB containing data in multiple vertex formats. Never used when drawing! +} gdraw_vformat; +/* Identifies one of the vertex data types. */ + +IDOC typedef struct GDraw_MakeVertexBuffer_ProcessingInfo +{ + U8 *vertex_data; // location to write vertex data + U8 *index_data; // location to write index data + + S32 vertex_data_length; // size of buffer to write vertex data + S32 index_data_length; // size of buffer to write index data + + void *p0,*p1,*p2,*p3,*p4,*p5,*p6,*p7; // Pointers for GDraw to store data across "passes" (never touched by Iggy) + U32 i0, i1, i2, i3, i4, i5, i6, i7; // Integers for GDraw to store data across "passes" (never touched by Iggy) +} GDraw_MakeVertexBuffer_ProcessingInfo; +/* $GDraw_MakeVertexBuffer_ProcessingInfo is used when building a vertex buffer. */ + +IDOC typedef struct GDraw_VertexBuffer_Description { + S32 size_in_bytes; // Size of the vertex buffer in bytes +} GDraw_VertexBuffer_Description; +/* $GDraw_VertexBuffer_Description contains information about a vertex buffer. */ + +IDOC typedef rrbool RADLINK gdraw_make_vertex_buffer_begin(void *unique_id, gdraw_vformat vformat, S32 vdata_len_in_bytes, S32 idata_len_in_bytes, GDraw_MakeVertexBuffer_ProcessingInfo *info, GDrawStats *stats); +/* Begins specifying a new vertex buffer. + + $:unique_id Unique value that identifies this texture, across potentially multiple flushes and re-creations of its $GDrawTexture handle in GDraw + $:vformat One of $gdraw_vformat, denoting the format of the vertex data submitted + $:return false if there was a problem, true if ok +*/ + +IDOC typedef rrbool RADLINK gdraw_make_vertex_buffer_more(GDraw_MakeVertexBuffer_ProcessingInfo *info); +/* Continues specifying a new vertex buffer. + + $:info The same handle initially passed to $gdraw_make_vertex_buffer_begin + $:return True if specification can continue, false if specification must be aborted +*/ + +IDOC typedef GDrawVertexBuffer * RADLINK gdraw_make_vertex_buffer_end(GDraw_MakeVertexBuffer_ProcessingInfo *info, GDrawStats *stats); +/* Ends specification of a new vertex buffer. + + $:info The same handle initially passed to $gdraw_make_texture_begin + $:return Handle for the newly created vertex buffer +*/ + +IDOC typedef void RADLINK gdraw_describe_vertex_buffer(GDrawVertexBuffer *buffer, GDraw_VertexBuffer_Description *desc); +/* Returns a description for a given GDrawVertexBuffer */ + + +IDOC typedef rrbool RADLINK gdraw_try_to_lock_texture(GDrawTexture *tex, void *unique_id, GDrawStats *stats); +/* Tells GDraw that a $GDrawTexture is going to be referenced. + + $:unique_id Must be the same value initially passed to $gdraw_make_texture_begin +*/ + +IDOC typedef rrbool RADLINK gdraw_try_to_lock_vertex_buffer(GDrawVertexBuffer *vb, void *unique_id, GDrawStats *stats); +/* Tells GDraw that a $GDrawVertexBuffer is going to be referenced. + + $:unique_id Must be the same value initially passed to $gdraw_make_vertex_buffer_begin +*/ + +IDOC typedef void RADLINK gdraw_unlock_handles(GDrawStats *stats); +/* Indicates that the user of GDraw will not try to reference anything without locking it again. + + Note that although a call to $gdraw_unlock_handles indicates that + all $GDrawTexture and $GDrawVertexBuffer handles that have had a + "unique_id" specified will no longer be referenced by the user of + GDraw, it does not affect those $GDrawTexture handles that were + created by $gdraw_start_texture_draw_buffer with a unique_id of 0. +*/ + +IDOC typedef void RADLINK gdraw_free_vertex_buffer(GDrawVertexBuffer *vb, void *unique_id, GDrawStats *stats); +/* Free a vertex buffer and invalidate the handle + + $:unique_id Must be the same value initially passed to $gdraw_make_vertex_buffer_begin +*/ + +IDOC typedef void RADLINK gdraw_free_texture(GDrawTexture *t, void *unique_id, GDrawStats *stats); +/* Free a texture and invalidate the handle. + + $:unique_id Must be the same value initially passed to $gdraw_make_texture_begin, or 0 for a texture created by $gdraw_end_texture_draw_buffer +*/ + +//////////////////////////////////////////////////////////// +// +// Render targets +// +//idoc(parent,GDrawAPI_Targets) + +IDOC typedef U32 gdraw_texturedrawbuffer_flags; +#define GDRAW_TEXTUREDRAWBUFFER_FLAGS_needs_color 1 IDOC // Tells GDraw that you will need the color channel when rendering a texture +#define GDRAW_TEXTUREDRAWBUFFER_FLAGS_needs_alpha 2 IDOC // Tells GDraw that you will need the alpha channel when rendering a texture +#define GDRAW_TEXTUREDRAWBUFFER_FLAGS_needs_stencil 4 IDOC // Tells GDraw that you will need the stencil channel when rendering a texture +#define GDRAW_TEXTUREDRAWBUFFER_FLAGS_needs_id 8 IDOC // Tells GDraw that you will need the id channel when rendering a texture + +/* Flags that control rendering to a texture. */ + +IDOC typedef rrbool RADLINK gdraw_texture_draw_buffer_begin(gswf_recti *region, gdraw_texture_format format, gdraw_texturedrawbuffer_flags flags, void *unique_id, GDrawStats *stats); +/* Starts rendering all GDraw commands to a new texture. + + Creates a rendertarget with destination alpha, initializes to all 0s and prepares to render into it +*/ + + +IDOC typedef GDrawTexture * RADLINK gdraw_texture_draw_buffer_end(GDrawStats *stats); +/* Ends rendering GDraw commands to a texture, and returns the texture created. + + You can get the size of the resulting texture with $gdraw_query_texture_size. +*/ + +//////////////////////////////////////////////////////////// +// +// Masking +// +//idoc(parent,GDrawAPI_Masking) + +IDOC typedef void RADLINK gdraw_draw_mask_begin(gswf_recti *region, S32 mask_bit, GDrawStats *stats); +/* Start a masking operation on the given region for the specified mask bit. + + For most drivers, no special preparation is necessary to start masking, so this is a no-op. +*/ + +IDOC typedef void RADLINK gdraw_draw_mask_end(gswf_recti *region, S32 mask_bit, GDrawStats *stats); +/* End a masking operation on the given region for the specified mask bit. + + For most drivers, no special preparation is necessary to end masking, so this is a no-op. +*/ + +//////////////////////////////////////////////////////////// +// +// GDraw API Function table +// +//idoc(parent,GDrawAPI_Base) + +IDOC struct GDrawFunctions +{ + // queries + gdraw_get_info *GetInfo; + + // drawing state + gdraw_set_view_size_and_world_scale * SetViewSizeAndWorldScale; + gdraw_render_tile_begin * RenderTileBegin; + gdraw_render_tile_end * RenderTileEnd; + gdraw_set_antialias_texture * SetAntialiasTexture; + + // drawing + gdraw_clear_stencil_bits * ClearStencilBits; + gdraw_clear_id * ClearID; + gdraw_filter_quad * FilterQuad; + gdraw_draw_indexed_triangles * DrawIndexedTriangles; + gdraw_make_texture_begin * MakeTextureBegin; + gdraw_make_texture_more * MakeTextureMore; + gdraw_make_texture_end * MakeTextureEnd; + gdraw_make_vertex_buffer_begin * MakeVertexBufferBegin; + gdraw_make_vertex_buffer_more * MakeVertexBufferMore; + gdraw_make_vertex_buffer_end * MakeVertexBufferEnd; + gdraw_try_to_lock_texture * TryToLockTexture; + gdraw_try_to_lock_vertex_buffer * TryToLockVertexBuffer; + gdraw_unlock_handles * UnlockHandles; + gdraw_free_texture * FreeTexture; + gdraw_free_vertex_buffer * FreeVertexBuffer; + gdraw_update_texture_begin * UpdateTextureBegin; + gdraw_update_texture_rect * UpdateTextureRect; + gdraw_update_texture_end * UpdateTextureEnd; + + // rendertargets + gdraw_texture_draw_buffer_begin * TextureDrawBufferBegin; + gdraw_texture_draw_buffer_end * TextureDrawBufferEnd; + + gdraw_describe_texture * DescribeTexture; + gdraw_describe_vertex_buffer * DescribeVertexBuffer; + + // new functions are always added at the end, so these have no structure + gdraw_set_texture_unique_id * SetTextureUniqueID; + + gdraw_draw_mask_begin * DrawMaskBegin; + gdraw_draw_mask_end * DrawMaskEnd; + + gdraw_rendering_begin * RenderingBegin; + gdraw_rendering_end * RenderingEnd; + + gdraw_make_texture_from_resource * MakeTextureFromResource; + gdraw_free_texture_from_resource * FreeTextureFromResource; + + gdraw_set_3d_transform * Set3DTransform; +}; +/* The function interface called by Iggy to render graphics on all + platforms. + + So that Iggy can integrate with the widest possible variety of + rendering scenarios, all of its renderer-specific drawing calls + go through this table of function pointers. This allows you + to dynamically configure which of RAD's supplied drawing layers + you wish to use, or to integrate it directly into your own + renderer by implementing your own versions of the drawing + functions Iggy requires. +*/ + +RADDEFEND + +#endif diff --git a/Minecraft.Client/Windows64/Iggy/include/iggy.h b/Minecraft.Client/Windows64/Iggy/include/iggy.h new file mode 100644 index 00000000..56638a32 --- /dev/null +++ b/Minecraft.Client/Windows64/Iggy/include/iggy.h @@ -0,0 +1,1295 @@ +// Iggy -- Copyright 2008-2013 RAD Game Tools + +#ifndef __RAD_INCLUDE_IGGY_H__ +#define __RAD_INCLUDE_IGGY_H__ + +#include // size_t + +#define IggyVersion "1.2.30" +#define IggyFlashVersion "9,1,2,30" + +#include "rrcore.h" // base data types, macros + +RADDEFSTART + +#ifndef IGGY_GDRAW_SHARED_TYPEDEF + + #define IGGY_GDRAW_SHARED_TYPEDEF + + typedef struct GDrawFunctions GDrawFunctions; + typedef struct GDrawTexture GDrawTexture; + +#endif//IGGY_GDRAW_SHARED_TYPEDEF + +#define IDOCN // Used by documentation generation system + +//////////////////////////////////////////////////////////// +// +// Basic Operations +// + +typedef enum IggyResult +{ + IGGY_RESULT_SUCCESS = 0, + + IGGY_RESULT_Warning_None = 0, + + IGGY_RESULT_Warning_Misc = 100, + IGGY_RESULT_Warning_GDraw = 101, + IGGY_RESULT_Warning_ProgramFlow = 102, + IGGY_RESULT_Warning_Actionscript = 103, + IGGY_RESULT_Warning_Graphics = 104, + IGGY_RESULT_Warning_Font = 105, + IGGY_RESULT_Warning_Timeline = 106, + IGGY_RESULT_Warning_Library = 107, + IGGY_RESULT_Warning_ValuePath = 108, + IGGY_RESULT_Warning_Audio = 109, + + IGGY_RESULT_Warning_CannotSustainFrameRate = 201, // During a call to $IggyPlayerReadyToTick, Iggy detected that its rendering of a Flash file was not keeping up with the frame rate requested. + IGGY_RESULT_Warning_ThrewException = 202, + + IGGY_RESULT_Error_Threshhold = 400, + + IGGY_RESULT_Error_Misc = 400, // an uncategorized error + IGGY_RESULT_Error_GDraw = 401, // an error occured in GDraw + IGGY_RESULT_Error_ProgramFlow = 402, // an error occured with the user's program flow through the Iggy API (e.g. reentrancy issues) + IGGY_RESULT_Error_Actionscript = 403, // an error occurred in Actionscript processing + IGGY_RESULT_Error_Graphics = 404, + IGGY_RESULT_Error_Font = 405, + IGGY_RESULT_Error_Create = 406, + IGGY_RESULT_Error_Library = 407, + IGGY_RESULT_Error_ValuePath = 408, // an error occurred while processing a ValuePath + IGGY_RESULT_Error_Audio = 409, + + IGGY_RESULT_Error_Internal = 499, + + IGGY_RESULT_Error_InvalidIggy = 501, + IGGY_RESULT_Error_InvalidArgument = 502, + IGGY_RESULT_Error_InvalidEntity = 503, + IGGY_RESULT_Error_UndefinedEntity = 504, + + IGGY_RESULT_Error_OutOfMemory = 1001, // Iggy ran out of memory while processing the SWF. The Iggy player is now invalid and you cannot do anything further with it (except read AS3 variables). Should this happen, you'll want to $IggyPlayerDestroy and reopen the $Iggy. +} IggyResult; + +typedef enum IggyDatatype +{ + IGGY_DATATYPE__invalid_request, // Set only when there is an error + + IGGY_DATATYPE_undefined, // Undefined data type + IGGY_DATATYPE_null, // No data type + IGGY_DATATYPE_boolean, // Data of type rrbool + + IGGY_DATATYPE_number, // Data of type F64 + IGGY_DATATYPE_string_UTF8, // Data of type $IggyStringUTF8 + IGGY_DATATYPE_string_UTF16, // Data of type $IggyStringUTF16 + IGGY_DATATYPE_fastname, // Only used when calling functions (avoids a copy operation) + IGGY_DATATYPE_valuepath, // Only used when calling functions + IGGY_DATATYPE_valueref, // Only used when calling functions + + // the following datatypes can be queried, but cannot appear + // as function arguments + + IGGY_DATATYPE_array, // Data of type Array in AS3 (appears in datatype query, never as arguments) + IGGY_DATATYPE_object, // Data of type Object (or a subclass) in AS3 (appears in datatype query, never as arguments) + IGGY_DATATYPE_displayobj, // Data of type DisplayObject (or a subclass) in AS3 (only appears in callbacks) + + IGGY_DATATYPE_xml, // Data of type XML or XMLList in AS3 (appears in datatype query, never as arguments) + + // the following datatypes also exists, but you can't access any data + // from within them. we give you the exact type for e.g. debugging + IGGY_DATATYPE_namespace, // Data of type Namespace in AS3 (appears in datatype query, never as arguments) + IGGY_DATATYPE_qname, // Data of type QName in AS3 (appears in datatype query, never as arguments) + IGGY_DATATYPE_function, // Data of type Function in AS3 (appears in datatype query, never as arguments) + IGGY_DATATYPE_class, // Data of type Class in AS3 (appears in datatype query, never as arguments) +} IggyDatatype; +/* Describes an AS3 datatype visible through iggy interface. */ + +#ifdef __RADWIN__ +#include +IDOCN typedef wchar_t IggyUTF16; +#else +typedef unsigned short IggyUTF16; +#endif + +typedef struct IggyStringUTF16 +{ + IggyUTF16 *string; // Null-terminated, UTF16-encoded characters + S32 length; // Count of 16-bit characters in string, not including the null terminator +} IggyStringUTF16; + +typedef struct IggyStringUTF8 +{ + char *string; // Null-terminated, UTF8-encoded characters + S32 length; // Count of 8-bit bytes in string, not including the null terminator +} IggyStringUTF8; + +typedef UINTa IggyName; +typedef struct IggyValuePath IggyValuePath; +typedef void *IggyValueRef; +typedef UINTa IggyTempRef; + +typedef struct IggyDataValue +{ + S32 type; // an $IggyDatatype which determines which of the union members is valid. + #ifdef __RAD64__ + S32 padding; + #endif + IggyTempRef temp_ref; // An opaque temporary reference which you can efficiently turn into an $IggyValueRef; this is written by Iggy on callbacks but never read by Iggy + union { + IggyStringUTF16 string16; // A UTF16 string, valid if type = $(IggyDatatype::IGGY_DATATYPE_string_UTF16) + IggyStringUTF8 string8; // A UTF8 string, valid if type = $(IggyDatatype::IGGY_DATATYPE_string_UTF8) + F64 number; // A 64-bit floating point number (a double); valid if type = $(IggyDatatype::IGGY_DATATYPE_number) + rrbool boolval; // A boolean value, valid if type = $(IggyDatatype::IGGY_DATATYPE_boolean) + IggyName fastname; // A fast name, valid if type = $(IggyDatatype::IGGY_DATATYPE_fastname); this is only an "in" type; Iggy will never define these itself + void * userdata; // A userdata pointer from a DisplayObject, valid if type = $(IggyDatatype::IGGY_DATATYPE_displayobj) + IggyValuePath * valuepath;// A path to an object in the AS3 VM, valid if type = $(IggyDatatype::IGGY_DATATYPE_valuepath); this is only an "in" type--Iggy will never output this + IggyValueRef valueref; // An IggyValueRef, valid if type = $(IggyDatatype::IGGY_DATATYPE_valueref); this is only an "in" type--Iggy will never output this + }; +} IggyDataValue; + +typedef struct IggyExternalFunctionCallUTF16 +{ + IggyStringUTF16 function_name; // The name of the function + S32 num_arguments; // The number of arguments that must be passed to the function + S32 padding; + IggyDataValue arguments[1]; // The argument types, assumed to contain num_arguments elements +} IggyExternalFunctionCallUTF16; + +typedef struct IggyExternalFunctionCallUTF8 +{ + IggyStringUTF8 function_name; // The name of the function + S32 num_arguments; // The number of arguments that must be passed to the function + S32 padding; + IggyDataValue arguments[1]; // The argument types, assumed to contain num_arguments elements +} IggyExternalFunctionCallUTF8; + +typedef void * RADLINK Iggy_AllocateFunction(void *alloc_callback_user_data, size_t size_requested, size_t *size_returned); +typedef void RADLINK Iggy_DeallocateFunction(void *alloc_callback_user_data, void *ptr); + +typedef struct IggyAllocator +{ + void *user_callback_data; + Iggy_AllocateFunction *mem_alloc; + Iggy_DeallocateFunction *mem_free; + #ifndef __RAD64__ + void *struct_padding; // pad to 8-byte boundary + #endif +} IggyAllocator; + +RADEXPFUNC void RADEXPLINK IggyInit(IggyAllocator *allocator); +RADEXPFUNC void RADEXPLINK IggyShutdown(void); + +typedef enum IggyConfigureBoolName +{ + IGGY_CONFIGURE_BOOL_StartupExceptionsAreWarnings, // if true, ActionScript exceptions thrown during startup will not prevent Iggy from being created (default false) + IGGY_CONFIGURE_BOOL_IgnoreFlashVersion, + IGGY_CONFIGURE_BOOL_NeverDelayGotoProcessing, + IGGY_CONFIGURE_BOOL_SuppressAntialiasingOnAllBitmaps, + IGGY_CONFIGURE_BOOL_SuppressAntialiasingOn9SliceBitmaps, +} IggyConfigureBoolName; + +RADEXPFUNC void RADEXPLINK IggyConfigureBool(IggyConfigureBoolName prop, rrbool value); + +typedef enum +{ + IGGY_VERSION_1_0_21 = 1, // behavior from 1.0.21 and earlier + IGGY_VERSION_1_0_24 = 3, // behavior from 1.0.24 and earlier + IGGY_VERSION_1_1_1 = 5, // behavior from 1.1.1 and earlier + IGGY_VERSION_1_1_8 = 7, // behavior from 1.1.8 and earlier + IGGY_VERSION_1_2_28 = 9, // behavior from 1.2.28 and earlier + IGGY_VERSION_default=0x7fffffff, // default (current) Iggy behavior +} IggyVersionNumber; + +typedef enum +{ + IGGY_VERSIONED_BEHAVIOR_movieclip_gotoand=128, // This changes the behavior of AS3 gotoAndPlay and gotoAndStop. Valid values: IGGY_VERSION_1_0_21, IGGY_VERSION_default + IGGY_VERSIONED_BEHAVIOR_textfield_position=129, // This changes the behavior of textfield positioning as reported by AS3 getBounds/getRect and width/height. Values with different behavior: IGGY_VERSION_1_0_24, IGGY_VERSION_default. + IGGY_VERSIONED_BEHAVIOR_bitmap_smoothing=130, + IGGY_VERSIONED_BEHAVIOR_textfield_autoscroll=131, // This makes textfield autoscrolling behave specially: Valid values: IGGY_VERSION_1_1_8, IGGY_VERSION_default + IGGY_VERSIONED_BEHAVIOR_fast_text_effects=132, // This fixes the behavior of fast text effects to be in the correct direction; Valid values: IGGY_VERSION_1_2_28, IGGY_VERSION_default +} IggyVersionedBehaviorName; + +RADEXPFUNC void RADEXPLINK IggyConfigureVersionedBehavior(IggyVersionedBehaviorName prop, IggyVersionNumber value); + +typedef enum IggyTelemetryAmount +{ + IGGY_TELEMETRY_normal, // Normal amount for users debugging applications using Iggy + IGGY_TELEMETRY_internal, // Shows more internal details, useful when optimizing Iggy itself +} IggyTelemetryAmount; + +RADEXPFUNC void RADEXPLINK IggyUseTmLite(void * context, IggyTelemetryAmount amount); +RADEXPFUNC void RADEXPLINK IggyUseTelemetry(void * context, IggyTelemetryAmount amount); + +//////////////////////////////////////////////////////////// +// +// Translation +// + + +typedef struct +{ + IggyUTF16 *object_name; /* null-terminated Textfield.name value at the time the text is set */ + rrbool autosize; /* true if the autosize value is non-zero at the time the text is set */ + F32 width; /* the objectspace width of the textfield at the time the text is set */ + F32 height; /* the objectspace height of the textfield at the time the text is set */ + rrbool is_html_text; /* whether the provided text is going through Textfield.htmlText or Textfield.text */ +} IggyTextfieldInfo; + +typedef void RADLINK Iggy_TranslationFreeFunction(void *callback_data, void *data, S32 length); +typedef rrbool RADLINK Iggy_TranslateFunctionUTF16(void *callback_data, IggyStringUTF16 *src, IggyStringUTF16 *dest); +typedef rrbool RADLINK Iggy_TranslateFunctionUTF8(void *callback_data, IggyStringUTF8 *src, IggyStringUTF8 *dest); +typedef rrbool RADLINK Iggy_TextfieldTranslateFunctionUTF16(void *callback_data, IggyStringUTF16 *src, IggyStringUTF16 *dest, IggyTextfieldInfo *textfield); +typedef rrbool RADLINK Iggy_TextfieldTranslateFunctionUTF8(void *callback_data, IggyStringUTF8 *src, IggyStringUTF8 *dest, IggyTextfieldInfo *textfield); + +RADEXPFUNC void RADEXPLINK IggySetLoadtimeTranslationFunction(Iggy_TranslateFunctionUTF16 *func, void *callback_data, Iggy_TranslationFreeFunction *freefunc, void *free_callback_data); +RADEXPFUNC void RADEXPLINK IggySetLoadtimeTranslationFunctionUTF16(Iggy_TranslateFunctionUTF16 *func, void *callback_data, Iggy_TranslationFreeFunction *freefunc, void *free_callback_data); +RADEXPFUNC void RADEXPLINK IggySetLoadtimeTranslationFunctionUTF8(Iggy_TranslateFunctionUTF8 *func, void *callback_data, Iggy_TranslationFreeFunction *freefunc, void *free_callback_data); +RADEXPFUNC void RADEXPLINK IggySetRuntimeTranslationFunction(Iggy_TranslateFunctionUTF16 *func, void *callback_data, Iggy_TranslationFreeFunction *freefunc, void *free_callback_data); +RADEXPFUNC void RADEXPLINK IggySetRuntimeTranslationFunctionUTF16(Iggy_TranslateFunctionUTF16 *func, void *callback_data, Iggy_TranslationFreeFunction *freefunc, void *free_callback_data); +RADEXPFUNC void RADEXPLINK IggySetRuntimeTranslationFunctionUTF8(Iggy_TranslateFunctionUTF8 *func, void *callback_data, Iggy_TranslationFreeFunction *freefunc, void *free_callback_data); +RADEXPFUNC void RADEXPLINK IggySetTextfieldTranslationFunctionUTF16(Iggy_TextfieldTranslateFunctionUTF16 *func, void *callback_data, Iggy_TranslationFreeFunction *freefunc, void *free_callback_data); +RADEXPFUNC void RADEXPLINK IggySetTextfieldTranslationFunctionUTF8(Iggy_TextfieldTranslateFunctionUTF8 *func, void *callback_data, Iggy_TranslationFreeFunction *freefunc, void *free_callback_data); + +typedef enum +{ + IGGY_LANG_default, + IGGY_LANG_ja, + IGGY_LANG_ja_flash, // more strictly matches Flash +} IggyLanguageCode; + +RADEXPFUNC void RADEXPLINK IggySetLanguage(IggyLanguageCode lang); + +//////////////////////////////////////////////////////////// +// +// Playback +// + +typedef struct Iggy Iggy; +typedef S32 IggyLibrary; + +typedef void RADLINK Iggy_TraceFunctionUTF16(void *user_callback_data, Iggy *player, IggyUTF16 const *utf16_string, S32 length_in_16bit_chars); +typedef void RADLINK Iggy_TraceFunctionUTF8(void *user_callback_data, Iggy *player, char const *utf8_string, S32 length_in_bytes); +typedef void RADLINK Iggy_WarningFunction(void *user_callback_data, Iggy *player, IggyResult error_code, char const *error_message); + +typedef struct +{ + S32 total_storage_in_bytes; // the total memory to use for the AS3 heap and garbage collector + S32 stack_size_in_bytes; // size of the stack used for AS3 expression evaluation and function activation records + S32 young_heap_size_in_bytes; // size of the heap from which initial allocations are made + S32 old_heap_size_in_bytes; // this parameter is not supported yet + S32 remembered_set_size_in_bytes; // storage used to keep track of pointers from old heap to young heap + S32 greylist_size_in_bytes; // storage used to keep track of partially-garbage collected objects on the old heap + S32 rootstack_size_in_bytes; // size of the stack used for exposing temporaries to the garbage collector + S32 padding; +} IggyPlayerGCSizes; + +typedef struct +{ + IggyAllocator allocator; + IggyPlayerGCSizes gc; + char *filename; + char *user_name; + rrbool load_in_place; + rrbool did_load_in_place; +} IggyPlayerConfig; + +RADEXPFUNC Iggy * RADEXPLINK IggyPlayerCreateFromFileAndPlay( + char const * filename, + IggyPlayerConfig const*config); + +RADEXPFUNC Iggy * RADEXPLINK IggyPlayerCreateFromMemory( + void const * data, + U32 data_size_in_bytes, + IggyPlayerConfig *config); + +#define IGGY_INVALID_LIBRARY -1 + +RADEXPFUNC IggyLibrary RADEXPLINK IggyLibraryCreateFromMemory( + char const * url_utf8_null_terminated, + void const * data, + U32 data_size_in_bytes, + IggyPlayerConfig *config); + +RADEXPFUNC IggyLibrary RADEXPLINK IggyLibraryCreateFromMemoryUTF16( + IggyUTF16 const * url_utf16_null_terminated, + void const * data, + U32 data_size_in_bytes, + IggyPlayerConfig *config); + +RADEXPFUNC void RADEXPLINK IggyPlayerDestroy(Iggy *player); +RADEXPFUNC void RADEXPLINK IggyLibraryDestroy(IggyLibrary lib); +RADEXPFUNC void RADEXPLINK IggySetWarningCallback(Iggy_WarningFunction *error, void *user_callback_data); +RADEXPFUNC void RADEXPLINK IggySetTraceCallbackUTF8(Iggy_TraceFunctionUTF8 *trace_utf8, void *user_callback_data); +RADEXPFUNC void RADEXPLINK IggySetTraceCallbackUTF16(Iggy_TraceFunctionUTF16 *trace_utf16, void *user_callback_data); + +typedef struct IggyProperties +{ + S32 movie_width_in_pixels; // the width of the "document" specified in the SWF file + S32 movie_height_in_pixels; // the height of the "document" specified in the SWF file + + F32 movie_frame_rate_current_in_fps; // the current frame rate Iggy is trying to achieve for the file + F32 movie_frame_rate_from_file_in_fps; // the frame rate specified in the SWF file + + S32 frames_passed; // the number of times Tick() has been called + S32 swf_major_version_number; // the major SWF version number of the file, currently always 9 + + F64 time_passed_in_seconds; // the total time passed since starting the file + F64 seconds_since_last_tick; // the number of seconds that have ocurred + F64 seconds_per_drawn_frame; // 1/render fps, updated on $IggyPlayerDrawTilesStart +} IggyProperties; + +RADEXPFUNC IggyProperties * RADEXPLINK IggyPlayerProperties(Iggy *player); + +typedef enum +{ + IGGY_PAUSE_continue_audio, + IGGY_PAUSE_pause_audio, + IGGY_PAUSE_stop_audio +} IggyAudioPauseMode; + +RADEXPFUNC void * RADEXPLINK IggyPlayerGetUserdata(Iggy *player); +RADEXPFUNC void RADEXPLINK IggyPlayerSetUserdata(Iggy *player, void *userdata); + +RADEXPFUNC void RADEXPLINK IggyPlayerInitializeAndTickRS(Iggy *player); +RADEXPFUNC rrbool RADEXPLINK IggyPlayerReadyToTick(Iggy *player); +RADEXPFUNC void RADEXPLINK IggyPlayerTickRS(Iggy *player); +RADEXPFUNC void RADEXPLINK IggyPlayerPause(Iggy *player, IggyAudioPauseMode pause_audio); +RADEXPFUNC void RADEXPLINK IggyPlayerPlay(Iggy *player); +RADEXPFUNC void RADEXPLINK IggyPlayerSetFrameRate(Iggy *player, F32 frame_rate_in_fps); +RADEXPFUNC void RADEXPLINK IggyPlayerGotoFrameRS(Iggy *f, S32 frame, rrbool stop); + +#ifndef __RAD_HIGGYEXP_ +#define __RAD_HIGGYEXP_ +typedef void * HIGGYEXP; +/* An IggyExplorer context, it represents a connection to Iggy Explorer. */ +#endif + +#ifndef __RAD_HIGGYPERFMON_ +#define __RAD_HIGGYPERFMON_ +typedef void * HIGGYPERFMON; +/* An IggyPerfMon context */ +#endif + + +IDOCN typedef void RADLINK iggyexp_detach_callback(void *ptr); + +IDOCN typedef struct +{ + U64 tick_ticks; + U64 draw_ticks; +} IggyPerfmonStats; + +IDOCN typedef struct +{ + void (RADLINK *get_stats)(Iggy* swf, IggyPerfmonStats* pdest); + const char* (RADLINK *get_display_name)(Iggy* swf); +} IggyForPerfmonFunctions; + +// This is used by both Iggy Explorer and Perfmon +IDOCN typedef struct +{ + rrbool (RADLINK *connection_valid)(Iggy* swf, HIGGYEXP iggyexp); // Iggy queries this to check if Iggy Explorer is still connected + S32 (RADLINK *poll_command)(Iggy* swf, HIGGYEXP iggyexp, U8 **buffer); // stores command in *buffer, returns number of bytes + void (RADLINK *send_command)(Iggy* swf, HIGGYEXP iggyexp, U8 command, void *buffer, S32 len); // writes a command with a payload of buffer:len + S32 (RADLINK *get_storage)(Iggy* swf, HIGGYEXP iggyexp, U8 **buffer); // returns temporary storage Iggy can use for assembling commands + rrbool (RADLINK *attach)(Iggy* swf, HIGGYEXP iggyexp, iggyexp_detach_callback *cb, void *cbdata, IggyForPerfmonFunctions* pmf); // an Iggy file is trying to attach itself to this connection (one at a time) + rrbool (RADLINK *detach)(Iggy* swf, HIGGYEXP iggyexp); // the current Iggy file should be detached (generate callback) + void (RADLINK *draw_tile_hook)(Iggy* swf, HIGGYEXP iggyexp, GDrawFunctions* iggy_gdraw); // only used by perfmon +} IggyExpFunctions; + +RADEXPFUNC void RADEXPLINK IggyInstallPerfmon(void *perfmon_context); + +RADEXPFUNC void RADEXPLINK IggyUseExplorer(Iggy *swf, void *context); +IDOCN RADEXPFUNC void RADEXPLINK IggyPlayerSendFrameToExplorer(Iggy *f); + +//////////////////////////////////////////////////////////// +// +// Fonts +// + +typedef struct +{ + F32 ascent; + F32 descent; + F32 line_gap; + F32 average_glyph_width_for_tab_stops; // for embedded fonts, Iggy uses width of 'g' + F32 largest_glyph_bbox_y1; +} IggyFontMetrics; + +typedef struct +{ + F32 x0,y0, x1,y1; // bounding box + F32 advance; // distance to move origin after this character +} IggyGlyphMetrics; + +typedef enum { + IGGY_VERTEX_move = 1, + IGGY_VERTEX_line = 2, + IGGY_VERTEX_curve = 3, +} IggyShapeVertexType; + +typedef struct +{ + F32 x,y; // if IGGY_VERTEX_move, point to start a new loop; if IGGY_VERTEX_line/curve, endpoint of segment + F32 cx,cy; // if IGGY_VERTEX_curve, control point on segment; ignored otherwise + U8 type; // value from $IggyShapeVertexType + + S8 padding; // ignore + U16 f0; // set to 1 + U16 f1; // set to 0 + U16 line; // ignore +} IggyShapeVertex; + +typedef struct +{ + IggyShapeVertex * vertices; + S32 num_vertices; + void * user_context_for_free; // you can use this to store data to access on the corresponding free call +} IggyVectorShape; + +typedef struct +{ + U8 *pixels_one_per_byte; // pixels from the top left, 0 is transparent and 255 is opaque + S32 width_in_pixels; // this is the actual width of the bitmap data + S32 height_in_pixels; // this is the actual height of the bitmap data + S32 stride_in_bytes; // the distance from one row to the next + S32 oversample; // this is the amount of oversampling (0 or 1 = not oversample, 2 = 2x oversampled, 4 = 4x oversampled) + rrbool point_sample; // if true, the bitmap will be drawn with point sampling; if false, it will be drawn with bilinear + S32 top_left_x; // the offset of the top left corner from the character origin + S32 top_left_y; // the offset of the top left corner from the character origin + F32 pixel_scale_correct; // the pixel_scale at which this character should be displayed at width_in_pixels + F32 pixel_scale_min; // the smallest pixel_scale to allow using this character (scaled down) + F32 pixel_scale_max; // the largest pixels cale to allow using this character (scaled up) + void * user_context_for_free; // you can use this to store data to access on the corresponding free call +} IggyBitmapCharacter; + +typedef IggyFontMetrics * RADLINK IggyFontGetFontMetrics(void *user_context, IggyFontMetrics *metrics); + +#define IGGY_GLYPH_INVALID -1 +typedef S32 RADLINK IggyFontGetCodepointGlyph(void *user_context, U32 codepoint); +typedef IggyGlyphMetrics * RADLINK IggyFontGetGlyphMetrics(void *user_context, S32 glyph, IggyGlyphMetrics *metrics); +typedef rrbool RADLINK IggyFontIsGlyphEmpty(void *user_context, S32 glyph); +typedef F32 RADLINK IggyFontGetKerningForGlyphPair(void *user_context, S32 first_glyph, S32 second_glyph); + +typedef void RADLINK IggyVectorFontGetGlyphShape(void *user_context, S32 glyph, IggyVectorShape *shape); +typedef void RADLINK IggyVectorFontFreeGlyphShape(void *user_context, S32 glyph, IggyVectorShape *shape); + +typedef rrbool RADLINK IggyBitmapFontCanProvideBitmap(void *user_context, S32 glyph, F32 pixel_scale); +typedef rrbool RADLINK IggyBitmapFontGetGlyphBitmap(void *user_context, S32 glyph, F32 pixel_scale, IggyBitmapCharacter *bitmap); +typedef void RADLINK IggyBitmapFontFreeGlyphBitmap(void *user_context, S32 glyph, F32 pixel_scale, IggyBitmapCharacter *bitmap); + + +typedef struct +{ + IggyFontGetFontMetrics *get_font_metrics; + + IggyFontGetCodepointGlyph *get_glyph_for_codepoint; + IggyFontGetGlyphMetrics *get_glyph_metrics; + IggyFontIsGlyphEmpty *is_empty; + IggyFontGetKerningForGlyphPair *get_kerning; + + IggyVectorFontGetGlyphShape *get_shape; + IggyVectorFontFreeGlyphShape *free_shape; + + S32 num_glyphs; + + void *userdata; +} IggyVectorFontProvider; + +typedef struct +{ + IggyFontGetFontMetrics *get_font_metrics; + + IggyFontGetCodepointGlyph *get_glyph_for_codepoint; + IggyFontGetGlyphMetrics *get_glyph_metrics; + IggyFontIsGlyphEmpty *is_empty; + IggyFontGetKerningForGlyphPair *get_kerning; + + IggyBitmapFontCanProvideBitmap *can_bitmap; + IggyBitmapFontGetGlyphBitmap *get_bitmap; + IggyBitmapFontFreeGlyphBitmap *free_bitmap; + + S32 num_glyphs; + + void *userdata; +} IggyBitmapFontProvider; + +typedef struct +{ + IggyBitmapFontCanProvideBitmap *can_bitmap; + IggyBitmapFontGetGlyphBitmap *get_bitmap; + IggyBitmapFontFreeGlyphBitmap *free_bitmap; + void *userdata; +} IggyBitmapFontOverride; + +RADEXPFUNC void RADEXPLINK IggySetInstalledFontMaxCount(S32 num); +RADEXPFUNC void RADEXPLINK IggySetIndirectFontMaxCount(S32 num); + +#define IGGY_FONTFLAG_none 0 +#define IGGY_FONTFLAG_bold 1 +#define IGGY_FONTFLAG_italic 2 +#define IGGY_FONTFLAG_all (~0U) // indirection only + +#define IGGY_TTC_INDEX_none 0 + +RADEXPFUNC void RADEXPLINK IggyFontInstallTruetypeUTF8(const void *truetype_storage, S32 ttc_index, const char *fontname, S32 namelen_in_bytes, U32 fontflags); +RADEXPFUNC void RADEXPLINK IggyFontInstallTruetypeUTF16(const void *truetype_storage, S32 ttc_index, const U16 *fontname, S32 namelen_in_16bit_quantities, U32 fontflags); +RADEXPFUNC void RADEXPLINK IggyFontInstallTruetypeFallbackCodepointUTF8(const char *fontname, S32 len, U32 fontflags, S32 fallback_codepoint); +RADEXPFUNC void RADEXPLINK IggyFontInstallTruetypeFallbackCodepointUTF16(const U16 *fontname, S32 len, U32 fontflags, S32 fallback_codepoint); +RADEXPFUNC void RADEXPLINK IggyFontInstallVectorUTF8(const IggyVectorFontProvider *vfp, const char *fontname, S32 namelen_in_bytes, U32 fontflags); +RADEXPFUNC void RADEXPLINK IggyFontInstallVectorUTF16(const IggyVectorFontProvider *vfp, const U16 *fontname, S32 namelen_in_16bit_quantities, U32 fontflags); +RADEXPFUNC void RADEXPLINK IggyFontInstallBitmapUTF8(const IggyBitmapFontProvider *bmf, const char *fontname, S32 namelen_in_bytes, U32 fontflags); +RADEXPFUNC void RADEXPLINK IggyFontInstallBitmapUTF16(const IggyBitmapFontProvider *bmf, const U16 *fontname, S32 namelen_in_16bit_quantities, U32 fontflags); +RADEXPFUNC void RADEXPLINK IggyFontInstallBitmapOverrideUTF8(const IggyBitmapFontOverride *bmf, const char *fontname, S32 namelen_in_bytes, U32 fontflags); +RADEXPFUNC void RADEXPLINK IggyFontInstallBitmapOverrideUTF16(const IggyBitmapFontOverride *bmf, const U16 *fontname, S32 namelen_in_16bit_quantities, U32 fontflags); + +RADEXPFUNC void RADEXPLINK IggyFontRemoveUTF8(const char *fontname, S32 namelen_in_bytes, U32 fontflags); +RADEXPFUNC void RADEXPLINK IggyFontRemoveUTF16(const U16 *fontname, S32 namelen_in_16bit_quantities, U32 fontflags); + +RADEXPFUNC void RADEXPLINK IggyFontSetIndirectUTF8(const char *request_name, S32 request_namelen, U32 request_flags, const char *result_name, S32 result_namelen, U32 result_flags); +RADEXPFUNC void RADEXPLINK IggyFontSetIndirectUTF16(const U16 *request_name, S32 request_namelen, U32 request_flags, const U16 *result_name, S32 result_namelen, U32 result_flags); + +RADEXPFUNC void RADEXPLINK IggyFontSetFallbackFontUTF8(const char *fontname, S32 fontname_len, U32 fontflags); +RADEXPFUNC void RADEXPLINK IggyFontSetFallbackFontUTF16(const U16 *fontname, S32 fontname_len, U32 fontflags); + +//////////////////////////////////////////////////////////// +// +// Audio +// + +struct _RadSoundSystem; +IDOCN typedef S32 (*IGGYSND_OPEN_FUNC)(struct _RadSoundSystem* i_SoundSystem, U32 i_MinBufferSizeInMs, U32 i_Frequency, U32 i_ChannelCount, U32 i_MaxLockSize, U32 i_Flags); + +IDOCN RADEXPFUNC void RADEXPLINK IggyAudioSetDriver(IGGYSND_OPEN_FUNC driver_open, U32 flags); + +// These functions cause Iggy to use a specific audio API, most of which +// are only actually defined on one target platform. Probably, you'll just +// want to call IggyAudioUseDefault. + +IDOCN RADEXPFUNC void RADEXPLINK IggyAudioUseDirectSound(void); +IDOCN RADEXPFUNC void RADEXPLINK IggyAudioUseWaveOut(void); +IDOCN RADEXPFUNC void RADEXPLINK IggyAudioUseXAudio2(void); +IDOCN RADEXPFUNC void RADEXPLINK IggyAudioUseLibAudio(void); +IDOCN RADEXPFUNC void RADEXPLINK IggyAudioUseAX(void); +IDOCN RADEXPFUNC void RADEXPLINK IggyAudioUseCoreAudio(void); + +RADEXPFUNC void RADEXPLINK IggyAudioUseDefault(void); + +#ifndef __RAD_DEFINE_IGGYMP3__ +#define __RAD_DEFINE_IGGYMP3__ +IDOCN typedef struct IggyMP3Interface IggyMP3Interface; +IDOCN typedef rrbool IggyGetMP3Decoder(IggyMP3Interface *decoder); +#endif + +#ifdef __RADNT__ + RADEXPFUNC void RADEXPLINK IggyAudioInstallMP3Decoder(void); + RADEXPFUNC void RADEXPLINK IggySetDLLDirectory(char *path); + RADEXPFUNC void RADEXPLINK IggySetDLLDirectoryW(wchar_t *path); +#else + // this is overkill for non-DLL implementations, which could call into Iggy + // directly, but it means everything goes through the same indirection internally + IDOCN RADEXPFUNC IggyGetMP3Decoder* RADEXPLINK IggyAudioGetMP3Decoder(void); + IDOCN RADEXPFUNC void RADEXPLINK IggyAudioInstallMP3DecoderExplicit(IggyGetMP3Decoder *init); + + #define IggyAudioInstallMP3Decoder() \ + IggyAudioInstallMP3DecoderExplicit(IggyAudioGetMP3Decoder()) IDOCN +#endif + +RADEXPFUNC rrbool RADEXPLINK IggyAudioSetMaxBufferTime(S32 ms); +RADEXPFUNC void RADEXPLINK IggyAudioSetLatency(S32 ms); +RADEXPFUNC void RADEXPLINK IggyPlayerSetAudioVolume(Iggy *iggy, F32 attenuation); + +#define IGGY_AUDIODEVICE_default 0 +#define IGGY_AUDIODEVICE_primary 1 +#define IGGY_AUDIODEVICE_secondary 2 + +IDOCN RADEXPFUNC void RADEXPLINK IggyPlayerSetAudioDevice(Iggy *iggy, S32 device); + + +//////////////////////////////////////////////////////////// +// +// Rendering +// + +typedef struct IggyCustomDrawCallbackRegion +{ + IggyUTF16 *name; // the name of the DisplayObject being substituted + F32 x0, y0, x1, y1; // the bounding box of the original DisplayObject, in object space + F32 rgba_mul[4]; // any multiplicative color effect specified for the DisplayObject or its parents + F32 rgba_add[4]; // any additive color effect specified for the DisplayObject or its parents + S32 scissor_x0, scissor_y0, scissor_x1, scissor_y1; // optional scissor rect box + U8 scissor_enable; // if non-zero, clip to the scissor rect + U8 stencil_func_mask; // D3DRS_STENCILMASK or equivalent + U8 stencil_func_ref; // D3DRS_STENCILREF or equivalent + U8 stencil_write_mask; // if non-zero, D3DRS_STENCILWRITEMASK or equivalent + struct gswf_matrix *o2w; // Iggy object-to-world matrix (used internally) +} IggyCustomDrawCallbackRegion; + +typedef void RADLINK Iggy_CustomDrawCallback(void *user_callback_data, Iggy *player, IggyCustomDrawCallbackRegion *Region); +typedef GDrawTexture* RADLINK Iggy_TextureSubstitutionCreateCallback(void *user_callback_data, IggyUTF16 *texture_name, S32 *width, S32 *height, void **destroy_callback_data); +typedef void RADLINK Iggy_TextureSubstitutionDestroyCallback(void *user_callback_data, void *destroy_callback_data, GDrawTexture *handle); +typedef GDrawTexture* RADLINK Iggy_TextureSubstitutionCreateCallbackUTF8(void *user_callback_data, char *texture_name, S32 *width, S32 *height, void **destroy_callback_data); + +RADEXPFUNC void RADEXPLINK IggySetCustomDrawCallback(Iggy_CustomDrawCallback *custom_draw, void *user_callback_data); +RADEXPFUNC void RADEXPLINK IggySetTextureSubstitutionCallbacks(Iggy_TextureSubstitutionCreateCallback *texture_create, Iggy_TextureSubstitutionDestroyCallback *texture_destroy, void *user_callback_data); +RADEXPFUNC void RADEXPLINK IggySetTextureSubstitutionCallbacksUTF8(Iggy_TextureSubstitutionCreateCallbackUTF8 *texture_create, Iggy_TextureSubstitutionDestroyCallback *texture_destroy, void *user_callback_data); + +typedef enum { + IGGY_FLUSH_no_callback, // do not generate the $Iggy_TextureSubstitutionDestroyCallback + IGGY_FLUSH_destroy_callback, // do generate the $Iggy_TextureSubstitutionDestroyCallback +} IggyTextureSubstitutionFlushMode; + +RADEXPFUNC void RADEXPLINK IggyTextureSubstitutionFlush(GDrawTexture *handle, IggyTextureSubstitutionFlushMode do_destroy_callback); +RADEXPFUNC void RADEXPLINK IggyTextureSubstitutionFlushAll(IggyTextureSubstitutionFlushMode do_destroy_callback); + +RADEXPFUNC void RADEXPLINK IggySetGDraw(GDrawFunctions *gdraw); +RADEXPFUNC void RADEXPLINK IggyPlayerGetBackgroundColor(Iggy *player, F32 output_color[3]); + +typedef enum +{ + IGGY_ROTATION_0_degrees = 0, + IGGY_ROTATION_90_degrees_counterclockwise = 1, + IGGY_ROTATION_180_degrees = 2, + IGGY_ROTATION_90_degrees_clockwise = 3, +} Iggy90DegreeRotation; + +RADEXPFUNC void RADEXPLINK IggyPlayerSetDisplaySize(Iggy *f, S32 w, S32 h); +RADEXPFUNC void RADEXPLINK IggyPlayerSetPixelShape(Iggy *swf, F32 pixel_x, F32 pixel_y); +RADEXPFUNC void RADEXPLINK IggyPlayerSetStageRotation(Iggy *f, Iggy90DegreeRotation rot); +RADEXPFUNC void RADEXPLINK IggyPlayerDraw(Iggy *f); +RADEXPFUNC void RADEXPLINK IggyPlayerSetStageSize(Iggy *f, S32 w, S32 h); +RADEXPFUNC void RADEXPLINK IggyPlayerSetFaux3DStage(Iggy *f, F32 *top_left, F32 *top_right, F32 *bottom_left, F32 *bottom_right, F32 depth_scale); +RADEXPFUNC void RADEXPLINK IggyPlayerForceMipmaps(Iggy *f, rrbool force_mipmaps); + +RADEXPFUNC void RADEXPLINK IggyPlayerDrawTile(Iggy *f, S32 x0, S32 y0, S32 x1, S32 y1, S32 padding); +RADEXPFUNC void RADEXPLINK IggyPlayerDrawTilesStart(Iggy *f); +RADEXPFUNC void RADEXPLINK IggyPlayerDrawTilesEnd(Iggy *f); +RADEXPFUNC void RADEXPLINK IggyPlayerSetRootTransform(Iggy *f, F32 mat[4], F32 tx, F32 ty); +RADEXPFUNC void RADEXPLINK IggyPlayerFlushAll(Iggy *player); +RADEXPFUNC void RADEXPLINK IggyLibraryFlushAll(IggyLibrary h); +RADEXPFUNC void RADEXPLINK IggySetTextCursorPixelWidth(S32 width); +RADEXPFUNC void RADEXPLINK IggyForceBitmapSmoothing(rrbool force_on); +RADEXPFUNC void RADEXPLINK IggyFlushInstalledFonts(void); +RADEXPFUNC void RADEXPLINK IggyFastTextFilterEffects(rrbool enable); + +typedef enum IggyAntialiasing +{ + IGGY_ANTIALIASING_FontsOnly = 2, // Anti-aliasing of bitmapped fonts only + IGGY_ANTIALIASING_FontsAndLinesOnly = 4, // Anti-aliasing of fonts and lines, but nothing else + IGGY_ANTIALIASING_PrettyGood = 8, // High-quality anti-aliasing on everything, but no rendertargets required + IGGY_ANTIALIASING_Good = 10, // High-quality anti-aliasing on everything (on platforms where GDraw doesn't support rendertargets, such as the Wii, this behaves the same as PrettyGood) +} IggyAntialiasing; + +RADEXPFUNC void RADEXPLINK IggyPlayerSetAntialiasing(Iggy *f, IggyAntialiasing antialias_mode); + +RADEXPFUNC void RADEXPLINK IggyPlayerSetBitmapFontCaching( + Iggy *f, + S32 tex_w, + S32 tex_h, + S32 max_char_pix_width, + S32 max_char_pix_height); + +RADEXPFUNC void RADEXPLINK IggySetFontCachingCalculationBuffer( + S32 max_chars, + void *optional_temp_buffer, + S32 optional_temp_buffer_size_in_bytes); + +typedef struct IggyGeneric IggyGeneric; + +RADEXPFUNC IggyGeneric * RADEXPLINK IggyPlayerGetGeneric(Iggy *player); +RADEXPFUNC IggyGeneric * RADEXPLINK IggyLibraryGetGeneric(IggyLibrary lib); + +// each texture metadata block contains one of these, where +// texture_info is an array of per-format data +IDOCN typedef struct +{ + U16 num_textures; + U16 load_alignment_log2; + U32 texture_file_size; + void *texture_info; +} IggyTextureResourceMetadata; + +RADEXPFUNC void RADEXPLINK IggyGenericInstallResourceFile(IggyGeneric *g, void *data, S32 data_length, rrbool *can_free_now); +RADEXPFUNC IggyTextureResourceMetadata *RADEXPLINK IggyGenericGetTextureResourceMetadata(IggyGeneric *f); +RADEXPFUNC void RADEXPLINK IggyGenericSetTextureFromResource(IggyGeneric *f, U16 id, GDrawTexture *handle); + +// this is the encoding for the "raw" texture type, which doesn't +// depend on any platform headers +typedef enum +{ + IFT_FORMAT_rgba_8888, + IFT_FORMAT_rgba_4444_LE, + IFT_FORMAT_rgba_5551_LE, + IFT_FORMAT_la_88, + IFT_FORMAT_la_44, + IFT_FORMAT_i_8, + IFT_FORMAT_i_4, + IFT_FORMAT_l_8, + IFT_FORMAT_l_4, + IFT_FORMAT_DXT1, + IFT_FORMAT_DXT3, + IFT_FORMAT_DXT5, +} IggyFileTexture_Format; + +typedef struct +{ + U32 file_offset; + U8 format; + U8 mipmaps; + U16 w,h; + U16 swf_id; +} IggyFileTextureRaw; + +IDOCN typedef struct +{ + U32 file_offset; + U16 swf_id; + U16 padding; + struct { + U32 data[13]; + } texture; +} IggyFileTexture360; + +IDOCN typedef struct +{ + U32 file_offset; + U16 swf_id; + U8 format; + U8 padding; + struct { + U32 data[6]; + } texture; +} IggyFileTexturePS3; + +IDOCN typedef struct +{ + U32 file_offset1; + U32 file_offset2; + U16 swf_id; + U8 format; + U8 padding; + struct { + U32 data1[39]; + } texture; +} IggyFileTextureWiiu; + +IDOCN typedef struct +{ + U32 file_offset; + U16 swf_id; + U8 format; + U8 padding; + struct { + U32 data[8]; + } texture; +} IggyFileTexturePS4; + +IDOCN typedef struct +{ + U32 file_offset; + U16 swf_id; + U8 format; + U8 padding; + struct { + U32 format; + U32 type; + U16 width; + U16 height; + U8 mip_count; + U8 pad[3]; + } texture; +} IggyFileTexturePSP2; + +//////////////////////////////////////////////////////////// +// +// AS3 +// + +typedef rrbool RADLINK Iggy_AS3ExternalFunctionUTF8(void *user_callback_data, Iggy *player, IggyExternalFunctionCallUTF8 *call); +typedef rrbool RADLINK Iggy_AS3ExternalFunctionUTF16(void *user_callback_data, Iggy *player, IggyExternalFunctionCallUTF16 *call); + +RADEXPFUNC void RADEXPLINK IggySetAS3ExternalFunctionCallbackUTF8(Iggy_AS3ExternalFunctionUTF8 *as3_external_function_utf8, void *user_callback_data); +RADEXPFUNC void RADEXPLINK IggySetAS3ExternalFunctionCallbackUTF16(Iggy_AS3ExternalFunctionUTF16 *as3_external_function_utf16, void *user_callback_data); +RADEXPFUNC IggyName RADEXPLINK IggyPlayerCreateFastName(Iggy *f, IggyUTF16 const *name, S32 len); +RADEXPFUNC IggyName RADEXPLINK IggyPlayerCreateFastNameUTF8(Iggy *f, char const *name, S32 len); +RADEXPFUNC IggyResult RADEXPLINK IggyPlayerCallFunctionRS(Iggy *player, IggyDataValue *result, IggyName function, S32 numargs, IggyDataValue *args); +RADEXPFUNC IggyResult RADEXPLINK IggyPlayerCallMethodRS(Iggy *f, IggyDataValue *result, IggyValuePath *target, IggyName methodname, S32 numargs, IggyDataValue *args); +RADEXPFUNC void RADEXPLINK IggyPlayerGarbageCollect(Iggy *player, S32 strength); + +#define IGGY_GC_MINIMAL 0 +#define IGGY_GC_NORMAL 30 +#define IGGY_GC_MAXIMAL 100 + +typedef struct +{ + U32 young_heap_size; // the size of the young heap is the smaller of this number and the size the young heap was originally allocated when the Iggy was created + U32 base_old_amount; // the base number of words to process on each minor cycle, default 200 + F32 old_heap_fraction; // the fraction 0..1 (default 0.125) of the outstanding allocations from the last major GC cycle to traverse during one GC cycle + F32 new_allocation_multiplier; // a number from 1..infinity (default 2) which is the amount of the allocations in the last cycle to traverse + F32 sweep_multiplier; // a positive number (default 2) which weights the amount of data swept vs marked +} IggyGarbageCollectorControl; + +typedef enum +{ + IGGY_GC_EVENT_tenure, + IGGY_GC_EVENT_mark_increment, + IGGY_GC_EVENT_mark_roots, + IGGY_GC_EVENT_sweep_finalize, + IGGY_GC_EVENT_sweep_increment, + IGGY_GC_WARNING_greylist_overflow, // the grey list overflowed, increase the size of $(IggyPlayerGCSizes::greylist_size_in_bytes). + IGGY_GC_WARNING_remembered_overflow, // the remembered set overflowed, increase the size of $(IggyPlayerGCSizes::remembered_set_size_in_bytes). +} IggyGarbageCollectionEvent; + +typedef struct +{ + U64 event_time_in_microseconds; + U64 total_marked_bytes; // total bytes ever marked by the GC + U64 total_swept_bytes; // total bytes ever swept by the GC + U64 total_allocated_bytes; // total bytes ever allocated from the old heap + U64 total_gc_time_in_microseconds; // total time spent in GC while notify callback was active + + char *name; + + IggyGarbageCollectionEvent event; // the type of garbage collection event that was just performed + + U32 increment_processing_bytes; // the number of bytes that were processed in that event + + U32 last_slice_tenured_bytes; // the number of bytes that were tenured from young-to-old heap since the previous GC step + U32 last_slice_old_allocation_bytes; // the number of bytes that were tenured or were directly allocated from the old heap since the previous GC step + + U32 heap_used_bytes; // the number of bytes in use in the old heap (the young heap is empty) + U32 heap_size_bytes; // the number of bytes allocated for the old heap + + U32 onstage_display_objects; // the number of on-stage display objects (MovieClips, TextFields, Shapes, etc) visited during tenuring only + U32 offstage_display_objects; // the number of off-stage display objects visited during tenuring only +} IggyGarbageCollectionInfo; + +typedef void RADLINK Iggy_GarbageCollectionCallback(Iggy *player, IggyGarbageCollectionInfo *info); +RADEXPFUNC void RADEXPLINK IggyPlayerConfigureGCBehavior(Iggy *player, Iggy_GarbageCollectionCallback *notify_callack, IggyGarbageCollectorControl *control); +RADEXPFUNC void RADEXPLINK IggyPlayerQueryGCSizes(Iggy *player, IggyPlayerGCSizes *sizes); + +RADEXPFUNC rrbool RADEXPLINK IggyPlayerGetValid(Iggy *f); + +IDOCN struct IggyValuePath +{ + Iggy *f; + IggyValuePath *parent; + //align 0 mod 8 + IggyName name; + IggyValueRef ref; + //align 0 mod 8 + S32 index; + S32 type; + //align 0 mod 8 +}; + +typedef enum +{ + IGGY_ValueRef, + IGGY_ValueRef_Weak, +} IggyValueRefType; + +RADEXPFUNC rrbool RADEXPLINK IggyValueRefCheck(IggyValueRef ref); +RADEXPFUNC void RADEXPLINK IggyValueRefFree(Iggy *p, IggyValueRef ref); +RADEXPFUNC IggyValueRef RADEXPLINK IggyValueRefFromPath(IggyValuePath *var, IggyValueRefType reftype); +RADEXPFUNC rrbool RADEXPLINK IggyIsValueRefSameObjectAsTempRef(IggyValueRef value_ref, IggyTempRef temp_ref); +RADEXPFUNC rrbool RADEXPLINK IggyIsValueRefSameObjectAsValuePath(IggyValueRef value_ref, IggyValuePath *path, IggyName sub_name, char const *sub_name_utf8); +RADEXPFUNC void RADEXPLINK IggySetValueRefLimit(Iggy *f, S32 max_value_refs); +RADEXPFUNC S32 RADEXPLINK IggyDebugGetNumValueRef(Iggy *f); +RADEXPFUNC IggyValueRef RADEXPLINK IggyValueRefCreateArray(Iggy *f, S32 num_slots); +RADEXPFUNC IggyValueRef RADEXPLINK IggyValueRefCreateEmptyObject(Iggy *f); +RADEXPFUNC IggyValueRef RADEXPLINK IggyValueRefFromTempRef(Iggy *f, IggyTempRef temp_ref, IggyValueRefType reftype); + +RADEXPFUNC IggyValuePath * RADEXPLINK IggyPlayerRootPath(Iggy *f); +RADEXPFUNC IggyValuePath * RADEXPLINK IggyPlayerCallbackResultPath(Iggy *f); +RADEXPFUNC rrbool RADEXPLINK IggyValuePathMakeNameRef(IggyValuePath *result, IggyValuePath *parent, char const *text_utf8); +RADEXPFUNC void RADEXPLINK IggyValuePathFromRef(IggyValuePath *result, Iggy *iggy, IggyValueRef ref); + +RADEXPFUNC void RADEXPLINK IggyValuePathMakeNameRefFast(IggyValuePath *result, IggyValuePath *parent, IggyName name); +RADEXPFUNC void RADEXPLINK IggyValuePathMakeArrayRef(IggyValuePath *result, IggyValuePath *array_path, int array_index); + +RADEXPFUNC void RADEXPLINK IggyValuePathSetParent(IggyValuePath *result, IggyValuePath *new_parent); +RADEXPFUNC void RADEXPLINK IggyValuePathSetArrayIndex(IggyValuePath *result, int new_index); + +RADEXPFUNC void RADEXPLINK IggyValuePathSetName(IggyValuePath *result, IggyName name); +RADEXPFUNC IggyResult RADEXPLINK IggyValueGetTypeRS(IggyValuePath *var, IggyName sub_name, char const *sub_name_utf8, IggyDatatype *result); + +RADEXPFUNC IggyResult RADEXPLINK IggyValueGetF64RS(IggyValuePath *var, IggyName sub_name, char const *sub_name_utf8, F64 *result); +RADEXPFUNC IggyResult RADEXPLINK IggyValueGetF32RS(IggyValuePath *var, IggyName sub_name, char const *sub_name_utf8, F32 *result); +RADEXPFUNC IggyResult RADEXPLINK IggyValueGetS32RS(IggyValuePath *var, IggyName sub_name, char const *sub_name_utf8, S32 *result); +RADEXPFUNC IggyResult RADEXPLINK IggyValueGetU32RS(IggyValuePath *var, IggyName sub_name, char const *sub_name_utf8, U32 *result); +RADEXPFUNC IggyResult RADEXPLINK IggyValueGetStringUTF8RS(IggyValuePath *var, IggyName sub_name, char const *sub_name_utf8, S32 max_result_len, char *utf8_result, S32 *result_len); +RADEXPFUNC IggyResult RADEXPLINK IggyValueGetStringUTF16RS(IggyValuePath *var, IggyName sub_name, char const *sub_name_utf8, S32 max_result_len, IggyUTF16 *utf16_result, S32 *result_len); +RADEXPFUNC IggyResult RADEXPLINK IggyValueGetBooleanRS(IggyValuePath *var, IggyName sub_name, char const *sub_name_utf8, rrbool *result); +RADEXPFUNC IggyResult RADEXPLINK IggyValueGetArrayLengthRS(IggyValuePath *var, IggyName sub_name, char const *sub_name_utf8, S32 *result); + +RADEXPFUNC rrbool RADEXPLINK IggyValueSetF64RS(IggyValuePath *var, IggyName sub_name, char const *sub_name_utf8, F64 value); +RADEXPFUNC rrbool RADEXPLINK IggyValueSetF32RS(IggyValuePath *var, IggyName sub_name, char const *sub_name_utf8, F32 value); +RADEXPFUNC rrbool RADEXPLINK IggyValueSetS32RS(IggyValuePath *var, IggyName sub_name, char const *sub_name_utf8, S32 value); +RADEXPFUNC rrbool RADEXPLINK IggyValueSetU32RS(IggyValuePath *var, IggyName sub_name, char const *sub_name_utf8, U32 value); +RADEXPFUNC rrbool RADEXPLINK IggyValueSetStringUTF8RS(IggyValuePath *var, IggyName sub_name, char const *sub_name_utf8, char const *utf8_string, S32 stringlen); +RADEXPFUNC rrbool RADEXPLINK IggyValueSetStringUTF16RS(IggyValuePath *var, IggyName sub_name, char const *sub_name_utf8, IggyUTF16 const *utf16_string, S32 stringlen); +RADEXPFUNC rrbool RADEXPLINK IggyValueSetBooleanRS(IggyValuePath *var, IggyName sub_name, char const *sub_name_utf8, rrbool value); +RADEXPFUNC rrbool RADEXPLINK IggyValueSetValueRefRS(IggyValuePath *var, IggyName sub_name, char const *sub_name_utf8, IggyValueRef value_ref); + +RADEXPFUNC rrbool RADEXPLINK IggyValueSetUserDataRS(IggyValuePath *result, void const *userdata); +RADEXPFUNC IggyResult RADEXPLINK IggyValueGetUserDataRS(IggyValuePath *result, void **userdata); + + +//////////////////////////////////////////////////////////// +// +// Input Events +// + +typedef enum IggyEventType +{ + IGGY_EVENTTYPE_None, + IGGY_EVENTTYPE_MouseLeftDown, + IGGY_EVENTTYPE_MouseLeftUp, + IGGY_EVENTTYPE_MouseRightDown, + IGGY_EVENTTYPE_MouseRightUp, + IGGY_EVENTTYPE_MouseMiddleDown, + IGGY_EVENTTYPE_MouseMiddleUp, + IGGY_EVENTTYPE_MouseMove, + IGGY_EVENTTYPE_MouseWheel, + IGGY_EVENTTYPE_KeyUp, + IGGY_EVENTTYPE_KeyDown, + IGGY_EVENTTYPE_Char, + IGGY_EVENTTYPE_Activate, + IGGY_EVENTTYPE_Deactivate, + IGGY_EVENTTYPE_Resize, + IGGY_EVENTTYPE_MouseLeave, + IGGY_EVENTTYPE_FocusLost, +} IggyEventType; + +typedef enum IggyKeyloc +{ + IGGY_KEYLOC_Standard = 0, // For keys that have no variants + // TODO(casey): Shouldn't these work for ALT and CONTROL too? The code in D3DTEST looks like it only handles VK_SHIFT... + IGGY_KEYLOC_Left = 1, // Specifies the left-hand-side key for keys with left/right variants (such as $(IggyKeycode::IGGY_KEYCODE_SHIFT), $(IggyKeycode::IGGY_KEYCODE_ALTERNATE), etc.) */ + IGGY_KEYLOC_Right = 2, // Specifies the right-hand-side key for keys with left/right variants (such as $(IggyKeycode::IGGY_KEYCODE_SHIFT), $(IggyKeycode::IGGY_KEYCODE_ALTERNATE), etc.) */ + IGGY_KEYLOC_Numpad = 3, // TODO(casey): Is this ever used? +} IggyKeyloc; + +typedef enum IggyKeyevent +{ + IGGY_KEYEVENT_Up = IGGY_EVENTTYPE_KeyUp, + IGGY_KEYEVENT_Down = IGGY_EVENTTYPE_KeyDown, +} IggyKeyevent; + +typedef enum IggyMousebutton +{ + IGGY_MOUSEBUTTON_LeftDown = IGGY_EVENTTYPE_MouseLeftDown, + IGGY_MOUSEBUTTON_LeftUp = IGGY_EVENTTYPE_MouseLeftUp, + IGGY_MOUSEBUTTON_RightDown = IGGY_EVENTTYPE_MouseRightDown, + IGGY_MOUSEBUTTON_RightUp = IGGY_EVENTTYPE_MouseRightUp, + IGGY_MOUSEBUTTON_MiddleDown = IGGY_EVENTTYPE_MouseMiddleDown, + IGGY_MOUSEBUTTON_MiddleUp = IGGY_EVENTTYPE_MouseMiddleUp, +} IggyMousebutton; + +typedef enum IggyActivestate +{ + IGGY_ACTIVESTATE_Activated = IGGY_EVENTTYPE_Activate, + IGGY_ACTIVESTATE_Deactivated = IGGY_EVENTTYPE_Deactivate, +} IggyActivestate; + +typedef enum IggyKeycode +{ + IGGY_KEYCODE_A = 65, + IGGY_KEYCODE_B = 66, + IGGY_KEYCODE_C = 67, + IGGY_KEYCODE_D = 68, + IGGY_KEYCODE_E = 69, + IGGY_KEYCODE_F = 70, + IGGY_KEYCODE_G = 71, + IGGY_KEYCODE_H = 72, + IGGY_KEYCODE_I = 73, + IGGY_KEYCODE_J = 74, + IGGY_KEYCODE_K = 75, + IGGY_KEYCODE_L = 76, + IGGY_KEYCODE_M = 77, + IGGY_KEYCODE_N = 78, + IGGY_KEYCODE_O = 79, + IGGY_KEYCODE_P = 80, + IGGY_KEYCODE_Q = 81, + IGGY_KEYCODE_R = 82, + IGGY_KEYCODE_S = 83, + IGGY_KEYCODE_T = 84, + IGGY_KEYCODE_U = 85, + IGGY_KEYCODE_V = 86, + IGGY_KEYCODE_W = 87, + IGGY_KEYCODE_X = 88, + IGGY_KEYCODE_Y = 89, + IGGY_KEYCODE_Z = 90, + + IGGY_KEYCODE_0 = 48, + IGGY_KEYCODE_1 = 49, + IGGY_KEYCODE_2 = 50, + IGGY_KEYCODE_3 = 51, + IGGY_KEYCODE_4 = 52, + IGGY_KEYCODE_5 = 53, + IGGY_KEYCODE_6 = 54, + IGGY_KEYCODE_7 = 55, + IGGY_KEYCODE_8 = 56, + IGGY_KEYCODE_9 = 57, + + IGGY_KEYCODE_F1 = 112, + IGGY_KEYCODE_F2 = 113, + IGGY_KEYCODE_F3 = 114, + IGGY_KEYCODE_F4 = 115, + IGGY_KEYCODE_F5 = 116, + IGGY_KEYCODE_F6 = 117, + IGGY_KEYCODE_F7 = 118, + IGGY_KEYCODE_F8 = 119, + IGGY_KEYCODE_F9 = 120, + IGGY_KEYCODE_F10 = 121, + IGGY_KEYCODE_F11 = 122, + IGGY_KEYCODE_F12 = 123, + IGGY_KEYCODE_F13 = 124, + IGGY_KEYCODE_F14 = 125, + IGGY_KEYCODE_F15 = 126, + + IGGY_KEYCODE_COMMAND = 15, + IGGY_KEYCODE_SHIFT = 16, + IGGY_KEYCODE_CONTROL = 17, + IGGY_KEYCODE_ALTERNATE = 18, + + IGGY_KEYCODE_BACKQUOTE = 192, + IGGY_KEYCODE_BACKSLASH = 220, + IGGY_KEYCODE_BACKSPACE = 8, + IGGY_KEYCODE_CAPS_LOCK = 20, + IGGY_KEYCODE_COMMA = 188, + IGGY_KEYCODE_DELETE = 46, + IGGY_KEYCODE_DOWN = 40, + IGGY_KEYCODE_END = 35, + IGGY_KEYCODE_ENTER = 13, + IGGY_KEYCODE_EQUAL = 187, + IGGY_KEYCODE_ESCAPE = 27, + IGGY_KEYCODE_HOME = 36, + IGGY_KEYCODE_INSERT = 45, + IGGY_KEYCODE_LEFT = 37, + IGGY_KEYCODE_LEFTBRACKET = 219, + IGGY_KEYCODE_MINUS = 189, + IGGY_KEYCODE_NUMPAD = 21, + IGGY_KEYCODE_NUMPAD_0 = 96, + IGGY_KEYCODE_NUMPAD_1 = 97, + IGGY_KEYCODE_NUMPAD_2 = 98, + IGGY_KEYCODE_NUMPAD_3 = 99, + IGGY_KEYCODE_NUMPAD_4 = 100, + IGGY_KEYCODE_NUMPAD_5 = 101, + IGGY_KEYCODE_NUMPAD_6 = 102, + IGGY_KEYCODE_NUMPAD_7 = 103, + IGGY_KEYCODE_NUMPAD_8 = 104, + IGGY_KEYCODE_NUMPAD_9 = 105, + IGGY_KEYCODE_NUMPAD_ADD = 107, + IGGY_KEYCODE_NUMPAD_DECIMAL = 110, + IGGY_KEYCODE_NUMPAD_DIVIDE = 111, + IGGY_KEYCODE_NUMPAD_ENTER = 108, + IGGY_KEYCODE_NUMPAD_MULTIPLY = 106, + IGGY_KEYCODE_NUMPAD_SUBTRACT = 109, + IGGY_KEYCODE_PAGE_DOWN = 34, + IGGY_KEYCODE_PAGE_UP = 33, + IGGY_KEYCODE_PERIOD = 190, + IGGY_KEYCODE_QUOTE = 222, + IGGY_KEYCODE_RIGHT = 39, + IGGY_KEYCODE_RIGHTBRACKET = 221, + IGGY_KEYCODE_SEMICOLON = 186, + IGGY_KEYCODE_SLASH = 191, + IGGY_KEYCODE_SPACE = 32, + IGGY_KEYCODE_TAB = 9, + IGGY_KEYCODE_UP = 38, +} IggyKeycode; + +typedef enum IggyEventFlag +{ + IGGY_EVENTFLAG_PreventDispatchToObject = 0x1, + IGGY_EVENTFLAG_PreventFocusTabbing = 0x2, + IGGY_EVENTFLAG_PreventDefault = 0x4, + IGGY_EVENTFLAG_RanAtLeastOneHandler = 0x8, +} IggyEventFlag; + +typedef struct IggyEvent +{ + S32 type; // an $IggyEventType + U32 flags; + S32 x,y; // mouse position at time of event + S32 keycode,keyloc; // keyboard inputs +} IggyEvent; + +typedef enum IggyFocusChange +{ + IGGY_FOCUS_CHANGE_None, // The keyboard focus didn't change + IGGY_FOCUS_CHANGE_TookFocus, // The keyboard focus changed to something in this Iggy + IGGY_FOCUS_CHANGE_LostFocus, // The keyboard focus was lost from this Iggy +} IggyFocusChange; + +typedef struct IggyEventResult +{ + U32 new_flags; + S32 focus_change; // an $IggyFocusChange that indicates how the focus (may have) changed in response to the event + S32 focus_direction; // +} IggyEventResult; + +RADEXPFUNC void RADEXPLINK IggyMakeEventNone(IggyEvent *event); + +RADEXPFUNC void RADEXPLINK IggyMakeEventResize(IggyEvent *event); +RADEXPFUNC void RADEXPLINK IggyMakeEventActivate(IggyEvent *event, IggyActivestate event_type); +RADEXPFUNC void RADEXPLINK IggyMakeEventMouseLeave(IggyEvent *event); +RADEXPFUNC void RADEXPLINK IggyMakeEventMouseMove(IggyEvent *event, S32 x, S32 y); +RADEXPFUNC void RADEXPLINK IggyMakeEventMouseButton(IggyEvent *event, IggyMousebutton event_type); +RADEXPFUNC void RADEXPLINK IggyMakeEventMouseWheel(IggyEvent *event, S16 mousewheel_delta); +RADEXPFUNC void RADEXPLINK IggyMakeEventKey(IggyEvent *event, IggyKeyevent event_type, IggyKeycode keycode, IggyKeyloc keyloc); +RADEXPFUNC void RADEXPLINK IggyMakeEventChar(IggyEvent *event, S32 charcode); +RADEXPFUNC void RADEXPLINK IggyMakeEventFocusLost(IggyEvent *event); +RADEXPFUNC void RADEXPLINK IggyMakeEventFocusGained(IggyEvent *event, S32 focus_direction); +RADEXPFUNC rrbool RADEXPLINK IggyPlayerDispatchEventRS(Iggy *player, IggyEvent *event, IggyEventResult *result); +RADEXPFUNC void RADEXPLINK IggyPlayerSetShiftState(Iggy *f, rrbool shift, rrbool control, rrbool alt, rrbool command); +RADEXPFUNC void RADEXPLINK IggySetDoubleClickTime(S32 time_in_ms_from_first_down_to_second_up); +RADEXPFUNC void RADEXPLINK IggySetTextCursorFlash(U32 cycle_time_in_ms, U32 visible_time_in_ms); + +RADEXPFUNC rrbool RADEXPLINK IggyPlayerHasFocusedEditableTextfield(Iggy *f); +RADEXPFUNC rrbool RADEXPLINK IggyPlayerPasteUTF16(Iggy *f, U16 *string, S32 stringlen); +RADEXPFUNC rrbool RADEXPLINK IggyPlayerPasteUTF8(Iggy *f, char *string, S32 stringlen); +RADEXPFUNC rrbool RADEXPLINK IggyPlayerCut(Iggy *f); + +#define IGGY_PLAYER_COPY_no_focused_textfield -1 +#define IGGY_PLAYER_COPY_textfield_has_no_selection 0 +RADEXPFUNC S32 RADEXPLINK IggyPlayerCopyUTF16(Iggy *f, U16 *buffer, S32 bufferlen); +RADEXPFUNC S32 RADEXPLINK IggyPlayerCopyUTF8(Iggy *f, char *buffer, S32 bufferlen); + + +//////////////////////////////////////////////////////////// +// +// IME +// + +#ifdef __RADNT__ +#define IGGY_IME_SUPPORT +#endif + +RADEXPFUNC void RADEXPLINK IggyPlayerSetIMEFontUTF8(Iggy *f, const char *font_name_utf8, S32 namelen_in_bytes); +RADEXPFUNC void RADEXPLINK IggyPlayerSetIMEFontUTF16(Iggy *f, const IggyUTF16 *font_name_utf16, S32 namelen_in_2byte_words); + +#ifdef IGGY_IME_SUPPORT + +#define IGGY_IME_MAX_CANDIDATE_LENGTH 256 // matches def in ImeUi.cpp, so no overflow checks needed when copying out. + +IDOCN typedef enum { + IGGY_IME_COMPOSITION_STYLE_NONE, + IGGY_IME_COMPOSITION_STYLE_UNDERLINE_DOTTED, + IGGY_IME_COMPOSITION_STYLE_UNDERLINE_DOTTED_THICK, + IGGY_IME_COMPOSITION_STYLE_UNDERLINE_SOLID, + IGGY_IME_COMPOSITION_STYLE_UNDERLINE_SOLID_THICK, +} IggyIMECompositionDrawStyle; + +IDOCN typedef enum { + IGGY_IME_COMPOSITION_CLAUSE_NORMAL, + IGGY_IME_COMPOSITION_CLAUSE_START, +} IggyIMECompositionClauseState; + +IDOCN typedef struct +{ + IggyUTF16 str[IGGY_IME_MAX_CANDIDATE_LENGTH]; + IggyIMECompositionDrawStyle char_style[IGGY_IME_MAX_CANDIDATE_LENGTH]; + IggyIMECompositionClauseState clause_state[IGGY_IME_MAX_CANDIDATE_LENGTH]; + S32 cursor_pos; + rrbool display_block_cursor; + int candicate_clause_start_pos; + int candicate_clause_end_pos; // inclusive +} IggyIMECompostitionStringState; + +IDOCN RADEXPFUNC void RADEXPLINK IggyIMEWin32SetCompositionState(Iggy* f, IggyIMECompostitionStringState* s); + +IDOCN RADEXPFUNC void RADEXPLINK IggyIMEGetTextExtents(Iggy* f, U32* pdw, U32* pdh, const IggyUTF16* str, U32 text_height); +IDOCN RADEXPFUNC void RADEXPLINK IggyIMEDrawString(Iggy* f, S32 px, S32 py, const IggyUTF16* str, U32 text_height, const U8 rgba[4]); + +IDOCN RADEXPFUNC void RADEXPLINK IggyIMEWin32GetCandidatePosition(Iggy* f, F32* pdx, F32* pdy, F32* pdcomp_str_height); +IDOCN RADEXPFUNC void* RADEXPLINK IggyIMEGetFocusedTextfield(Iggy* f); +IDOCN RADEXPFUNC void RADEXPLINK IggyIMEDrawRect(S32 x0, S32 y0, S32 x1, S32 y1, const U8 rgb[3]); + +#endif + +//////////////////////////////////////////////////////////// +// +// Input focus handling +// + +typedef void *IggyFocusHandle; + +#define IGGY_FOCUS_NULL 0 + +typedef struct +{ + IggyFocusHandle object; // unique identifier of Iggy object + F32 x0, y0, x1, y1; // bounding box of displayed shape +} IggyFocusableObject; + +RADEXPFUNC rrbool RADEXPLINK IggyPlayerGetFocusableObjects(Iggy *f, IggyFocusHandle *current_focus, + IggyFocusableObject *objs, S32 max_obj, S32 *num_obj); +RADEXPFUNC void RADEXPLINK IggyPlayerSetFocusRS(Iggy *f, IggyFocusHandle object, int focus_key_char); + +//////////////////////////////////////////////////////////// +// +// GDraw helper functions accessors +// + +RADEXPFUNC void * RADEXPLINK IggyGDrawMalloc(SINTa size); +#define IggyGDrawMalloc(size) IggyGDrawMallocAnnotated(size, __FILE__, __LINE__) IDOCN +IDOCN RADEXPFUNC void * RADEXPLINK IggyGDrawMallocAnnotated(SINTa size, const char *file, int line); + +RADEXPFUNC void RADEXPLINK IggyGDrawFree(void *ptr); +RADEXPFUNC void RADEXPLINK IggyGDrawSendWarning(Iggy *f, char const *message, ...); +RADEXPFUNC void RADEXPLINK IggyWaitOnFence(void *id, U32 fence); +RADEXPFUNC void RADEXPLINK IggyDiscardVertexBufferCallback(void *owner, void *vertex_buffer); +RADEXPFUNC void RADEXPLINK IggyPlayerDebugEnableFilters(Iggy *f, rrbool enable); +RADEXPFUNC void RADEXPLINK IggyPlayerDebugSetTime(Iggy *f, F64 time); + +IDOCN RADEXPFUNC void RADEXPLINK IggyPlayerDebugBatchStartFrame(void); +IDOCN RADEXPFUNC void RADEXPLINK IggyPlayerDebugBatchInit(void); +IDOCN RADEXPFUNC void RADEXPLINK IggyPlayerDebugBatchMove(S32 dir); +IDOCN RADEXPFUNC void RADEXPLINK IggyPlayerDebugBatchSplit(void); +IDOCN RADEXPFUNC void RADEXPLINK IggyPlayerDebugBatchChooseEnd(S32 end); + +//////////////////////////////////////////////////////////// +// +// debugging +// + +IDOCN RADEXPFUNC void RADEXPLINK IggyPlayerDebugUpdateReadyToTickWithFakeRender(Iggy *f); +IDOCN RADEXPFUNC void RADEXPLINK IggyDebugBreakOnAS3Exception(void); + + +typedef struct +{ + S32 size; + char *source_file; + S32 source_line; + char *iggy_file; + char *info; +} IggyLeakResultData; + +typedef void RADLINK IggyLeakResultCallback(IggyLeakResultData *data); + +typedef struct +{ + char *subcategory; + S32 subcategory_stringlen; + + S32 static_allocation_count; // number of non-freeable allocations for this subcategory + S32 static_allocation_bytes; // bytes of non-freeable allocations for this subcategory + + S32 dynamic_allocation_count; // number of freeable allocations for this subcategory + S32 dynamic_allocation_bytes; // estimated bytes of freeable allocations for this subcategory +} IggyMemoryUseInfo; + +RADEXPFUNC rrbool RADEXPLINK IggyDebugGetMemoryUseInfo(Iggy *player, IggyLibrary lib, char const *category_string, S32 category_stringlen, S32 iteration, IggyMemoryUseInfo *data); +RADEXPFUNC void RADEXPLINK IggyDebugSetLeakResultCallback(IggyLeakResultCallback *leak_result_func); + +IDOCN RADEXPFUNC void RADEXPLINK iggy_sync_check_todisk(char *filename_or_null, U32 flags); +IDOCN RADEXPFUNC void RADEXPLINK iggy_sync_check_fromdisk(char *filename_or_null, U32 flags); +IDOCN RADEXPFUNC void RADEXPLINK iggy_sync_check_end(void); +#define IGGY_SYNCCHECK_readytotick 1U IDOCN + +RADDEFEND + +#endif diff --git a/Minecraft.Client/Windows64/Iggy/include/iggyexpruntime.h b/Minecraft.Client/Windows64/Iggy/include/iggyexpruntime.h new file mode 100644 index 00000000..1f1a90a1 --- /dev/null +++ b/Minecraft.Client/Windows64/Iggy/include/iggyexpruntime.h @@ -0,0 +1,49 @@ +#ifndef __RAD_INCLUDE_IGGYEXPRUNTIME_H__ +#define __RAD_INCLUDE_IGGYEXPRUNTIME_H__ + +#include "rrCore.h" + +#define IDOC + +RADDEFSTART + +#ifndef __RAD_HIGGYEXP_ +#define __RAD_HIGGYEXP_ +typedef void * HIGGYEXP; +#endif + +//idoc(parent,IggyExpRuntime_API) + +#define IGGYEXP_MIN_STORAGE 1024 IDOC +/* The minimum-sized block you must provide to $IggyExpCreate */ + +IDOC RADEXPFUNC HIGGYEXP RADEXPLINK IggyExpCreate(char *ip_address, S32 port, void *storage, S32 storage_size_in_bytes); +/* Opens a connection to $IggyExplorer and returns an $HIGGYEXP wrapping the connection. + + $:ip_address The address of the machine running Iggy Explorer (can be numeric with dots, or textual, including "localhost") + $:port The port number on which Iggy Explorer is listening for a network connection (the default is 9190) + $:storage A small block of storage that needed to store the $HIGGYEXP, must be at least $IGGYEXP_MIN_STORAGE + $:storage_size_in_bytes The size of the block pointer to by storage + +Returns a NULL HIGGYEXP if the IP address/hostname can't be resolved, or no Iggy Explorer +can be contacted at the specified address/port. Otherwise returns a non-NULL $HIGGYEXP +which you can pass to $IggyUseExplorer. */ + +IDOC RADEXPFUNC void RADEXPLINK IggyExpDestroy(HIGGYEXP p); +/* Closes and destroys a connection to $IggyExplorer */ + +IDOC RADEXPFUNC rrbool RADEXPLINK IggyExpCheckValidity(HIGGYEXP p); +/* Checks if the connection represented by an $HIGGYEXP is still valid, i.e. +still connected to $IggyExplorer. + +Returns true if the connection is still valid; returns false if it is not valid. + +This might happen if someone closes Iggy Explorer, Iggy Explorer crashes, or +the network fails. You can this to poll and detect these conditions and do +something in response, such as trying to open a new connection. + +An invalid $HIGGYEXP must still be shutdown with $IggyExpDestroy. */ + +RADDEFEND + +#endif//__RAD_INCLUDE_IGGYEXPRUNTIME_H__ \ No newline at end of file diff --git a/Minecraft.Client/Windows64/Iggy/include/iggyperfmon.h b/Minecraft.Client/Windows64/Iggy/include/iggyperfmon.h new file mode 100644 index 00000000..85b84b60 --- /dev/null +++ b/Minecraft.Client/Windows64/Iggy/include/iggyperfmon.h @@ -0,0 +1,89 @@ +// $$COPYRIGHT$$ + +#ifndef __RAD_INCLUDE_IGGYPERFMON_H__ +#define __RAD_INCLUDE_IGGYPERFMON_H__ + +#include "rrCore.h" + +#define IDOC + +RADDEFSTART + +#ifndef __RAD_HIGGYPERFMON_ +#define __RAD_HIGGYPERFMON_ +typedef void * HIGGYPERFMON; +#endif + +//idoc(parent,IggyPerfmon_API) + +typedef void * RADLINK iggyperfmon_malloc(void *handle, U32 size); +typedef void RADLINK iggyperfmon_free(void *handle, void *ptr); + +IDOC RADEXPFUNC HIGGYPERFMON RADEXPLINK IggyPerfmonCreate(iggyperfmon_malloc *perf_malloc, iggyperfmon_free *perf_free, void *callback_handle); +/* Creates an IggyPerfmon. + +You must supply allocator functions. The amount allocated depends on the complexity +of the Iggys being profiled. */ + +typedef struct Iggy Iggy; +typedef struct GDrawFunctions GDrawFunctions; + +IDOC typedef union { + U32 bits; + struct { + U32 dpad_up :1; + U32 dpad_down :1; + U32 dpad_left :1; + U32 dpad_right :1; + U32 button_up :1; // XBox Y, PS3 tri + U32 button_down :1; // XBox A, PS3 X + U32 button_left :1; // XBox X, PS3 square + U32 button_right :1; // XBox B, PS3 circle + U32 shoulder_left_hi :1; // LB/L1 + U32 shoulder_right_hi :1; // RB/R1 + U32 trigger_left_low :1; + U32 trigger_right_low :1; + } field; +} IggyPerfmonPad; + +#define IggyPerfmonPadFromXInputStatePointer(pad, xis) \ + (pad).bits = 0, \ + (pad).field.dpad_up = 0 != ((xis)->Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_UP), \ + (pad).field.dpad_down = 0 != ((xis)->Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_DOWN), \ + (pad).field.dpad_left = 0 != ((xis)->Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_LEFT), \ + (pad).field.dpad_right = 0 != ((xis)->Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_RIGHT), \ + (pad).field.button_up = 0 != ((xis)->Gamepad.wButtons & XINPUT_GAMEPAD_Y), \ + (pad).field.button_down = 0 != ((xis)->Gamepad.wButtons & XINPUT_GAMEPAD_A), \ + (pad).field.button_left = 0 != ((xis)->Gamepad.wButtons & XINPUT_GAMEPAD_X), \ + (pad).field.button_right = 0 != ((xis)->Gamepad.wButtons & XINPUT_GAMEPAD_B), \ + (pad).field.shoulder_left_hi = 0 != ((xis)->Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_SHOULDER), \ + (pad).field.shoulder_right_hi = 0 != ((xis)->Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_SHOULDER), \ + (pad).field.trigger_left_low = 0 != ((xis)->Gamepad.bLeftTrigger >= XINPUT_GAMEPAD_TRIGGER_THRESHOLD), \ + (pad).field.trigger_right_low = 0 != ((xis)->Gamepad.bRightTrigger >= XINPUT_GAMEPAD_TRIGGER_THRESHOLD) + +// All positions in window coords +IDOC RADEXPFUNC void RADEXPLINK IggyPerfmonTickAndDraw(HIGGYPERFMON p, GDrawFunctions* gdraw_funcs, + const IggyPerfmonPad* pad, + int pm_tile_ul_x, int pm_tile_ul_y, int pm_tile_lr_x, int pm_tile_lr_y); +/* Draw and tick an IggyPerfmon. + +$:p A perfmon context previously created with IggyPerfmonCreate +$:gdraw_functions The same GDraw handle used for rendering Iggy +$:pad An abstracted gamepad state structure. iggyperfmon.h +includes an example that initializes the abstract gamepad from a 360 controller +as defined by XInput; this will work on both Windows and the Xbox 360. +$:pm_tile_ul_x The left coordinate of the rectangle where the perfmon display should be drawn +$:pm_tile_ul_y The top coordinate of the rectangle where the perfmon display should be drawn +$:pm_tile_lr_x The right coordinate of the rectangle where the perfmon display should be drawn +$:pm_tile_lr_y The bottom coordinate of the rectangle where the perfmon display should be drawn + +You should only call this function when you want Iggy Perfmon to be visible. +See $IggyPerfmon for more information. */ + +IDOC RADEXPFUNC void RADEXPLINK IggyPerfmonDestroy(HIGGYPERFMON p, GDrawFunctions* iggy_draw); +/* Closes and destroys an IggyPerfmon */ + + +RADDEFEND + +#endif//__RAD_INCLUDE_IGGYPERFMON_H__ \ No newline at end of file diff --git a/Minecraft.Client/Windows64/Iggy/include/rrCore.h b/Minecraft.Client/Windows64/Iggy/include/rrCore.h new file mode 100644 index 00000000..e88b5f8c --- /dev/null +++ b/Minecraft.Client/Windows64/Iggy/include/rrCore.h @@ -0,0 +1,2322 @@ +/// ======================================================================== +// (C) Copyright 1994- 2014 RAD Game Tools, Inc. Global types header file +// ======================================================================== + +#ifndef __RADRR_COREH__ +#define __RADRR_COREH__ +#define RADCOPYRIGHT "Copyright (C) 1994-2014, RAD Game Tools, Inc." + +// __RAD16__ means 16 bit code (Win16) +// __RAD32__ means 32 bit code (DOS, Win386, Win32s, Mac AND Win64) +// __RAD64__ means 64 bit code (x64) + +// Note oddness - __RAD32__ essentially means "at *least* 32-bit code". +// So, on 64-bit systems, both __RAD32__ and __RAD64__ will be defined. + +// __RADDOS__ means DOS code (16 or 32 bit) +// __RADWIN__ means Windows API (Win16, Win386, Win32s, Win64, Xbox, Xenon) +// __RADWINEXT__ means Windows 386 extender (Win386) +// __RADNT__ means Win32 or Win64 code +// __RADWINRTAPI__ means Windows RT API (Win 8, Win Phone, ARM, Durango) +// __RADMAC__ means Macintosh +// __RADCARBON__ means Carbon +// __RADMACH__ means MachO +// __RADXBOX__ means the XBox console +// __RADXENON__ means the Xenon console +// __RADDURANGO__ or __RADXBOXONE__ means Xbox One +// __RADNGC__ means the Nintendo GameCube +// __RADWII__ means the Nintendo Wii +// __RADWIIU__ means the Nintendo Wii U +// __RADNDS__ means the Nintendo DS +// __RADTWL__ means the Nintendo DSi (__RADNDS__ also defined) +// __RAD3DS__ means the Nintendo 3DS +// __RADPS2__ means the Sony PlayStation 2 +// __RADPSP__ means the Sony PlayStation Portable +// __RADPS3__ means the Sony PlayStation 3 +// __RADPS4__ means the Sony PlayStation 4 +// __RADANDROID__ means Android NDK +// __RADNACL__ means Native Client SDK +// __RADNTBUILDLINUX__ means building Linux on NT +// __RADLINUX__ means actually building on Linux (most likely with GCC) +// __RADPSP2__ means NGP +// __RADBSD__ means a BSD-style UNIX (OS X, FreeBSD, OpenBSD, NetBSD) +// __RADPOSIX__ means POSIX-compliant +// __RADQNX__ means QNX +// __RADIPHONE__ means iphone +// __RADIPHONESIM__ means iphone simulator + +// __RADX86__ means Intel x86 +// __RADMMX__ means Intel x86 MMX instructions are allowed +// __RADX64__ means Intel/AMD x64 (NOT IA64=Itanium) +// __RAD68K__ means 68K +// __RADPPC__ means PowerPC +// __RADMIPS__ means Mips (only R5900 right now) +// __RADARM__ mean ARM processors + +// __RADLITTLEENDIAN__ means processor is little-endian (x86) +// __RADBIGENDIAN__ means processor is big-endian (680x0, PPC) + +// __RADNOVARARGMACROS__ means #defines can't use ... + + #ifdef WINAPI_FAMILY + // If this is #defined, we might be in a Windows Store App. But + // VC++ by default #defines this to a symbolic name, not an integer + // value, and those names are defined in "winapifamily.h". So if + // WINAPI_FAMILY is #defined, #include the header so we can parse it. + #include + #define RAD_WINAPI_IS_APP (!WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)) + #else + #define RAD_WINAPI_IS_APP 0 + #endif + + #ifndef __RADRES__ + // Theoretically, this is to pad structs on platforms that don't support pragma pack or do it poorly. (PS3, PS2) + // In general it is assumed that your padding is set via pragma, so this is just a struct. + #define RADSTRUCT struct + + #ifdef __GNUC_MINOR__ + // make a combined GCC version for testing : + + #define __RAD_GCC_VERSION__ (__GNUC__ * 10000 \ + + __GNUC_MINOR__ * 100 \ + + __GNUC_PATCHLEVEL__) + + /* Test for GCC > 3.2.0 */ + // #if GCC_VERSION > 30200 + #endif + + #if defined(__RADX32__) + + #define __RADX86__ + #define __RADMMX__ + #define __RAD32__ + #define __RADLITTLEENDIAN__ + #define RADINLINE inline + #define RADRESTRICT __restrict + + // known platforms under the RAD generic build type + #if defined(_WIN32) || defined(_Windows) || defined(WIN32) || defined(__WINDOWS__) || defined(_WINDOWS) + #define __RADNT__ + #define __RADWIN__ + #elif (defined(__MWERKS__) && !defined(__INTEL__)) || defined(__MRC__) || defined(THINK_C) || defined(powerc) || defined(macintosh) || defined(__powerc) || defined(__APPLE__) || defined(__MACH__) + #define __RADMAC__ + #undef RADSTRUCT + #define RADSTRUCT struct __attribute__((__packed__)) + #elif defined(__linux__) + #define __RADLINUX__ + #undef RADSTRUCT + #define RADSTRUCT struct __attribute__((__packed__)) + #endif + +#elif defined(ANDROID) + #define __RADANDROID__ + #define __RAD32__ + #define __RADLITTLEENDIAN__ + #ifdef __i386__ + #define __RADX86__ + #else + #define __RADARM__ + #endif + #define RADINLINE inline + #define RADRESTRICT __restrict + #undef RADSTRUCT + #define RADSTRUCT struct __attribute__((__packed__)) + +#elif defined(__QNX__) + #define __RAD32__ + #define __RADQNX__ + +#ifdef __arm__ + #define __RADARM__ +#elif defined __i386__ + #define __RADX86__ +#else + #error Unknown processor +#endif + #define __RADLITTLEENDIAN__ + #define RADINLINE inline + #define RADRESTRICT __restrict + + #undef RADSTRUCT + #define RADSTRUCT struct __attribute__((__packed__)) +#elif defined(__linux__) && defined(__arm__) //This should pull in Raspberry Pi as well + + #define __RAD32__ + #define __RADLINUX__ + #define __RADARM__ + #define __RADLITTLEENDIAN__ + #define RADINLINE inline + #define RADRESTRICT __restrict + + #undef RADSTRUCT + #define RADSTRUCT struct __attribute__((__packed__)) + +#elif defined(__native_client__) + #define __RADNACL__ + #define __RAD32__ + #define __RADLITTLEENDIAN__ + #define __RADX86__ + #define RADINLINE inline + #define RADRESTRICT __restrict + + #undef RADSTRUCT + #define RADSTRUCT struct __attribute__((__packed__)) + + #elif defined(_DURANGO) || defined(_SEKRIT) || defined(_SEKRIT1) || defined(_XBOX_ONE) + + #define __RADDURANGO__ 1 + #define __RADXBOXONE__ 1 + #if !defined(__RADSEKRIT__) // keep sekrit around for a bit for compat + #define __RADSEKRIT__ 1 + #endif + + #define __RADWIN__ + #define __RAD32__ + #define __RAD64__ + #define __RADX64__ + #define __RADMMX__ + #define __RADX86__ + #define __RAD64REGS__ + #define __RADLITTLEENDIAN__ + #define RADINLINE __inline + #define RADRESTRICT __restrict + #define __RADWINRTAPI__ + + #elif defined(__ORBIS__) + + #define __RADPS4__ + #if !defined(__RADSEKRIT2__) // keep sekrit2 around for a bit for compat + #define __RADSEKRIT2__ 1 + #endif + #define __RAD32__ + #define __RAD64__ + #define __RADX64__ + #define __RADMMX__ + #define __RADX86__ + #define __RAD64REGS__ + #define __RADLITTLEENDIAN__ + #define RADINLINE inline + #define RADRESTRICT __restrict + + #undef RADSTRUCT + #define RADSTRUCT struct __attribute__((__packed__)) + + #elif defined(WINAPI_FAMILY) && RAD_WINAPI_IS_APP + + #define __RADWINRTAPI__ + #define __RADWIN__ + #define RADINLINE __inline + #define RADRESTRICT __restrict + + #if defined(_M_IX86) // WinRT on x86 + + #define __RAD32__ + #define __RADX86__ + #define __RADMMX__ + #define __RADLITTLEENDIAN__ + + #elif defined(_M_X64) // WinRT on x64 + #define __RAD32__ + #define __RAD64__ + #define __RADX86__ + #define __RADX64__ + #define __RADMMX__ + #define __RAD64REGS__ + #define __RADLITTLEENDIAN__ + + #elif defined(_M_ARM) // WinRT on ARM + + #define __RAD32__ + #define __RADARM__ + #define __RADLITTLEENDIAN__ + + #else + + #error Unrecognized WinRT platform! + + #endif + + #elif defined(_WIN64) + + #define __RADWIN__ + #define __RADNT__ + // See note at top for why both __RAD32__ and __RAD64__ are defined. + #define __RAD32__ + #define __RAD64__ + #define __RADX64__ + #define __RADMMX__ + #define __RADX86__ + #define __RAD64REGS__ + #define __RADLITTLEENDIAN__ + #define RADINLINE __inline + #define RADRESTRICT __restrict + + #elif defined(GENERIC_ARM) + + #define __RAD32__ + #define __RADARM__ + #define __RADLITTLEENDIAN__ + #define __RADFIXEDPOINT__ + #define RADINLINE inline + #if (defined(__GCC__) || defined(__GNUC__)) + #define RADRESTRICT __restrict + #else + #define RADRESTRICT // __restrict not supported on cw + #endif + #undef RADSTRUCT + #define RADSTRUCT struct __attribute__((__packed__)) + + #elif defined(CAFE) // has to be before HOLLYWOOD_REV since it also defines it + + #define __RADWIIU__ + #define __RAD32__ + #define __RADPPC__ + #define __RADBIGENDIAN__ + #define RADINLINE inline + #define RADRESTRICT __restrict + #undef RADSTRUCT + #define RADSTRUCT struct __attribute__((__packed__)) + + + #elif defined(HOLLYWOOD_REV) || defined(REVOLUTION) + + #define __RADWII__ + #define __RAD32__ + #define __RADPPC__ + #define __RADBIGENDIAN__ + #define RADINLINE inline + #define RADRESTRICT __restrict + + #elif defined(NN_PLATFORM_CTR) + + #define __RAD3DS__ + #define __RAD32__ + #define __RADARM__ + #define __RADLITTLEENDIAN__ + #define RADINLINE inline + #define RADRESTRICT + #undef RADSTRUCT + #define RADSTRUCT struct __attribute__((__packed__)) + + #elif defined(GEKKO) + + #define __RADNGC__ + #define __RAD32__ + #define __RADPPC__ + #define __RADBIGENDIAN__ + #define RADINLINE inline + #define RADRESTRICT // __restrict not supported on cw + + #elif defined(SDK_ARM9) || defined(SDK_TWL) || (defined(__arm) && defined(__MWERKS__)) + + #define __RADNDS__ + #define __RAD32__ + #define __RADARM__ + #define __RADLITTLEENDIAN__ + #define __RADFIXEDPOINT__ + #define RADINLINE inline + #if (defined(__GCC__) || defined(__GNUC__)) + #define RADRESTRICT __restrict + #else + #define RADRESTRICT // __restrict not supported on cw + #endif + + #if defined(SDK_TWL) + #define __RADTWL__ + #endif + + #elif defined(R5900) + + #define __RADPS2__ + #define __RAD32__ + #define __RADMIPS__ + #define __RADLITTLEENDIAN__ + #define RADINLINE inline + #define RADRESTRICT __restrict + #define __RAD64REGS__ + #define U128 u_long128 + + #if !defined(__MWERKS__) + #undef RADSTRUCT + #define RADSTRUCT struct __attribute__((__packed__)) + #endif + + #elif defined(__psp__) + + #define __RADPSP__ + #define __RAD32__ + #define __RADMIPS__ + #define __RADLITTLEENDIAN__ + #define RADINLINE inline + #define RADRESTRICT __restrict + + #undef RADSTRUCT + #define RADSTRUCT struct __attribute__((__packed__)) + + #elif defined(__psp2__) + + #undef RADSTRUCT + #define RADSTRUCT struct __attribute__((__packed__)) + + #define __RADPSP2__ + #define __RAD32__ + #define __RADARM__ + #define __RADLITTLEENDIAN__ + #define RADINLINE inline + #define RADRESTRICT __restrict + + // need packed attribute for struct with snc? + #elif defined(__CELLOS_LV2__) + + // CB change : 10-29-10 : RAD64REGS on PPU but NOT SPU + + #ifdef __SPU__ + #define __RADSPU__ + #define __RAD32__ + #define __RADCELL__ + #define __RADBIGENDIAN__ + #define RADINLINE inline + #define RADRESTRICT __restrict + #else + #define __RAD64REGS__ + #define __RADPS3__ + #define __RADPPC__ + #define __RAD32__ + #define __RADCELL__ + #define __RADBIGENDIAN__ + #define RADINLINE inline + #define RADRESTRICT __restrict + #define __RADALTIVEC__ + #endif + + #undef RADSTRUCT + #define RADSTRUCT struct __attribute__((__packed__)) + + #ifndef __LP32__ + #error "PS3 32bit ABI support only" + #endif + #elif (defined(__MWERKS__) && !defined(__INTEL__)) || defined(__MRC__) || defined(THINK_C) || defined(powerc) || defined(macintosh) || defined(__powerc) || defined(__APPLE__) || defined(__MACH__) + #ifdef __APPLE__ + #include "TargetConditionals.h" + #endif + + #if ((defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE) || (defined(TARGET_IPHONE_SIMULATOR) && TARGET_IPHONE_SIMULATOR)) + + // iPhone/iPad/iOS + #define __RADIPHONE__ + #define __RADMACAPI__ + + #define __RAD32__ + #if defined(__x86_64__) + #define __RAD64__ + #endif + + #define __RADLITTLEENDIAN__ + #define RADINLINE inline + #define RADRESTRICT __restrict + #define __RADMACH__ + + #undef RADSTRUCT + #define RADSTRUCT struct __attribute__((__packed__)) + + #if defined(TARGET_IPHONE_SIMULATOR) && TARGET_IPHONE_SIMULATOR + #if defined( __x86_64__) + #define __RADX64__ + #else + #define __RADX86__ + #endif + #define __RADIPHONESIM__ + #elif defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE + #define __RADARM__ + #endif + #else + + // An actual MacOSX machine + #define __RADMAC__ + #define __RADMACAPI__ + + #if defined(powerc) || defined(__powerc) || defined(__ppc__) + #define __RADPPC__ + #define __RADBIGENDIAN__ + #define __RADALTIVEC__ + #define RADRESTRICT + #elif defined(__i386__) + #define __RADX86__ + #define __RADMMX__ + #define __RADLITTLEENDIAN__ + #define RADRESTRICT __restrict + #elif defined(__x86_64__) + #define __RAD32__ + #define __RAD64__ + #define __RADX86__ + #define __RADX64__ + #define __RAD64REGS__ + #define __RADMMX__ + #define __RADLITTLEENDIAN__ + #define RADRESTRICT __restrict + #else + #define __RAD68K__ + #define __RADBIGENDIAN__ + #define __RADALTIVEC__ + #define RADRESTRICT + #endif + + #define __RAD32__ + + #if defined(__MWERKS__) + #if (defined(__cplusplus) || ! __option(only_std_keywords)) + #define RADINLINE inline + #endif + #ifdef __MACH__ + #define __RADMACH__ + #endif + #elif defined(__MRC__) + #if defined(__cplusplus) + #define RADINLINE inline + #endif + #elif defined(__GNUC__) || defined(__GNUG__) || defined(__MACH__) + #define RADINLINE inline + #define __RADMACH__ + + #undef RADRESTRICT /* could have been defined above... */ + #define RADRESTRICT __restrict + + #undef RADSTRUCT + #define RADSTRUCT struct __attribute__((__packed__)) + #endif + + #ifdef __RADX86__ + #ifndef __RADCARBON__ + #define __RADCARBON__ + #endif + #endif + + #ifdef TARGET_API_MAC_CARBON + #if TARGET_API_MAC_CARBON + #ifndef __RADCARBON__ + #define __RADCARBON__ + #endif + #endif + #endif + #endif + #elif defined(__linux__) + + #define __RADLINUX__ + #define __RADMMX__ + #define __RADLITTLEENDIAN__ + #define __RADX86__ + #ifdef __x86_64 + #define __RAD32__ + #define __RAD64__ + #define __RADX64__ + #define __RAD64REGS__ + #else + #define __RAD32__ + #endif + #define RADINLINE inline + #define RADRESTRICT __restrict + + #undef RADSTRUCT + #define RADSTRUCT struct __attribute__((__packed__)) + + #else + + #if _MSC_VER >= 1400 + #undef RADRESTRICT + #define RADRESTRICT __restrict + #else + #define RADRESTRICT + #define __RADNOVARARGMACROS__ + #endif + + #if defined(_XENON) || ( defined(_XBOX_VER) && (_XBOX_VER == 200) ) + // Remember that Xenon also defines _XBOX + #define __RADPPC__ + #define __RADBIGENDIAN__ + #define __RADALTIVEC__ + #else + #define __RADX86__ + #define __RADMMX__ + #define __RADLITTLEENDIAN__ + #endif + + #ifdef __MWERKS__ + #define _WIN32 + #endif + + #ifdef __DOS__ + #define __RADDOS__ + #define S64_DEFINED // turn off these types + #define U64_DEFINED + #define S64 double //should error + #define U64 double //should error + #define __RADNOVARARGMACROS__ + #endif + + #ifdef __386__ + #define __RAD32__ + #endif + + #ifdef _Windows //For Borland + #ifdef __WIN32__ + #define WIN32 + #else + #define __WINDOWS__ + #endif + #endif + + #ifdef _WINDOWS //For MS + #ifndef _WIN32 + #define __WINDOWS__ + #endif + #endif + + #ifdef _WIN32 + #if defined(_XENON) || ( defined(_XBOX_VER) && (_XBOX_VER == 200) ) + // Remember that Xenon also defines _XBOX + #define __RADXENON__ + #define __RAD64REGS__ + #elif defined(_XBOX) + #define __RADXBOX__ + #elif !defined(__RADWINRTAPI__) + #define __RADNT__ + #endif + #define __RADWIN__ + #define __RAD32__ + #else + #ifdef __NT__ + #if defined(_XENON) || (_XBOX_VER == 200) + // Remember that Xenon also defines _XBOX + #define __RADXENON__ + #define __RAD64REGS__ + #elif defined(_XBOX) + #define __RADXBOX__ + #else + #define __RADNT__ + #endif + #define __RADWIN__ + #define __RAD32__ + #else + #ifdef __WINDOWS_386__ + #define __RADWIN__ + #define __RADWINEXT__ + #define __RAD32__ + #define S64_DEFINED // turn off these types + #define U64_DEFINED + #define S64 double //should error + #define U64 double //should error + #else + #ifdef __WINDOWS__ + #define __RADWIN__ + #define __RAD16__ + #else + #ifdef WIN32 + #if defined(_XENON) || (_XBOX_VER == 200) + // Remember that Xenon also defines _XBOX + #define __RADXENON__ + #elif defined(_XBOX) + #define __RADXBOX__ + #else + #define __RADNT__ + #endif + #define __RADWIN__ + #define __RAD32__ + #endif + #endif + #endif + #endif + #endif + + #ifdef __WATCOMC__ + #define RADINLINE + #else + #define RADINLINE __inline + #endif + #endif + + #if defined __RADMAC__ || defined __RADIPHONE__ + #define __RADBSD__ + #endif + + #if defined __RADBSD__ || defined __RADLINUX__ + #define __RADPOSIX__ + #endif + + #if (!defined(__RADDOS__) && !defined(__RADWIN__) && !defined(__RADMAC__) && \ + !defined(__RADNGC__) && !defined(__RADNDS__) && !defined(__RADXBOX__) && \ + !defined(__RADXENON__) && !defined(__RADDURANGO__) && !defined(__RADPS4__) && !defined(__RADLINUX__) && !defined(__RADPS2__) && \ + !defined(__RADPSP__) && !defined(__RADPSP2__) && !defined(__RADPS3__) && !defined(__RADSPU__) && \ + !defined(__RADWII__) && !defined(__RADIPHONE__) && !defined(__RADX32__) && !defined(__RADARM__) && \ + !defined(__RADWIIU__) && !defined(__RADANDROID__) && !defined(__RADNACL__) && !defined (__RADQNX__) ) + #error "RAD.H did not detect your platform. Define DOS, WINDOWS, WIN32, macintosh, powerpc, or appropriate console." + #endif + + + #ifdef __RADFINAL__ + #define RADTODO(str) { char __str[0]=str; } + #else + #define RADTODO(str) + #endif + + #ifdef __RADX32__ + #if defined(_MSC_VER) + #define RADLINK __stdcall + #define RADEXPLINK __stdcall + #else + #define RADLINK __attribute__((stdcall)) + #define RADEXPLINK __attribute__((stdcall)) + #endif + #define RADEXPFUNC RADDEFFUNC + + #elif (defined(__RADNGC__) || defined(__RADWII__) || defined( __RADPS2__) || \ + defined(__RADPSP__) || defined(__RADPSP2__) || defined(__RADPS3__) || \ + defined(__RADSPU__) || defined(__RADNDS__) || defined(__RADIPHONE__) || \ + (defined(__RADARM__) && !defined(__RADWINRTAPI__)) || defined(__RADWIIU__) || defined(__RADPS4__) ) + + #define RADLINK + #define RADEXPLINK + #define RADEXPFUNC RADDEFFUNC + #define RADASMLINK + + #elif defined(__RADANDROID__) + #define RADLINK + #define RADEXPLINK + #define RADEXPFUNC RADDEFFUNC + #define RADASMLINK + #elif defined(__RADNACL__) + #define RADLINK + #define RADEXPLINK + #define RADEXPFUNC RADDEFFUNC + #define RADASMLINK + #elif defined(__RADLINUX__) || defined (__RADQNX__) + + #ifdef __RAD64__ + #define RADLINK + #define RADEXPLINK + #else + #define RADLINK __attribute__((cdecl)) + #define RADEXPLINK __attribute__((cdecl)) + #endif + + #define RADEXPFUNC RADDEFFUNC + #define RADASMLINK + + #elif defined(__RADMAC__) + + // this define is for CodeWarrior 11's stupid new libs (even though + // we don't use longlong's). + + #define __MSL_LONGLONG_SUPPORT__ + + #define RADLINK + #define RADEXPLINK + + #if defined(__CFM68K__) || defined(__MWERKS__) + #ifdef __RADINDLL__ + #define RADEXPFUNC RADDEFFUNC __declspec(export) + #else + #define RADEXPFUNC RADDEFFUNC __declspec(import) + #endif + #else + #if defined(__RADMACH__) && !defined(__MWERKS__) + #ifdef __RADINDLL__ + #define RADEXPFUNC RADDEFFUNC __attribute__((visibility("default"))) + #else + #define RADEXPFUNC RADDEFFUNC + #endif + #else + #define RADEXPFUNC RADDEFFUNC + #endif + #endif + #define RADASMLINK + + #else + + #ifdef __RADNT__ + #ifndef _WIN32 + #define _WIN32 + #endif + #ifndef WIN32 + #define WIN32 + #endif + #endif + + #ifdef __RADWIN__ + #ifdef __RAD32__ + + #ifdef __RADXBOX__ + + #define RADLINK __stdcall + #define RADEXPLINK __stdcall + #define RADEXPFUNC RADDEFFUNC + + #elif defined(__RADXENON__) || defined(__RADDURANGO__) + + #define RADLINK __stdcall + #define RADEXPLINK __stdcall + + #define RADEXPFUNC RADDEFFUNC + + #elif defined(__RADWINRTAPI__) + + #define RADLINK __stdcall + #define RADEXPLINK __stdcall + + #if ( defined(__RADINSTATICLIB__) || defined(__RADNOEXPORTS__ ) || ( defined(__RADNOEXEEXPORTS__) && ( !defined(__RADINDLL__) ) && ( !defined(__RADINSTATICLIB__) ) ) ) + #define RADEXPFUNC RADDEFFUNC + #else + #ifndef __RADINDLL__ + #define RADEXPFUNC RADDEFFUNC __declspec(dllimport) + #else + #define RADEXPFUNC RADDEFFUNC __declspec(dllexport) + #endif + #endif + + #elif defined(__RADNTBUILDLINUX__) + + #define RADLINK __cdecl + #define RADEXPLINK __cdecl + #define RADEXPFUNC RADDEFFUNC + + #else + #ifdef __RADNT__ + + #define RADLINK __stdcall + #define RADEXPLINK __stdcall + + #if ( defined(__RADINSTATICLIB__) || defined(__RADNOEXPORTS__ ) || ( defined(__RADNOEXEEXPORTS__) && ( !defined(__RADINDLL__) ) && ( !defined(__RADINSTATICLIB__) ) ) ) + #define RADEXPFUNC RADDEFFUNC + #else + #ifndef __RADINDLL__ + #define RADEXPFUNC RADDEFFUNC __declspec(dllimport) + #ifdef __BORLANDC__ + #if __BORLANDC__<=0x460 + #undef RADEXPFUNC + #define RADEXPFUNC RADDEFFUNC + #endif + #endif + #else + #define RADEXPFUNC RADDEFFUNC __declspec(dllexport) + #endif + #endif + #else + #define RADLINK __pascal + #define RADEXPLINK __far __pascal + #define RADEXPFUNC RADDEFFUNC + #endif + #endif + #else + #define RADLINK __pascal + #define RADEXPLINK __far __pascal __export + #define RADEXPFUNC RADDEFFUNC + #endif + #else + #define RADLINK __pascal + #define RADEXPLINK __pascal + #define RADEXPFUNC RADDEFFUNC + #endif + + #define RADASMLINK __cdecl + + #endif + + #if !defined(__RADXBOX__) && !defined(__RADXENON__) && !defined(__RADDURANGO__) && !defined(__RADXBOXONE__) + #ifdef __RADWIN__ + #ifndef _WINDOWS + #define _WINDOWS + #endif + #endif + #endif + + #ifdef __RADLITTLEENDIAN__ + #ifdef __RADBIGENDIAN__ + #error both endians !? + #endif + #endif + + #if !defined(__RADLITTLEENDIAN__) && !defined(__RADBIGENDIAN__) + #error neither endian! + #endif + + + //----------------------------------------------------------------- + + #ifndef RADDEFFUNC + + #ifdef __cplusplus + #define RADDEFFUNC extern "C" + #define RADDEFSTART extern "C" { + #define RADDEFEND } + #define RADDEFINEDATA extern "C" + #define RADDECLAREDATA extern "C" + #define RADDEFAULT( val ) =val + + #define RR_NAMESPACE rr + #define RR_NAMESPACE_START namespace RR_NAMESPACE { + #define RR_NAMESPACE_END }; + #define RR_NAMESPACE_USE using namespace RR_NAMESPACE; + + #else + #define RADDEFFUNC + #define RADDEFSTART + #define RADDEFEND + #define RADDEFINEDATA + #define RADDECLAREDATA extern + #define RADDEFAULT( val ) + + #define RR_NAMESPACE + #define RR_NAMESPACE_START + #define RR_NAMESPACE_END + #define RR_NAMESPACE_USE + + #endif + + #endif + + // probably s.b: RAD_DECLARE_ALIGNED(type, name, alignment) + #if (defined(__RADWII__) || defined(__RADWIIU__) || defined(__RADPSP__) || defined(__RADPSP2__) || \ + defined(__RADPS3__) || defined(__RADSPU__) || defined(__RADPS4__) || \ + defined(__RADLINUX__) || defined(__RADMAC__)) || defined(__RADNDS__) || defined(__RAD3DS__) || \ + defined(__RADIPHONE__) || defined(__RADANDROID__) || defined (__RADQNX__) + #define RAD_ALIGN(type,var,num) type __attribute__ ((aligned (num))) var + #elif (defined(__RADNGC__) || defined(__RADPS2__)) + #define RAD_ALIGN(type,var,num) __attribute__ ((aligned (num))) type var + #elif (defined(_MSC_VER) && (_MSC_VER >= 1300)) || defined(__RADWINRTAPI__) + #define RAD_ALIGN(type,var,num) type __declspec(align(num)) var + #else + // NOTE: / / is a guaranteed parse error in C/C++. + #define RAD_ALIGN(type,var,num) RAD_ALIGN_USED_BUT_NOT_DEFINED / / + #endif + + // WARNING : RAD_TLS should really only be used for debug/tools stuff + // it's not reliable because even if we are built as a lib, our lib can + // be put into a DLL and then it doesn't work + #if defined(__RADNT__) || defined(__RADXENON__) + #ifndef __RADINDLL__ + // note that you can't use this in windows DLLs + #define RAD_TLS(type,var) __declspec(thread) type var + #endif + #elif defined(__RADPS3__) || defined(__RADLINUX__) || defined(__RADMAC__) + // works on PS3/gcc I believe : + #define RAD_TLS(type,var) __thread type var + #else + // RAD_TLS not defined + #endif + + // Note that __RAD16__/__RAD32__/__RAD64__ refers to the size of a pointer. + // The size of integers is specified explicitly in the code, i.e. u32 or whatever. + + #define RAD_S8 signed char + #define RAD_U8 unsigned char + + #if defined(__RAD64__) + // Remember that __RAD32__ will also be defined! + #if defined(__RADX64__) + // x64 still has 32-bit ints! + #define RAD_U32 unsigned int + #define RAD_S32 signed int + // But pointers are 64 bits. + #if (_MSC_VER >= 1300 && defined(_Wp64) && _Wp64 ) + #define RAD_SINTa __w64 signed __int64 + #define RAD_UINTa __w64 unsigned __int64 + #else // non-vc.net compiler or /Wp64 turned off + #define RAD_UINTa unsigned long long + #define RAD_SINTa signed long long + #endif + #else + #error Unknown 64-bit processor (see radbase.h) + #endif + #elif defined(__RAD32__) + #define RAD_U32 unsigned int + #define RAD_S32 signed int + // Pointers are 32 bits. + + #if ( ( defined(_MSC_VER) && (_MSC_VER >= 1300 ) ) && ( defined(_Wp64) && ( _Wp64 ) ) ) + #define RAD_SINTa __w64 signed long + #define RAD_UINTa __w64 unsigned long + #else // non-vc.net compiler or /Wp64 turned off + #ifdef _Wp64 + #define RAD_SINTa signed long + #define RAD_UINTa unsigned long + #else + #define RAD_SINTa signed int + #define RAD_UINTa unsigned int + #endif + #endif + #else + #define RAD_U32 unsigned long + #define RAD_S32 signed long + // Pointers in 16-bit land are still 32 bits. + #define RAD_UINTa unsigned long + #define RAD_SINTa signed long + #endif + + #define RAD_F32 float + #if defined(__RADPS2__) || defined(__RADPSP__) + typedef RADSTRUCT RAD_F64 // do this so that we don't accidentally use doubles + { // while using the same space + RAD_U32 vals[ 2 ]; + } RAD_F64; + #define RAD_F64_OR_32 float // type is F64 if available, otherwise F32 + #else + #define RAD_F64 double + #define RAD_F64_OR_32 double // type is F64 if available, otherwise F32 + #endif + + #if (defined(__RADMAC__) || defined(__MRC__) || defined( __RADNGC__ ) || \ + defined(__RADLINUX__) || defined( __RADWII__ ) || defined(__RADWIIU__) || \ + defined(__RADNDS__) || defined(__RADPSP__) || defined(__RADPS3__) || defined(__RADPS4__) || \ + defined(__RADSPU__) || defined(__RADIPHONE__) || defined(__RADNACL__) || defined( __RADANDROID__) || defined( __RADQNX__ ) ) + #define RAD_U64 unsigned long long + #define RAD_S64 signed long long + #elif defined(__RADPS2__) + #define RAD_U64 unsigned long + #define RAD_S64 signed long + #elif defined(__RADARM__) + #define RAD_U64 unsigned long long + #define RAD_S64 signed long long + #elif defined(__RADX64__) || defined(__RAD32__) + #define RAD_U64 unsigned __int64 + #define RAD_S64 signed __int64 + #else + // 16-bit + typedef RADSTRUCT RAD_U64 // do this so that we don't accidentally use U64s + { // while using the same space + RAD_U32 vals[ 2 ]; + } RAD_U64; + typedef RADSTRUCT RAD_S64 // do this so that we don't accidentally use S64s + { // while using the same space + RAD_S32 vals[ 2 ]; + } RAD_S64; + #endif + + #if defined(__RAD32__) + #define PTR4 + #define RAD_U16 unsigned short + #define RAD_S16 signed short + #else + #define PTR4 __far + #define RAD_U16 unsigned int + #define RAD_S16 signed int + #endif + + //------------------------------------------------- + // RAD_PTRBITS and such defined here without using sizeof() + // so that they can be used in align() and other macros + + #ifdef __RAD64__ + + #define RAD_PTRBITS 64 + #define RAD_PTRBYTES 8 + #define RAD_TWOPTRBYTES 16 + + #else + + #define RAD_PTRBITS 32 + #define RAD_PTRBYTES 4 + #define RAD_TWOPTRBYTES 8 + + #endif + + + //------------------------------------------------- + // UINTr = int the size of a register + + #ifdef __RAD64REGS__ + + #define RAD_UINTr RAD_U64 + #define RAD_SINTr RAD_S64 + + #else + + #define RAD_UINTr RAD_U32 + #define RAD_SINTr RAD_S32 + + #endif + + //=========================================================================== + + /* + // CB : meh this is enough of a mess that it's probably best to just let each + #if defined(__RADX86__) && defined(_MSC_VER) && _MSC_VER >= 1300 + #define __RADX86INTRIN2003__ + #endif + */ + + // RADASSUME(expr) tells the compiler that expr is always true + // RADUNREACHABLE must never be reachable - even in event of error + // eg. it's okay for compiler to generate completely invalid code after RADUNREACHABLE + + #ifdef _MSC_VER + #define RADFORCEINLINE __forceinline + #if _MSC_VER >= 1300 + #define RADNOINLINE __declspec(noinline) + #else + #define RADNOINLINE + #endif + #define RADUNREACHABLE __assume(0) + #define RADASSUME(exp) __assume(exp) + #elif defined(__clang__) + #ifdef _DEBUG + #define RADFORCEINLINE inline + #else + #define RADFORCEINLINE inline __attribute((always_inline)) + #endif + #define RADNOINLINE __attribute__((noinline)) + + #define RADUNREACHABLE __builtin_unreachable() + + #if __has_builtin(__builtin_assume) + #define RADASSUME(exp) __builtin_assume(exp) + #else + #define RADASSUME(exp) RAD_STATEMENT_WRAPPER( if ( ! (exp) ) __builtin_unreachable(); ) + #endif + #elif (defined(__GCC__) || defined(__GNUC__)) || defined(ANDROID) + #ifdef _DEBUG + #define RADFORCEINLINE inline + #else + #define RADFORCEINLINE inline __attribute((always_inline)) + #endif + #define RADNOINLINE __attribute__((noinline)) + + #if __RAD_GCC_VERSION__ >= 40500 + #define RADUNREACHABLE __builtin_unreachable() + #define RADASSUME(exp) RAD_STATEMENT_WRAPPER( if ( ! (exp) ) __builtin_unreachable(); ) + #else + #define RADUNREACHABLE RAD_INFINITE_LOOP( RR_BREAK(); ) + #define RADASSUME(exp) + #endif + #elif defined(__CWCC__) + #define RADFORCEINLINE inline + #define RADNOINLINE __attribute__((never_inline)) + #define RADUNREACHABLE + #define RADASSUME(x) (void)0 + #else + // ? #define RADFORCEINLINE ? + #define RADFORCEINLINE inline + #define RADNOINLINE + #define RADASSUME(x) (void)0 + #endif + + //=========================================================================== + + // RAD_ALIGN_HINT tells the compiler how a given pointer is aligned + // it *must* be true, but the compiler may or may not use that information + // it is not for cases where the pointer is to an inherently aligned data type, + // it's when the compiler cannot tell the alignment but you have extra information. + // eg : + // U8 * ptr = rrMallocAligned(256,16); + // RAD_ALIGN_HINT(ptr,16,0); + + #ifdef __RADSPU__ + #define RAD_ALIGN_HINT(ptr,alignment,offset) __align_hint(ptr,alignment,offset); RR_ASSERT( ((UINTa)(ptr) & ((alignment)-1)) == (UINTa)(offset) ) + #else + #define RAD_ALIGN_HINT(ptr,alignment,offset) RADASSUME( ((UINTa)(ptr) & ((alignment)-1)) == (UINTa)(offset) ) + #endif + + //=========================================================================== + + // RAD_EXPECT is to tell the compiler the *likely* value of an expression + // different than RADASSUME in that expr might not have that value + // it's use for branch code layout and static branch prediction + // condition can technically be a variable but should usually be 0 or 1 + + #if (defined(__GCC__) || defined(__GNUC__)) || defined(__clang__) + + // __builtin_expect returns value of expr + #define RAD_EXPECT(expr,cond) __builtin_expect(expr,cond) + + #else + + #define RAD_EXPECT(expr,cond) (expr) + + #endif + + // helpers for doing an if ( ) with expect : + // if ( RAD_LIKELY(expr) ) { ... } + + #define RAD_LIKELY(expr) RAD_EXPECT(expr,1) + #define RAD_UNLIKELY(expr) RAD_EXPECT(expr,0) + + //=========================================================================== + + // __RADX86ASM__ means you can use __asm {} style inline assembly + #if defined(__RADX86__) && !defined(__RADX64__) && defined(_MSC_VER) + #define __RADX86ASM__ + #endif + + //------------------------------------------------- + // typedefs : + + #ifndef RADNOTYPEDEFS + + #ifndef S8_DEFINED + #define S8_DEFINED + typedef RAD_S8 S8; + #endif + + #ifndef U8_DEFINED + #define U8_DEFINED + typedef RAD_U8 U8; + #endif + + #ifndef S16_DEFINED + #define S16_DEFINED + typedef RAD_S16 S16; + #endif + + #ifndef U16_DEFINED + #define U16_DEFINED + typedef RAD_U16 U16; + #endif + + #ifndef S32_DEFINED + #define S32_DEFINED + typedef RAD_S32 S32; + #endif + + #ifndef U32_DEFINED + #define U32_DEFINED + typedef RAD_U32 U32; + #endif + + #ifndef S64_DEFINED + #define S64_DEFINED + typedef RAD_S64 S64; + #endif + + #ifndef U64_DEFINED + #define U64_DEFINED + typedef RAD_U64 U64; + #endif + + #ifndef F32_DEFINED + #define F32_DEFINED + typedef RAD_F32 F32; + #endif + + #ifndef F64_DEFINED + #define F64_DEFINED + typedef RAD_F64 F64; + #endif + + #ifndef F64_OR_32_DEFINED + #define F64_OR_32_DEFINED + typedef RAD_F64_OR_32 F64_OR_32; + #endif + + // UINTa and SINTa are the ints big enough for an address + + #ifndef SINTa_DEFINED + #define SINTa_DEFINED + typedef RAD_SINTa SINTa; + #endif + + #ifndef UINTa_DEFINED + #define UINTa_DEFINED + typedef RAD_UINTa UINTa; + #endif + + #ifndef UINTr_DEFINED + #define UINTr_DEFINED + typedef RAD_UINTr UINTr; + #endif + + #ifndef SINTr_DEFINED + #define SINTr_DEFINED + typedef RAD_SINTr SINTr; + #endif + + #elif !defined(RADNOTYPEDEFINES) + + #ifndef S8_DEFINED + #define S8_DEFINED + #define S8 RAD_S8 + #endif + + #ifndef U8_DEFINED + #define U8_DEFINED + #define U8 RAD_U8 + #endif + + #ifndef S16_DEFINED + #define S16_DEFINED + #define S16 RAD_S16 + #endif + + #ifndef U16_DEFINED + #define U16_DEFINED + #define U16 RAD_U16 + #endif + + #ifndef S32_DEFINED + #define S32_DEFINED + #define S32 RAD_S32 + #endif + + #ifndef U32_DEFINED + #define U32_DEFINED + #define U32 RAD_U32 + #endif + + #ifndef S64_DEFINED + #define S64_DEFINED + #define S64 RAD_S64 + #endif + + #ifndef U64_DEFINED + #define U64_DEFINED + #define U64 RAD_U64 + #endif + + #ifndef F32_DEFINED + #define F32_DEFINED + #define F32 RAD_F32 + #endif + + #ifndef F64_DEFINED + #define F64_DEFINED + #define F64 RAD_F64 + #endif + + #ifndef F64_OR_32_DEFINED + #define F64_OR_32_DEFINED + #define F64_OR_32 RAD_F64_OR_32 + #endif + + // UINTa and SINTa are the ints big enough for an address (pointer) + #ifndef SINTa_DEFINED + #define SINTa_DEFINED + #define SINTa RAD_SINTa + #endif + + #ifndef UINTa_DEFINED + #define UINTa_DEFINED + #define UINTa RAD_UINTa + #endif + + #ifndef UINTr_DEFINED + #define UINTr_DEFINED + #define UINTr RAD_UINTr + #endif + + #ifndef SINTr_DEFINED + #define SINTr_DEFINED + #define SINTr RAD_SINTr + #endif + + #endif + + /// Some error-checking. + #if defined(__RAD64__) && !defined(__RAD32__) + // See top of file for why this is. + #error __RAD64__ must not be defined without __RAD32__ (see radbase.h) + #endif + +#ifdef _MSC_VER + // microsoft compilers + + #if _MSC_VER >= 1400 + #define RAD_STATEMENT_START \ + do { + + #define RAD_STATEMENT_END_FALSE \ + __pragma(warning(push)) \ + __pragma(warning(disable:4127)) \ + } while(0) \ + __pragma(warning(pop)) + + #define RAD_STATEMENT_END_TRUE \ + __pragma(warning(push)) \ + __pragma(warning(disable:4127)) \ + } while(1) \ + __pragma(warning(pop)) + + #else + #define RAD_USE_STANDARD_LOOP_CONSTRUCT + #endif +#else + #define RAD_USE_STANDARD_LOOP_CONSTRUCT +#endif + +#ifdef RAD_USE_STANDARD_LOOP_CONSTRUCT + #define RAD_STATEMENT_START \ + do { + + #define RAD_STATEMENT_END_FALSE \ + } while ( (void)0,0 ) + + #define RAD_STATEMENT_END_TRUE \ + } while ( (void)1,1 ) + +#endif + +#define RAD_STATEMENT_WRAPPER( code ) \ + RAD_STATEMENT_START \ + code \ + RAD_STATEMENT_END_FALSE + +#define RAD_INFINITE_LOOP( code ) \ + RAD_STATEMENT_START \ + code \ + RAD_STATEMENT_END_TRUE + + +// Must be placed after variable declarations for code compiled as .c +#if defined(_MSC_VER) && _MSC_VER >= 1700 // in 2012 aka 11.0 and later +# define RR_UNUSED_VARIABLE(x) (void) x +#else +# define RR_UNUSED_VARIABLE(x) (void)(sizeof(x)) +#endif + +//----------------------------------------------- +// RR_UINT3264 is a U64 in 64-bit code and a U32 in 32-bit code +// eg. it's pointer sized and the same type as a U32/U64 of the same size +// +// @@ CB 05/21/2012 : I think RR_UINT3264 may be deprecated +// it was useful back when UINTa was /Wp64 +// but since we removed that maybe it's not anymore ? +// + +#ifdef __RAD64__ +#define RR_UINT3264 U64 +#else +#define RR_UINT3264 U32 +#endif + +//RR_COMPILER_ASSERT( sizeof(RR_UINT3264) == sizeof(UINTa) ); + +//-------------------------------------------------- + +// RR_LINESTRING is the current line number as a string +#define RR_STRINGIZE( L ) #L +#define RR_DO_MACRO( M, X ) M(X) +#define RR_STRINGIZE_DELAY( X ) RR_DO_MACRO( RR_STRINGIZE, X ) +#define RR_LINESTRING RR_STRINGIZE_DELAY( __LINE__ ) + +#define RR_CAT(X,Y) X ## Y + +// RR_STRING_JOIN joins strings in the preprocessor and works with LINESTRING +#define RR_STRING_JOIN(arg1, arg2) RR_STRING_JOIN_DELAY(arg1, arg2) +#define RR_STRING_JOIN_DELAY(arg1, arg2) RR_STRING_JOIN_IMMEDIATE(arg1, arg2) +#define RR_STRING_JOIN_IMMEDIATE(arg1, arg2) arg1 ## arg2 + +// RR_NUMBERNAME is a macro to make a name unique, so that you can use it to declare +// variable names and they won't conflict with each other +// using __LINE__ is broken in MSVC with /ZI , but __COUNTER__ is an MSVC extension that works + +#ifdef _MSC_VER + #define RR_NUMBERNAME(name) RR_STRING_JOIN(name,__COUNTER__) +#else + #define RR_NUMBERNAME(name) RR_STRING_JOIN(name,__LINE__) +#endif + +//-------------------------------------------------- +// current plan is to use "rrbool" with plain old "true" and "false" +// if true and false give us trouble we might have to go to rrtrue and rrfalse +// BTW there's a danger for evil bugs here !! If you're checking == true +// then the rrbool must be set to exactly "1" not just "not zero" !! + +#ifndef RADNOTYPEDEFS + #ifndef RRBOOL_DEFINED + #define RRBOOL_DEFINED + typedef S32 rrbool; + typedef S32 RRBOOL; + #endif +#elif !defined(RADNOTYPEDEFINES) + #ifndef RRBOOL_DEFINED + #define RRBOOL_DEFINED + #define rrbool S32 + #define RRBOOL S32 + #endif +#endif + +//-------------------------------------------------- +// Range macros + + #ifndef RR_MIN + #define RR_MIN(a,b) ( (a) < (b) ? (a) : (b) ) + #endif + + #ifndef RR_MAX + #define RR_MAX(a,b) ( (a) > (b) ? (a) : (b) ) + #endif + + #ifndef RR_ABS + #define RR_ABS(a) ( ((a) < 0) ? -(a) : (a) ) + #endif + + #ifndef RR_CLAMP + #define RR_CLAMP(val,lo,hi) RR_MAX( RR_MIN(val,hi), lo ) + #endif + +//-------------------------------------------------- +// Data layout macros + + #define RR_ARRAY_SIZE(array) ( sizeof(array)/sizeof(array[0]) ) + + // MEMBER_OFFSET tells you the offset of a member in a type + #ifdef __RAD3DS__ + #define RR_MEMBER_OFFSET(type,member) (unsigned int)(( (char *) &(((type *)0)->member) - (char *) 0 )) + #elif defined(__RADANDROID__) || defined(__RADPSP__) || defined(__RADPS3__) || defined(__RADSPU__) + // offsetof() gets mucked with by system headers on android, making things dependent on #include order. + #define RR_MEMBER_OFFSET(type,member) __builtin_offsetof(type, member) + #elif defined(__RADLINUX__) + #define RR_MEMBER_OFFSET(type,member) (offsetof(type, member)) + #else + #define RR_MEMBER_OFFSET(type,member) ( (size_t) (UINTa) &(((type *)0)->member) ) + #endif + + // MEMBER_SIZE tells you the size of a member in a type + #define RR_MEMBER_SIZE(type,member) ( sizeof( ((type *) 0)->member) ) + + // just to make gcc shut up about derefing null : + #define RR_MEMBER_OFFSET_PTR(type,member,ptr) ( (SINTa) &(((type *)(ptr))->member) - (SINTa)(ptr) ) + #define RR_MEMBER_SIZE_PTR(type,member,ptr) ( sizeof( ((type *) (ptr))->member) ) + + // MEMBER_TO_OWNER takes a pointer to a member and gives you back the base of the object + // you should then RR_ASSERT( &(ret->member) == ptr ); + #define RR_MEMBER_TO_OWNER(type,member,ptr) (type *)( ((char *)(ptr)) - RR_MEMBER_OFFSET_PTR(type,member,ptr) ) + +//-------------------------------------------------- +// Cache / prefetch macros : + +// RR_PREFETCH for various platforms : +// +// RR_PREFETCH_SEQUENTIAL : prefetch memory for reading in a sequential scan +// platforms that automatically prefetch sequential (eg. PC) should be a no-op here +// RR_PREFETCH_WRITE_INVALIDATE : prefetch memory for writing - contents of memory are undefined +// (may be a no-op, may be a normal prefetch, may zero memory) +// warning : RR_PREFETCH_WRITE_INVALIDATE may write memory so don't do it past the end of buffers + +#ifdef __RADX86__ + +#define RR_PREFETCH_SEQUENTIAL(ptr,offset) // nop +#define RR_PREFETCH_WRITE_INVALIDATE(ptr,offset) // nop + +#elif defined(__RADXENON__) + +#define RR_PREFETCH_SEQUENTIAL(ptr,offset) __dcbt((int)(offset),(void *)(ptr)) +#define RR_PREFETCH_WRITE_INVALIDATE(ptr,offset) __dcbz128((int)(offset),(void *)(ptr)) + +#elif defined(__RADPS3__) + +#define RR_PREFETCH_SEQUENTIAL(ptr,offset) __dcbt((char *)(ptr) + (int)(offset)) +#define RR_PREFETCH_WRITE_INVALIDATE(ptr,offset) __dcbz((char *)(ptr) + (int)(offset)) + +#elif defined(__RADSPU__) + +#define RR_PREFETCH_SEQUENTIAL(ptr,offset) // intentional NOP +#define RR_PREFETCH_WRITE_INVALIDATE(ptr,offset) // nop + +#elif defined(__RADWII__) || defined(__RADWIIU__) + +#define RR_PREFETCH_SEQUENTIAL(ptr,offset) // intentional NOP for now +#define RR_PREFETCH_WRITE_INVALIDATE(ptr,offset) // nop + +#elif defined(__RAD3DS__) + +#define RR_PREFETCH_SEQUENTIAL(ptr,offset) __pld((char *)(ptr) + (int)(offset)) +#define RR_PREFETCH_WRITE_INVALIDATE(ptr,offset) __pldw((char *)(ptr) + (int)(offset)) + +#else + +// other platform +#define RR_PREFETCH_SEQUENTIAL(ptr,offset) // need_prefetch // compile error +#define RR_PREFETCH_WRITE_INVALIDATE(ptr,offset) // need_writezero // error + +#endif + +//-------------------------------------------------- +// LIGHTWEIGHT ASSERTS without rrAssert.h + +RADDEFSTART + +// set up RR_BREAK : + + #ifdef __RADNGC__ + + #define RR_BREAK() asm(" .long 0x00000001") + #define RR_CACHE_LINE_SIZE xxx + + #elif defined(__RADWII__) + + #define RR_BREAK() __asm__ volatile("trap") + #define RR_CACHE_LINE_SIZE 32 + + #elif defined(__RADWIIU__) + + #define RR_BREAK() asm("trap") + #define RR_CACHE_LINE_SIZE 32 + + #elif defined(__RAD3DS__) + + #define RR_BREAK() *((int volatile*)0)=0 + #define RR_CACHE_LINE_SIZE 32 + + #elif defined(__RADNDS__) + + #define RR_BREAK() asm("BKPT 0") + #define RR_CACHE_LINE_SIZE xxx + + #elif defined(__RADPS2__) + + #define RR_BREAK() __asm__ volatile("break") + #define RR_CACHE_LINE_SIZE 64 + + #elif defined(__RADPSP__) + + #define RR_BREAK() __asm__("break 0") + #define RR_CACHE_LINE_SIZE 64 + + #elif defined(__RADPSP2__) + + #define RR_BREAK() { __asm__ volatile("bkpt 0x0000"); } + #define RR_CACHE_LINE_SIZE 32 + + #elif defined (__RADQNX__) + #define RR_BREAK() __builtin_trap() + #define RR_CACHE_LINE_SIZE 32 + #elif defined (__RADARM__) && defined (__RADLINUX__) + #define RR_BREAK() __builtin_trap() + #define RR_CACHE_LINE_SIZE 32 + #elif defined(__RADSPU__) + + #define RR_BREAK() __asm volatile ("stopd 0,1,1") + #define RR_CACHE_LINE_SIZE 128 + + #elif defined(__RADPS3__) + + // #ifdef snPause // in LibSN.h + // snPause + // __asm__ volatile ( "tw 31,1,1" ) + + #define RR_BREAK() __asm__ volatile ( "tw 31,1,1" ) + //#define RR_BREAK() __asm__ volatile("trap"); + + #define RR_CACHE_LINE_SIZE 128 + + #elif defined(__RADMAC__) + + #if defined(__GNUG__) || defined(__GNUC__) + #ifdef __RADX86__ + #define RR_BREAK() __asm__ volatile ( "int $3" ) + #else + #define RR_BREAK() __builtin_trap() + #endif + #else + #ifdef __RADMACH__ + void DebugStr(unsigned char const *); + #else + void pascal DebugStr(unsigned char const *); + #endif + #define RR_BREAK() DebugStr("\pRR_BREAK() was called") + #endif + + #define RR_CACHE_LINE_SIZE 64 + + #elif defined(__RADIPHONE__) + #define RR_BREAK() __builtin_trap() + #define RR_CACHE_LINE_SIZE 32 + #elif defined(__RADXENON__) + #define RR_BREAK() __debugbreak() + #define RR_CACHE_LINE_SIZE 128 + #elif defined(__RADANDROID__) + #define RR_BREAK() __builtin_trap() + #define RR_CACHE_LINE_SIZE 32 + #elif defined(__RADPS4__) + #define RR_BREAK() __builtin_trap() + #define RR_CACHE_LINE_SIZE 64 + #elif defined(__RADNACL__) + #define RR_BREAK() __builtin_trap() + #define RR_CACHE_LINE_SIZE 64 + #else + // x86 : + #define RR_CACHE_LINE_SIZE 64 + + #ifdef __RADLINUX__ + #define RR_BREAK() __asm__ volatile ( "int $3" ) + #elif defined(__WATCOMC__) + + void RR_BREAK( void ); + #pragma aux RR_BREAK = "int 0x3"; + + #elif defined(__RADWIN__) && defined(_MSC_VER) && _MSC_VER >= 1300 + + #define RR_BREAK __debugbreak + + #else + + #define RR_BREAK() RAD_STATEMENT_WRAPPER( __asm {int 3} ) + + #endif + + #endif + +// simple RR_ASSERT : + +// CB 5-27-10 : use RR_DO_ASSERTS to toggle asserts on and off : +#if (defined(_DEBUG) && !defined(NDEBUG)) || defined(ASSERT_IN_RELEASE) + #define RR_DO_ASSERTS +#endif + +/********* + +rrAsserts : + +RR_ASSERT(exp) - the normal assert thing, toggled with RR_DO_ASSERTS +RR_ASSERT_ALWAYS(exp) - assert that you want to test even in ALL builds (including final!) +RR_ASSERT_RELEASE(exp) - assert that you want to test even in release builds (not for final!) +RR_ASSERT_LITE(exp) - normal assert is not safe from threads or inside malloc; use this instead +RR_DURING_ASSERT(exp) - wrap operations that compute stuff for assert in here +RR_DO_ASSERTS - toggle tells you if asserts are enabled or not + +RR_BREAK() - generate a debug break - always ! +RR_ASSERT_BREAK() - RR_BREAK for asserts ; disable with RAD_NO_BREAK + +RR_ASSERT_FAILURE(str) - just break with a messsage; like assert with no condition +RR_ASSERT_FAILURE_ALWAYS(str) - RR_ASSERT_FAILURE in release builds too +RR_CANT_GET_HERE() - put in spots execution should never go +RR_COMPILER_ASSERT(exp) - checks constant conditions at compile time + +RADTODO - note to search for nonfinal stuff +RR_PRAGMA_MESSAGE - message dealy, use with #pragma in MSVC + +*************/ + +//----------------------------------------------------------- + + +#if defined(__GNUG__) || defined(__GNUC__) || (defined(_MSC_VER) && _MSC_VER > 1200) + #define RR_FUNCTION_NAME __FUNCTION__ +#else + #define RR_FUNCTION_NAME 0 + + // __func__ is in the C99 standard +#endif + +//----------------------------------------------------------- + +// rrDisplayAssertion might just log, or it might pop a message box, depending on settings +// rrDisplayAssertion returns whether you should break or not +typedef rrbool (RADLINK fp_rrDisplayAssertion)(int * Ignored, const char * fileName,const int line,const char * function,const char * message); + +extern fp_rrDisplayAssertion * g_fp_rrDisplayAssertion; + +// if I have func pointer, call it, else true ; true = do int 3 +#define rrDisplayAssertion(i,n,l,f,m) ( ( g_fp_rrDisplayAssertion ) ? (*g_fp_rrDisplayAssertion)(i,n,l,f,m) : 1 ) + +//----------------------------------------------------------- + +// RAD_NO_BREAK : option if you don't like your assert to break +// CB : RR_BREAK is *always* a break ; RR_ASSERT_BREAK is optional +#ifdef RAD_NO_BREAK +#define RR_ASSERT_BREAK() 0 +#else +#define RR_ASSERT_BREAK() RR_BREAK() +#endif + +// assert_always is on FINAL ! +#define RR_ASSERT_ALWAYS(exp) RAD_STATEMENT_WRAPPER( static int Ignored=0; if ( ! (exp) ) { if ( rrDisplayAssertion(&Ignored,__FILE__,__LINE__,RR_FUNCTION_NAME,#exp) ) RR_ASSERT_BREAK(); } ) + +// RR_ASSERT_FAILURE is like an assert without a condition - if you hit it, you're bad +#define RR_ASSERT_FAILURE_ALWAYS(str) RAD_STATEMENT_WRAPPER( static int Ignored=0; if ( rrDisplayAssertion(&Ignored,__FILE__,__LINE__,RR_FUNCTION_NAME,str) ) RR_ASSERT_BREAK(); ) + +#define RR_ASSERT_LITE_ALWAYS(exp) RAD_STATEMENT_WRAPPER( if ( ! (exp) ) { RR_ASSERT_BREAK(); } ) + +//----------------------------------- +#ifdef RR_DO_ASSERTS + +#define RR_ASSERT(exp) RR_ASSERT_ALWAYS(exp) +#define RR_ASSERT_LITE(exp) RR_ASSERT_LITE_ALWAYS(exp) +#define RR_ASSERT_NO_ASSUME(exp) RR_ASSERT_ALWAYS(exp) +// RR_DURING_ASSERT is to set up expressions or declare variables that are only used in asserts +#define RR_DURING_ASSERT(exp) exp + +#define RR_ASSERT_FAILURE(str) RR_ASSERT_FAILURE_ALWAYS(str) + +// RR_CANT_GET_HERE is for like defaults in switches that should never be hit +#define RR_CANT_GET_HERE() RAD_STATEMENT_WRAPPER( RR_ASSERT_FAILURE("can't get here"); RADUNREACHABLE; ) + + +#else // RR_DO_ASSERTS //----------------------------------- + +#define RR_ASSERT(exp) (void)0 +#define RR_ASSERT_LITE(exp) (void)0 +#define RR_ASSERT_NO_ASSUME(exp) (void)0 + +#define RR_DURING_ASSERT(exp) (void)0 + +#define RR_ASSERT_FAILURE(str) (void)0 + +#define RR_CANT_GET_HERE() RADUNREACHABLE + +#endif // RR_DO_ASSERTS //----------------------------------- + +//================================================================= + +// RR_ASSERT_RELEASE is on in release build, but not final + +#ifndef __RADFINAL__ + +#define RR_ASSERT_RELEASE(exp) RR_ASSERT_ALWAYS(exp) +#define RR_ASSERT_LITE_RELEASE(exp) RR_ASSERT_LITE_ALWAYS(exp) + +#else + +#define RR_ASSERT_RELEASE(exp) (void)0 +#define RR_ASSERT_LITE_RELEASE(exp) (void)0 + +#endif + +// BH: This never gets compiled away except for __RADFINAL__ +#define RR_ASSERT_ALWAYS_NO_SHIP RR_ASSERT_RELEASE + +#define rrAssert RR_ASSERT +#define rrassert RR_ASSERT + +#ifdef _MSC_VER + // without this, our assert errors... + #if _MSC_VER >= 1300 + #pragma warning( disable : 4127) // conditional expression is constant + #endif +#endif + +//--------------------------------------- +// Get/Put from memory in little or big endian : +// +// val = RR_GET32_BE(ptr) +// RR_PUT32_BE(ptr,val) +// +// available here : +// RR_[GET/PUT][16/32]_[BE/LE][_UNALIGNED][_OFFSET] +// +// if you don't specify _UNALIGNED , then ptr & offset shoud both be aligned to type size +// _OFFSET is in *bytes* ! + +// you can #define RR_GET_RESTRICT to make all RR_GETs be RESTRICT +// if you set nothing they are not + +#ifdef RR_GET_RESTRICT +#define RR_GET_PTR_POST RADRESTRICT +#endif +#ifndef RR_GET_PTR_POST +#define RR_GET_PTR_POST +#endif + +// native version of get/put is always trivial : + +#define RR_GET16_NATIVE(ptr) *((const U16 * RR_GET_PTR_POST)(ptr)) +#define RR_PUT16_NATIVE(ptr,val) *((U16 * RR_GET_PTR_POST)(ptr)) = (val) + +// offset is in bytes +#define RR_U16_PTR_OFFSET(ptr,offset) ((U16 * RR_GET_PTR_POST)((char *)(ptr) + (offset))) +#define RR_GET16_NATIVE_OFFSET(ptr,offset) *( RR_U16_PTR_OFFSET((ptr),offset) ) +#define RR_PUT16_NATIVE_OFFSET(ptr,val,offset) *( RR_U16_PTR_OFFSET((ptr),offset)) = (val) + +#define RR_GET32_NATIVE(ptr) *((const U32 * RR_GET_PTR_POST)(ptr)) +#define RR_PUT32_NATIVE(ptr,val) *((U32 * RR_GET_PTR_POST)(ptr)) = (val) + +// offset is in bytes +#define RR_U32_PTR_OFFSET(ptr,offset) ((U32 * RR_GET_PTR_POST)((char *)(ptr) + (offset))) +#define RR_GET32_NATIVE_OFFSET(ptr,offset) *( RR_U32_PTR_OFFSET((ptr),offset) ) +#define RR_PUT32_NATIVE_OFFSET(ptr,val,offset) *( RR_U32_PTR_OFFSET((ptr),offset)) = (val) + +#define RR_GET64_NATIVE(ptr) *((const U64 * RR_GET_PTR_POST)(ptr)) +#define RR_PUT64_NATIVE(ptr,val) *((U64 * RR_GET_PTR_POST)(ptr)) = (val) + +// offset is in bytes +#define RR_U64_PTR_OFFSET(ptr,offset) ((U64 * RR_GET_PTR_POST)((char *)(ptr) + (offset))) +#define RR_GET64_NATIVE_OFFSET(ptr,offset) *( RR_U64_PTR_OFFSET((ptr),offset) ) +#define RR_PUT64_NATIVE_OFFSET(ptr,val,offset) *( RR_U64_PTR_OFFSET((ptr),offset)) = (val) + +//--------------------------------------------------- + +#ifdef __RADLITTLEENDIAN__ + +#define RR_GET16_LE RR_GET16_NATIVE +#define RR_PUT16_LE RR_PUT16_NATIVE +#define RR_GET16_LE_OFFSET RR_GET16_NATIVE_OFFSET +#define RR_PUT16_LE_OFFSET RR_PUT16_NATIVE_OFFSET + +#define RR_GET32_LE RR_GET32_NATIVE +#define RR_PUT32_LE RR_PUT32_NATIVE +#define RR_GET32_LE_OFFSET RR_GET32_NATIVE_OFFSET +#define RR_PUT32_LE_OFFSET RR_PUT32_NATIVE_OFFSET + +#define RR_GET64_LE RR_GET64_NATIVE +#define RR_PUT64_LE RR_PUT64_NATIVE +#define RR_GET64_LE_OFFSET RR_GET64_NATIVE_OFFSET +#define RR_PUT64_LE_OFFSET RR_PUT64_NATIVE_OFFSET + +#else + +#define RR_GET16_BE RR_GET16_NATIVE +#define RR_PUT16_BE RR_PUT16_NATIVE +#define RR_GET16_BE_OFFSET RR_GET16_NATIVE_OFFSET +#define RR_PUT16_BE_OFFSET RR_PUT16_NATIVE_OFFSET + +#define RR_GET32_BE RR_GET32_NATIVE +#define RR_PUT32_BE RR_PUT32_NATIVE +#define RR_GET32_BE_OFFSET RR_GET32_NATIVE_OFFSET +#define RR_PUT32_BE_OFFSET RR_PUT32_NATIVE_OFFSET + +#define RR_GET64_BE RR_GET64_NATIVE +#define RR_PUT64_BE RR_PUT64_NATIVE +#define RR_GET64_BE_OFFSET RR_GET64_NATIVE_OFFSET +#define RR_PUT64_BE_OFFSET RR_PUT64_NATIVE_OFFSET + +#endif + +//------------------------- +// non-native Get/Put implementations go here : + +#if defined(__RADX86__) +// good implementation for X86 : + +#if (_MSC_VER >= 1300) + +unsigned short __cdecl _byteswap_ushort (unsigned short _Short); +unsigned long __cdecl _byteswap_ulong (unsigned long _Long); +#pragma intrinsic(_byteswap_ushort, _byteswap_ulong) + +#define RR_BSWAP16 _byteswap_ushort +#define RR_BSWAP32 _byteswap_ulong + +unsigned __int64 __cdecl _byteswap_uint64 (unsigned __int64 val); +#pragma intrinsic(_byteswap_uint64) +#define RR_BSWAP64 _byteswap_uint64 + +#elif defined(_MSC_VER) // VC6 + +RADFORCEINLINE unsigned long RR_BSWAP16 (unsigned long _Long) +{ + __asm { + mov eax, [_Long] + rol ax, 8 + mov [_Long], eax; + } + return _Long; +} + +RADFORCEINLINE unsigned long RR_BSWAP32 (unsigned long _Long) +{ + __asm { + mov eax, [_Long] + bswap eax + mov [_Long], eax + } + return _Long; +} + +RADFORCEINLINE unsigned __int64 RR_BSWAP64 (unsigned __int64 _Long) +{ + __asm { + mov eax, DWORD PTR _Long + mov edx, DWORD PTR _Long+4 + bswap eax + bswap edx + mov DWORD PTR _Long, edx + mov DWORD PTR _Long+4, eax + } + return _Long; +} + +#elif defined(__GNUC__) || defined(__clang__) + +// GCC has __builtin_bswap16, but Clang only seems to have added it recently. +// We use __builtin_bswap32/64 but 16 just uses the macro version. (No big +// deal if that turns into shifts anyway) +#define RR_BSWAP16(u16) ( (U16) ( ((u16) >> 8) | ((u16) << 8) ) ) +#define RR_BSWAP32 __builtin_bswap32 +#define RR_BSWAP64 __builtin_bswap64 + +#endif + +#define RR_GET16_BE(ptr) RR_BSWAP16(*((U16 *)(ptr))) +#define RR_PUT16_BE(ptr,val) *((U16 *)(ptr)) = (U16) RR_BSWAP16(val) +#define RR_GET16_BE_OFFSET(ptr,offset) RR_BSWAP16(*RR_U16_PTR_OFFSET(ptr,offset)) +#define RR_PUT16_BE_OFFSET(ptr,val,offset) *RR_U16_PTR_OFFSET(ptr,offset) = RR_BSWAP16(val) + +#define RR_GET32_BE(ptr) RR_BSWAP32(*((U32 *)(ptr))) +#define RR_PUT32_BE(ptr,val) *((U32 *)(ptr)) = RR_BSWAP32(val) +#define RR_GET32_BE_OFFSET(ptr,offset) RR_BSWAP32(*RR_U32_PTR_OFFSET(ptr,offset)) +#define RR_PUT32_BE_OFFSET(ptr,val,offset) *RR_U32_PTR_OFFSET(ptr,offset) = RR_BSWAP32(val) + +#define RR_GET64_BE(ptr) RR_BSWAP64(*((U64 *)(ptr))) +#define RR_PUT64_BE(ptr,val) *((U64 *)(ptr)) = RR_BSWAP64(val) +#define RR_GET64_BE_OFFSET(ptr,offset) RR_BSWAP64(*RR_U64_PTR_OFFSET(ptr,offset)) +#define RR_PUT64_BE_OFFSET(ptr,val,offset) *RR_U64_PTR_OFFSET(ptr,offset) = RR_BSWAP64(val) + +// end _MSC_VER + +#elif defined(__RADXENON__) // Xenon has built-in funcs for this + +unsigned short __loadshortbytereverse(int offset, const void *base); +unsigned long __loadwordbytereverse (int offset, const void *base); + +void __storeshortbytereverse(unsigned short val, int offset, void *base); +void __storewordbytereverse (unsigned int val, int offset, void *base); + +#define RR_GET16_LE(ptr) __loadshortbytereverse(0, ptr) +#define RR_PUT16_LE(ptr,val) __storeshortbytereverse((U16) (val), 0, ptr) + +#define RR_GET16_LE_OFFSET(ptr,offset) __loadshortbytereverse(offset, ptr) +#define RR_PUT16_LE_OFFSET(ptr,val,offset) __storeshortbytereverse((U16) (val), offset, ptr) + +#define RR_GET32_LE(ptr) __loadwordbytereverse(0, ptr) +#define RR_PUT32_LE(ptr,val) __storewordbytereverse((U32) (val), 0, ptr) + +#define RR_GET32_LE_OFFSET(ptr,offset) __loadwordbytereverse(offset, ptr) +#define RR_PUT32_LE_OFFSET(ptr,val,offset) __storewordbytereverse((U32) (val), offset, ptr) + +#define RR_GET64_LE(ptr) ( ((U64)RR_GET32_OFFSET_LE(ptr,4)<<32) | RR_GET32_LE(ptr) ) +#define RR_PUT64_LE(ptr,val) RR_PUT32_LE(ptr, (U32) (val)), RR_PUT32_OFFSET_LE(ptr, (U32) ((val)>>32),4) + +#elif defined(__RADPS3__) + +#include + +#define RR_GET16_LE(ptr) __lhbrx(ptr) +#define RR_PUT16_LE(ptr,val) __sthbrx(ptr, (U16) (val)) + +#define RR_GET16_LE_OFFSET(ptr,offset) __lhbrx(RR_U16_PTR_OFFSET(ptr, offset)) +#define RR_PUT16_LE_OFFSET(ptr,val,offset) __sthbrx(RR_U16_PTR_OFFSET(ptr, offset), (U16) (val)) + +#define RR_GET32_LE(ptr) __lwbrx(ptr) +#define RR_PUT32_LE(ptr,val) __stwbrx(ptr, (U32) (val)) + +#define RR_GET64_LE(ptr) __ldbrx(ptr) +#define RR_PUT64_LE(ptr,val) __stdbrx(ptr, (U32) (val)) + +#define RR_GET32_LE_OFFSET(ptr,offset) __lwbrx(RR_U32_PTR_OFFSET(ptr, offset)) +#define RR_PUT32_LE_OFFSET(ptr,val,offset) __stwbrx(RR_U32_PTR_OFFSET(ptr, offset), (U32) (val)) + +#elif defined(__RADWII__) + +#define RR_GET16_LE(ptr) __lhbrx(ptr, 0) +#define RR_PUT16_LE(ptr,val) __sthbrx((U16) (val), ptr, 0) + +#define RR_GET16_LE_OFFSET(ptr,offset) __lhbrx(ptr, offset) +#define RR_PUT16_LE_OFFSET(ptr,val,offset) __sthbrx((U16) (val), ptr, offset) + +#define RR_GET32_LE(ptr) __lwbrx(ptr, 0) +#define RR_PUT32_LE(ptr,val) __stwbrx((U32) (val), ptr, 0) + +#define RR_GET32_LE_OFFSET(ptr,offset) __lwbrx(ptr, offset) +#define RR_PUT32_LE_OFFSET(ptr,val,offset) __stwbrx((U32) (val), ptr, offset) + +#elif defined(__RAD3DS__) + +#define RR_GET16_BE(ptr) __rev16(*(U16 *) (ptr)) +#define RR_PUT16_BE(ptr,val) *(U16 *) (ptr) = __rev16(val) + +#define RR_GET16_BE_OFFSET(ptr,offset) __rev16(*RR_U16_PTR_OFFSET(ptr,offset)) +#define RR_PUT16_BE_OFFSET(ptr,offset,val) *RR_U16_PTR_OFFSET(ptr,offset) = __rev16(val) + +#define RR_GET32_BE(ptr) __rev(*(U32 *) (ptr)) +#define RR_PUT32_BE(ptr,val) *(U32 *) (ptr) = __rev(val) + +#define RR_GET32_BE_OFFSET(ptr,offset) __rev(*RR_U32_PTR_OFFSET(ptr,offset)) +#define RR_PUT32_BE_OFFSET(ptr,offset,val) *RR_U32_PTR_OFFSET(ptr,offset) = __rev(val) + +#elif defined(__RADIPHONE__) + +// iPhone does not seem to have intrinsics for this, so use generic fallback! + +// Bswap is just here for use of implementing get/put +// caller should use Get/Put , not bswap +#define RR_BSWAP16(u16) ( (U16) ( ((u16) >> 8) | ((u16) << 8) ) ) +#define RR_BSWAP32(u32) ( (U32) ( ((u32) >> 24) | (((u32)<<8) & 0x00FF0000) | (((u32)>>8) & 0x0000FF00) | ((u32) << 24) ) ) + +#define RR_GET16_BE(ptr) RR_BSWAP16(*((U16 *)(ptr))) +#define RR_PUT16_BE(ptr,val) *((U16 *)(ptr)) = RR_BSWAP16(val) + +#define RR_GET32_BE(ptr) RR_BSWAP32(*((U32 *)(ptr))) +#define RR_PUT32_BE(ptr,val) *((U32 *)(ptr)) = RR_BSWAP32(val) + +#elif defined(__RADWIIU__) + +#include + +#define RR_GET16_LE(ptr) (*(__bytereversed U16 *) (ptr)) +#define RR_PUT16_LE(ptr,val) *(__bytereversed U16 *) (ptr) = val + +#define RR_GET16_LE_OFFSET(ptr,offset) (*(__bytereversed U16 *)RR_U16_PTR_OFFSET(ptr,offset)) +#define RR_PUT16_LE_OFFSET(ptr,val,offset) *(__bytereversed U16 *)RR_U16_PTR_OFFSET(ptr,offset) = val + +#define RR_GET32_LE(ptr) (*(__bytereversed U32 *) (ptr)) +#define RR_PUT32_LE(ptr,val) *(__bytereversed U32 *) (ptr) = val + +#define RR_GET32_LE_OFFSET(ptr,offset) (*(__bytereversed U32 *)RR_U32_PTR_OFFSET(ptr,offset)) +#define RR_PUT32_LE_OFFSET(ptr,val,offset) *(__bytereversed U32 *)RR_U32_PTR_OFFSET(ptr,offset) = val + +#define RR_GET64_LE(ptr) (*(__bytereversed U64 *) (ptr)) +#define RR_PUT64_LE(ptr,val) *(__bytereversed U64 *) (ptr) = val + +#define RR_GET64_LE_OFFSET(ptr,offset) (*(__bytereversed U64 *)RR_U32_PTR_OFFSET(ptr,offset)) +#define RR_PUT64_LE_OFFSET(ptr,val,offset) *(__bytereversed U64 *)RR_U32_PTR_OFFSET(ptr,offset) = val + +#elif defined(__RADWINRTAPI__) && defined(__RADARM__) + +#include + +#define RR_BSWAP16(u16) _arm_rev16(u16) +#define RR_BSWAP32(u32) _arm_rev(u32) + +#define RR_GET16_BE(ptr) RR_BSWAP16(*((U16 *)(ptr))) +#define RR_PUT16_BE(ptr,val) *((U16 *)(ptr)) = RR_BSWAP16(val) + +#define RR_GET32_BE(ptr) RR_BSWAP32(*((U32 *)(ptr))) +#define RR_PUT32_BE(ptr,val) *((U32 *)(ptr)) = RR_BSWAP32(val) + +#elif defined(__RADPSP2__) + +// no rev16 exposed +#define RR_BSWAP16(u16) ( (U16) ( ((u16) >> 8) | ((u16) << 8) ) ) +#define RR_BSWAP32(u32) __builtin_rev(u32) + +#define RR_GET16_BE(ptr) RR_BSWAP16(*((U16 *)(ptr))) +#define RR_PUT16_BE(ptr,val) *((U16 *)(ptr)) = RR_BSWAP16(val) + +#define RR_GET32_BE(ptr) RR_BSWAP32(*((U32 *)(ptr))) +#define RR_PUT32_BE(ptr,val) *((U32 *)(ptr)) = RR_BSWAP32(val) + +#else // other platforms ? + +// fall back : + +// Bswap is just here for use of implementing get/put +// caller should use Get/Put , not bswap +#define RR_BSWAP16(u16) ( (U16) ( ((u16) >> 8) | ((u16) << 8) ) ) +#define RR_BSWAP32(u32) ( (U32) ( ((u32) >> 24) | (((u32)<<8) & 0x00FF0000) | (((u32)>>8) & 0x0000FF00) | ((u32) << 24) ) ) +#define RR_BSWAP64(u64) ( ((U64) RR_BSWAP32((U32) (u64)) << 32) | (U64) RR_BSWAP32((U32) ((u64) >> 32)) ) + +#ifdef __RADLITTLEENDIAN__ + +// comment out fallbacks so users will get errors +//#define RR_GET16_BE(ptr) RR_BSWAP16(*((U16 *)(ptr))) +//#define RR_PUT16_BE(ptr,val) *((U16 *)(ptr)) = RR_BSWAP16(val) +//#define RR_GET32_BE(ptr) RR_BSWAP32(*((U32 *)(ptr))) +//#define RR_PUT32_BE(ptr,val) *((U32 *)(ptr)) = RR_BSWAP32(val) + +#else + +// comment out fallbacks so users will get errors +//#define RR_GET16_LE(ptr) RR_BSWAP16(*((U16 *)(ptr))) +//#define RR_PUT16_LE(ptr,val) *((U16 *)(ptr)) = RR_BSWAP16(val) +//#define RR_GET32_LE(ptr) RR_BSWAP32(*((U32 *)(ptr))) +//#define RR_PUT32_LE(ptr,val) *((U32 *)(ptr)) = RR_BSWAP32(val) + +#endif + +#endif + +//=================================================================== +// @@ TEMP : Aliases for old names : remove me when possible : + +#define RR_GET32_OFFSET_LE RR_GET32_LE_OFFSET +#define RR_GET32_OFFSET_BE RR_GET32_BE_OFFSET +#define RR_PUT32_OFFSET_LE RR_PUT32_LE_OFFSET +#define RR_PUT32_OFFSET_BE RR_PUT32_BE_OFFSET +#define RR_GET16_OFFSET_LE RR_GET16_LE_OFFSET +#define RR_GET16_OFFSET_BE RR_GET16_BE_OFFSET +#define RR_PUT16_OFFSET_LE RR_PUT16_LE_OFFSET +#define RR_PUT16_OFFSET_BE RR_PUT16_BE_OFFSET + + +//=================================================================== +// UNALIGNED VERSIONS : + +#if defined(__RADX86__) || defined(__RADPPC__) // platforms where unaligned is fast : + +#define RR_GET32_BE_UNALIGNED(ptr) RR_GET32_BE(ptr) +#define RR_GET32_BE_UNALIGNED_OFFSET(ptr,offset) RR_GET32_BE_OFFSET(ptr,offset) +#define RR_GET16_BE_UNALIGNED(ptr) RR_GET16_BE(ptr) +#define RR_GET16_BE_UNALIGNED_OFFSET(ptr,offset) RR_GET16_BE_OFFSET(ptr,offset) + +#define RR_GET32_LE_UNALIGNED(ptr) RR_GET32_LE(ptr) +#define RR_GET32_LE_UNALIGNED_OFFSET(ptr,offset) RR_GET32_LE_OFFSET(ptr,offset) +#define RR_GET16_LE_UNALIGNED(ptr) RR_GET16_LE(ptr) +#define RR_GET16_LE_UNALIGNED_OFFSET(ptr,offset) RR_GET16_LE_OFFSET(ptr,offset) + +#elif defined(__RAD3DS__) + +// arm has a "__packed" qualifier to tell the compiler to do unaligned accesses +#define RR_U16_PTR_OFFSET_UNALIGNED(ptr,offset) ((__packed U16 * RR_GET_PTR_POST)((char *)(ptr) + (offset))) +#define RR_U32_PTR_OFFSET_UNALIGNED(ptr,offset) ((__packed U32 * RR_GET_PTR_POST)((char *)(ptr) + (offset))) + +#define RR_GET32_BE_UNALIGNED(ptr) __rev(*RR_U32_PTR_OFFSET_UNALIGNED(ptr,0)) +#define RR_GET32_BE_UNALIGNED_OFFSET(ptr,offset) __rev(*RR_U32_PTR_OFFSET_UNALIGNED(ptr,offset)) +#define RR_GET16_BE_UNALIGNED(ptr) __rev16(*RR_U16_PTR_OFFSET_UNALIGNED(ptr,0)) +#define RR_GET16_BE_UNALIGNED_OFFSET(ptr,offset) __rev16(*RR_U16_PTR_OFFSET_UNALIGNED(ptr,offset)) + +#define RR_GET32_LE_UNALIGNED(ptr) *RR_U32_PTR_OFFSET_UNALIGNED(ptr,0) +#define RR_GET32_LE_UNALIGNED_OFFSET(ptr,offset) *RR_U32_PTR_OFFSET_UNALIGNED(ptr,offset) +#define RR_GET16_LE_UNALIGNED(ptr) *RR_U16_PTR_OFFSET_UNALIGNED(ptr,0) +#define RR_GET16_LE_UNALIGNED_OFFSET(ptr,offset) *RR_U16_PTR_OFFSET_UNALIGNED(ptr,offset) + +#elif defined(__RADPSP2__) + +#define RR_U16_PTR_OFFSET_UNALIGNED(ptr,offset) ((U16 __unaligned * RR_GET_PTR_POST)((char *)(ptr) + (offset))) +#define RR_U32_PTR_OFFSET_UNALIGNED(ptr,offset) ((U32 __unaligned * RR_GET_PTR_POST)((char *)(ptr) + (offset))) + +#define RR_GET32_BE_UNALIGNED(ptr) RR_BSWAP32(*RR_U32_PTR_OFFSET_UNALIGNED(ptr,0)) +#define RR_GET32_BE_UNALIGNED_OFFSET(ptr,offset) RR_BSWAP32(*RR_U32_PTR_OFFSET_UNALIGNED(ptr,offset)) +#define RR_GET16_BE_UNALIGNED(ptr) RR_BSWAP16(*RR_U16_PTR_OFFSET_UNALIGNED(ptr,0)) +#define RR_GET16_BE_UNALIGNED_OFFSET(ptr,offset) RR_BSWAP16(*RR_U16_PTR_OFFSET_UNALIGNED(ptr,offset)) + +#define RR_GET32_LE_UNALIGNED(ptr) *RR_U32_PTR_OFFSET_UNALIGNED(ptr,0) +#define RR_GET32_LE_UNALIGNED_OFFSET(ptr,offset) *RR_U32_PTR_OFFSET_UNALIGNED(ptr,offset) +#define RR_GET16_LE_UNALIGNED(ptr) *RR_U16_PTR_OFFSET_UNALIGNED(ptr,0) +#define RR_GET16_LE_UNALIGNED_OFFSET(ptr,offset) *RR_U16_PTR_OFFSET_UNALIGNED(ptr,offset) + +#else +// Unaligned via bytes : + +#define RR_GET32_BE_UNALIGNED(ptr) ( \ + ( (U32)(((const U8 * RR_GET_PTR_POST)(ptr)))[0] << 24 ) | \ + ( (U32)(((const U8 * RR_GET_PTR_POST)(ptr)))[1] << 16 ) | \ + ( (U32)(((const U8 * RR_GET_PTR_POST)(ptr)))[2] << 8 ) | \ + ( (U32)(((const U8 * RR_GET_PTR_POST)(ptr)))[3] << 0 ) ) + +#define RR_GET32_BE_UNALIGNED_OFFSET(ptr,offset) ( \ + ( (U32)(((const U8 * RR_GET_PTR_POST)(ptr))+(offset))[0] << 24 ) | \ + ( (U32)(((const U8 * RR_GET_PTR_POST)(ptr))+(offset))[1] << 16 ) | \ + ( (U32)(((const U8 * RR_GET_PTR_POST)(ptr))+(offset))[2] << 8 ) | \ + ( (U32)(((const U8 * RR_GET_PTR_POST)(ptr))+(offset))[3] << 0 ) ) + +#define RR_GET16_BE_UNALIGNED(ptr) ( \ + ( (U16)(((const U8 * RR_GET_PTR_POST)(ptr)))[0] << 8 ) | \ + ( (U16)(((const U8 * RR_GET_PTR_POST)(ptr)))[1] << 0 ) ) + +#define RR_GET16_BE_UNALIGNED_OFFSET(ptr,offset) ( \ + ( (U16)(((const U8 * RR_GET_PTR_POST)(ptr))+(offset))[0] << 8 ) | \ + ( (U16)(((const U8 * RR_GET_PTR_POST)(ptr))+(offset))[1] << 0 ) ) + +#define RR_GET32_LE_UNALIGNED(ptr) ( \ + ( (U32)(((const U8 * RR_GET_PTR_POST)(ptr)))[3] << 24 ) | \ + ( (U32)(((const U8 * RR_GET_PTR_POST)(ptr)))[2] << 16 ) | \ + ( (U32)(((const U8 * RR_GET_PTR_POST)(ptr)))[1] << 8 ) | \ + ( (U32)(((const U8 * RR_GET_PTR_POST)(ptr)))[0] << 0 ) ) + +#define RR_GET32_LE_UNALIGNED_OFFSET(ptr,offset) ( \ + ( (U32)(((const U8 * RR_GET_PTR_POST)(ptr))+(offset))[3] << 24 ) | \ + ( (U32)(((const U8 * RR_GET_PTR_POST)(ptr))+(offset))[2] << 16 ) | \ + ( (U32)(((const U8 * RR_GET_PTR_POST)(ptr))+(offset))[1] << 8 ) | \ + ( (U32)(((const U8 * RR_GET_PTR_POST)(ptr))+(offset))[0] << 0 ) ) + +#define RR_GET16_LE_UNALIGNED(ptr) ( \ + ( (U16)(((const U8 * RR_GET_PTR_POST)(ptr)))[1] << 8 ) | \ + ( (U16)(((const U8 * RR_GET_PTR_POST)(ptr)))[0] << 0 ) ) + +#define RR_GET16_LE_UNALIGNED_OFFSET(ptr,offset) ( \ + ( (U16)(((const U8 * RR_GET_PTR_POST)(ptr))+(offset))[1] << 8 ) | \ + ( (U16)(((const U8 * RR_GET_PTR_POST)(ptr))+(offset))[0] << 0 ) ) + +#endif + +//=================================================================== +// RR_ROTL32 : 32-bit rotate +// + +#ifdef _MSC_VER + + unsigned long __cdecl _lrotl(unsigned long, int); + #pragma intrinsic(_lrotl) + + #define RR_ROTL32(x,k) _lrotl((unsigned long)(x),(int)(k)) + +#elif defined(__RADCELL__) || defined(__RADLINUX__) || defined(__RADWII__) || defined(__RADMACAPI__) || defined(__RADWIIU__) || defined(__RADPS4__) || defined(__RADPSP2__) + + // Compiler turns this into rotate correctly : + #define RR_ROTL32(u32,num) ( ( (u32) << (num) ) | ( (u32) >> (32 - (num))) ) + +#elif defined(__RAD3DS__) + + #define RR_ROTL32(u32,num) __ror(u32, (-(num))&31) + +#else + +// comment out fallbacks so users will get errors +// fallback implementation using shift and or : +//#define RR_ROTL32(u32,num) ( ( (u32) << (num) ) | ( (u32) >> (32 - (num))) ) + +#endif + + +//=================================================================== +// RR_ROTL64 : 64-bit rotate + +#if ( defined(_MSC_VER) && _MSC_VER >= 1300) + +unsigned __int64 __cdecl _rotl64(unsigned __int64 _Val, int _Shift); +#pragma intrinsic(_rotl64) + +#define RR_ROTL64(x,k) _rotl64((unsigned __int64)(x),(int)(k)) + +#elif defined(__RADCELL__) + +// PS3 GCC turns this into rotate correctly : +#define RR_ROTL64(u64,num) ( ( (u64) << (num) ) | ( (u64) >> (64 - (num))) ) + +#elif defined(__RADLINUX__) || defined(__RADMACAPI__) + +//APTODO: Just to compile linux. Should we be doing better than this? If not, combine with above. +#define RR_ROTL64(u64,num) ( ( (u64) << (num) ) | ( (u64) >> (64 - (num))) ) + +#else + +// comment out fallbacks so users will get errors +// fallback implementation using shift and or : +//#define RR_ROTL64(u64,num) ( ( (u64) << (num) ) | ( (u64) >> (64 - (num))) ) + +#endif + +//=================================================================== + +RADDEFEND + +//=================================================================== + +// RR_COMPILER_ASSERT +#if defined(__cplusplus) && !defined(RR_COMPILER_ASSERT) + #if defined(_MSC_VER) && (_MSC_VER >=1400) + + // better version of COMPILER_ASSERT using boost technique + template struct RR_COMPILER_ASSERT_FAILURE; + + template <> struct RR_COMPILER_ASSERT_FAILURE<1> { enum { value = 1 }; }; + + template struct rr_compiler_assert_test{}; + + // __LINE__ macro broken when -ZI is used see Q199057 + #define RR_COMPILER_ASSERT( B ) \ + typedef rr_compiler_assert_test<\ + sizeof(RR_COMPILER_ASSERT_FAILURE< (B) ? 1 : 0 >)\ + > rr_compiler_assert_typedef_ + + #endif +#endif + +#ifndef RR_COMPILER_ASSERT + // this happens at declaration time, so if it's inside a function in a C file, drop {} around it + #define RR_COMPILER_ASSERT(exp) typedef char RR_STRING_JOIN(_dummy_array, __LINE__) [ (exp) ? 1 : -1 ] +#endif + +//=================================================================== +// some error checks : + + RR_COMPILER_ASSERT( sizeof(RAD_UINTa) == sizeof( RR_STRING_JOIN(RAD_U,RAD_PTRBITS) ) ); + RR_COMPILER_ASSERT( sizeof(RAD_UINTa) == RAD_PTRBYTES ); + RR_COMPILER_ASSERT( RAD_TWOPTRBYTES == 2* RAD_PTRBYTES ); + +//=================================================================== + + #endif // __RADRES__ + +//include "testconstant.inl" // uncomment and include to test statement constants + +#endif // __RADRR_COREH__ + + diff --git a/Minecraft.Client/Windows64/Iggy/lib/iggy_w32.lib b/Minecraft.Client/Windows64/Iggy/lib/iggy_w32.lib new file mode 100644 index 00000000..3c6ad976 Binary files /dev/null and b/Minecraft.Client/Windows64/Iggy/lib/iggy_w32.lib differ diff --git a/Minecraft.Client/Windows64/Iggy/lib/iggy_w64.lib b/Minecraft.Client/Windows64/Iggy/lib/iggy_w64.lib new file mode 100644 index 00000000..64effcbf Binary files /dev/null and b/Minecraft.Client/Windows64/Iggy/lib/iggy_w64.lib differ diff --git a/Minecraft.Client/Windows64/Iggy/lib/iggyexpruntime_w32.lib b/Minecraft.Client/Windows64/Iggy/lib/iggyexpruntime_w32.lib new file mode 100644 index 00000000..06905e7c Binary files /dev/null and b/Minecraft.Client/Windows64/Iggy/lib/iggyexpruntime_w32.lib differ diff --git a/Minecraft.Client/Windows64/Iggy/lib/iggyexpruntime_w64.lib b/Minecraft.Client/Windows64/Iggy/lib/iggyexpruntime_w64.lib new file mode 100644 index 00000000..693fa9a2 Binary files /dev/null and b/Minecraft.Client/Windows64/Iggy/lib/iggyexpruntime_w64.lib differ diff --git a/Minecraft.Client/Windows64/Iggy/lib/iggyperfmon_w32.lib b/Minecraft.Client/Windows64/Iggy/lib/iggyperfmon_w32.lib new file mode 100644 index 00000000..25ba046e Binary files /dev/null and b/Minecraft.Client/Windows64/Iggy/lib/iggyperfmon_w32.lib differ diff --git a/Minecraft.Client/Windows64/Iggy/lib/iggyperfmon_w64.lib b/Minecraft.Client/Windows64/Iggy/lib/iggyperfmon_w64.lib new file mode 100644 index 00000000..e5885929 Binary files /dev/null and b/Minecraft.Client/Windows64/Iggy/lib/iggyperfmon_w64.lib differ diff --git a/Minecraft.Client/Windows64/Iggy/lib/redist64/iggy_w64.dll b/Minecraft.Client/Windows64/Iggy/lib/redist64/iggy_w64.dll new file mode 100644 index 00000000..bd2cbd7e Binary files /dev/null and b/Minecraft.Client/Windows64/Iggy/lib/redist64/iggy_w64.dll differ -- cgit v1.2.3