diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/glx/x11/dri2_glx.c | 7 | ||||
-rw-r--r-- | src/glx/x11/dri_common.c | 2 | ||||
-rw-r--r-- | src/glx/x11/glxcmds.c | 1 | ||||
-rw-r--r-- | src/glx/x11/single2.c | 5 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_clip_state.c | 16 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_draw.c | 1 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_draw_upload.c | 1 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_sf_state.c | 3 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_urb.c | 41 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_vs_state.c | 16 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_wm_state.c | 9 | ||||
-rw-r--r-- | src/mesa/shader/prog_print.c | 10 | ||||
-rw-r--r-- | src/mesa/shader/prog_print.h | 3 | ||||
-rw-r--r-- | src/mesa/shader/slang/library/slang_common_builtin.gc | 1 | ||||
-rw-r--r-- | src/mesa/shader/slang/library/slang_common_builtin_gc.h | 369 | ||||
-rw-r--r-- | src/mesa/shader/slang/slang_builtin.c | 8 | ||||
-rw-r--r-- | src/mesa/shader/slang/slang_codegen.c | 20 | ||||
-rw-r--r-- | src/mesa/shader/slang/slang_emit.c | 628 | ||||
-rw-r--r-- | src/mesa/shader/slang/slang_ir.c | 18 | ||||
-rw-r--r-- | src/mesa/shader/slang/slang_ir.h | 1 |
20 files changed, 660 insertions, 500 deletions
diff --git a/src/glx/x11/dri2_glx.c b/src/glx/x11/dri2_glx.c index c16df6b7c2..2bee67780b 100644 --- a/src/glx/x11/dri2_glx.c +++ b/src/glx/x11/dri2_glx.c @@ -186,11 +186,12 @@ static __GLXDRIdrawable *dri2CreateDrawable(__GLXscreenConfigs *psc, static void dri2CopySubBuffer(__GLXDRIdrawable *pdraw, int x, int y, int width, int height) { + __GLXDRIdrawablePrivate *priv = (__GLXDRIdrawablePrivate *) pdraw; XRectangle xrect; XserverRegion region; xrect.x = x; - xrect.y = y; + xrect.y = priv->height - y - height; xrect.width = width; xrect.height = height; @@ -331,7 +332,11 @@ static __GLXDRIscreen *dri2CreateScreen(__GLXscreenConfigs *psc, int screen, psp->createContext = dri2CreateContext; psp->createDrawable = dri2CreateDrawable; psp->swapBuffers = dri2SwapBuffers; + + /* DRI2 suports SubBuffer through DRI2CopyRegion, so it's always + * available.*/ psp->copySubBuffer = dri2CopySubBuffer; + __glXEnableDirectExtension(psc, "GLX_MESA_copy_sub_buffer"); Xfree(driverName); Xfree(deviceName); diff --git a/src/glx/x11/dri_common.c b/src/glx/x11/dri_common.c index fcb579f3bf..4fda649e59 100644 --- a/src/glx/x11/dri_common.c +++ b/src/glx/x11/dri_common.c @@ -340,7 +340,7 @@ driBindExtensions(__GLXscreenConfigs *psc, int dri2) #ifdef __DRI_COPY_SUB_BUFFER if (strcmp(extensions[i]->name, __DRI_COPY_SUB_BUFFER) == 0) { psc->driCopySubBuffer = (__DRIcopySubBufferExtension *) extensions[i]; - __glXEnableDirectExtension(psc, "GLX_MESA_copy_sub_buffer_bit"); + __glXEnableDirectExtension(psc, "GLX_MESA_copy_sub_buffer"); } #endif diff --git a/src/glx/x11/glxcmds.c b/src/glx/x11/glxcmds.c index 4e2641bd69..391e0be05e 100644 --- a/src/glx/x11/glxcmds.c +++ b/src/glx/x11/glxcmds.c @@ -2500,6 +2500,7 @@ static void __glXCopySubBufferMESA(Display *dpy, GLXDrawable drawable, if ( pdraw != NULL ) { __GLXscreenConfigs * const psc = GetGLXScreenConfigs(dpy, screen); if (psc->driScreen->copySubBuffer != NULL) { + glFlush(); (*psc->driScreen->copySubBuffer)(pdraw, x, y, width, height); } diff --git a/src/glx/x11/single2.c b/src/glx/x11/single2.c index fc9c63a464..b008c6996c 100644 --- a/src/glx/x11/single2.c +++ b/src/glx/x11/single2.c @@ -37,6 +37,11 @@ #include "indirect_vertex_array.h" #include "dispatch.h" #include "glapi.h" +#ifdef USE_XCB +#include <xcb/xcb.h> +#include <xcb/glx.h> +#endif /* USE_XCB */ + /* Used for GL_ARB_transpose_matrix */ static void diff --git a/src/mesa/drivers/dri/i965/brw_clip_state.c b/src/mesa/drivers/dri/i965/brw_clip_state.c index 740c7cbd10..9b0d7eab7b 100644 --- a/src/mesa/drivers/dri/i965/brw_clip_state.c +++ b/src/mesa/drivers/dri/i965/brw_clip_state.c @@ -88,7 +88,21 @@ clip_unit_create_from_key(struct brw_context *brw, clip.thread4.nr_urb_entries = key->nr_urb_entries; clip.thread4.urb_entry_allocation_size = key->urb_size - 1; - clip.thread4.max_threads = 1; /* 2 threads */ + /* If we have enough clip URB entries to run two threads, do so. + */ + if (key->nr_urb_entries >= 10) { + /* Half of the URB entries go to each thread, and it has to be an + * even number. + */ + assert(key->nr_urb_entries % 2 == 0); + clip.thread4.max_threads = 2 - 1; + } else { + assert(key->nr_urb_entries >= 5); + clip.thread4.max_threads = 1 - 1; + } + + if (INTEL_DEBUG & DEBUG_SINGLE_THREAD) + clip.thread4.max_threads = 0; if (INTEL_DEBUG & DEBUG_STATS) clip.thread4.stats_enable = 1; diff --git a/src/mesa/drivers/dri/i965/brw_draw.c b/src/mesa/drivers/dri/i965/brw_draw.c index d87b8f8a84..f893dd6742 100644 --- a/src/mesa/drivers/dri/i965/brw_draw.c +++ b/src/mesa/drivers/dri/i965/brw_draw.c @@ -105,6 +105,7 @@ static GLuint brw_set_prim(struct brw_context *brw, GLenum prim) } brw_validate_state(brw); + brw_upload_state(brw); } return hw_prim[prim]; diff --git a/src/mesa/drivers/dri/i965/brw_draw_upload.c b/src/mesa/drivers/dri/i965/brw_draw_upload.c index 4080c5e322..73d6dea01e 100644 --- a/src/mesa/drivers/dri/i965/brw_draw_upload.c +++ b/src/mesa/drivers/dri/i965/brw_draw_upload.c @@ -353,6 +353,7 @@ static void brw_prepare_vertices(struct brw_context *brw) intel_buffer_object(input->glarray->BufferObj); /* Named buffer object: Just reference its contents directly. */ + dri_bo_unreference(input->bo); input->bo = intel_bufferobj_buffer(intel, intel_buffer, INTEL_READ); dri_bo_reference(input->bo); diff --git a/src/mesa/drivers/dri/i965/brw_sf_state.c b/src/mesa/drivers/dri/i965/brw_sf_state.c index 4f925d1810..506126fcfb 100644 --- a/src/mesa/drivers/dri/i965/brw_sf_state.c +++ b/src/mesa/drivers/dri/i965/brw_sf_state.c @@ -172,7 +172,8 @@ sf_unit_create_from_key(struct brw_context *brw, struct brw_sf_unit_key *key, sf.thread4.nr_urb_entries = key->nr_urb_entries; sf.thread4.urb_entry_allocation_size = key->sfsize - 1; - sf.thread4.max_threads = MIN2(12, key->nr_urb_entries / 2) - 1; + /* Each SF thread produces 1 PUE, and there can be up to 24 threads */ + sf.thread4.max_threads = MIN2(24, key->nr_urb_entries) - 1; if (INTEL_DEBUG & DEBUG_SINGLE_THREAD) sf.thread4.max_threads = 0; diff --git a/src/mesa/drivers/dri/i965/brw_urb.c b/src/mesa/drivers/dri/i965/brw_urb.c index 1a004176de..7673dd36eb 100644 --- a/src/mesa/drivers/dri/i965/brw_urb.c +++ b/src/mesa/drivers/dri/i965/brw_urb.c @@ -42,7 +42,44 @@ #define SF 3 #define CS 4 -/* XXX: Are the min_entry_size numbers useful? +/** @file brw_urb.c + * + * Manages the division of the URB space between the various fixed-function + * units. + * + * See the Thread Initiation Management section of the GEN4 B-Spec, and + * the individual *_STATE structures for restrictions on numbers of + * entries and threads. + */ + +/* + * Generally, a unit requires a min_nr_entries based on how many entries + * it produces before the downstream unit gets unblocked and can use and + * dereference some of its handles. + * + * The SF unit preallocates a PUE at the start of thread dispatch, and only + * uses that one. So it requires one entry per thread. + * + * For CLIP, the SF unit will hold the previous primitive while the + * next is getting assembled, meaning that linestrips require 3 CLIP VUEs + * (vertices) to ensure continued processing, trifans require 4, and tristrips + * require 5. There can be 1 or 2 threads, and each has the same requirement. + * + * GS has the same requirement as CLIP, but it never handles tristrips, + * so we can lower the minimum to 4 for the POLYGONs (trifans) it produces. + * We only run it single-threaded. + * + * For VS, the number of entries may be 8, 12, 16, or 32 (or 64 on G4X). + * Each thread processes 2 preallocated VUEs (vertices) at a time, and they + * get streamed down as soon as threads processing earlier vertices get + * theirs accepted. + * + * Each unit will take the number of URB entries we give it (based on the + * entry size calculated in brw_vs_emit.c for VUEs, brw_sf_emit.c for PUEs, + * and brw_curbe.c for the CURBEs) and decide its maximum number of + * threads it can support based on that. in brw_*_state.c. + * + * XXX: Are the min_entry_size numbers useful? * XXX: Verify min_nr_entries, esp for VS. * XXX: Verify SF min_entry_size. */ @@ -54,7 +91,7 @@ static const struct { } limits[CS+1] = { { 16, 32, 1, 5 }, /* vs */ { 4, 8, 1, 5 }, /* gs */ - { 6, 8, 1, 5 }, /* clp */ + { 5, 10, 1, 5 }, /* clp */ { 1, 8, 1, 12 }, /* sf */ { 1, 4, 1, 32 } /* cs */ }; diff --git a/src/mesa/drivers/dri/i965/brw_vs_state.c b/src/mesa/drivers/dri/i965/brw_vs_state.c index 6e66f54524..942581696d 100644 --- a/src/mesa/drivers/dri/i965/brw_vs_state.c +++ b/src/mesa/drivers/dri/i965/brw_vs_state.c @@ -77,12 +77,19 @@ vs_unit_create_from_key(struct brw_context *brw, struct brw_vs_unit_key *key) { struct brw_vs_unit_state vs; dri_bo *bo; + int chipset_max_threads; memset(&vs, 0, sizeof(vs)); vs.thread0.kernel_start_pointer = brw->vs.prog_bo->offset >> 6; /* reloc */ vs.thread0.grf_reg_count = ALIGN(key->total_grf, 16) / 16 - 1; vs.thread1.floating_point_mode = BRW_FLOATING_POINT_NON_IEEE_754; + /* Choosing multiple program flow means that we may get 2-vertex threads, + * which will have the channel mask for dwords 4-7 enabled in the thread, + * and those dwords will be written to the second URB handle when we + * brw_urb_WRITE() results. + */ + vs.thread1.single_program_flow = 0; vs.thread3.urb_entry_read_length = key->urb_entry_read_length; vs.thread3.const_urb_entry_read_length = key->curb_entry_read_length; vs.thread3.dispatch_grf_start_reg = 1; @@ -91,8 +98,13 @@ vs_unit_create_from_key(struct brw_context *brw, struct brw_vs_unit_key *key) vs.thread4.nr_urb_entries = key->nr_urb_entries; vs.thread4.urb_entry_allocation_size = key->urb_size - 1; - vs.thread4.max_threads = MIN2(MAX2(0, (key->nr_urb_entries - 6) / 2 - 1), - 15); + + if (BRW_IS_G4X(brw)) + chipset_max_threads = 32; + else + chipset_max_threads = 16; + vs.thread4.max_threads = CLAMP(key->nr_urb_entries / 2, + 1, chipset_max_threads) - 1; if (INTEL_DEBUG & DEBUG_SINGLE_THREAD) vs.thread4.max_threads = 0; diff --git a/src/mesa/drivers/dri/i965/brw_wm_state.c b/src/mesa/drivers/dri/i965/brw_wm_state.c index 61fe97a463..fd461618bc 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_state.c +++ b/src/mesa/drivers/dri/i965/brw_wm_state.c @@ -67,8 +67,13 @@ wm_unit_populate_key(struct brw_context *brw, struct brw_wm_unit_key *key) if (INTEL_DEBUG & DEBUG_SINGLE_THREAD) key->max_threads = 1; - else - key->max_threads = 32; + else { + /* WM maximum threads is number of EUs times number of threads per EU. */ + if (BRW_IS_G4X(brw)) + key->max_threads = 10 * 5; + else + key->max_threads = 8 * 4; + } /* CACHE_NEW_WM_PROG */ key->total_grf = brw->wm.prog_data->total_grf; diff --git a/src/mesa/shader/prog_print.c b/src/mesa/shader/prog_print.c index 22b8f1de3c..db6eac4fd9 100644 --- a/src/mesa/shader/prog_print.c +++ b/src/mesa/shader/prog_print.c @@ -215,7 +215,7 @@ reg_string(enum register_file f, GLint index, gl_prog_print_mode mode, switch (mode) { case PROG_PRINT_DEBUG: if (relAddr) - sprintf(str, "%s[ADDR%s%d]", file_string(f, mode), (index > 0) ? "+" : "", index); + sprintf(str, "%s[ADDR+%d]", file_string(f, mode), index); else sprintf(str, "%s[%d]", file_string(f, mode), index); break; @@ -371,8 +371,8 @@ _mesa_print_swizzle(GLuint swizzle) } -static const char * -writemask_string(GLuint writeMask) +const char * +_mesa_writemask_string(GLuint writeMask) { static char s[10]; GLuint i = 0; @@ -420,7 +420,7 @@ print_dst_reg(const struct prog_dst_register *dstReg, gl_prog_print_mode mode, _mesa_printf("%s%s", reg_string((enum register_file) dstReg->File, dstReg->Index, mode, dstReg->RelAddr, prog), - writemask_string(dstReg->WriteMask)); + _mesa_writemask_string(dstReg->WriteMask)); if (dstReg->CondMask != COND_TR) { _mesa_printf(" (%s.%s)", @@ -432,7 +432,7 @@ print_dst_reg(const struct prog_dst_register *dstReg, gl_prog_print_mode mode, _mesa_printf("%s[%d]%s", file_string((enum register_file) dstReg->File, mode), dstReg->Index, - writemask_string(dstReg->WriteMask)); + _mesa_writemask_string(dstReg->WriteMask)); #endif } diff --git a/src/mesa/shader/prog_print.h b/src/mesa/shader/prog_print.h index 3cdb1b195e..3966909aed 100644 --- a/src/mesa/shader/prog_print.h +++ b/src/mesa/shader/prog_print.h @@ -43,6 +43,9 @@ _mesa_condcode_string(GLuint condcode); extern const char * _mesa_swizzle_string(GLuint swizzle, GLuint negateBase, GLboolean extended); +const char * +_mesa_writemask_string(GLuint writeMask); + extern void _mesa_print_swizzle(GLuint swizzle); diff --git a/src/mesa/shader/slang/library/slang_common_builtin.gc b/src/mesa/shader/slang/library/slang_common_builtin.gc index 561e94f6ba..a051c53eea 100644 --- a/src/mesa/shader/slang/library/slang_common_builtin.gc +++ b/src/mesa/shader/slang/library/slang_common_builtin.gc @@ -47,7 +47,6 @@ uniform mat4 gl_ModelViewProjectionMatrix; uniform mat4 gl_TextureMatrix[gl_MaxTextureCoords]; uniform mat3 gl_NormalMatrix; -uniform mat3 __NormalMatrixTranspose; // Mesa only uniform mat4 gl_ModelViewMatrixInverse; uniform mat4 gl_ProjectionMatrixInverse; diff --git a/src/mesa/shader/slang/library/slang_common_builtin_gc.h b/src/mesa/shader/slang/library/slang_common_builtin_gc.h index 1dc4825b37..dfe406c233 100644 --- a/src/mesa/shader/slang/library/slang_common_builtin_gc.h +++ b/src/mesa/shader/slang/library/slang_common_builtin_gc.h @@ -22,193 +22,192 @@ 100,101,108,86,105,101,119,80,114,111,106,101,99,116,105,111,110,77,97,116,114,105,120,0,0,0,2,2, 90,95,4,0,15,1,103,108,95,84,101,120,116,117,114,101,77,97,116,114,105,120,0,3,18,103,108,95,77,97, 120,84,101,120,116,117,114,101,67,111,111,114,100,115,0,0,0,2,2,90,95,4,0,14,1,103,108,95,78,111, -114,109,97,108,77,97,116,114,105,120,0,0,0,2,2,90,95,4,0,14,1,95,95,78,111,114,109,97,108,77,97, -116,114,105,120,84,114,97,110,115,112,111,115,101,0,0,0,2,2,90,95,4,0,15,1,103,108,95,77,111,100, -101,108,86,105,101,119,77,97,116,114,105,120,73,110,118,101,114,115,101,0,0,0,2,2,90,95,4,0,15,1, -103,108,95,80,114,111,106,101,99,116,105,111,110,77,97,116,114,105,120,73,110,118,101,114,115,101, -0,0,0,2,2,90,95,4,0,15,1,103,108,95,77,111,100,101,108,86,105,101,119,80,114,111,106,101,99,116, -105,111,110,77,97,116,114,105,120,73,110,118,101,114,115,101,0,0,0,2,2,90,95,4,0,15,1,103,108,95, -84,101,120,116,117,114,101,77,97,116,114,105,120,73,110,118,101,114,115,101,0,3,18,103,108,95,77, -97,120,84,101,120,116,117,114,101,67,111,111,114,100,115,0,0,0,2,2,90,95,4,0,15,1,103,108,95,77, -111,100,101,108,86,105,101,119,77,97,116,114,105,120,84,114,97,110,115,112,111,115,101,0,0,0,2,2, -90,95,4,0,15,1,103,108,95,80,114,111,106,101,99,116,105,111,110,77,97,116,114,105,120,84,114,97, -110,115,112,111,115,101,0,0,0,2,2,90,95,4,0,15,1,103,108,95,77,111,100,101,108,86,105,101,119,80, -114,111,106,101,99,116,105,111,110,77,97,116,114,105,120,84,114,97,110,115,112,111,115,101,0,0,0,2, -2,90,95,4,0,15,1,103,108,95,84,101,120,116,117,114,101,77,97,116,114,105,120,84,114,97,110,115,112, -111,115,101,0,3,18,103,108,95,77,97,120,84,101,120,116,117,114,101,67,111,111,114,100,115,0,0,0,2, -2,90,95,4,0,15,1,103,108,95,77,111,100,101,108,86,105,101,119,77,97,116,114,105,120,73,110,118,101, -114,115,101,84,114,97,110,115,112,111,115,101,0,0,0,2,2,90,95,4,0,15,1,103,108,95,80,114,111,106, -101,99,116,105,111,110,77,97,116,114,105,120,73,110,118,101,114,115,101,84,114,97,110,115,112,111, +114,109,97,108,77,97,116,114,105,120,0,0,0,2,2,90,95,4,0,15,1,103,108,95,77,111,100,101,108,86,105, +101,119,77,97,116,114,105,120,73,110,118,101,114,115,101,0,0,0,2,2,90,95,4,0,15,1,103,108,95,80, +114,111,106,101,99,116,105,111,110,77,97,116,114,105,120,73,110,118,101,114,115,101,0,0,0,2,2,90, +95,4,0,15,1,103,108,95,77,111,100,101,108,86,105,101,119,80,114,111,106,101,99,116,105,111,110,77, +97,116,114,105,120,73,110,118,101,114,115,101,0,0,0,2,2,90,95,4,0,15,1,103,108,95,84,101,120,116, +117,114,101,77,97,116,114,105,120,73,110,118,101,114,115,101,0,3,18,103,108,95,77,97,120,84,101, +120,116,117,114,101,67,111,111,114,100,115,0,0,0,2,2,90,95,4,0,15,1,103,108,95,77,111,100,101,108, +86,105,101,119,77,97,116,114,105,120,84,114,97,110,115,112,111,115,101,0,0,0,2,2,90,95,4,0,15,1, +103,108,95,80,114,111,106,101,99,116,105,111,110,77,97,116,114,105,120,84,114,97,110,115,112,111, 115,101,0,0,0,2,2,90,95,4,0,15,1,103,108,95,77,111,100,101,108,86,105,101,119,80,114,111,106,101, -99,116,105,111,110,77,97,116,114,105,120,73,110,118,101,114,115,101,84,114,97,110,115,112,111,115, -101,0,0,0,2,2,90,95,4,0,15,1,103,108,95,84,101,120,116,117,114,101,77,97,116,114,105,120,73,110, -118,101,114,115,101,84,114,97,110,115,112,111,115,101,0,3,18,103,108,95,77,97,120,84,101,120,116, -117,114,101,67,111,111,114,100,115,0,0,0,2,2,90,95,4,0,9,1,103,108,95,78,111,114,109,97,108,83,99, -97,108,101,0,0,0,2,2,90,95,0,0,24,103,108,95,68,101,112,116,104,82,97,110,103,101,80,97,114,97,109, -101,116,101,114,115,0,9,110,101,97,114,0,0,0,1,9,102,97,114,0,0,0,1,9,100,105,102,102,0,0,0,0,0,0, -2,2,90,95,4,0,25,103,108,95,68,101,112,116,104,82,97,110,103,101,80,97,114,97,109,101,116,101,114, -115,0,1,103,108,95,68,101,112,116,104,82,97,110,103,101,0,0,0,2,2,90,95,4,0,12,1,103,108,95,67,108, -105,112,80,108,97,110,101,0,3,18,103,108,95,77,97,120,67,108,105,112,80,108,97,110,101,115,0,0,0,2, -2,90,95,0,0,24,103,108,95,80,111,105,110,116,80,97,114,97,109,101,116,101,114,115,0,9,115,105,122, -101,0,0,0,1,9,115,105,122,101,77,105,110,0,0,0,1,9,115,105,122,101,77,97,120,0,0,0,1,9,102,97,100, -101,84,104,114,101,115,104,111,108,100,83,105,122,101,0,0,0,1,9,100,105,115,116,97,110,99,101,67, -111,110,115,116,97,110,116,65,116,116,101,110,117,97,116,105,111,110,0,0,0,1,9,100,105,115,116,97, -110,99,101,76,105,110,101,97,114,65,116,116,101,110,117,97,116,105,111,110,0,0,0,1,9,100,105,115, -116,97,110,99,101,81,117,97,100,114,97,116,105,99,65,116,116,101,110,117,97,116,105,111,110,0,0,0, -0,0,0,2,2,90,95,4,0,25,103,108,95,80,111,105,110,116,80,97,114,97,109,101,116,101,114,115,0,1,103, -108,95,80,111,105,110,116,0,0,0,2,2,90,95,0,0,24,103,108,95,77,97,116,101,114,105,97,108,80,97,114, -97,109,101,116,101,114,115,0,12,101,109,105,115,115,105,111,110,0,0,0,1,12,97,109,98,105,101,110, -116,0,0,0,1,12,100,105,102,102,117,115,101,0,0,0,1,12,115,112,101,99,117,108,97,114,0,0,0,1,9,115, -104,105,110,105,110,101,115,115,0,0,0,0,0,0,2,2,90,95,4,0,25,103,108,95,77,97,116,101,114,105,97, -108,80,97,114,97,109,101,116,101,114,115,0,1,103,108,95,70,114,111,110,116,77,97,116,101,114,105, -97,108,0,0,0,2,2,90,95,4,0,25,103,108,95,77,97,116,101,114,105,97,108,80,97,114,97,109,101,116,101, -114,115,0,1,103,108,95,66,97,99,107,77,97,116,101,114,105,97,108,0,0,0,2,2,90,95,0,0,24,103,108,95, -76,105,103,104,116,83,111,117,114,99,101,80,97,114,97,109,101,116,101,114,115,0,12,97,109,98,105, -101,110,116,0,0,0,1,12,100,105,102,102,117,115,101,0,0,0,1,12,115,112,101,99,117,108,97,114,0,0,0, -1,12,112,111,115,105,116,105,111,110,0,0,0,1,12,104,97,108,102,86,101,99,116,111,114,0,0,0,1,11, -115,112,111,116,68,105,114,101,99,116,105,111,110,0,0,0,1,9,115,112,111,116,69,120,112,111,110,101, -110,116,0,0,0,1,9,115,112,111,116,67,117,116,111,102,102,0,0,0,1,9,115,112,111,116,67,111,115,67, -117,116,111,102,102,0,0,0,1,9,99,111,110,115,116,97,110,116,65,116,116,101,110,117,97,116,105,111, -110,0,0,0,1,9,108,105,110,101,97,114,65,116,116,101,110,117,97,116,105,111,110,0,0,0,1,9,113,117, -97,100,114,97,116,105,99,65,116,116,101,110,117,97,116,105,111,110,0,0,0,0,0,0,2,2,90,95,4,0,25, -103,108,95,76,105,103,104,116,83,111,117,114,99,101,80,97,114,97,109,101,116,101,114,115,0,1,103, -108,95,76,105,103,104,116,83,111,117,114,99,101,0,3,18,103,108,95,77,97,120,76,105,103,104,116,115, -0,0,0,2,2,90,95,0,0,24,103,108,95,76,105,103,104,116,77,111,100,101,108,80,97,114,97,109,101,116, -101,114,115,0,12,97,109,98,105,101,110,116,0,0,0,0,0,0,2,2,90,95,4,0,25,103,108,95,76,105,103,104, -116,77,111,100,101,108,80,97,114,97,109,101,116,101,114,115,0,1,103,108,95,76,105,103,104,116,77, -111,100,101,108,0,0,0,2,2,90,95,0,0,24,103,108,95,76,105,103,104,116,77,111,100,101,108,80,114,111, -100,117,99,116,115,0,12,115,99,101,110,101,67,111,108,111,114,0,0,0,0,0,0,2,2,90,95,4,0,25,103,108, -95,76,105,103,104,116,77,111,100,101,108,80,114,111,100,117,99,116,115,0,1,103,108,95,70,114,111, -110,116,76,105,103,104,116,77,111,100,101,108,80,114,111,100,117,99,116,0,0,0,2,2,90,95,4,0,25,103, -108,95,76,105,103,104,116,77,111,100,101,108,80,114,111,100,117,99,116,115,0,1,103,108,95,66,97,99, -107,76,105,103,104,116,77,111,100,101,108,80,114,111,100,117,99,116,0,0,0,2,2,90,95,0,0,24,103,108, -95,76,105,103,104,116,80,114,111,100,117,99,116,115,0,12,97,109,98,105,101,110,116,0,0,0,1,12,100, -105,102,102,117,115,101,0,0,0,1,12,115,112,101,99,117,108,97,114,0,0,0,0,0,0,2,2,90,95,4,0,25,103, -108,95,76,105,103,104,116,80,114,111,100,117,99,116,115,0,1,103,108,95,70,114,111,110,116,76,105, -103,104,116,80,114,111,100,117,99,116,0,3,18,103,108,95,77,97,120,76,105,103,104,116,115,0,0,0,2,2, -90,95,4,0,25,103,108,95,76,105,103,104,116,80,114,111,100,117,99,116,115,0,1,103,108,95,66,97,99, -107,76,105,103,104,116,80,114,111,100,117,99,116,0,3,18,103,108,95,77,97,120,76,105,103,104,116, -115,0,0,0,2,2,90,95,4,0,12,1,103,108,95,84,101,120,116,117,114,101,69,110,118,67,111,108,111,114,0, -3,18,103,108,95,77,97,120,84,101,120,116,117,114,101,73,109,97,103,101,85,110,105,116,115,0,0,0,2, -2,90,95,4,0,12,1,103,108,95,69,121,101,80,108,97,110,101,83,0,3,18,103,108,95,77,97,120,84,101,120, -116,117,114,101,67,111,111,114,100,115,0,0,0,2,2,90,95,4,0,12,1,103,108,95,69,121,101,80,108,97, -110,101,84,0,3,18,103,108,95,77,97,120,84,101,120,116,117,114,101,67,111,111,114,100,115,0,0,0,2,2, -90,95,4,0,12,1,103,108,95,69,121,101,80,108,97,110,101,82,0,3,18,103,108,95,77,97,120,84,101,120, -116,117,114,101,67,111,111,114,100,115,0,0,0,2,2,90,95,4,0,12,1,103,108,95,69,121,101,80,108,97, -110,101,81,0,3,18,103,108,95,77,97,120,84,101,120,116,117,114,101,67,111,111,114,100,115,0,0,0,2,2, -90,95,4,0,12,1,103,108,95,79,98,106,101,99,116,80,108,97,110,101,83,0,3,18,103,108,95,77,97,120,84, -101,120,116,117,114,101,67,111,111,114,100,115,0,0,0,2,2,90,95,4,0,12,1,103,108,95,79,98,106,101, -99,116,80,108,97,110,101,84,0,3,18,103,108,95,77,97,120,84,101,120,116,117,114,101,67,111,111,114, -100,115,0,0,0,2,2,90,95,4,0,12,1,103,108,95,79,98,106,101,99,116,80,108,97,110,101,82,0,3,18,103, -108,95,77,97,120,84,101,120,116,117,114,101,67,111,111,114,100,115,0,0,0,2,2,90,95,4,0,12,1,103, -108,95,79,98,106,101,99,116,80,108,97,110,101,81,0,3,18,103,108,95,77,97,120,84,101,120,116,117, -114,101,67,111,111,114,100,115,0,0,0,2,2,90,95,0,0,24,103,108,95,70,111,103,80,97,114,97,109,101, -116,101,114,115,0,12,99,111,108,111,114,0,0,0,1,9,100,101,110,115,105,116,121,0,0,0,1,9,115,116,97, -114,116,0,0,0,1,9,101,110,100,0,0,0,1,9,115,99,97,108,101,0,0,0,0,0,0,2,2,90,95,4,0,25,103,108,95, -70,111,103,80,97,114,97,109,101,116,101,114,115,0,1,103,108,95,70,111,103,0,0,0,1,90,95,0,0,9,0, -114,97,100,105,97,110,115,0,1,1,0,0,9,100,101,103,0,0,0,1,3,2,90,95,1,0,9,1,99,0,2,17,51,0,49,52, +99,116,105,111,110,77,97,116,114,105,120,84,114,97,110,115,112,111,115,101,0,0,0,2,2,90,95,4,0,15, +1,103,108,95,84,101,120,116,117,114,101,77,97,116,114,105,120,84,114,97,110,115,112,111,115,101,0, +3,18,103,108,95,77,97,120,84,101,120,116,117,114,101,67,111,111,114,100,115,0,0,0,2,2,90,95,4,0,15, +1,103,108,95,77,111,100,101,108,86,105,101,119,77,97,116,114,105,120,73,110,118,101,114,115,101,84, +114,97,110,115,112,111,115,101,0,0,0,2,2,90,95,4,0,15,1,103,108,95,80,114,111,106,101,99,116,105, +111,110,77,97,116,114,105,120,73,110,118,101,114,115,101,84,114,97,110,115,112,111,115,101,0,0,0,2, +2,90,95,4,0,15,1,103,108,95,77,111,100,101,108,86,105,101,119,80,114,111,106,101,99,116,105,111, +110,77,97,116,114,105,120,73,110,118,101,114,115,101,84,114,97,110,115,112,111,115,101,0,0,0,2,2, +90,95,4,0,15,1,103,108,95,84,101,120,116,117,114,101,77,97,116,114,105,120,73,110,118,101,114,115, +101,84,114,97,110,115,112,111,115,101,0,3,18,103,108,95,77,97,120,84,101,120,116,117,114,101,67, +111,111,114,100,115,0,0,0,2,2,90,95,4,0,9,1,103,108,95,78,111,114,109,97,108,83,99,97,108,101,0,0, +0,2,2,90,95,0,0,24,103,108,95,68,101,112,116,104,82,97,110,103,101,80,97,114,97,109,101,116,101, +114,115,0,9,110,101,97,114,0,0,0,1,9,102,97,114,0,0,0,1,9,100,105,102,102,0,0,0,0,0,0,2,2,90,95,4, +0,25,103,108,95,68,101,112,116,104,82,97,110,103,101,80,97,114,97,109,101,116,101,114,115,0,1,103, +108,95,68,101,112,116,104,82,97,110,103,101,0,0,0,2,2,90,95,4,0,12,1,103,108,95,67,108,105,112,80, +108,97,110,101,0,3,18,103,108,95,77,97,120,67,108,105,112,80,108,97,110,101,115,0,0,0,2,2,90,95,0, +0,24,103,108,95,80,111,105,110,116,80,97,114,97,109,101,116,101,114,115,0,9,115,105,122,101,0,0,0, +1,9,115,105,122,101,77,105,110,0,0,0,1,9,115,105,122,101,77,97,120,0,0,0,1,9,102,97,100,101,84,104, +114,101,115,104,111,108,100,83,105,122,101,0,0,0,1,9,100,105,115,116,97,110,99,101,67,111,110,115, +116,97,110,116,65,116,116,101,110,117,97,116,105,111,110,0,0,0,1,9,100,105,115,116,97,110,99,101, +76,105,110,101,97,114,65,116,116,101,110,117,97,116,105,111,110,0,0,0,1,9,100,105,115,116,97,110, +99,101,81,117,97,100,114,97,116,105,99,65,116,116,101,110,117,97,116,105,111,110,0,0,0,0,0,0,2,2, +90,95,4,0,25,103,108,95,80,111,105,110,116,80,97,114,97,109,101,116,101,114,115,0,1,103,108,95,80, +111,105,110,116,0,0,0,2,2,90,95,0,0,24,103,108,95,77,97,116,101,114,105,97,108,80,97,114,97,109, +101,116,101,114,115,0,12,101,109,105,115,115,105,111,110,0,0,0,1,12,97,109,98,105,101,110,116,0,0, +0,1,12,100,105,102,102,117,115,101,0,0,0,1,12,115,112,101,99,117,108,97,114,0,0,0,1,9,115,104,105, +110,105,110,101,115,115,0,0,0,0,0,0,2,2,90,95,4,0,25,103,108,95,77,97,116,101,114,105,97,108,80,97, +114,97,109,101,116,101,114,115,0,1,103,108,95,70,114,111,110,116,77,97,116,101,114,105,97,108,0,0, +0,2,2,90,95,4,0,25,103,108,95,77,97,116,101,114,105,97,108,80,97,114,97,109,101,116,101,114,115,0, +1,103,108,95,66,97,99,107,77,97,116,101,114,105,97,108,0,0,0,2,2,90,95,0,0,24,103,108,95,76,105, +103,104,116,83,111,117,114,99,101,80,97,114,97,109,101,116,101,114,115,0,12,97,109,98,105,101,110, +116,0,0,0,1,12,100,105,102,102,117,115,101,0,0,0,1,12,115,112,101,99,117,108,97,114,0,0,0,1,12,112, +111,115,105,116,105,111,110,0,0,0,1,12,104,97,108,102,86,101,99,116,111,114,0,0,0,1,11,115,112,111, +116,68,105,114,101,99,116,105,111,110,0,0,0,1,9,115,112,111,116,69,120,112,111,110,101,110,116,0,0, +0,1,9,115,112,111,116,67,117,116,111,102,102,0,0,0,1,9,115,112,111,116,67,111,115,67,117,116,111, +102,102,0,0,0,1,9,99,111,110,115,116,97,110,116,65,116,116,101,110,117,97,116,105,111,110,0,0,0,1, +9,108,105,110,101,97,114,65,116,116,101,110,117,97,116,105,111,110,0,0,0,1,9,113,117,97,100,114,97, +116,105,99,65,116,116,101,110,117,97,116,105,111,110,0,0,0,0,0,0,2,2,90,95,4,0,25,103,108,95,76, +105,103,104,116,83,111,117,114,99,101,80,97,114,97,109,101,116,101,114,115,0,1,103,108,95,76,105, +103,104,116,83,111,117,114,99,101,0,3,18,103,108,95,77,97,120,76,105,103,104,116,115,0,0,0,2,2,90, +95,0,0,24,103,108,95,76,105,103,104,116,77,111,100,101,108,80,97,114,97,109,101,116,101,114,115,0, +12,97,109,98,105,101,110,116,0,0,0,0,0,0,2,2,90,95,4,0,25,103,108,95,76,105,103,104,116,77,111,100, +101,108,80,97,114,97,109,101,116,101,114,115,0,1,103,108,95,76,105,103,104,116,77,111,100,101,108, +0,0,0,2,2,90,95,0,0,24,103,108,95,76,105,103,104,116,77,111,100,101,108,80,114,111,100,117,99,116, +115,0,12,115,99,101,110,101,67,111,108,111,114,0,0,0,0,0,0,2,2,90,95,4,0,25,103,108,95,76,105,103, +104,116,77,111,100,101,108,80,114,111,100,117,99,116,115,0,1,103,108,95,70,114,111,110,116,76,105, +103,104,116,77,111,100,101,108,80,114,111,100,117,99,116,0,0,0,2,2,90,95,4,0,25,103,108,95,76,105, +103,104,116,77,111,100,101,108,80,114,111,100,117,99,116,115,0,1,103,108,95,66,97,99,107,76,105, +103,104,116,77,111,100,101,108,80,114,111,100,117,99,116,0,0,0,2,2,90,95,0,0,24,103,108,95,76,105, +103,104,116,80,114,111,100,117,99,116,115,0,12,97,109,98,105,101,110,116,0,0,0,1,12,100,105,102, +102,117,115,101,0,0,0,1,12,115,112,101,99,117,108,97,114,0,0,0,0,0,0,2,2,90,95,4,0,25,103,108,95, +76,105,103,104,116,80,114,111,100,117,99,116,115,0,1,103,108,95,70,114,111,110,116,76,105,103,104, +116,80,114,111,100,117,99,116,0,3,18,103,108,95,77,97,120,76,105,103,104,116,115,0,0,0,2,2,90,95,4, +0,25,103,108,95,76,105,103,104,116,80,114,111,100,117,99,116,115,0,1,103,108,95,66,97,99,107,76, +105,103,104,116,80,114,111,100,117,99,116,0,3,18,103,108,95,77,97,120,76,105,103,104,116,115,0,0,0, +2,2,90,95,4,0,12,1,103,108,95,84,101,120,116,117,114,101,69,110,118,67,111,108,111,114,0,3,18,103, +108,95,77,97,120,84,101,120,116,117,114,101,73,109,97,103,101,85,110,105,116,115,0,0,0,2,2,90,95,4, +0,12,1,103,108,95,69,121,101,80,108,97,110,101,83,0,3,18,103,108,95,77,97,120,84,101,120,116,117, +114,101,67,111,111,114,100,115,0,0,0,2,2,90,95,4,0,12,1,103,108,95,69,121,101,80,108,97,110,101,84, +0,3,18,103,108,95,77,97,120,84,101,120,116,117,114,101,67,111,111,114,100,115,0,0,0,2,2,90,95,4,0, +12,1,103,108,95,69,121,101,80,108,97,110,101,82,0,3,18,103,108,95,77,97,120,84,101,120,116,117,114, +101,67,111,111,114,100,115,0,0,0,2,2,90,95,4,0,12,1,103,108,95,69,121,101,80,108,97,110,101,81,0,3, +18,103,108,95,77,97,120,84,101,120,116,117,114,101,67,111,111,114,100,115,0,0,0,2,2,90,95,4,0,12,1, +103,108,95,79,98,106,101,99,116,80,108,97,110,101,83,0,3,18,103,108,95,77,97,120,84,101,120,116, +117,114,101,67,111,111,114,100,115,0,0,0,2,2,90,95,4,0,12,1,103,108,95,79,98,106,101,99,116,80,108, +97,110,101,84,0,3,18,103,108,95,77,97,120,84,101,120,116,117,114,101,67,111,111,114,100,115,0,0,0, +2,2,90,95,4,0,12,1,103,108,95,79,98,106,101,99,116,80,108,97,110,101,82,0,3,18,103,108,95,77,97, +120,84,101,120,116,117,114,101,67,111,111,114,100,115,0,0,0,2,2,90,95,4,0,12,1,103,108,95,79,98, +106,101,99,116,80,108,97,110,101,81,0,3,18,103,108,95,77,97,120,84,101,120,116,117,114,101,67,111, +111,114,100,115,0,0,0,2,2,90,95,0,0,24,103,108,95,70,111,103,80,97,114,97,109,101,116,101,114,115, +0,12,99,111,108,111,114,0,0,0,1,9,100,101,110,115,105,116,121,0,0,0,1,9,115,116,97,114,116,0,0,0,1, +9,101,110,100,0,0,0,1,9,115,99,97,108,101,0,0,0,0,0,0,2,2,90,95,4,0,25,103,108,95,70,111,103,80,97, +114,97,109,101,116,101,114,115,0,1,103,108,95,70,111,103,0,0,0,1,90,95,0,0,9,0,114,97,100,105,97, +110,115,0,1,1,0,0,9,100,101,103,0,0,0,1,3,2,90,95,1,0,9,1,99,0,2,17,51,0,49,52,49,53,57,50,54,0,0, +17,49,56,48,0,48,0,0,49,0,0,4,118,101,99,52,95,109,117,108,116,105,112,108,121,0,18,95,95,114,101, +116,86,97,108,0,0,18,100,101,103,0,0,18,99,0,0,0,0,1,90,95,0,0,10,0,114,97,100,105,97,110,115,0,1, +1,0,0,10,100,101,103,0,0,0,1,3,2,90,95,1,0,9,1,99,0,2,17,51,0,49,52,49,53,57,50,54,0,0,17,49,56,48, +0,48,0,0,49,0,0,4,118,101,99,52,95,109,117,108,116,105,112,108,121,0,18,95,95,114,101,116,86,97, +108,0,59,120,121,0,0,18,100,101,103,0,59,120,121,0,0,18,99,0,59,120,120,0,0,0,0,1,90,95,0,0,11,0, +114,97,100,105,97,110,115,0,1,1,0,0,11,100,101,103,0,0,0,1,3,2,90,95,1,0,9,1,99,0,2,17,51,0,49,52, 49,53,57,50,54,0,0,17,49,56,48,0,48,0,0,49,0,0,4,118,101,99,52,95,109,117,108,116,105,112,108,121, -0,18,95,95,114,101,116,86,97,108,0,0,18,100,101,103,0,0,18,99,0,0,0,0,1,90,95,0,0,10,0,114,97,100, -105,97,110,115,0,1,1,0,0,10,100,101,103,0,0,0,1,3,2,90,95,1,0,9,1,99,0,2,17,51,0,49,52,49,53,57,50, -54,0,0,17,49,56,48,0,48,0,0,49,0,0,4,118,101,99,52,95,109,117,108,116,105,112,108,121,0,18,95,95, -114,101,116,86,97,108,0,59,120,121,0,0,18,100,101,103,0,59,120,121,0,0,18,99,0,59,120,120,0,0,0,0, -1,90,95,0,0,11,0,114,97,100,105,97,110,115,0,1,1,0,0,11,100,101,103,0,0,0,1,3,2,90,95,1,0,9,1,99,0, -2,17,51,0,49,52,49,53,57,50,54,0,0,17,49,56,48,0,48,0,0,49,0,0,4,118,101,99,52,95,109,117,108,116, -105,112,108,121,0,18,95,95,114,101,116,86,97,108,0,59,120,121,122,0,0,18,100,101,103,0,59,120,121, -122,0,0,18,99,0,59,120,120,120,0,0,0,0,1,90,95,0,0,12,0,114,97,100,105,97,110,115,0,1,1,0,0,12,100, -101,103,0,0,0,1,3,2,90,95,1,0,9,1,99,0,2,17,51,0,49,52,49,53,57,50,54,0,0,17,49,56,48,0,48,0,0,49, -0,0,4,118,101,99,52,95,109,117,108,116,105,112,108,121,0,18,95,95,114,101,116,86,97,108,0,0,18,100, -101,103,0,0,18,99,0,59,120,120,120,120,0,0,0,0,1,90,95,0,0,9,0,100,101,103,114,101,101,115,0,1,1,0, -0,9,114,97,100,0,0,0,1,3,2,90,95,1,0,9,1,99,0,2,17,49,56,48,0,48,0,0,17,51,0,49,52,49,53,57,50,54, -0,0,49,0,0,4,118,101,99,52,95,109,117,108,116,105,112,108,121,0,18,95,95,114,101,116,86,97,108,0,0, -18,114,97,100,0,0,18,99,0,0,0,0,1,90,95,0,0,10,0,100,101,103,114,101,101,115,0,1,1,0,0,10,114,97, -100,0,0,0,1,3,2,90,95,1,0,9,1,99,0,2,17,49,56,48,0,48,0,0,17,51,0,49,52,49,53,57,50,54,0,0,49,0,0, -4,118,101,99,52,95,109,117,108,116,105,112,108,121,0,18,95,95,114,101,116,86,97,108,0,59,120,121,0, -0,18,114,97,100,0,59,120,121,0,0,18,99,0,59,120,120,0,0,0,0,1,90,95,0,0,11,0,100,101,103,114,101, -101,115,0,1,1,0,0,11,114,97,100,0,0,0,1,3,2,90,95,1,0,9,1,99,0,2,17,49,56,48,0,48,0,0,17,51,0,49, -52,49,53,57,50,54,0,0,49,0,0,4,118,101,99,52,95,109,117,108,116,105,112,108,121,0,18,95,95,114,101, -116,86,97,108,0,59,120,121,122,0,0,18,114,97,100,0,59,120,121,122,0,0,18,99,0,59,120,120,120,0,0,0, -0,1,90,95,0,0,12,0,100,101,103,114,101,101,115,0,1,1,0,0,12,114,97,100,0,0,0,1,3,2,90,95,1,0,9,1, -99,0,2,17,49,56,48,0,48,0,0,17,51,0,49,52,49,53,57,50,54,0,0,49,0,0,4,118,101,99,52,95,109,117,108, -116,105,112,108,121,0,18,95,95,114,101,116,86,97,108,0,0,18,114,97,100,0,0,18,99,0,59,120,120,120, -120,0,0,0,0,1,90,95,0,0,9,0,115,105,110,0,1,1,0,0,9,114,97,100,105,97,110,115,0,0,0,1,4,102,108, -111,97,116,95,115,105,110,101,0,18,95,95,114,101,116,86,97,108,0,0,18,114,97,100,105,97,110,115,0, -0,0,0,1,90,95,0,0,10,0,115,105,110,0,1,1,0,0,10,114,97,100,105,97,110,115,0,0,0,1,4,102,108,111,97, -116,95,115,105,110,101,0,18,95,95,114,101,116,86,97,108,0,59,120,0,0,18,114,97,100,105,97,110,115, -0,59,120,0,0,0,4,102,108,111,97,116,95,115,105,110,101,0,18,95,95,114,101,116,86,97,108,0,59,121,0, -0,18,114,97,100,105,97,110,115,0,59,121,0,0,0,0,1,90,95,0,0,11,0,115,105,110,0,1,1,0,0,11,114,97, -100,105,97,110,115,0,0,0,1,4,102,108,111,97,116,95,115,105,110,101,0,18,95,95,114,101,116,86,97, -108,0,59,120,0,0,18,114,97,100,105,97,110,115,0,59,120,0,0,0,4,102,108,111,97,116,95,115,105,110, -101,0,18,95,95,114,101,116,86,97,108,0,59,121,0,0,18,114,97,100,105,97,110,115,0,59,121,0,0,0,4, -102,108,111,97,116,95,115,105,110,101,0,18,95,95,114,101,116,86,97,108,0,59,122,0,0,18,114,97,100, -105,97,110,115,0,59,122,0,0,0,0,1,90,95,0,0,12,0,115,105,110,0,1,1,0,0,12,114,97,100,105,97,110, -115,0,0,0,1,4,102,108,111,97,116,95,115,105,110,101,0,18,95,95,114,101,116,86,97,108,0,59,120,0,0, -18,114,97,100,105,97,110,115,0,59,120,0,0,0,4,102,108,111,97,116,95,115,105,110,101,0,18,95,95,114, -101,116,86,97,108,0,59,121,0,0,18,114,97,100,105,97,110,115,0,59,121,0,0,0,4,102,108,111,97,116,95, -115,105,110,101,0,18,95,95,114,101,116,86,97,108,0,59,122,0,0,18,114,97,100,105,97,110,115,0,59, -122,0,0,0,4,102,108,111,97,116,95,115,105,110,101,0,18,95,95,114,101,116,86,97,108,0,59,119,0,0,18, -114,97,100,105,97,110,115,0,59,119,0,0,0,0,1,90,95,0,0,9,0,99,111,115,0,1,1,0,0,9,114,97,100,105, -97,110,115,0,0,0,1,4,102,108,111,97,116,95,99,111,115,105,110,101,0,18,95,95,114,101,116,86,97,108, -0,0,18,114,97,100,105,97,110,115,0,0,0,0,1,90,95,0,0,10,0,99,111,115,0,1,1,0,0,10,114,97,100,105, -97,110,115,0,0,0,1,4,102,108,111,97,116,95,99,111,115,105,110,101,0,18,95,95,114,101,116,86,97,108, -0,59,120,0,0,18,114,97,100,105,97,110,115,0,59,120,0,0,0,4,102,108,111,97,116,95,99,111,115,105, -110,101,0,18,95,95,114,101,116,86,97,108,0,59,121,0,0,18,114,97,100,105,97,110,115,0,59,121,0,0,0, -0,1,90,95,0,0,11,0,99,111,115,0,1,1,0,0,11,114,97,100,105,97,110,115,0,0,0,1,4,102,108,111,97,116, -95,99,111,115,105,110,101,0,18,95,95,114,101,116,86,97,108,0,59,120,0,0,18,114,97,100,105,97,110, -115,0,59,120,0,0,0,4,102,108,111,97,116,95,99,111,115,105,110,101,0,18,95,95,114,101,116,86,97,108, -0,59,121,0,0,18,114,97,100,105,97,110,115,0,59,121,0,0,0,4,102,108,111,97,116,95,99,111,115,105, -110,101,0,18,95,95,114,101,116,86,97,108,0,59,122,0,0,18,114,97,100,105,97,110,115,0,59,122,0,0,0, -0,1,90,95,0,0,12,0,99,111,115,0,1,1,0,0,12,114,97,100,105,97,110,115,0,0,0,1,4,102,108,111,97,116, -95,99,111,115,105,110,101,0,18,95,95,114,101,116,86,97,108,0,59,120,0,0,18,114,97,100,105,97,110, -115,0,59,120,0,0,0,4,102,108,111,97,116,95,99,111,115,105,110,101,0,18,95,95,114,101,116,86,97,108, -0,59,121,0,0,18,114,97,100,105,97,110,115,0,59,121,0,0,0,4,102,108,111,97,116,95,99,111,115,105, -110,101,0,18,95,95,114,101,116,86,97,108,0,59,122,0,0,18,114,97,100,105,97,110,115,0,59,122,0,0,0, -4,102,108,111,97,116,95,99,111,115,105,110,101,0,18,95,95,114,101,116,86,97,108,0,59,119,0,0,18, -114,97,100,105,97,110,115,0,59,119,0,0,0,0,1,90,95,0,0,9,0,116,97,110,0,1,1,0,0,9,97,110,103,108, -101,0,0,0,1,3,2,90,95,1,0,9,1,115,0,2,58,115,105,110,0,18,97,110,103,108,101,0,0,0,0,0,3,2,90,95,1, -0,9,1,99,0,2,58,99,111,115,0,18,97,110,103,108,101,0,0,0,0,0,8,18,115,0,18,99,0,49,0,0,1,90,95,0,0, -10,0,116,97,110,0,1,1,0,0,10,97,110,103,108,101,0,0,0,1,3,2,90,95,1,0,10,1,115,0,2,58,115,105,110, -0,18,97,110,103,108,101,0,0,0,0,0,3,2,90,95,1,0,10,1,99,0,2,58,99,111,115,0,18,97,110,103,108,101, -0,0,0,0,0,8,18,115,0,18,99,0,49,0,0,1,90,95,0,0,11,0,116,97,110,0,1,1,0,0,11,97,110,103,108,101,0, -0,0,1,3,2,90,95,1,0,11,1,115,0,2,58,115,105,110,0,18,97,110,103,108,101,0,0,0,0,0,3,2,90,95,1,0,11, -1,99,0,2,58,99,111,115,0,18,97,110,103,108,101,0,0,0,0,0,8,18,115,0,18,99,0,49,0,0,1,90,95,0,0,12, -0,116,97,110,0,1,1,0,0,12,97,110,103,108,101,0,0,0,1,3,2,90,95,1,0,12,1,115,0,2,58,115,105,110,0, -18,97,110,103,108,101,0,0,0,0,0,3,2,90,95,1,0,12,1,99,0,2,58,99,111,115,0,18,97,110,103,108,101,0, -0,0,0,0,8,18,115,0,18,99,0,49,0,0,1,90,95,0,0,9,0,97,115,105,110,0,1,1,0,0,9,120,0,0,0,1,3,2,90,95, -1,0,9,1,97,48,0,2,17,49,0,53,55,48,55,50,56,56,0,0,0,0,3,2,90,95,1,0,9,1,97,49,0,2,17,48,0,50,49, -50,49,49,52,52,0,0,54,0,0,3,2,90,95,1,0,9,1,97,50,0,2,17,48,0,48,55,52,50,54,49,48,0,0,0,0,3,2,90, -95,1,0,9,1,104,97,108,102,80,105,0,2,17,51,0,49,52,49,53,57,50,54,0,0,17,48,0,53,0,0,48,0,0,3,2,90, -95,1,0,9,1,121,0,2,58,97,98,115,0,18,120,0,0,0,0,0,9,18,95,95,114,101,116,86,97,108,0,18,104,97, -108,102,80,105,0,58,115,113,114,116,0,17,49,0,48,0,0,18,121,0,47,0,0,18,97,48,0,18,121,0,18,97,49, -0,18,97,50,0,18,121,0,48,46,48,46,48,47,58,115,105,103,110,0,18,120,0,0,0,48,20,0,0,1,90,95,0,0,10, -0,97,115,105,110,0,1,1,0,0,10,118,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,59,120,0,58,97,115, -105,110,0,18,118,0,59,120,0,0,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,121,0,58,97,115,105,110, -0,18,118,0,59,121,0,0,0,20,0,0,1,90,95,0,0,11,0,97,115,105,110,0,1,1,0,0,11,118,0,0,0,1,9,18,95,95, -114,101,116,86,97,108,0,59,120,0,58,97,115,105,110,0,18,118,0,59,120,0,0,0,20,0,9,18,95,95,114,101, -116,86,97,108,0,59,121,0,58,97,115,105,110,0,18,118,0,59,121,0,0,0,20,0,9,18,95,95,114,101,116,86, -97,108,0,59,122,0,58,97,115,105,110,0,18,118,0,59,122,0,0,0,20,0,0,1,90,95,0,0,12,0,97,115,105,110, -0,1,1,0,0,12,118,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,59,120,0,58,97,115,105,110,0,18,118,0, -59,120,0,0,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,121,0,58,97,115,105,110,0,18,118,0,59,121, -0,0,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,122,0,58,97,115,105,110,0,18,118,0,59,122,0,0,0, -20,0,9,18,95,95,114,101,116,86,97,108,0,59,119,0,58,97,115,105,110,0,18,118,0,59,119,0,0,0,20,0,0, -1,90,95,0,0,9,0,97,99,111,115,0,1,1,0,0,9,120,0,0,0,1,3,2,90,95,1,0,9,1,104,97,108,102,80,105,0,2, -17,51,0,49,52,49,53,57,50,54,0,0,17,48,0,53,0,0,48,0,0,9,18,95,95,114,101,116,86,97,108,0,18,104, -97,108,102,80,105,0,58,97,115,105,110,0,18,120,0,0,0,47,20,0,0,1,90,95,0,0,10,0,97,99,111,115,0,1, -1,0,0,10,118,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,59,120,0,58,97,99,111,115,0,18,118,0,59, -120,0,0,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,121,0,58,97,99,111,115,0,18,118,0,59,121,0,0, -0,20,0,0,1,90,95,0,0,11,0,97,99,111,115,0,1,1,0,0,11,118,0,0,0,1,9,18,95,95,114,101,116,86,97,108, -0,59,120,0,58,97,99,111,115,0,18,118,0,59,120,0,0,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,121, -0,58,97,99,111,115,0,18,118,0,59,121,0,0,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,122,0,58,97, -99,111,115,0,18,118,0,59,122,0,0,0,20,0,0,1,90,95,0,0,12,0,97,99,111,115,0,1,1,0,0,12,118,0,0,0,1, -9,18,95,95,114,101,116,86,97,108,0,59,120,0,58,97,99,111,115,0,18,118,0,59,120,0,0,0,20,0,9,18,95, -95,114,101,116,86,97,108,0,59,121,0,58,97,99,111,115,0,18,118,0,59,121,0,0,0,20,0,9,18,95,95,114, -101,116,86,97,108,0,59,122,0,58,97,99,111,115,0,18,118,0,59,122,0,0,0,20,0,9,18,95,95,114,101,116, -86,97,108,0,59,119,0,58,97,99,111,115,0,18,118,0,59,119,0,0,0,20,0,0,1,90,95,0,0,9,0,97,116,97,110, -0,1,1,0,0,9,120,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,58,97,115,105,110,0,18,120,0,58,105,110, -118,101,114,115,101,115,113,114,116,0,18,120,0,18,120,0,48,17,49,0,48,0,0,46,0,0,48,0,0,20,0,0,1, -90,95,0,0,10,0,97,116,97,110,0,1,1,0,0,10,121,95,111,118,101,114,95,120,0,0,0,1,9,18,95,95,114,101, -116,86,97,108,0,59,120,0,58,97,116,97,110,0,18,121,95,111,118,101,114,95,120,0,59,120,0,0,0,20,0,9, -18,95,95,114,101,116,86,97,108,0,59,121,0,58,97,116,97,110,0,18,121,95,111,118,101,114,95,120,0,59, +0,18,95,95,114,101,116,86,97,108,0,59,120,121,122,0,0,18,100,101,103,0,59,120,121,122,0,0,18,99,0, +59,120,120,120,0,0,0,0,1,90,95,0,0,12,0,114,97,100,105,97,110,115,0,1,1,0,0,12,100,101,103,0,0,0,1, +3,2,90,95,1,0,9,1,99,0,2,17,51,0,49,52,49,53,57,50,54,0,0,17,49,56,48,0,48,0,0,49,0,0,4,118,101,99, +52,95,109,117,108,116,105,112,108,121,0,18,95,95,114,101,116,86,97,108,0,0,18,100,101,103,0,0,18, +99,0,59,120,120,120,120,0,0,0,0,1,90,95,0,0,9,0,100,101,103,114,101,101,115,0,1,1,0,0,9,114,97,100, +0,0,0,1,3,2,90,95,1,0,9,1,99,0,2,17,49,56,48,0,48,0,0,17,51,0,49,52,49,53,57,50,54,0,0,49,0,0,4, +118,101,99,52,95,109,117,108,116,105,112,108,121,0,18,95,95,114,101,116,86,97,108,0,0,18,114,97, +100,0,0,18,99,0,0,0,0,1,90,95,0,0,10,0,100,101,103,114,101,101,115,0,1,1,0,0,10,114,97,100,0,0,0,1, +3,2,90,95,1,0,9,1,99,0,2,17,49,56,48,0,48,0,0,17,51,0,49,52,49,53,57,50,54,0,0,49,0,0,4,118,101,99, +52,95,109,117,108,116,105,112,108,121,0,18,95,95,114,101,116,86,97,108,0,59,120,121,0,0,18,114,97, +100,0,59,120,121,0,0,18,99,0,59,120,120,0,0,0,0,1,90,95,0,0,11,0,100,101,103,114,101,101,115,0,1,1, +0,0,11,114,97,100,0,0,0,1,3,2,90,95,1,0,9,1,99,0,2,17,49,56,48,0,48,0,0,17,51,0,49,52,49,53,57,50, +54,0,0,49,0,0,4,118,101,99,52,95,109,117,108,116,105,112,108,121,0,18,95,95,114,101,116,86,97,108, +0,59,120,121,122,0,0,18,114,97,100,0,59,120,121,122,0,0,18,99,0,59,120,120,120,0,0,0,0,1,90,95,0,0, +12,0,100,101,103,114,101,101,115,0,1,1,0,0,12,114,97,100,0,0,0,1,3,2,90,95,1,0,9,1,99,0,2,17,49,56, +48,0,48,0,0,17,51,0,49,52,49,53,57,50,54,0,0,49,0,0,4,118,101,99,52,95,109,117,108,116,105,112,108, +121,0,18,95,95,114,101,116,86,97,108,0,0,18,114,97,100,0,0,18,99,0,59,120,120,120,120,0,0,0,0,1,90, +95,0,0,9,0,115,105,110,0,1,1,0,0,9,114,97,100,105,97,110,115,0,0,0,1,4,102,108,111,97,116,95,115, +105,110,101,0,18,95,95,114,101,116,86,97,108,0,0,18,114,97,100,105,97,110,115,0,0,0,0,1,90,95,0,0, +10,0,115,105,110,0,1,1,0,0,10,114,97,100,105,97,110,115,0,0,0,1,4,102,108,111,97,116,95,115,105, +110,101,0,18,95,95,114,101,116,86,97,108,0,59,120,0,0,18,114,97,100,105,97,110,115,0,59,120,0,0,0, +4,102,108,111,97,116,95,115,105,110,101,0,18,95,95,114,101,116,86,97,108,0,59,121,0,0,18,114,97, +100,105,97,110,115,0,59,121,0,0,0,0,1,90,95,0,0,11,0,115,105,110,0,1,1,0,0,11,114,97,100,105,97, +110,115,0,0,0,1,4,102,108,111,97,116,95,115,105,110,101,0,18,95,95,114,101,116,86,97,108,0,59,120, +0,0,18,114,97,100,105,97,110,115,0,59,120,0,0,0,4,102,108,111,97,116,95,115,105,110,101,0,18,95,95, +114,101,116,86,97,108,0,59,121,0,0,18,114,97,100,105,97,110,115,0,59,121,0,0,0,4,102,108,111,97, +116,95,115,105,110,101,0,18,95,95,114,101,116,86,97,108,0,59,122,0,0,18,114,97,100,105,97,110,115, +0,59,122,0,0,0,0,1,90,95,0,0,12,0,115,105,110,0,1,1,0,0,12,114,97,100,105,97,110,115,0,0,0,1,4,102, +108,111,97,116,95,115,105,110,101,0,18,95,95,114,101,116,86,97,108,0,59,120,0,0,18,114,97,100,105, +97,110,115,0,59,120,0,0,0,4,102,108,111,97,116,95,115,105,110,101,0,18,95,95,114,101,116,86,97,108, +0,59,121,0,0,18,114,97,100,105,97,110,115,0,59,121,0,0,0,4,102,108,111,97,116,95,115,105,110,101,0, +18,95,95,114,101,116,86,97,108,0,59,122,0,0,18,114,97,100,105,97,110,115,0,59,122,0,0,0,4,102,108, +111,97,116,95,115,105,110,101,0,18,95,95,114,101,116,86,97,108,0,59,119,0,0,18,114,97,100,105,97, +110,115,0,59,119,0,0,0,0,1,90,95,0,0,9,0,99,111,115,0,1,1,0,0,9,114,97,100,105,97,110,115,0,0,0,1, +4,102,108,111,97,116,95,99,111,115,105,110,101,0,18,95,95,114,101,116,86,97,108,0,0,18,114,97,100, +105,97,110,115,0,0,0,0,1,90,95,0,0,10,0,99,111,115,0,1,1,0,0,10,114,97,100,105,97,110,115,0,0,0,1, +4,102,108,111,97,116,95,99,111,115,105,110,101,0,18,95,95,114,101,116,86,97,108,0,59,120,0,0,18, +114,97,100,105,97,110,115,0,59,120,0,0,0,4,102,108,111,97,116,95,99,111,115,105,110,101,0,18,95,95, +114,101,116,86,97,108,0,59,121,0,0,18,114,97,100,105,97,110,115,0,59,121,0,0,0,0,1,90,95,0,0,11,0, +99,111,115,0,1,1,0,0,11,114,97,100,105,97,110,115,0,0,0,1,4,102,108,111,97,116,95,99,111,115,105, +110,101,0,18,95,95,114,101,116,86,97,108,0,59,120,0,0,18,114,97,100,105,97,110,115,0,59,120,0,0,0, +4,102,108,111,97,116,95,99,111,115,105,110,101,0,18,95,95,114,101,116,86,97,108,0,59,121,0,0,18, +114,97,100,105,97,110,115,0,59,121,0,0,0,4,102,108,111,97,116,95,99,111,115,105,110,101,0,18,95,95, +114,101,116,86,97,108,0,59,122,0,0,18,114,97,100,105,97,110,115,0,59,122,0,0,0,0,1,90,95,0,0,12,0, +99,111,115,0,1,1,0,0,12,114,97,100,105,97,110,115,0,0,0,1,4,102,108,111,97,116,95,99,111,115,105, +110,101,0,18,95,95,114,101,116,86,97,108,0,59,120,0,0,18,114,97,100,105,97,110,115,0,59,120,0,0,0, +4,102,108,111,97,116,95,99,111,115,105,110,101,0,18,95,95,114,101,116,86,97,108,0,59,121,0,0,18, +114,97,100,105,97,110,115,0,59,121,0,0,0,4,102,108,111,97,116,95,99,111,115,105,110,101,0,18,95,95, +114,101,116,86,97,108,0,59,122,0,0,18,114,97,100,105,97,110,115,0,59,122,0,0,0,4,102,108,111,97, +116,95,99,111,115,105,110,101,0,18,95,95,114,101,116,86,97,108,0,59,119,0,0,18,114,97,100,105,97, +110,115,0,59,119,0,0,0,0,1,90,95,0,0,9,0,116,97,110,0,1,1,0,0,9,97,110,103,108,101,0,0,0,1,3,2,90, +95,1,0,9,1,115,0,2,58,115,105,110,0,18,97,110,103,108,101,0,0,0,0,0,3,2,90,95,1,0,9,1,99,0,2,58,99, +111,115,0,18,97,110,103,108,101,0,0,0,0,0,8,18,115,0,18,99,0,49,0,0,1,90,95,0,0,10,0,116,97,110,0, +1,1,0,0,10,97,110,103,108,101,0,0,0,1,3,2,90,95,1,0,10,1,115,0,2,58,115,105,110,0,18,97,110,103, +108,101,0,0,0,0,0,3,2,90,95,1,0,10,1,99,0,2,58,99,111,115,0,18,97,110,103,108,101,0,0,0,0,0,8,18, +115,0,18,99,0,49,0,0,1,90,95,0,0,11,0,116,97,110,0,1,1,0,0,11,97,110,103,108,101,0,0,0,1,3,2,90,95, +1,0,11,1,115,0,2,58,115,105,110,0,18,97,110,103,108,101,0,0,0,0,0,3,2,90,95,1,0,11,1,99,0,2,58,99, +111,115,0,18,97,110,103,108,101,0,0,0,0,0,8,18,115,0,18,99,0,49,0,0,1,90,95,0,0,12,0,116,97,110,0, +1,1,0,0,12,97,110,103,108,101,0,0,0,1,3,2,90,95,1,0,12,1,115,0,2,58,115,105,110,0,18,97,110,103, +108,101,0,0,0,0,0,3,2,90,95,1,0,12,1,99,0,2,58,99,111,115,0,18,97,110,103,108,101,0,0,0,0,0,8,18, +115,0,18,99,0,49,0,0,1,90,95,0,0,9,0,97,115,105,110,0,1,1,0,0,9,120,0,0,0,1,3,2,90,95,1,0,9,1,97, +48,0,2,17,49,0,53,55,48,55,50,56,56,0,0,0,0,3,2,90,95,1,0,9,1,97,49,0,2,17,48,0,50,49,50,49,49,52, +52,0,0,54,0,0,3,2,90,95,1,0,9,1,97,50,0,2,17,48,0,48,55,52,50,54,49,48,0,0,0,0,3,2,90,95,1,0,9,1, +104,97,108,102,80,105,0,2,17,51,0,49,52,49,53,57,50,54,0,0,17,48,0,53,0,0,48,0,0,3,2,90,95,1,0,9,1, +121,0,2,58,97,98,115,0,18,120,0,0,0,0,0,9,18,95,95,114,101,116,86,97,108,0,18,104,97,108,102,80, +105,0,58,115,113,114,116,0,17,49,0,48,0,0,18,121,0,47,0,0,18,97,48,0,18,121,0,18,97,49,0,18,97,50, +0,18,121,0,48,46,48,46,48,47,58,115,105,103,110,0,18,120,0,0,0,48,20,0,0,1,90,95,0,0,10,0,97,115, +105,110,0,1,1,0,0,10,118,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,59,120,0,58,97,115,105,110,0, +18,118,0,59,120,0,0,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,121,0,58,97,115,105,110,0,18,118, +0,59,121,0,0,0,20,0,0,1,90,95,0,0,11,0,97,115,105,110,0,1,1,0,0,11,118,0,0,0,1,9,18,95,95,114,101, +116,86,97,108,0,59,120,0,58,97,115,105,110,0,18,118,0,59,120,0,0,0,20,0,9,18,95,95,114,101,116,86, +97,108,0,59,121,0,58,97,115,105,110,0,18,118,0,59,121,0,0,0,20,0,9,18,95,95,114,101,116,86,97,108, +0,59,122,0,58,97,115,105,110,0,18,118,0,59,122,0,0,0,20,0,0,1,90,95,0,0,12,0,97,115,105,110,0,1,1, +0,0,12,118,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,59,120,0,58,97,115,105,110,0,18,118,0,59,120, +0,0,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,121,0,58,97,115,105,110,0,18,118,0,59,121,0,0,0, +20,0,9,18,95,95,114,101,116,86,97,108,0,59,122,0,58,97,115,105,110,0,18,118,0,59,122,0,0,0,20,0,9, +18,95,95,114,101,116,86,97,108,0,59,119,0,58,97,115,105,110,0,18,118,0,59,119,0,0,0,20,0,0,1,90,95, +0,0,9,0,97,99,111,115,0,1,1,0,0,9,120,0,0,0,1,3,2,90,95,1,0,9,1,104,97,108,102,80,105,0,2,17,51,0, +49,52,49,53,57,50,54,0,0,17,48,0,53,0,0,48,0,0,9,18,95,95,114,101,116,86,97,108,0,18,104,97,108, +102,80,105,0,58,97,115,105,110,0,18,120,0,0,0,47,20,0,0,1,90,95,0,0,10,0,97,99,111,115,0,1,1,0,0, +10,118,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,59,120,0,58,97,99,111,115,0,18,118,0,59,120,0,0, +0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,121,0,58,97,99,111,115,0,18,118,0,59,121,0,0,0,20,0,0, +1,90,95,0,0,11,0,97,99,111,115,0,1,1,0,0,11,118,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,59,120, +0,58,97,99,111,115,0,18,118,0,59,120,0,0,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,121,0,58,97, +99,111,115,0,18,118,0,59,121,0,0,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,122,0,58,97,99,111, +115,0,18,118,0,59,122,0,0,0,20,0,0,1,90,95,0,0,12,0,97,99,111,115,0,1,1,0,0,12,118,0,0,0,1,9,18,95, +95,114,101,116,86,97,108,0,59,120,0,58,97,99,111,115,0,18,118,0,59,120,0,0,0,20,0,9,18,95,95,114, +101,116,86,97,108,0,59,121,0,58,97,99,111,115,0,18,118,0,59,121,0,0,0,20,0,9,18,95,95,114,101,116, +86,97,108,0,59,122,0,58,97,99,111,115,0,18,118,0,59,122,0,0,0,20,0,9,18,95,95,114,101,116,86,97, +108,0,59,119,0,58,97,99,111,115,0,18,118,0,59,119,0,0,0,20,0,0,1,90,95,0,0,9,0,97,116,97,110,0,1,1, +0,0,9,120,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,58,97,115,105,110,0,18,120,0,58,105,110,118, +101,114,115,101,115,113,114,116,0,18,120,0,18,120,0,48,17,49,0,48,0,0,46,0,0,48,0,0,20,0,0,1,90,95, +0,0,10,0,97,116,97,110,0,1,1,0,0,10,121,95,111,118,101,114,95,120,0,0,0,1,9,18,95,95,114,101,116, +86,97,108,0,59,120,0,58,97,116,97,110,0,18,121,95,111,118,101,114,95,120,0,59,120,0,0,0,20,0,9,18, +95,95,114,101,116,86,97,108,0,59,121,0,58,97,116,97,110,0,18,121,95,111,118,101,114,95,120,0,59, 121,0,0,0,20,0,0,1,90,95,0,0,11,0,97,116,97,110,0,1,1,0,0,11,121,95,111,118,101,114,95,120,0,0,0,1, 9,18,95,95,114,101,116,86,97,108,0,59,120,0,58,97,116,97,110,0,18,121,95,111,118,101,114,95,120,0, 59,120,0,0,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,121,0,58,97,116,97,110,0,18,121,95,111,118, diff --git a/src/mesa/shader/slang/slang_builtin.c b/src/mesa/shader/slang/slang_builtin.c index ed6de40d4b..db00c54b8a 100644 --- a/src/mesa/shader/slang/slang_builtin.c +++ b/src/mesa/shader/slang/slang_builtin.c @@ -80,9 +80,7 @@ lookup_statevar(const char *var, GLint index1, GLint index2, const char *field, { "gl_TextureMatrixTranspose", STATE_TEXTURE_MATRIX, 0 }, { "gl_TextureMatrixInverseTranspose", STATE_TEXTURE_MATRIX, STATE_MATRIX_INVERSE }, - /* XXX verify these!!! */ { "gl_NormalMatrix", STATE_MODELVIEW_MATRIX, STATE_MATRIX_TRANSPOSE }, - { "__NormalMatrixTranspose", STATE_MODELVIEW_MATRIX, 0 }, { NULL, 0, 0 } }; @@ -109,10 +107,14 @@ lookup_statevar(const char *var, GLint index1, GLint index2, const char *field, if (isMatrix) { if (tokens[0] == STATE_TEXTURE_MATRIX) { if (index1 >= 0) { - tokens[1] = index1; + tokens[1] = index1; /* which texture matrix */ index1 = 0; /* prevent extra addition at end of function */ } } + if (index1 < 0) { + /* index1 is unused: prevent extra addition at end of function */ + index1 = 0; + } } else if (strcmp(var, "gl_DepthRange") == 0) { tokens[0] = STATE_DEPTH_RANGE; diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c index dea1fcf087..d23ae4d8cb 100644 --- a/src/mesa/shader/slang/slang_codegen.c +++ b/src/mesa/shader/slang/slang_codegen.c @@ -480,7 +480,6 @@ new_node3(slang_ir_opcode op, n->Children[0] = c0; n->Children[1] = c1; n->Children[2] = c2; - n->Writemask = WRITEMASK_XYZW; n->InstLocation = -1; } return n; @@ -1602,19 +1601,6 @@ resolve_swizzle(const slang_operation *oper) /** - * As above, but produce a writemask. - */ -static GLuint -resolve_writemask(slang_assemble_ctx *A, const slang_operation *oper) -{ - GLuint swizzle = resolve_swizzle(oper); - GLuint writemask, swizzleOut; - swizzle_to_writemask(A, swizzle, &writemask, &swizzleOut); - return writemask; -} - - -/** * Recursively descend through swizzle nodes to find the node's storage info. */ static slang_ir_storage * @@ -1677,14 +1663,11 @@ _slang_gen_asm(slang_assemble_ctx *A, slang_operation *oper, /* Setup n->Store to be a particular location. Otherwise, storage * for the result (a temporary) will be allocated later. */ - GLuint writemask = WRITEMASK_XYZW; slang_operation *dest_oper; slang_ir_node *n0; dest_oper = &oper->children[0]; - writemask = resolve_writemask(A, dest_oper); - n0 = _slang_gen_operation(A, dest_oper); if (!n0) return NULL; @@ -3064,7 +3047,6 @@ _slang_gen_assignment(slang_assemble_ctx * A, slang_operation *oper) rhs = _slang_gen_swizzle(rhs, newSwizzle); } n = new_node2(IR_COPY, lhs, rhs); - n->Writemask = writemask; return n; } else { @@ -3221,8 +3203,6 @@ _slang_gen_array_element(slang_assemble_ctx * A, slang_operation *oper) SWIZZLE_NIL, SWIZZLE_NIL); n = _slang_gen_swizzle(n, swizzle); - /*n->Store = _slang_clone_ir_storage_swz(n->Store, */ - n->Writemask = WRITEMASK_X << index; } assert(n->Store); return n; diff --git a/src/mesa/shader/slang/slang_emit.c b/src/mesa/shader/slang/slang_emit.c index 827760c917..b67cea7617 100644 --- a/src/mesa/shader/slang/slang_emit.c +++ b/src/mesa/shader/slang/slang_emit.c @@ -108,6 +108,30 @@ writemask_to_swizzle(GLuint writemask) /** + * Convert a swizzle mask to a writemask. + * Note that the slang_ir_storage->Swizzle field can represent either a + * swizzle mask or a writemask, depending on how it's used. For example, + * when we parse "direction.yz" alone, we don't know whether .yz is a + * writemask or a swizzle. In this case, we encode ".yz" in store->Swizzle + * as a swizzle mask (.yz?? actually). Later, if direction.yz is used as + * an R-value, we use store->Swizzle as-is. Otherwise, if direction.yz is + * used as an L-value, we convert it to a writemask. + */ +static GLuint +swizzle_to_writemask(GLuint swizzle) +{ + GLuint i, writemask = 0x0; + for (i = 0; i < 4; i++) { + GLuint swz = GET_SWZ(swizzle, i); + if (swz <= SWIZZLE_W) { + writemask |= (1 << swz); + } + } + return writemask; +} + + +/** * Swizzle a swizzle (function composition). * That is, return swz2(swz1), or said another way: swz1.szw2 * Example: swizzle_swizzle(".zwxx", ".xxyw") yields ".zzwx" @@ -233,8 +257,7 @@ fix_swizzle(GLuint swizzle) * Convert IR storage to an instruction dst register. */ static void -storage_to_dst_reg(struct prog_dst_register *dst, const slang_ir_storage *st, - GLuint writemask) +storage_to_dst_reg(struct prog_dst_register *dst, const slang_ir_storage *st) { const GLint size = st->Size; GLint index = st->Index; @@ -256,12 +279,27 @@ storage_to_dst_reg(struct prog_dst_register *dst, const slang_ir_storage *st, assert(size >= 1); assert(size <= 4); - if (size == 1) { - GLuint comp = GET_SWZ(swizzle, 0); - assert(comp < 4); - dst->WriteMask = WRITEMASK_X << comp; + if (swizzle != SWIZZLE_XYZW) { + dst->WriteMask = swizzle_to_writemask(swizzle); } else { + GLuint writemask; + switch (size) { + case 1: + writemask = WRITEMASK_X << GET_SWZ(st->Swizzle, 0); + break; + case 2: + writemask = WRITEMASK_XY; + break; + case 3: + writemask = WRITEMASK_XYZ; + break; + case 4: + writemask = WRITEMASK_XYZW; + break; + default: + ; /* error would have been caught above */ + } dst->WriteMask = writemask; } } @@ -309,38 +347,28 @@ storage_to_src_reg(struct prog_src_register *src, const slang_ir_storage *st) /* - * Setup an instrucion src register to point to a scalar constant. + * Setup storage pointing to a scalar constant/literal. */ static void -constant_to_src_reg(struct prog_src_register *src, GLfloat val, - slang_emit_info *emitInfo) +constant_to_storage(slang_emit_info *emitInfo, + GLfloat val, + slang_ir_storage *store) { - GLuint zeroSwizzle; - GLint zeroReg; + GLuint swizzle; + GLint reg; GLfloat value[4]; value[0] = val; - zeroReg = _mesa_add_unnamed_constant(emitInfo->prog->Parameters, - value, 1, &zeroSwizzle); - assert(zeroReg >= 0); + reg = _mesa_add_unnamed_constant(emitInfo->prog->Parameters, + value, 1, &swizzle); - src->File = PROGRAM_CONSTANT; - src->Index = zeroReg; - src->Swizzle = zeroSwizzle; + memset(store, 0, sizeof(*store)); + store->File = PROGRAM_CONSTANT; + store->Index = reg; + store->Swizzle = swizzle; } -static void -address_to_dst_reg(struct prog_dst_register *dst, GLuint index) -{ - assert(index == 0); /* only one address reg at this time */ - dst->File = PROGRAM_ADDRESS; - dst->Index = index; - dst->WriteMask = WRITEMASK_X; -} - - - /** * Add new instruction at end of given program. * \param prog the program to append instruction onto @@ -376,6 +404,77 @@ new_instruction(slang_emit_info *emitInfo, gl_inst_opcode opcode) /** + * Emit a new instruction with given opcode, operands. + */ +static struct prog_instruction * +emit_instruction(slang_emit_info *emitInfo, + gl_inst_opcode opcode, + const slang_ir_storage *dst, + const slang_ir_storage *src1, + const slang_ir_storage *src2, + const slang_ir_storage *src3) +{ + struct gl_program *prog = emitInfo->prog; + struct prog_instruction *inst; + + prog->Instructions = _mesa_realloc_instructions(prog->Instructions, + prog->NumInstructions, + prog->NumInstructions + 1); + inst = prog->Instructions + prog->NumInstructions; + prog->NumInstructions++; + + _mesa_init_instructions(inst, 1); + inst->Opcode = opcode; + inst->BranchTarget = -1; /* invalid */ + + if (dst) + storage_to_dst_reg(&inst->DstReg, dst); + + if (src1) + storage_to_src_reg(&inst->SrcReg[0], src1); + if (src2) + storage_to_src_reg(&inst->SrcReg[1], src2); + if (src3) + storage_to_src_reg(&inst->SrcReg[2], src3); + + return inst; +} + + +/** + * Emit an ARL instruction. + */ +static struct prog_instruction * +emit_arl_instruction(slang_emit_info *emitInfo, + GLint addrReg, + const slang_ir_storage *src) +{ + struct prog_instruction *inst; + + assert(addrReg == 0); /* only one addr reg at this time */ + inst = new_instruction(emitInfo, OPCODE_ARL); + storage_to_src_reg(&inst->SrcReg[0], src); + inst->DstReg.File = PROGRAM_ADDRESS; + inst->DstReg.Index = addrReg; + inst->DstReg.WriteMask = WRITEMASK_X; + return inst; +} + + + +/** + * Put a comment on the given instruction. + */ +static void +inst_comment(struct prog_instruction *inst, const char *comment) +{ + if (inst) + inst->Comment = _mesa_strdup(comment); +} + + + +/** * Return pointer to last instruction in program. */ static struct prog_instruction * @@ -531,12 +630,10 @@ instruction_annotation(gl_inst_opcode opcode, char *dstAnnot, * Emit an instruction that's just a comment. */ static struct prog_instruction * -emit_comment(slang_emit_info *emitInfo, const char *s) +emit_comment(slang_emit_info *emitInfo, const char *comment) { struct prog_instruction *inst = new_instruction(emitInfo, OPCODE_NOP); - if (inst) { - inst->Comment = _mesa_strdup(s); - } + inst_comment(inst, comment); return inst; } @@ -548,22 +645,13 @@ emit_comment(slang_emit_info *emitInfo, const char *s) static struct prog_instruction * emit_arith(slang_emit_info *emitInfo, slang_ir_node *n) { - struct prog_instruction *inst; const slang_ir_info *info = _slang_ir_info(n->Opcode); - char *srcAnnot[3], *dstAnnot; + struct prog_instruction *inst; GLuint i; - slang_ir_node *temps[3]; - - /* we'll save pointers to nodes/storage to free in temps[] until - * the very end. - */ - temps[0] = temps[1] = temps[2] = NULL; assert(info); assert(info->InstOpcode != OPCODE_NOP); - srcAnnot[0] = srcAnnot[1] = srcAnnot[2] = dstAnnot = NULL; - #if PEEPHOLE_OPTIMIZATIONS /* Look for MAD opportunity */ if (info->NumParams == 2 && @@ -572,85 +660,67 @@ emit_arith(slang_emit_info *emitInfo, slang_ir_node *n) emit(emitInfo, n->Children[0]->Children[0]); /* A */ emit(emitInfo, n->Children[0]->Children[1]); /* B */ emit(emitInfo, n->Children[1]); /* C */ - /* generate MAD instruction */ - inst = new_instruction(emitInfo, OPCODE_MAD); - /* operands: A, B, C: */ - storage_to_src_reg(&inst->SrcReg[0], n->Children[0]->Children[0]->Store); - storage_to_src_reg(&inst->SrcReg[1], n->Children[0]->Children[1]->Store); - storage_to_src_reg(&inst->SrcReg[2], n->Children[1]->Store); - temps[0] = n->Children[0]->Children[0]; - temps[1] = n->Children[0]->Children[1]; - temps[2] = n->Children[1]; - } - else if (info->NumParams == 2 && - n->Opcode == IR_ADD && n->Children[1]->Opcode == IR_MUL) { + alloc_node_storage(emitInfo, n, -1); /* dest */ + + inst = emit_instruction(emitInfo, + OPCODE_MAD, + n->Store, + n->Children[0]->Children[0]->Store, + n->Children[0]->Children[1]->Store, + n->Children[1]->Store); + + free_node_storage(emitInfo->vt, n->Children[0]->Children[0]); + free_node_storage(emitInfo->vt, n->Children[0]->Children[1]); + free_node_storage(emitInfo->vt, n->Children[1]); + return inst; + } + + if (info->NumParams == 2 && + n->Opcode == IR_ADD && n->Children[1]->Opcode == IR_MUL) { /* found pattern IR_ADD(A, IR_MUL(B, C)) */ emit(emitInfo, n->Children[0]); /* A */ emit(emitInfo, n->Children[1]->Children[0]); /* B */ emit(emitInfo, n->Children[1]->Children[1]); /* C */ - /* generate MAD instruction */ - inst = new_instruction(emitInfo, OPCODE_MAD); - /* operands: B, C, A */ - storage_to_src_reg(&inst->SrcReg[0], n->Children[1]->Children[0]->Store); - storage_to_src_reg(&inst->SrcReg[1], n->Children[1]->Children[1]->Store); - storage_to_src_reg(&inst->SrcReg[2], n->Children[0]->Store); - temps[0] = n->Children[1]->Children[0]; - temps[1] = n->Children[1]->Children[1]; - temps[2] = n->Children[0]; + alloc_node_storage(emitInfo, n, -1); /* dest */ + + inst = emit_instruction(emitInfo, + OPCODE_MAD, + n->Store, + n->Children[1]->Children[0]->Store, + n->Children[1]->Children[1]->Store, + n->Children[0]->Store); + + free_node_storage(emitInfo->vt, n->Children[1]->Children[0]); + free_node_storage(emitInfo->vt, n->Children[1]->Children[1]); + free_node_storage(emitInfo->vt, n->Children[0]); + return inst; } - else #endif - { - /* normal case */ - /* gen code for children */ - for (i = 0; i < info->NumParams; i++) { - emit(emitInfo, n->Children[i]); - if (!n->Children[i] || !n->Children[i]->Store) { - /* error recovery */ - return NULL; - } + /* gen code for children, may involve temp allocation */ + for (i = 0; i < info->NumParams; i++) { + emit(emitInfo, n->Children[i]); + if (!n->Children[i] || !n->Children[i]->Store) { + /* error recovery */ + return NULL; } - - /* gen this instruction and src registers */ - inst = new_instruction(emitInfo, info->InstOpcode); - for (i = 0; i < info->NumParams; i++) - storage_to_src_reg(&inst->SrcReg[i], n->Children[i]->Store); - - /* annotation */ - for (i = 0; i < info->NumParams; i++) - srcAnnot[i] = storage_annotation(n->Children[i], emitInfo->prog); - - /* record (potential) temps to free */ - for (i = 0; i < info->NumParams; i++) - temps[i] = n->Children[i]; } /* result storage */ alloc_node_storage(emitInfo, n, -1); - assert(n->Store->Index >= 0); - if (n->Store->Size == 2) - n->Writemask = WRITEMASK_XY; - else if (n->Store->Size == 3) - n->Writemask = WRITEMASK_XYZ; - else if (n->Store->Size == 1) - n->Writemask = WRITEMASK_X << GET_SWZ(n->Store->Swizzle, 0); - - - storage_to_dst_reg(&inst->DstReg, n->Store, n->Writemask); + inst = emit_instruction(emitInfo, + info->InstOpcode, + n->Store, /* dest */ + (info->NumParams > 0 ? n->Children[0]->Store : NULL), + (info->NumParams > 1 ? n->Children[1]->Store : NULL), + (info->NumParams > 2 ? n->Children[2]->Store : NULL) + ); - dstAnnot = storage_annotation(n, emitInfo->prog); - - inst->Comment = instruction_annotation(inst->Opcode, dstAnnot, srcAnnot[0], - srcAnnot[1], srcAnnot[2]); - - /* really free temps now */ - for (i = 0; i < 3; i++) - if (temps[i]) - free_node_storage(emitInfo->vt, temps[i]); + /* free temps */ + for (i = 0; i < info->NumParams; i++) + free_node_storage(emitInfo->vt, n->Children[i]); - /*_mesa_print_instruction(inst);*/ return inst; } @@ -662,7 +732,7 @@ emit_arith(slang_emit_info *emitInfo, slang_ir_node *n) static struct prog_instruction * emit_compare(slang_emit_info *emitInfo, slang_ir_node *n) { - struct prog_instruction *inst; + struct prog_instruction *inst = NULL; GLint size; assert(n->Opcode == IR_EQUAL || n->Opcode == IR_NOTEQUAL); @@ -683,15 +753,20 @@ emit_compare(slang_emit_info *emitInfo, slang_ir_node *n) size = n->Children[0]->Store->Size; if (size == 1) { - gl_inst_opcode opcode; - - opcode = n->Opcode == IR_EQUAL ? OPCODE_SEQ : OPCODE_SNE; - inst = new_instruction(emitInfo, opcode); - storage_to_src_reg(&inst->SrcReg[0], n->Children[0]->Store); - storage_to_src_reg(&inst->SrcReg[1], n->Children[1]->Store); - storage_to_dst_reg(&inst->DstReg, n->Store, n->Writemask); + gl_inst_opcode opcode = n->Opcode == IR_EQUAL ? OPCODE_SEQ : OPCODE_SNE; + inst = emit_instruction(emitInfo, + opcode, + n->Store, /* dest */ + n->Children[0]->Store, + n->Children[1]->Store, + NULL); } else if (size <= 4) { + /* compare two vectors. + * Unfortunately, there's no instruction to compare vectors and + * return a scalar result. Do it with some compare and dot product + * instructions... + */ GLuint swizzle; gl_inst_opcode dotOp; slang_ir_storage tempStore; @@ -716,29 +791,37 @@ emit_compare(slang_emit_info *emitInfo, slang_ir_node *n) } /* Compute inequality (temp = (A != B)) */ - inst = new_instruction(emitInfo, OPCODE_SNE); - storage_to_dst_reg(&inst->DstReg, &tempStore, n->Writemask); - storage_to_src_reg(&inst->SrcReg[0], n->Children[0]->Store); - storage_to_src_reg(&inst->SrcReg[1], n->Children[1]->Store); - inst->Comment = _mesa_strdup("Compare values"); + inst = emit_instruction(emitInfo, + OPCODE_SNE, + &tempStore, + n->Children[0]->Store, + n->Children[1]->Store, + NULL); + inst_comment(inst, "Compare values"); /* Compute val = DOT(temp, temp) (reduction) */ - inst = new_instruction(emitInfo, dotOp); - storage_to_dst_reg(&inst->DstReg, n->Store, n->Writemask); - storage_to_src_reg(&inst->SrcReg[0], &tempStore); - storage_to_src_reg(&inst->SrcReg[1], &tempStore); + inst = emit_instruction(emitInfo, + dotOp, + n->Store, + &tempStore, + &tempStore, + NULL); inst->SrcReg[0].Swizzle = inst->SrcReg[1].Swizzle = swizzle; /*override*/ - inst->Comment = _mesa_strdup("Reduce vec to bool"); + inst_comment(inst, "Reduce vec to bool"); _slang_free_temp(emitInfo->vt, &tempStore); /* free temp */ if (n->Opcode == IR_EQUAL) { /* compute val = !val.x with SEQ val, val, 0; */ - inst = new_instruction(emitInfo, OPCODE_SEQ); - storage_to_src_reg(&inst->SrcReg[0], n->Store); - constant_to_src_reg(&inst->SrcReg[1], 0.0, emitInfo); - storage_to_dst_reg(&inst->DstReg, n->Store, n->Writemask); - inst->Comment = _mesa_strdup("Invert true/false"); + slang_ir_storage zero; + constant_to_storage(emitInfo, 0.0, &zero); + inst = emit_instruction(emitInfo, + OPCODE_SEQ, + n->Store, /* dest */ + n->Store, + &zero, + NULL); + inst_comment(inst, "Invert true/false"); } } else { @@ -755,41 +838,54 @@ emit_compare(slang_emit_info *emitInfo, slang_ir_node *n) return NULL; for (i = 0; i < num; i++) { - /* SNE sneTemp, left[i], right[i] */ - inst = new_instruction(emitInfo, OPCODE_SNE); - storage_to_src_reg(&inst->SrcReg[0], n->Children[0]->Store); - storage_to_src_reg(&inst->SrcReg[1], n->Children[1]->Store); - inst->SrcReg[0].Index += i; - inst->SrcReg[1].Index += i; + slang_ir_storage srcStore0 = *n->Children[0]->Store; + slang_ir_storage srcStore1 = *n->Children[1]->Store; + srcStore0.Index += i; + srcStore1.Index += i; + if (i == 0) { - storage_to_dst_reg(&inst->DstReg, &accTemp, WRITEMASK_XYZW); - inst->Comment = _mesa_strdup("Begin struct/array comparison"); + /* SNE accTemp, left[i], right[i] */ + inst = emit_instruction(emitInfo, OPCODE_SNE, + &accTemp, /* dest */ + &srcStore0, + &srcStore1, + NULL); + inst_comment(inst, "Begin struct/array comparison"); } else { - storage_to_dst_reg(&inst->DstReg, &sneTemp, WRITEMASK_XYZW); - + /* SNE sneTemp, left[i], right[i] */ + inst = emit_instruction(emitInfo, OPCODE_SNE, + &sneTemp, /* dest */ + &srcStore0, + &srcStore1, + NULL); /* ADD accTemp, accTemp, sneTemp; # like logical-OR */ - inst = new_instruction(emitInfo, OPCODE_ADD); - storage_to_dst_reg(&inst->DstReg, &accTemp, WRITEMASK_XYZW); - storage_to_src_reg(&inst->SrcReg[0], &accTemp); - storage_to_src_reg(&inst->SrcReg[1], &sneTemp); + inst = emit_instruction(emitInfo, OPCODE_ADD, + &accTemp, /* dest */ + &accTemp, + &sneTemp, + NULL); } } /* compute accTemp.x || accTemp.y || accTemp.z || accTemp.w with DOT4 */ - inst = new_instruction(emitInfo, OPCODE_DP4); - storage_to_dst_reg(&inst->DstReg, n->Store, n->Writemask); - storage_to_src_reg(&inst->SrcReg[0], &accTemp); - storage_to_src_reg(&inst->SrcReg[1], &accTemp); - inst->Comment = _mesa_strdup("End struct/array comparison"); + inst = emit_instruction(emitInfo, OPCODE_DP4, + n->Store, + &accTemp, + &accTemp, + NULL); + inst_comment(inst, "End struct/array comparison"); if (n->Opcode == IR_EQUAL) { /* compute tmp.x = !tmp.x via tmp.x = (tmp.x == 0) */ - inst = new_instruction(emitInfo, OPCODE_SEQ); - storage_to_dst_reg(&inst->DstReg, n->Store, n->Writemask); - storage_to_src_reg(&inst->SrcReg[0], n->Store); - constant_to_src_reg(&inst->SrcReg[1], 0.0, emitInfo); - inst->Comment = _mesa_strdup("Invert true/false"); + slang_ir_storage zero; + constant_to_storage(emitInfo, 0.0, &zero); + inst = emit_instruction(emitInfo, OPCODE_SEQ, + n->Store, /* dest */ + n->Store, + &zero, + NULL); + inst_comment(inst, "Invert true/false"); } _slang_free_temp(emitInfo->vt, &accTemp); @@ -865,16 +961,18 @@ emit_clamp(slang_emit_info *emitInfo, slang_ir_node *n) alloc_node_storage(emitInfo, &tmpNode, n->Store->Size); /* tmp = max(ch[0], ch[1]) */ - inst = new_instruction(emitInfo, OPCODE_MAX); - storage_to_dst_reg(&inst->DstReg, tmpNode.Store, n->Writemask); - storage_to_src_reg(&inst->SrcReg[0], n->Children[0]->Store); - storage_to_src_reg(&inst->SrcReg[1], n->Children[1]->Store); + inst = emit_instruction(emitInfo, OPCODE_MAX, + tmpNode.Store, /* dest */ + n->Children[0]->Store, + n->Children[1]->Store, + NULL); /* n->dest = min(tmp, ch[2]) */ - inst = new_instruction(emitInfo, OPCODE_MIN); - storage_to_dst_reg(&inst->DstReg, n->Store, n->Writemask); - storage_to_src_reg(&inst->SrcReg[0], tmpNode.Store); - storage_to_src_reg(&inst->SrcReg[1], n->Children[2]->Store); + inst = emit_instruction(emitInfo, OPCODE_MIN, + n->Store, /* dest */ + tmpNode.Store, + n->Children[2]->Store, + NULL); free_node_storage(emitInfo->vt, &tmpNode); @@ -896,9 +994,12 @@ emit_negation(slang_emit_info *emitInfo, slang_ir_node *n) if (!alloc_node_storage(emitInfo, n, n->Children[0]->Store->Size)) return NULL; - inst = new_instruction(emitInfo, OPCODE_MOV); - storage_to_dst_reg(&inst->DstReg, n->Store, n->Writemask); - storage_to_src_reg(&inst->SrcReg[0], n->Children[0]->Store); + inst = emit_instruction(emitInfo, + OPCODE_MOV, + n->Store, /* dest */ + n->Children[0]->Store, + NULL, + NULL); inst->SrcReg[0].NegateBase = NEGATE_XYZW; return inst; } @@ -951,7 +1052,7 @@ emit_fcall(slang_emit_info *emitInfo, slang_ir_node *n) * really just a NOP to attach the label to. */ inst = new_instruction(emitInfo, OPCODE_BGNSUB); - inst->Comment = _mesa_strdup(n->Label->Name); + inst_comment(inst, n->Label->Name); } /* body of function: */ @@ -966,7 +1067,7 @@ emit_fcall(slang_emit_info *emitInfo, slang_ir_node *n) if (emitInfo->EmitBeginEndSub) { inst = new_instruction(emitInfo, OPCODE_ENDSUB); - inst->Comment = _mesa_strdup(n->Label->Name); + inst_comment(inst, n->Label->Name); } /* pop/restore cur program */ @@ -976,7 +1077,7 @@ emit_fcall(slang_emit_info *emitInfo, slang_ir_node *n) inst = new_instruction(emitInfo, OPCODE_CAL); /* The branch target is just the subroutine number (changed later) */ inst->BranchTarget = subroutineId; - inst->Comment = _mesa_strdup(n->Label->Name); + inst_comment(inst, n->Label->Name); assert(inst->BranchTarget >= 0); return inst; @@ -1022,28 +1123,33 @@ static struct prog_instruction * emit_tex(slang_emit_info *emitInfo, slang_ir_node *n) { struct prog_instruction *inst; - - (void) emit(emitInfo, n->Children[1]); + gl_inst_opcode opcode; if (n->Opcode == IR_TEX) { - inst = new_instruction(emitInfo, OPCODE_TEX); + opcode = OPCODE_TEX; } else if (n->Opcode == IR_TEXB) { - inst = new_instruction(emitInfo, OPCODE_TXB); + opcode = OPCODE_TXB; } else { assert(n->Opcode == IR_TEXP); - inst = new_instruction(emitInfo, OPCODE_TXP); + opcode = OPCODE_TXP; } + /* emit code for the texcoord operand */ + (void) emit(emitInfo, n->Children[1]); + + /* alloc storage for result of texture fetch */ if (!alloc_node_storage(emitInfo, n, 4)) return NULL; - storage_to_dst_reg(&inst->DstReg, n->Store, n->Writemask); - - /* Child[1] is the coord */ - assert(n->Children[1]->Store->Index >= 0); - storage_to_src_reg(&inst->SrcReg[0], n->Children[1]->Store); + /* emit TEX instruction; Child[1] is the texcoord */ + inst = emit_instruction(emitInfo, + opcode, + n->Store, + n->Children[1]->Store, + NULL, + NULL); /* Child[0] is the sampler (a uniform which'll indicate the texture unit) */ assert(n->Children[0]->Store); @@ -1054,14 +1160,8 @@ emit_tex(slang_emit_info *emitInfo, slang_ir_node *n) assert(n->Children[0]->Store->Size <= TEXTURE_RECT_INDEX); inst->TexSrcTarget = n->Children[0]->Store->Size; -#if 0 - inst->TexSrcUnit = 27; /* Dummy value; the TexSrcUnit will be computed at - * link time, using the sampler uniform's value. - */ - inst->Sampler = n->Children[0]->Store->Index; /* i.e. uniform's index */ -#else inst->TexSrcUnit = n->Children[0]->Store->Index; /* i.e. uniform's index */ -#endif + return inst; } @@ -1118,6 +1218,11 @@ emit_copy(slang_emit_info *emitInfo, slang_ir_node *n) * Modify the RHS (and the prev instruction) to store its results * in the destination specified by n->Children[0]. * Then, this MOVE is a no-op. + * Ex: + * MUL tmp, x, y; + * MOV a, tmp; + * becomes: + * MUL a, x, y; */ if (n->Children[1]->Opcode != IR_SWIZZLE) _slang_free_temp(emitInfo->vt, n->Children[1]->Store); @@ -1126,11 +1231,7 @@ emit_copy(slang_emit_info *emitInfo, slang_ir_node *n) /* fixup the previous instruction (which stored the RHS result) */ assert(n->Children[0]->Store->Index >= 0); - /* use tighter writemask when possible */ - if (n->Writemask == WRITEMASK_XYZW) - n->Writemask = inst->DstReg.WriteMask; - - storage_to_dst_reg(&inst->DstReg, n->Children[0]->Store, n->Writemask); + storage_to_dst_reg(&inst->DstReg, n->Children[0]->Store); return inst; } else @@ -1141,15 +1242,16 @@ emit_copy(slang_emit_info *emitInfo, slang_ir_node *n) slang_ir_storage dstStore = *n->Children[0]->Store; slang_ir_storage srcStore = *n->Children[1]->Store; GLint size = srcStore.Size; - ASSERT(n->Children[0]->Writemask == WRITEMASK_XYZW); ASSERT(n->Children[1]->Store->Swizzle == SWIZZLE_NOOP); dstStore.Size = 4; srcStore.Size = 4; while (size >= 4) { - inst = new_instruction(emitInfo, OPCODE_MOV); - inst->Comment = _mesa_strdup("IR_COPY block"); - storage_to_dst_reg(&inst->DstReg, &dstStore, n->Writemask); - storage_to_src_reg(&inst->SrcReg[0], &srcStore); + inst = emit_instruction(emitInfo, OPCODE_MOV, + &dstStore, + &srcStore, + NULL, + NULL); + inst_comment(inst, "IR_COPY block"); srcStore.Index++; dstStore.Index++; size -= 4; @@ -1158,10 +1260,12 @@ emit_copy(slang_emit_info *emitInfo, slang_ir_node *n) else { /* single register move */ char *srcAnnot, *dstAnnot; - inst = new_instruction(emitInfo, OPCODE_MOV); assert(n->Children[0]->Store->Index >= 0); - storage_to_dst_reg(&inst->DstReg, n->Children[0]->Store, n->Writemask); - storage_to_src_reg(&inst->SrcReg[0], n->Children[1]->Store); + inst = emit_instruction(emitInfo, OPCODE_MOV, + n->Children[0]->Store, /* dest */ + n->Children[1]->Store, + NULL, + NULL); dstAnnot = storage_annotation(n->Children[0], emitInfo->prog); srcAnnot = storage_annotation(n->Children[1], emitInfo->prog); inst->Comment = instruction_annotation(inst->Opcode, dstAnnot, @@ -1218,12 +1322,14 @@ emit_cond(slang_emit_info *emitInfo, slang_ir_node *n) */ if (!alloc_node_storage(emitInfo, n, 1)) return NULL; - inst = new_instruction(emitInfo, OPCODE_MOV); + inst = emit_instruction(emitInfo, OPCODE_MOV, + n->Store, /* dest */ + n->Children[0]->Store, + NULL, + NULL); inst->CondUpdate = GL_TRUE; - storage_to_dst_reg(&inst->DstReg, n->Store, n->Writemask); - storage_to_src_reg(&inst->SrcReg[0], n->Children[0]->Store); + inst_comment(inst, "COND expr"); _slang_free_temp(emitInfo->vt, n->Store); - inst->Comment = _mesa_strdup("COND expr"); return inst; } } @@ -1253,6 +1359,7 @@ emit_not(slang_emit_info *emitInfo, slang_ir_node *n) { 0, 0 } }; struct prog_instruction *inst; + slang_ir_storage zero; GLuint i; /* child expr */ @@ -1275,13 +1382,17 @@ emit_not(slang_emit_info *emitInfo, slang_ir_node *n) if (!alloc_node_storage(emitInfo, n, n->Children[0]->Store->Size)) return NULL; - inst = new_instruction(emitInfo, OPCODE_SEQ); - storage_to_dst_reg(&inst->DstReg, n->Store, n->Writemask); - storage_to_src_reg(&inst->SrcReg[0], n->Children[0]->Store); - constant_to_src_reg(&inst->SrcReg[1], 0.0, emitInfo); + constant_to_storage(emitInfo, 0.0, &zero); + inst = emit_instruction(emitInfo, + OPCODE_SEQ, + n->Store, + n->Children[0]->Store, + &zero, + NULL); + inst_comment(inst, "NOT"); + free_node_storage(emitInfo->vt, n->Children[0]); - inst->Comment = _mesa_strdup("NOT"); return inst; } @@ -1315,8 +1426,10 @@ emit_if(slang_emit_info *emitInfo, slang_ir_node *n) ifInstLoc = prog->NumInstructions; if (emitInfo->EmitHighLevelInstructions) { - struct prog_instruction *ifInst = new_instruction(emitInfo, OPCODE_IF); if (emitInfo->EmitCondCodes) { + /* IF condcode THEN ... */ + struct prog_instruction *ifInst; + ifInst = new_instruction(emitInfo, OPCODE_IF); ifInst->DstReg.CondMask = COND_NE; /* if cond is non-zero */ /* only test the cond code (1 of 4) that was updated by the * previous instruction. @@ -1324,15 +1437,19 @@ emit_if(slang_emit_info *emitInfo, slang_ir_node *n) ifInst->DstReg.CondSwizzle = writemask_to_swizzle(condWritemask); } else { - /* test reg.x */ - storage_to_src_reg(&ifInst->SrcReg[0], n->Children[0]->Store); + /* IF src[0] THEN ... */ + emit_instruction(emitInfo, OPCODE_IF, + NULL, /* dst */ + n->Children[0]->Store, /* op0 */ + NULL, + NULL); } } else { /* conditional jump to else, or endif */ struct prog_instruction *ifInst = new_instruction(emitInfo, OPCODE_BRA); ifInst->DstReg.CondMask = COND_EQ; /* BRA if cond is zero */ - ifInst->Comment = _mesa_strdup("if zero"); + inst_comment(ifInst, "if zero"); ifInst->DstReg.CondSwizzle = writemask_to_swizzle(condWritemask); } @@ -1349,7 +1466,7 @@ emit_if(slang_emit_info *emitInfo, slang_ir_node *n) /* jump to endif instruction */ struct prog_instruction *inst; inst = new_instruction(emitInfo, OPCODE_BRA); - inst->Comment = _mesa_strdup("else"); + inst_comment(inst, "else"); inst->DstReg.CondMask = COND_TR; /* always branch */ } prog->Instructions[ifInstLoc].BranchTarget = prog->NumInstructions; @@ -1520,8 +1637,11 @@ emit_cont_break_if_true(slang_emit_info *emitInfo, slang_ir_node *n) */ GLint ifInstLoc; ifInstLoc = emitInfo->prog->NumInstructions; - inst = new_instruction(emitInfo, OPCODE_IF); - storage_to_src_reg(&inst->SrcReg[0], n->Children[0]->Store); + inst = emit_instruction(emitInfo, OPCODE_IF, + NULL, /* dest */ + n->Children[0]->Store, + NULL, + NULL); n->InstLocation = emitInfo->prog->NumInstructions; inst = new_instruction(emitInfo, opcode); @@ -1576,18 +1696,17 @@ move_block(slang_emit_info *emitInfo, /* move matrix/struct etc (block of registers) */ slang_ir_storage dstStore = *dst; slang_ir_storage srcStore = *src; - //GLint size = srcStore.Size; - /*ASSERT(n->Children[0]->Writemask == WRITEMASK_XYZW); - ASSERT(n->Children[1]->Store->Swizzle == SWIZZLE_NOOP); - */ + dstStore.Size = 4; srcStore.Size = 4; while (size >= 4) { - inst = new_instruction(emitInfo, OPCODE_MOV); - inst->Comment = _mesa_strdup("IR_COPY block"); - storage_to_dst_reg(&inst->DstReg, &dstStore, WRITEMASK_XYZW); - storage_to_src_reg(&inst->SrcReg[0], &srcStore); + inst = emit_instruction(emitInfo, OPCODE_MOV, + &dstStore, + &srcStore, + NULL, + NULL); inst->SrcReg[0].RelAddr = relAddr; + inst_comment(inst, "IR_COPY block"); srcStore.Index++; dstStore.Index++; size -= 4; @@ -1595,18 +1714,12 @@ move_block(slang_emit_info *emitInfo, } else { /* single register move */ - GLuint writemask; - if (size == 1) { - GLuint comp = GET_SWZ(src->Swizzle, 0); - assert(comp < 4); - writemask = WRITEMASK_X << comp; - } - else { - writemask = WRITEMASK_XYZW; - } - inst = new_instruction(emitInfo, OPCODE_MOV); - storage_to_dst_reg(&inst->DstReg, dst, writemask); - storage_to_src_reg(&inst->SrcReg[0], src); + inst = emit_instruction(emitInfo, + OPCODE_MOV, + dst, + src, + NULL, + NULL); inst->SrcReg[0].RelAddr = relAddr; } return inst; @@ -1617,26 +1730,28 @@ move_block(slang_emit_info *emitInfo, /** * Dereference array element. Just resolve storage for the array * element represented by this node. + * This is typically where Indirect addressing comes into play. + * See comments on struct slang_ir_storage. */ static struct prog_instruction * emit_array_element(slang_emit_info *emitInfo, slang_ir_node *n) { - slang_ir_storage *root; - assert(n->Opcode == IR_ELEMENT); assert(n->Store); assert(n->Store->File == PROGRAM_UNDEFINED); assert(n->Store->Parent); assert(n->Store->Size > 0); - root = n->Store; - while (root->Parent) - root = root->Parent; + { + slang_ir_storage *root = n->Store; + while (root->Parent) + root = root->Parent; - if (root->File == PROGRAM_STATE_VAR) { - GLint index = _slang_alloc_statevar(n, emitInfo->prog->Parameters); - assert(n->Store->Index == index); - return NULL; + if (root->File == PROGRAM_STATE_VAR) { + GLint index = _slang_alloc_statevar(n, emitInfo->prog->Parameters); + assert(n->Store->Index == index); + return NULL; + } } /* do codegen for array */ @@ -1668,30 +1783,30 @@ emit_array_element(slang_emit_info *emitInfo, slang_ir_node *n) if (n->Store->Size > 4) { /* need to multiply the index by the element size */ - GLint elemSize = (n->Store->Size + 3) / 4; - slang_ir_storage indexTemp; + const GLint elemSize = (n->Store->Size + 3) / 4; + slang_ir_storage indexTemp, elemSizeStore; + + /* constant containing the element size */ + constant_to_storage(emitInfo, (float) elemSize, &elemSizeStore); /* allocate 1 float indexTemp */ alloc_local_temp(emitInfo, &indexTemp, 1); /* MUL temp, index, elemSize */ - inst = new_instruction(emitInfo, OPCODE_MUL); - storage_to_dst_reg(&inst->DstReg, &indexTemp, WRITEMASK_X); - storage_to_src_reg(&inst->SrcReg[0], n->Children[1]->Store); - constant_to_src_reg(&inst->SrcReg[1], elemSize, emitInfo); + inst = emit_instruction(emitInfo, OPCODE_MUL, + &indexTemp, /* dest */ + n->Children[1]->Store, /* the index */ + &elemSizeStore, + NULL); /* load ADDR[0].X = temp */ - inst = new_instruction(emitInfo, OPCODE_ARL); - storage_to_src_reg(&inst->SrcReg[0], &indexTemp); - address_to_dst_reg(&inst->DstReg, 0); + inst = emit_arl_instruction(emitInfo, 0, &indexTemp); _slang_free_temp(emitInfo->vt, &indexTemp); } else { /* simply load address reg w/ array index */ - inst = new_instruction(emitInfo, OPCODE_ARL); - storage_to_src_reg(&inst->SrcReg[0], n->Children[1]->Store); - address_to_dst_reg(&inst->DstReg, 0); + inst = emit_arl_instruction(emitInfo, 0, n->Children[1]->Store); } /* copy from array element to temp storage */ @@ -1750,8 +1865,6 @@ emit_struct_field(slang_emit_info *emitInfo, slang_ir_node *n) static struct prog_instruction * emit_var_decl(slang_emit_info *emitInfo, slang_ir_node *n) { - struct prog_instruction *inst; - assert(n->Store); assert(n->Store->File != PROGRAM_UNDEFINED); assert(n->Store->Size > 0); @@ -1788,8 +1901,7 @@ emit_var_decl(slang_emit_info *emitInfo, slang_ir_node *n) _mesa_swizzle_string(n->Store->Swizzle, 0, GL_FALSE), (n->Var ? (char *) n->Var->a_name : "anonymous"), n->Store->Size); - inst = emit_comment(emitInfo, s); - return inst; + emit_comment(emitInfo, s); } return NULL; } diff --git a/src/mesa/shader/slang/slang_ir.c b/src/mesa/shader/slang/slang_ir.c index 9d055bf354..4fe3a2b85d 100644 --- a/src/mesa/shader/slang/slang_ir.c +++ b/src/mesa/shader/slang/slang_ir.c @@ -243,22 +243,6 @@ _slang_free_ir_tree(slang_ir_node *n) } - -static const char * -writemask_string(GLuint writemask) -{ - static char s[6]; - GLuint i, j = 0; - s[j++] = '.'; - for (i = 0; i < 4; i++) { - if (writemask & (1 << i)) - s[j++] = "xyzw"[i]; - } - s[j] = 0; - return s; -} - - static const char * storage_string(const slang_ir_storage *st) { @@ -332,7 +316,7 @@ _slang_print_ir_tree(const slang_ir_node *n, int indent) _slang_print_ir_tree(n->Children[0], indent + 3); break; case IR_COPY: - printf("COPY (writemask = %s)\n", writemask_string(n->Writemask)); + printf("COPY\n"); _slang_print_ir_tree(n->Children[0], indent+3); _slang_print_ir_tree(n->Children[1], indent+3); break; diff --git a/src/mesa/shader/slang/slang_ir.h b/src/mesa/shader/slang/slang_ir.h index ab0353c28a..a4552ae144 100644 --- a/src/mesa/shader/slang/slang_ir.h +++ b/src/mesa/shader/slang/slang_ir.h @@ -173,7 +173,6 @@ typedef struct slang_ir_node_ /** special fields depending on Opcode: */ const char *Field; /**< If Opcode == IR_FIELD */ - GLuint Writemask; /**< If Opcode == IR_MOVE */ GLfloat Value[4]; /**< If Opcode == IR_FLOAT */ slang_variable *Var; /**< If Opcode == IR_VAR or IR_VAR_DECL */ struct slang_ir_node_ *List; /**< For various linked lists */ |