This page's goal is to describe parts of Nintendo's OpenGL implementation for the 3DS as we reverse engineer it to better understand how to use the PICA200. Some of the information on this page is specific to Steeldiver : Sub Wars. The reason for this is that it's a fairly graphics-heavy game that's available on the eShop for free, so it seems like a good target for a community REing effort.

Rendering pipeline

Description

The PICA200 is an opengl ES 1.1 compliant GPU manufactured by DMP. It comes loaded with a number of extensions that make it similar to an openGL ES 2.0 compliant GPU (ability to run programmable vertex/geometry shaders, for instance). Because of this, Nintendo wrapped GPU access into an openGL ES 2.0 implementation with some limitations. As the fragment stage of the pipeline is non-programmable, Nintendo instead gives developers the ability to configure a number of fragment-related values through glGetUniformLocation and glUniformXX. See below for the full list.

Shader program structure

When uniform values are set (in shm_uniformfv/shm_uniformiv), they are attached to the current shader program and stored into the corresponding shader program structure. They are later written to the GPU command buffer in __shv_validateShaderValidator or equivalent.

Shader program struct :

Offset Size Description
0x000 0x04 Value 0x0 ?
0x004 0x04 Program ID
0x008 0x04 Value -1 ?
0x01C 0x04 Pointer to program-specific uniform table
0x020 0x04 Total number of uniforms for program
0x028 0x04 Number of program-specific uniforms
0x414 0x04 Pointer to vertex shader struct
0x64C 0x04 Value for GPU register 0x0104
0x7C0 0x04 Bitfield containing dmp_FragmentLightSource[n].shadowed values
0x7D8 0x04 Bitfield containing dmp_FragmentLightSource[n].geomFactor0 / dmp_FragmentLightSource[n].geomFactor1 / dmp_FragmentLightSource[n].twoSideDiffuse values
0xA20 0x70*8 Table of structs for 8 dmp_FragmentLightSource

dmp_FragmentLightSource struct:

Offset Size Description
0x00 0x01 dmp_FragmentLightSource[k].enabled
0x04 0x10 dmp_FragmentLightSource[k].ambient (float[4])
0x14 0x10 dmp_FragmentLightSource[k].diffuse (float[4])
0x24 0x10 dmp_FragmentLightSource[k].specular0 (float[4])
0x34 0x10 dmp_FragmentLightSource[k].specular1 (float[4])
0x44 0x10 dmp_FragmentLightSource[k].position (float[4])
0x54 0x10 dmp_FragmentLightSource[k].spotDirection (float[3])
0x60 0x04 dmp_FragmentLightSource[k].samplerSP (u32)
0x64 0x04 dmp_FragmentLightSource[k].distanceAttenuationBias (float)
0x68 0x04 dmp_FragmentLightSource[k].distanceAttenuationScale (float)

vertex/geometry shader struct:

Offset Size Description
0x0 0x4 Pointer to shader code data
0x4 0x4 Size of shader code (in words)
0x8 0x4 Pointer to shader opdesc data
0xC 0x4 Size of shader opdescs (in words)

Proposed REing methodology

1. Choose a "uniform" you want to RE below

2. Take note of its ID and type !

3. Depending on whether its a float or not, go through the gigantic switches in shm_uniformfv or shm_uniformiv (non-float) based on the ID of your uniform (in the case of steeldiver: sub wars you can now just go directly to the handler as it's listed in the table below)

4. Once you find the piece of code specific to your uniform, take note of how the values passed to shm_uniformfv/shm_uniformiv are written to the shader object

5. Go through __shv_validateShaderValidator looking for where those fields written to in shm_uniformfv/shm_uniformiv are used and written to the GPU command buffer either directly or through __cb_writeRegs, __cb_multiWriteReg or __cb_fillRegs.

6. Document findings on 3Dbrew ! (that's the most important step)

Fragment "uniform" list

Uniform ID Type Name Handler address (Steeldiver : Sub Wars) Shader Program struct offset GPU Register
0x0 GL_BOOL dmp_Texture[0].perspectiveShadow 0x0012A504 ? 0x008B bit0 (0 = enable??)
0x1 GL_FLOAT dmp_Texture[0].shadowZBias 0x00155584 0xE44 ?
0x2 GL_FLOAT dmp_Texture[0].shadowZScale 0x001556A0 0xE48 ?
0x3 GL_INT dmp_Texture[0].samplerType 0x0012A5D0 ? ?
0x4 GL_INT dmp_Texture[1].samplerType 0x0012A6F8 ? ?
0x5 GL_INT dmp_Texture[2].samplerType 0x0012A774 ? ?
0x6 GL_INT dmp_Texture[3].samplerType 0x0012A7F0 ? 0x0080 bit10 (?)
0x7 GL_INT dmp_Texture[2].texcoord 0x0012A8B4 ? 0x0080 bit13 (1 = use texcoords from texture unit 1)
0x8 GL_INT dmp_Texture[3].texcoord 0x0012A97C ? 0x0080 bit8-9 (0-2 = use texcoords from texture unit 0-2 resp., 3 = forbidden?)
0x9 GL_INT dmp_Texture[3].ptRgbMap 0x0012AA54 ? 0x00A8 bit6-9
0xA GL_INT dmp_Texture[3].ptAlphaMap 0x0012AB94 ? 0x00A8 bit10-13
0xB GL_BOOL dmp_Texture[3].ptAlphaSeparate 0x0012ACD4 ? 0x00A8 bit14
0xC GL_INT dmp_Texture[3].ptClampU 0x0012ADB8 ? 0x00A8 bit0-2
0xD GL_INT dmp_Texture[3].ptClampV 0x0012AEC0 ? 0x00A8 bit3-5
0xE GL_INT dmp_Texture[3].ptShiftU 0x0012AFD0 ? 0x00A8 bit16-17
0xF GL_INT dmp_Texture[3].ptShiftV 0x0012B0A0 ? 0x00A8 bit18-19
0x10 GL_INT dmp_Texture[3].ptMinFilter 0x0012B168 ? 0x00AC bit0-2
0x11 GL_INT dmp_Texture[3].ptTexWidth 0x0012B270 ? 0x00AC bit11-18
0x12 GL_INT dmp_Texture[3].ptTexOffset 0x0012B334 ? 0x00AD bit0-7
0x13 GL_FLOAT dmp_Texture[3].ptTexBias 0x001556B4 0xE10 0x00A8 bit20-27
0x14 GL_BOOL dmp_Texture[3].ptNoiseEnable 0x0012B3E0 ? 0x00A8 bit15
0x15 GL_FLOAT_VEC3 dmp_Texture[3].ptNoiseU 0x00155878 0xE14 0x00A9, 0x00AB
0x16 GL_FLOAT_VEC3 dmp_Texture[3].ptNoiseV 0x00155A7C 0xE20 0x00AA, 0x00AB
0x17 GL_SAMPLER_1D dmp_Texture[3].ptSamplerRgbMap 0x0012B4B0 0xDF0 ?
0x18 GL_SAMPLER_1D dmp_Texture[3].ptSamplerAlphaMap 0x0012B4F4 0xDF4 ?
0x19 GL_SAMPLER_1D dmp_Texture[3].ptSamplerNoiseMap 0x0012B540 0xDF8 ?
0x1A GL_SAMPLER_1D dmp_Texture[3].ptSamplerR 0x0012B58C 0xDFC ?
0x1B GL_SAMPLER_1D dmp_Texture[3].ptSamplerG 0x0012B5D8 0xE00 ?
0x1C GL_SAMPLER_1D dmp_Texture[3].ptSamplerB 0x0012B624 0xE04 ?
0x1D GL_SAMPLER_1D dmp_Texture[3].ptSamplerA 0x0012B670 0xE08 ?
0x1E GL_INT dmp_FragOperation.mode 0x0012B6BC 0xE38 ?
0x1F GL_FLOAT dmp_FragOperation.penumbraScale 0x00155C98 0xE40 ?
0x20 GL_FLOAT dmp_FragOperation.penumbraBias 0x00155D8C 0xE3C ?
0x21 GL_FLOAT dmp_FragOperation.wScale 0x00155E9C 0xE4C ?
0x22 GL_BOOL dmp_FragOperation.enableClippingPlane 0x0012EAEC 0x568 0x0047 bit0
0x23 GL_FLOAT_VEC4 dmp_FragOperation.clippingPlane 0x00159474 0xE50 ?
0x24 GL_BOOL dmp_FragOperation.enableAlphaTest 0x0012EBAC 0x64C ?
0x25 GL_INT dmp_FragOperation.alphaTestFunc 0x0012EC64 0x64C ?
0x26 GL_FLOAT dmp_FragOperation.alphaRefValue 0x0015971C 0x64C ? ?
0x27 GL_FLOAT_VEC3 dmp_Gas.lightXY 0x001560EC 0xE84 ?
0x28 GL_FLOAT_VEC4 dmp_Gas.lightZ 0x00156268 0xE90 ?
0x29 GL_FLOAT dmp_Gas.deltaZ 0x001564D4 0xEA0 ?
0x2A GL_FLOAT dmp_Gas.accMax 0x001565C0 0xEA4 ?
0x2B GL_BOOL dmp_Gas.autoAcc 0x0012B790 0xE74 ?
0x2C GL_FLOAT dmp_Gas.attenuation 0x00156684 0xEA8 ?
0x2D GL_INT dmp_Gas.colorLutInput 0x0012B7A4 0x640 ?
0x2E GL_INT dmp_Gas.shadingDensitySrc 0x0012B854 0x624 ?
0x2F GL_SAMPLER_1D dmp_Gas.samplerTR 0x0012B910 0xE78 ?
0x30 GL_SAMPLER_1D dmp_Gas.samplerTG 0x0012B95C 0xE7C ?
0x31 GL_SAMPLER_1D dmp_Gas.samplerTB 0x0012B9A8 0xE80 ?
0x32 GL_BOOL dmp_FragmentLighting.enabled 0x0012B9F4 0x590 0x00A8 ?
0x33 GL_FLOAT_VEC4 dmp_FragmentLighting.ambient 0x00156744 0xA10 ?
0x34 GL_FLOAT_VEC4 dmp_FragmentMaterial.emission 0x00156E1C 0xDE0 ?
0x35 GL_FLOAT_VEC4 dmp_FragmentMaterial.ambient 0x0015696C 0xDA0 ?
0x36 GL_FLOAT_VEC4 dmp_FragmentMaterial.diffuse 0x00157048 0xDB0 ?
0x37 GL_FLOAT_VEC4 dmp_FragmentMaterial.specular0 0x001572E0 0xDC0 ?
0x38 GL_FLOAT_VEC4 dmp_FragmentMaterial.specular1 0x0015756C 0xDD0 ?
0x39 GL_BOOL dmp_FragmentLightSource[0].enabled 0x0012BD24 0xA20+0*0x70+0x00 0x01C5
0x3A GL_BOOL dmp_FragmentLightSource[1].enabled 0x0012BD24 0xA20+1*0x70+0x00 0x01C5
0x3B GL_BOOL dmp_FragmentLightSource[2].enabled 0x0012BD24 0xA20+2*0x70+0x00 0x01C5
0x3C GL_BOOL dmp_FragmentLightSource[3].enabled 0x0012BD24 0xA20+3*0x70+0x00 0x01C5
0x3D GL_BOOL dmp_FragmentLightSource[4].enabled 0x0012BD24 0xA20+4*0x70+0x00 0x01C5
0x3E GL_BOOL dmp_FragmentLightSource[5].enabled 0x0012BD24 0xA20+5*0x70+0x00 0x01C5
0x3F GL_BOOL dmp_FragmentLightSource[6].enabled 0x0012BD24 0xA20+6*0x70+0x00 0x01C5
0x40 GL_BOOL dmp_FragmentLightSource[7].enabled 0x0012BD24 0xA20+7*0x70+0x00 0x01C5
0x41 GL_FLOAT_VEC4 dmp_FragmentLightSource[0].ambient 0x001579CC 0xA20+0*0x70+0x04 0x0143
0x42 GL_FLOAT_VEC4 dmp_FragmentLightSource[1].ambient 0x001579CC 0xA20+1*0x70+0x04 0x0153
0x43 GL_FLOAT_VEC4 dmp_FragmentLightSource[2].ambient 0x001579CC 0xA20+2*0x70+0x04 0x0163
0x44 GL_FLOAT_VEC4 dmp_FragmentLightSource[3].ambient 0x001579CC 0xA20+3*0x70+0x04 0x0173
0x45 GL_FLOAT_VEC4 dmp_FragmentLightSource[4].ambient 0x001579CC 0xA20+4*0x70+0x04 0x0183
0x46 GL_FLOAT_VEC4 dmp_FragmentLightSource[5].ambient 0x001579CC 0xA20+5*0x70+0x04 0x0193
0x47 GL_FLOAT_VEC4 dmp_FragmentLightSource[6].ambient 0x001579CC 0xA20+6*0x70+0x04 0x01A3
0x48 GL_FLOAT_VEC4 dmp_FragmentLightSource[7].ambient 0x001579CC 0xA20+7*0x70+0x04 0x01B3
0x49 GL_FLOAT_VEC4 dmp_FragmentLightSource[0].diffuse 0x00157C10 0xA20+0*0x70+0x14 0x0142
0x4A GL_FLOAT_VEC4 dmp_FragmentLightSource[1].diffuse 0x00157C10 0xA20+1*0x70+0x14 0x0152
0x4B GL_FLOAT_VEC4 dmp_FragmentLightSource[2].diffuse 0x00157C10 0xA20+2*0x70+0x14 0x0162
0x4C GL_FLOAT_VEC4 dmp_FragmentLightSource[3].diffuse 0x00157C10 0xA20+3*0x70+0x14 0x0172
0x4D GL_FLOAT_VEC4 dmp_FragmentLightSource[4].diffuse 0x00157C10 0xA20+4*0x70+0x14 0x0182
0x4E GL_FLOAT_VEC4 dmp_FragmentLightSource[5].diffuse 0x00157C10 0xA20+5*0x70+0x14 0x0192
0x4F GL_FLOAT_VEC4 dmp_FragmentLightSource[6].diffuse 0x00157C10 0xA20+6*0x70+0x14 0x01A2
0x50 GL_FLOAT_VEC4 dmp_FragmentLightSource[7].diffuse 0x00157C10 0xA20+7*0x70+0x14 0x01B2
0x51 GL_FLOAT_VEC4 dmp_FragmentLightSource[0].specular0 0x00157E5C 0xA20+0*0x70+0x24 0x01C8 ?
0x52 GL_FLOAT_VEC4 dmp_FragmentLightSource[1].specular0 0x00157E5C 0xA20+1*0x70+0x24 0x01C8 ?
0x53 GL_FLOAT_VEC4 dmp_FragmentLightSource[2].specular0 0x00157E5C 0xA20+2*0x70+0x24 0x01C8 ?
0x54 GL_FLOAT_VEC4 dmp_FragmentLightSource[3].specular0 0x00157E5C 0xA20+3*0x70+0x24 0x01C8 ?
0x55 GL_FLOAT_VEC4 dmp_FragmentLightSource[4].specular0 0x00157E5C 0xA20+4*0x70+0x24 0x01C8 ?
0x56 GL_FLOAT_VEC4 dmp_FragmentLightSource[5].specular0 0x00157E5C 0xA20+5*0x70+0x24 0x01C8 ?
0x57 GL_FLOAT_VEC4 dmp_FragmentLightSource[6].specular0 0x00157E5C 0xA20+6*0x70+0x24 0x01C8 ?
0x58 GL_FLOAT_VEC4 dmp_FragmentLightSource[7].specular0 0x00157E5C 0xA20+7*0x70+0x24 0x01C8 ?
0x59 GL_FLOAT_VEC4 dmp_FragmentLightSource[0].specular1 0x001580B4 0xA20+0*0x70+0x34 0x01C8 ?
0x5A GL_FLOAT_VEC4 dmp_FragmentLightSource[1].specular1 0x001580B4 0xA20+1*0x70+0x34 0x01C8 ?
0x5B GL_FLOAT_VEC4 dmp_FragmentLightSource[2].specular1 0x001580B4 0xA20+2*0x70+0x34 0x01C8 ?
0x5C GL_FLOAT_VEC4 dmp_FragmentLightSource[3].specular1 0x001580B4 0xA20+3*0x70+0x34 0x01C8 ?
0x5D GL_FLOAT_VEC4 dmp_FragmentLightSource[4].specular1 0x001580B4 0xA20+4*0x70+0x34 0x01C8 ?
0x5E GL_FLOAT_VEC4 dmp_FragmentLightSource[5].specular1 0x001580B4 0xA20+5*0x70+0x34 0x01C8 ?
0x5F GL_FLOAT_VEC4 dmp_FragmentLightSource[6].specular1 0x001580B4 0xA20+6*0x70+0x34 0x01C8 ?
0x60 GL_FLOAT_VEC4 dmp_FragmentLightSource[7].specular1 0x001580B4 0xA20+7*0x70+0x34 0x01C8 ?
0x61 GL_FLOAT_VEC4 dmp_FragmentLightSource[0].position 0x001584B0 0xA20+0*0x70+0x44 0x01C8 ?
0x62 GL_FLOAT_VEC4 dmp_FragmentLightSource[1].position 0x001584B0 0xA20+1*0x70+0x44 0x01C8 ?
0x63 GL_FLOAT_VEC4 dmp_FragmentLightSource[2].position 0x001584B0 0xA20+2*0x70+0x44 0x01C8 ?
0x64 GL_FLOAT_VEC4 dmp_FragmentLightSource[3].position 0x001584B0 0xA20+3*0x70+0x44 0x01C8 ?
0x65 GL_FLOAT_VEC4 dmp_FragmentLightSource[4].position 0x001584B0 0xA20+4*0x70+0x44 0x01C8 ?
0x66 GL_FLOAT_VEC4 dmp_FragmentLightSource[5].position 0x001584B0 0xA20+5*0x70+0x44 0x01C8 ?
0x67 GL_FLOAT_VEC4 dmp_FragmentLightSource[6].position 0x001584B0 0xA20+6*0x70+0x44 0x01C8 ?
0x68 GL_FLOAT_VEC4 dmp_FragmentLightSource[7].position 0x001584B0 0xA20+7*0x70+0x44 0x01C8 ?
0x69 GL_FLOAT_VEC3 dmp_FragmentLightSource[0].spotDirection 0x001587E4 0xA20+0*0x70+0x54 0x01C8 ?
0x6A GL_FLOAT_VEC3 dmp_FragmentLightSource[1].spotDirection 0x001587E4 0xA20+1*0x70+0x54 0x01C8 ?
0x6B GL_FLOAT_VEC3 dmp_FragmentLightSource[2].spotDirection 0x001587E4 0xA20+2*0x70+0x54 0x01C8 ?
0x6C GL_FLOAT_VEC3 dmp_FragmentLightSource[3].spotDirection 0x001587E4 0xA20+3*0x70+0x54 0x01C8 ?
0x6D GL_FLOAT_VEC3 dmp_FragmentLightSource[4].spotDirection 0x001587E4 0xA20+4*0x70+0x54 0x01C8 ?
0x6E GL_FLOAT_VEC3 dmp_FragmentLightSource[5].spotDirection 0x001587E4 0xA20+5*0x70+0x54 0x01C8 ?
0x6F GL_FLOAT_VEC3 dmp_FragmentLightSource[6].spotDirection 0x001587E4 0xA20+6*0x70+0x54 0x01C8 ?
0x70 GL_FLOAT_VEC3 dmp_FragmentLightSource[7].spotDirection 0x001587E4 0xA20+7*0x70+0x54 0x01C8 ?
0x71 GL_BOOL dmp_FragmentLightSource[0].shadowed 0x0012C20C 0x7C0 0x01C8 ?
0x72 GL_BOOL dmp_FragmentLightSource[1].shadowed 0x0012C20C 0x7C0 0x01C8 ?
0x73 GL_BOOL dmp_FragmentLightSource[2].shadowed 0x0012C20C 0x7C0 0x01C8 ?
0x74 GL_BOOL dmp_FragmentLightSource[3].shadowed 0x0012C20C 0x7C0 0x01C8 ?
0x75 GL_BOOL dmp_FragmentLightSource[4].shadowed 0x0012C20C 0x7C0 0x01C8 ?
0x76 GL_BOOL dmp_FragmentLightSource[5].shadowed 0x0012C20C 0x7C0 0x01C8 ?
0x77 GL_BOOL dmp_FragmentLightSource[6].shadowed 0x0012C20C 0x7C0 0x01C8 ?
0x78 GL_BOOL dmp_FragmentLightSource[7].shadowed 0x0012C20C 0x7C0 0x01C8 ?
0x79 GL_BOOL dmp_FragmentLightSource[0].geomFactor0 0x0012C018 0x7D8 0x0149 bit2
0x7A GL_BOOL dmp_FragmentLightSource[1].geomFactor0 0x0012C018 0x7D8 0x0159 bit2
0x7B GL_BOOL dmp_FragmentLightSource[2].geomFactor0 0x0012C018 0x7D8 0x0169 bit2
0x7C GL_BOOL dmp_FragmentLightSource[3].geomFactor0 0x0012C018 0x7D8 0x0179 bit2
0x7D GL_BOOL dmp_FragmentLightSource[4].geomFactor0 0x0012C018 0x7D8 0x0189 bit2
0x7E GL_BOOL dmp_FragmentLightSource[5].geomFactor0 0x0012C018 0x7D8 0x0199 bit2
0x7F GL_BOOL dmp_FragmentLightSource[6].geomFactor0 0x0012C018 0x7D8 0x01A9 bit2
0x80 GL_BOOL dmp_FragmentLightSource[7].geomFactor0 0x0012C018 0x7D8 0x01B9 bit2
0x81 GL_BOOL dmp_FragmentLightSource[0].geomFactor1 0x0012C114 0x7D8 0x0149 bit3
0x82 GL_BOOL dmp_FragmentLightSource[1].geomFactor1 0x0012C114 0x7D8 0x0159 bit3
0x83 GL_BOOL dmp_FragmentLightSource[2].geomFactor1 0x0012C114 0x7D8 0x0169 bit3
0x84 GL_BOOL dmp_FragmentLightSource[3].geomFactor1 0x0012C114 0x7D8 0x0179 bit3
0x85 GL_BOOL dmp_FragmentLightSource[4].geomFactor1 0x0012C114 0x7D8 0x0189 bit3
0x86 GL_BOOL dmp_FragmentLightSource[5].geomFactor1 0x0012C114 0x7D8 0x0199 bit3
0x87 GL_BOOL dmp_FragmentLightSource[6].geomFactor1 0x0012C114 0x7D8 0x01A9 bit3
0x88 GL_BOOL dmp_FragmentLightSource[7].geomFactor1 0x0012C114 0x7D8 0x01B9 bit3
0x89 GL_BOOL dmp_FragmentLightSource[0].twoSideDiffuse 0x0012BF10 0x7D8 0x0149 bit1
0x8A GL_BOOL dmp_FragmentLightSource[1].twoSideDiffuse 0x0012BF10 0x7D8 0x0159 bit1
0x8B GL_BOOL dmp_FragmentLightSource[2].twoSideDiffuse 0x0012BF10 0x7D8 0x0169 bit1
0x8C GL_BOOL dmp_FragmentLightSource[3].twoSideDiffuse 0x0012BF10 0x7D8 0x0179 bit1
0x8D GL_BOOL dmp_FragmentLightSource[4].twoSideDiffuse 0x0012BF10 0x7D8 0x0189 bit1
0x8E GL_BOOL dmp_FragmentLightSource[5].twoSideDiffuse 0x0012BF10 0x7D8 0x0199 bit1
0x8F GL_BOOL dmp_FragmentLightSource[6].twoSideDiffuse 0x0012BF10 0x7D8 0x01A9 bit1
0x90 GL_BOOL dmp_FragmentLightSource[7].twoSideDiffuse 0x0012BF10 0x7D8 0x01B9 bit1
0x91 GL_SAMPLER_1D dmp_FragmentLightSource[0].samplerSP 0x0012C31C 0xA20+0*0x70+0x60 0x01C8 ?
0x92 GL_SAMPLER_1D dmp_FragmentLightSource[1].samplerSP 0x0012C31C 0xA20+1*0x70+0x60 0x01C8 ?
0x93 GL_SAMPLER_1D dmp_FragmentLightSource[2].samplerSP 0x0012C31C 0xA20+2*0x70+0x60 0x01C8 ?
0x94 GL_SAMPLER_1D dmp_FragmentLightSource[3].samplerSP 0x0012C31C 0xA20+3*0x70+0x60 0x01C8 ?
0x95 GL_SAMPLER_1D dmp_FragmentLightSource[4].samplerSP 0x0012C31C 0xA20+4*0x70+0x60 0x01C8 ?
0x96 GL_SAMPLER_1D dmp_FragmentLightSource[5].samplerSP 0x0012C31C 0xA20+5*0x70+0x60 0x01C8 ?
0x97 GL_SAMPLER_1D dmp_FragmentLightSource[6].samplerSP 0x0012C31C 0xA20+6*0x70+0x60 0x01C8 ?
0x98 GL_SAMPLER_1D dmp_FragmentLightSource[7].samplerSP 0x0012C31C 0xA20+7*0x70+0x60 0x01C8 ?
0x99 GL_BOOL dmp_FragmentLightSource[0].spotEnabled 0x0012C380 ? 0x01C4 bit3 (1 = disable?)
0x9A GL_BOOL dmp_FragmentLightSource[1].spotEnabled 0x0012C380 ? 0x01C4 bit4 (1 = disable?)
0x9B GL_BOOL dmp_FragmentLightSource[2].spotEnabled 0x0012C380 ? 0x01C4 bit5 (1 = disable?)
0x9C GL_BOOL dmp_FragmentLightSource[3].spotEnabled 0x0012C380 ? 0x01C4 bit6 (1 = disable?)
0x9D GL_BOOL dmp_FragmentLightSource[4].spotEnabled 0x0012C380 ? 0x01C4 bit7 (1 = disable?)
0x9E GL_BOOL dmp_FragmentLightSource[5].spotEnabled 0x0012C380 ? 0x01C4 bit8 (1 = disable?)
0x9F GL_BOOL dmp_FragmentLightSource[6].spotEnabled 0x0012C380 ? 0x01C4 bit9 (1 = disable?)
0xA0 GL_BOOL dmp_FragmentLightSource[7].spotEnabled 0x0012C380 ? 0x01C4 bit10 (1 = disable?)
0xA1 GL_FLOAT dmp_FragmentLightSource[0].distanceAttenuationBias 0x00158AE8 0xA20+0*0x70+0x64 0x01C8 ?
0xA2 GL_FLOAT dmp_FragmentLightSource[1].distanceAttenuationBias 0x00158AE8 0xA20+1*0x70+0x64 0x01C8 ?
0xA3 GL_FLOAT dmp_FragmentLightSource[2].distanceAttenuationBias 0x00158AE8 0xA20+2*0x70+0x64 0x01C8 ?
0xA4 GL_FLOAT dmp_FragmentLightSource[3].distanceAttenuationBias 0x00158AE8 0xA20+3*0x70+0x64 0x01C8 ?
0xA5 GL_FLOAT dmp_FragmentLightSource[4].distanceAttenuationBias 0x00158AE8 0xA20+4*0x70+0x64 0x01C8 ?
0xA6 GL_FLOAT dmp_FragmentLightSource[5].distanceAttenuationBias 0x00158AE8 0xA20+5*0x70+0x64 0x01C8 ?
0xA7 GL_FLOAT dmp_FragmentLightSource[6].distanceAttenuationBias 0x00158AE8 0xA20+6*0x70+0x64 0x01C8 ?
0xA8 GL_FLOAT dmp_FragmentLightSource[7].distanceAttenuationBias 0x00158AE8 0xA20+7*0x70+0x64 0x01C8 ?
0xA9 GL_FLOAT dmp_FragmentLightSource[0].distanceAttenuationScale 0x00158C44 0xA20+0*0x70+0x68 0x01C8 ?
0xAA GL_FLOAT dmp_FragmentLightSource[1].distanceAttenuationScale 0x00158C44 0xA20+1*0x70+0x68 0x01C8 ?
0xAB GL_FLOAT dmp_FragmentLightSource[2].distanceAttenuationScale 0x00158C44 0xA20+2*0x70+0x68 0x01C8 ?
0xAC GL_FLOAT dmp_FragmentLightSource[3].distanceAttenuationScale 0x00158C44 0xA20+3*0x70+0x68 0x01C8 ?
0xAD GL_FLOAT dmp_FragmentLightSource[4].distanceAttenuationScale 0x00158C44 0xA20+4*0x70+0x68 0x01C8 ?
0xAE GL_FLOAT dmp_FragmentLightSource[5].distanceAttenuationScale 0x00158C44 0xA20+5*0x70+0x68 0x01C8 ?
0xAF GL_FLOAT dmp_FragmentLightSource[6].distanceAttenuationScale 0x00158C44 0xA20+6*0x70+0x68 0x01C8 ?
0xB0 GL_FLOAT dmp_FragmentLightSource[7].distanceAttenuationScale 0x00158C44 0xA20+7*0x70+0x68 0x01C8 ?
0xB1 GL_BOOL dmp_FragmentLightSource[0].distanceAttenuationEnabled 0x0012C4A0 ? 0x01C8 ?
0xB2 GL_BOOL dmp_FragmentLightSource[1].distanceAttenuationEnabled 0x0012C4A0 ? 0x01C8 ?
0xB3 GL_BOOL dmp_FragmentLightSource[2].distanceAttenuationEnabled 0x0012C4A0 ? 0x01C8 ?
0xB4 GL_BOOL dmp_FragmentLightSource[3].distanceAttenuationEnabled 0x0012C4A0 ? 0x01C8 ?
0xB5 GL_BOOL dmp_FragmentLightSource[4].distanceAttenuationEnabled 0x0012C4A0 ? 0x01C8 ?
0xB6 GL_BOOL dmp_FragmentLightSource[5].distanceAttenuationEnabled 0x0012C4A0 ? 0x01C8 ?
0xB7 GL_BOOL dmp_FragmentLightSource[6].distanceAttenuationEnabled 0x0012C4A0 ? 0x01C8 ?
0xB8 GL_BOOL dmp_FragmentLightSource[7].distanceAttenuationEnabled 0x0012C4A0 ? 0x01C8 ?
0xB9 GL_SAMPLER_1D dmp_FragmentLightSource[0].samplerDA 0x0012C578 0xA20+0*0x70+0x6C 0x01C8 ?
0xBA GL_SAMPLER_1D dmp_FragmentLightSource[1].samplerDA 0x0012C578 0xA20+1*0x70+0x6C 0x01C8 ?
0xBB GL_SAMPLER_1D dmp_FragmentLightSource[2].samplerDA 0x0012C578 0xA20+2*0x70+0x6C 0x01C8 ?
0xBC GL_SAMPLER_1D dmp_FragmentLightSource[3].samplerDA 0x0012C578 0xA20+3*0x70+0x6C 0x01C8 ?
0xBD GL_SAMPLER_1D dmp_FragmentLightSource[4].samplerDA 0x0012C578 0xA20+4*0x70+0x6C 0x01C8 ?
0xBE GL_SAMPLER_1D dmp_FragmentLightSource[5].samplerDA 0x0012C578 0xA20+5*0x70+0x6C 0x01C8 ?
0xBF GL_SAMPLER_1D dmp_FragmentLightSource[6].samplerDA 0x0012C578 0xA20+6*0x70+0x6C 0x01C8 ?
0xC0 GL_SAMPLER_1D dmp_FragmentLightSource[7].samplerDA 0x0012C578 0xA20+7*0x70+0x6C 0x01C8 ?
0xC1 GL_BOOL dmp_LightEnv.absLutInputD0 0x0012C5D8 ? 0x01D0 bit12 (1 = disable?)
0xC2 GL_BOOL dmp_LightEnv.absLutInputD1 0x0012C5D8 ? 0x01D0 bit13 (1 = disable?)
0xC3 GL_BOOL dmp_LightEnv.absLutInputSP 0x0012C5D8 ? 0x01D0 bit14 (1 = disable?)
0xC4 GL_BOOL dmp_LightEnv.absLutInputFR 0x0012C5D8 ? 0x01D0 bit15 (1 = disable?)
0xC5 GL_BOOL dmp_LightEnv.absLutInputRB 0x0012C5D8 ? 0x01D0 bit16 (1 = disable?)
0xC6 GL_BOOL dmp_LightEnv.absLutInputRG 0x0012C5D8 ? 0x01D0 bit17 (1 = disable?)
0xC7 GL_BOOL dmp_LightEnv.absLutInputRR 0x0012C5D8 ? 0x01D0 bit18 (1 = disable?)
0xC8 GL_INT dmp_LightEnv.lutInputD0 0x0012C6E8 ? 0x01D1 bit0-2
0xC9 GL_INT dmp_LightEnv.lutInputD1 0x0012C6E8 ? 0x01D1 bit4-6
0xCA GL_INT dmp_LightEnv.lutInputSP 0x0012C6E8 ? 0x01D1 bit8-10
0xCB GL_INT dmp_LightEnv.lutInputFR 0x0012C6E8 ? 0x01D1 bit12-14
0xCC GL_INT dmp_LightEnv.lutInputRB 0x0012C6E8 ? 0x01D1 bit16-18
0xCD GL_INT dmp_LightEnv.lutInputRG 0x0012C6E8 ? 0x01D1 bit20-22
0xCE GL_INT dmp_LightEnv.lutInputRR 0x0012C6E8 ? 0x01D1 bit24-26
0xCF GL_FLOAT dmp_LightEnv.lutScaleD0 0x00155404 ? ?
0xD0 GL_FLOAT dmp_LightEnv.lutScaleD1 0x00155404 ? ?
0xD1 GL_FLOAT dmp_LightEnv.lutScaleSP 0x00155404 ? ?
0xD2 GL_FLOAT dmp_LightEnv.lutScaleFR 0x00155404 ? ?
0xD3 GL_FLOAT dmp_LightEnv.lutScaleRB 0x00155404 ? ?
0xD4 GL_FLOAT dmp_LightEnv.lutScaleRG 0x00155404 ? ?
0xD5 GL_FLOAT dmp_LightEnv.lutScaleRR 0x00155404 ? ?
0xD6 GL_SAMPLER_1D dmp_FragmentMaterial.samplerD0 0x0012C7D0 ? ?
0xD7 GL_SAMPLER_1D dmp_FragmentMaterial.samplerD1 0x0012C7D0 ? ?
0xD8 GL_SAMPLER_1D dmp_FragmentMaterial.samplerFR 0x0012C7D0 ? ?
0xD9 GL_SAMPLER_1D dmp_FragmentMaterial.samplerRB 0x0012C7D0 ? ?
0xDA GL_SAMPLER_1D dmp_FragmentMaterial.samplerRG 0x0012C7D0 ? ?
0xDB GL_SAMPLER_1D dmp_FragmentMaterial.samplerRR 0x0012C7D0 ? ?
0xDC GL_INT dmp_LightEnv.shadowSelector 0x0012CE44 ? 0x01C3 bit24-25
0xDD GL_INT dmp_LightEnv.bumpSelector 0x0012CD88 ? 0x01C3 bit22-23
0xDE GL_INT dmp_LightEnv.bumpMode 0x0012D4B4 ? ?
0xDF GL_BOOL dmp_LightEnv.bumpRenorm 0x0012D8A0 ? ?
0xE0 GL_INT dmp_LightEnv.config 0x0012D5E4 ? ?
0xE1 GL_BOOL dmp_LightEnv.invertShadow 0x0012CF04 ? ?
0xE2 GL_BOOL dmp_LightEnv.shadowPrimary 0x0012CFD4 ? ?
0xE3 GL_BOOL dmp_LightEnv.shadowSecondary 0x0012D1B8 ? ?
0xE4 GL_BOOL dmp_LightEnv.shadowAlpha 0x0012D350 ? ?
0xE5 GL_INT dmp_LightEnv.fresnelSelector 0x0012D720 ? ?
0xE6 GL_BOOL dmp_LightEnv.clampHighlights 0x0012D9B0 ? ?
0xE7 GL_BOOL dmp_LightEnv.lutEnabledD0 0x0012DA80 ? ?
0xE8 GL_BOOL dmp_LightEnv.lutEnabledD1 0x0012DB58 ? ?
0xE9 GL_BOOL dmp_LightEnv.lutEnabledRefl 0x0012C83C ? ?
0xEA GL_INT dmp_TexEnv[0].combineRgb 0x0012DC2C ? 0xC2
0xEB GL_INT dmp_TexEnv[1].combineRgb 0x0012DC2C ? 0xCA
0xEC GL_INT dmp_TexEnv[2].combineRgb 0x0012DC2C ? 0xD2
0xED GL_INT dmp_TexEnv[3].combineRgb 0x0012DC2C ? 0xDA
0xEE GL_INT dmp_TexEnv[4].combineRgb 0x0012DC2C ? 0xF2
0xEF GL_INT dmp_TexEnv[5].combineRgb 0x0012DC2C ? 0xFA
0xF0 GL_INT dmp_TexEnv[0].combineAlpha 0x0012DD9C ? 0xC2
0xF1 GL_INT dmp_TexEnv[1].combineAlpha 0x0012DD9C ? 0xCA
0xF2 GL_INT dmp_TexEnv[2].combineAlpha 0x0012DD9C ? 0xD2
0xF3 GL_INT dmp_TexEnv[3].combineAlpha 0x0012DD9C ? 0xDA
0xF4 GL_INT dmp_TexEnv[4].combineAlpha 0x0012DD9C ? 0xF2
0xF5 GL_INT dmp_TexEnv[5].combineAlpha 0x0012DD9C ? 0xFA
0xF6 GL_INT_VEC3 dmp_TexEnv[0].srcRgb 0x0012DF08 ? 0xC0
0xF7 GL_INT_VEC3 dmp_TexEnv[1].srcRgb 0x0012DF08 ? 0xC8
0xF8 GL_INT_VEC3 dmp_TexEnv[2].srcRgb 0x0012DF08 ? 0xD0
0xF9 GL_INT_VEC3 dmp_TexEnv[3].srcRgb 0x0012DF08 ? 0xD8
0xFA GL_INT_VEC3 dmp_TexEnv[4].srcRgb 0x0012DF08 ? 0xF0
0xFB GL_INT_VEC3 dmp_TexEnv[5].srcRgb 0x0012DF08 ? 0xF8
0xFC GL_INT_VEC3 dmp_TexEnv[0].srcAlpha 0x0012E0FC ? 0xC0
0xFD GL_INT_VEC3 dmp_TexEnv[1].srcAlpha 0x0012E0FC ? 0xC8
0xFE GL_INT_VEC3 dmp_TexEnv[2].srcAlpha 0x0012E0FC ? 0xD0
0xFF GL_INT_VEC3 dmp_TexEnv[3].srcAlpha 0x0012E0FC ? 0xD8
0x100 GL_INT_VEC3 dmp_TexEnv[4].srcAlpha 0x0012E0FC ? 0xF0
0x101 GL_INT_VEC3 dmp_TexEnv[5].srcAlpha 0x0012E0FC ? 0xF8
0x102 GL_INT_VEC3 dmp_TexEnv[0].operandRgb 0x0012E2F0 ? 0xC1
0x103 GL_INT_VEC3 dmp_TexEnv[1].operandRgb 0x0012E2F0 ? 0xC9
0x104 GL_INT_VEC3 dmp_TexEnv[2].operandRgb 0x0012E2F0 ? 0xD1
0x105 GL_INT_VEC3 dmp_TexEnv[3].operandRgb 0x0012E2F0 ? 0xD9
0x106 GL_INT_VEC3 dmp_TexEnv[4].operandRgb 0x0012E2F0 ? 0xF1
0x107 GL_INT_VEC3 dmp_TexEnv[5].operandRgb 0x0012E2F0 ? 0xF9
0x108 GL_INT_VEC3 dmp_TexEnv[0].operandAlpha 0x0012E51C ? 0xC1
0x109 GL_INT_VEC3 dmp_TexEnv[1].operandAlpha 0x0012E51C ? 0xC9
0x10A GL_INT_VEC3 dmp_TexEnv[2].operandAlpha 0x0012E51C ? 0xD1
0x10B GL_INT_VEC3 dmp_TexEnv[3].operandAlpha 0x0012E51C ? 0xD9
0x10C GL_INT_VEC3 dmp_TexEnv[4].operandAlpha 0x0012E51C ? 0xF1
0x10D GL_INT_VEC3 dmp_TexEnv[5].operandAlpha 0x0012E51C ? 0xF9
0x10E GL_FLOAT dmp_TexEnv[0].scaleRgb 0x00155464 ? ?
0x10F GL_FLOAT dmp_TexEnv[1].scaleRgb 0x00155464 ? ?
0x110 GL_FLOAT dmp_TexEnv[2].scaleRgb 0x00155464 ? ?
0x111 GL_FLOAT dmp_TexEnv[3].scaleRgb 0x00155464 ? ?
0x112 GL_FLOAT dmp_TexEnv[4].scaleRgb 0x00155464 ? ?
0x113 GL_FLOAT dmp_TexEnv[5].scaleRgb 0x00155464 ? ?
0x114 GL_FLOAT dmp_TexEnv[0].scaleAlpha 0x00158EDC ? ?
0x115 GL_FLOAT dmp_TexEnv[1].scaleAlpha 0x00158EDC ? ?
0x116 GL_FLOAT dmp_TexEnv[2].scaleAlpha 0x00158EDC ? ?
0x117 GL_FLOAT dmp_TexEnv[3].scaleAlpha 0x00158EDC ? ?
0x118 GL_FLOAT dmp_TexEnv[4].scaleAlpha 0x00158EDC ? ?
0x119 GL_FLOAT dmp_TexEnv[5].scaleAlpha 0x00158EDC ? ?
0x11A GL_FLOAT_VEC4 dmp_TexEnv[0].constRgba 0x00158FF4 ? 0xC3
0x11B GL_FLOAT_VEC4 dmp_TexEnv[1].constRgba 0x00158FF4 ? 0xCB
0x11C GL_FLOAT_VEC4 dmp_TexEnv[2].constRgba 0x00158FF4 ? 0xD3
0x11D GL_FLOAT_VEC4 dmp_TexEnv[3].constRgba 0x00158FF4 ? 0xDB
0x11E GL_FLOAT_VEC4 dmp_TexEnv[4].constRgba 0x00158FF4 ? 0xF3
0x11F GL_FLOAT_VEC4 dmp_TexEnv[5].constRgba 0x00158FF4 ? 0xFB
0x120 GL_FLOAT_VEC4 dmp_TexEnv[0].bufferColor 0x001591C0 ? ?
0x121 GL_INT_VEC2 dmp_TexEnv[1].bufferInput 0x0012E6D0 ? ?
0x122 GL_INT_VEC2 dmp_TexEnv[2].bufferInput 0x0012E6D0 ? ?
0x123 GL_INT_VEC2 dmp_TexEnv[3].bufferInput 0x0012E6D0 ? ?
0x124 GL_INT_VEC2 dmp_TexEnv[4].bufferInput 0x0012E6D0 ? ?
0x125 GL_INT dmp_Fog.mode 0x0012E7F8 ? ?
0x126 GL_FLOAT_VEC3 dmp_Fog.color 0x00159338 ? ?
0x127 GL_BOOL dmp_Fog.zFlip 0x0012E9DC ? ?
0x128 GL_SAMPLER_1D dmp_Fog.sampler 0x0012EAA4 ? ?

On steeldiver's uniform handlers : R1 is a pointer to the current shader program object, R12 is a pointer to the data the uniform is being set to.