diff options
| author | daoge_cmd <3523206925@qq.com> | 2026-03-01 12:16:08 +0800 |
|---|---|---|
| committer | daoge_cmd <3523206925@qq.com> | 2026-03-01 12:16:08 +0800 |
| commit | b691c43c44ff180d10e7d4a9afc83b98551ff586 (patch) | |
| tree | 3e9849222cbc6ba49f2f1fc6e5fe7179632c7390 /Minecraft.Client/Windows64/Iggy/gdraw | |
| parent | def8cb415354ac390b7e89052a50605285f1aca9 (diff) | |
Initial commit
Diffstat (limited to 'Minecraft.Client/Windows64/Iggy/gdraw')
| -rw-r--r-- | Minecraft.Client/Windows64/Iggy/gdraw/gdraw_d3d.cpp | 2228 | ||||
| -rw-r--r-- | Minecraft.Client/Windows64/Iggy/gdraw/gdraw_d3d.h | 107 | ||||
| -rw-r--r-- | Minecraft.Client/Windows64/Iggy/gdraw/gdraw_d3d10.cpp | 138 | ||||
| -rw-r--r-- | Minecraft.Client/Windows64/Iggy/gdraw/gdraw_d3d10.h | 132 | ||||
| -rw-r--r-- | Minecraft.Client/Windows64/Iggy/gdraw/gdraw_d3d10_shaders.inl | 3427 | ||||
| -rw-r--r-- | Minecraft.Client/Windows64/Iggy/gdraw/gdraw_d3d11.cpp | 147 | ||||
| -rw-r--r-- | Minecraft.Client/Windows64/Iggy/gdraw/gdraw_d3d11.h | 139 | ||||
| -rw-r--r-- | Minecraft.Client/Windows64/Iggy/gdraw/gdraw_d3d1x_shared.inl | 2491 | ||||
| -rw-r--r-- | Minecraft.Client/Windows64/Iggy/gdraw/gdraw_d3d9_shaders.inl | 1075 | ||||
| -rw-r--r-- | Minecraft.Client/Windows64/Iggy/gdraw/gdraw_gl_shaders.inl | 1084 | ||||
| -rw-r--r-- | Minecraft.Client/Windows64/Iggy/gdraw/gdraw_gl_shared.inl | 2428 | ||||
| -rw-r--r-- | Minecraft.Client/Windows64/Iggy/gdraw/gdraw_shared.inl | 2595 | ||||
| -rw-r--r-- | Minecraft.Client/Windows64/Iggy/gdraw/gdraw_wgl.c | 202 | ||||
| -rw-r--r-- | Minecraft.Client/Windows64/Iggy/gdraw/gdraw_wgl.h | 38 |
14 files changed, 16231 insertions, 0 deletions
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 <windows.h> +#include <d3d9.h> +#include <string.h> +#include <math.h> + +// 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>..<w,h> + 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<typename T> +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 <windows.h> +#include <d3d10.h> +#include "gdraw.h" +#include "iggy.h" +#include <string.h> +#include <math.h> + +#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 <windows.h> +#include <d3d11.h> +#include "gdraw.h" +#include "iggy.h" +#include <string.h> +#include <math.h> + +#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>..<w,h> + 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<typename T> +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>..<w,h> -- 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 <assert.h> +#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 <stdio.h> + +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 "<sentinel>"; + 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 <stdlib.h> +#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 <windows.h> +#include <gl/gl.h> +#include "glext.h" +#include <string.h> +#include <math.h> + +#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) \ + /* <end> */ + +#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 |
